diff --git a/src/include/OpenImageIO/imagebuf.h b/src/include/OpenImageIO/imagebuf.h index ab4e1b4283..03d9b86d2f 100644 --- a/src/include/OpenImageIO/imagebuf.h +++ b/src/include/OpenImageIO/imagebuf.h @@ -1324,6 +1324,8 @@ class OIIO_API ImageBuf { return m_ib->deep_value_uint(m_x, m_y, m_z, c, s); } + bool localpixels() const { return m_localpixels; } + // Did we encounter an error while we iterated? bool has_error() const { return m_readerror; } @@ -1369,6 +1371,7 @@ class OIIO_API ImageBuf { OIIO_DASSERT(m_exists && m_valid); // precondition OIIO_DASSERT(valid(m_x, m_y, m_z)); // should be true by definition if (m_localpixels) { + OIIO_DASSERT(m_proxydata != nullptr); m_proxydata += m_pixel_stride; if (OIIO_UNLIKELY(m_x >= m_img_xend)) pos_xincr_local_past_end(); diff --git a/src/libOpenImageIO/imagebuf.cpp b/src/libOpenImageIO/imagebuf.cpp index 800a0a4045..ec227bfd2c 100644 --- a/src/libOpenImageIO/imagebuf.cpp +++ b/src/libOpenImageIO/imagebuf.cpp @@ -3110,17 +3110,17 @@ ImageBuf::IteratorBase::init_ib(WrapMode wrap, bool write) if (!m_localpixels && write) { const_cast(m_ib)->make_writable(true); OIIO_DASSERT(m_ib->storage() != IMAGECACHE); - m_tile = nullptr; - m_proxydata = nullptr; - } - m_img_xbegin = spec.x; - m_img_xend = spec.x + spec.width; - m_img_ybegin = spec.y; - m_img_yend = spec.y + spec.height; - m_img_zbegin = spec.z; - m_img_zend = spec.z + spec.depth; - m_nchannels = spec.nchannels; - // m_tilewidth = spec.tile_width; + m_tile = nullptr; + m_proxydata = nullptr; + m_localpixels = !m_deep; + } + m_img_xbegin = spec.x; + m_img_xend = spec.x + spec.width; + m_img_ybegin = spec.y; + m_img_yend = spec.y + spec.height; + m_img_zbegin = spec.z; + m_img_zend = spec.z + spec.depth; + m_nchannels = spec.nchannels; m_pixel_stride = m_ib->pixel_stride(); m_x = 1 << 31; m_y = 1 << 31; diff --git a/src/libOpenImageIO/imagebuf_test.cpp b/src/libOpenImageIO/imagebuf_test.cpp index 69bdcdefe1..6a9de04506 100644 --- a/src/libOpenImageIO/imagebuf_test.cpp +++ b/src/libOpenImageIO/imagebuf_test.cpp @@ -511,6 +511,35 @@ test_uncaught_error() +void +test_mutable_iterator_with_imagecache() +{ + // Make 4x4 1-channel float source image, value 0.5, write it. + char srcfilename[] = "tmp_f1.exr"; + ImageSpec fsize1(4, 4, 1, TypeFloat); + ImageBuf src(fsize1); + ImageBufAlgo::fill(src, 0.5f); + src.write(srcfilename); + + ImageBuf buf(srcfilename, 0, 0, ImageCache::create()); + // Using the cache, it should look tiled + OIIO_CHECK_EQUAL(buf.spec().tile_width, buf.spec().width); + + // Make a mutable iterator, even though it's an image file reference. + // Merely establishing the iterator ought to read the file and make the + // buffer writeable. + ImageBuf::Iterator it(buf); + OIIO_CHECK_EQUAL(buf.spec().tile_width, 0); // should look untiled + OIIO_CHECK_ASSERT(buf.localpixels()); // should look local + for (; !it.done(); ++it) + it[0] = 1.0f; + + ImageCache::create()->invalidate(ustring(srcfilename)); + Filesystem::remove(srcfilename); +} + + + int main(int /*argc*/, char* /*argv*/[]) { @@ -533,6 +562,7 @@ main(int /*argc*/, char* /*argv*/[]) "periodic"); iterator_wrap_test>(ImageBuf::WrapMirror, "mirror"); + test_mutable_iterator_with_imagecache(); ImageBuf_test_appbuffer(); ImageBuf_test_appbuffer_strided();