From 24de3d1f88107d4266e28816de7a457502fb2df4 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Sat, 20 Jun 2026 21:47:32 -0700 Subject: [PATCH] fix(iff): Fix allocation bug when reading 16 bit RGBA + float z We were allocating a temporary buffer big enough for the RGBA but neglecting the z. Only for the 16 bit case. Signed-off-by: Larry Gritz --- src/iff.imageio/iffinput.cpp | 21 +++++---------------- testsuite/iff/ref/out.txt | 5 +++++ testsuite/iff/run.py | 4 ++++ testsuite/iff/src/tiny_rgba16z.iff | Bin 0 -> 108 bytes 4 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 testsuite/iff/src/tiny_rgba16z.iff diff --git a/src/iff.imageio/iffinput.cpp b/src/iff.imageio/iffinput.cpp index e812d2b509..3686f538f5 100644 --- a/src/iff.imageio/iffinput.cpp +++ b/src/iff.imageio/iffinput.cpp @@ -785,10 +785,6 @@ IffInput::readimg() + (py * m_header.width + xmin) * m_header.pixel_bytes(); - std::vector scanline(tw - * m_header.rgba_count); - span sl_span(scanline); - int sx = 0; for (uint16_t px = xmin; px <= xmax; ++px, ++sx) { size_t offset = (sy * tw + sx) @@ -805,6 +801,9 @@ IffInput::readimg() = input.subspan(offset, m_header.rgba_channels_bytes()); + uint8_t* out_p = out_dy + + sx * m_header.pixel_bytes(); + for (int c = m_header.rgba_count - 1; c >= 0; --c) { uint16_t pixel; memcpy(&pixel, pixel_in.data() + c * 2, 2); @@ -813,20 +812,10 @@ IffInput::readimg() swap_endian(&pixel); } - if (sl_span.empty()) { - errorfmt( - "scanline span overflow at ({}, {})", - px, py); - return false; - } - - sl_span.front() = pixel; - sl_span = sl_span.subspan(1); + memcpy(out_p, &pixel, sizeof(pixel)); + out_p += sizeof(pixel); } } - - memcpy(out_dy, scanline.data(), - tw * m_header.pixel_bytes()); } } } else { diff --git a/testsuite/iff/ref/out.txt b/testsuite/iff/ref/out.txt index d990d44e2a..e0720171a8 100644 --- a/testsuite/iff/ref/out.txt +++ b/testsuite/iff/ref/out.txt @@ -2,3 +2,8 @@ Comparing "../oiio-images/grid.tif" and "gridscanline.iff" PASS Comparing "../oiio-images/grid.tif" and "gridtile.iff" PASS +Reading src/tiny_rgba16z.iff +src/tiny_rgba16z.iff : 1 x 1, 5 channel, uint16/uint16/uint16/uint16/float iff + SHA-1: 1B90DDB531A3ABD137C5050BA7A955AD4F711B4C + channel list: R (uint16), G (uint16), B (uint16), A (uint16), Z (float) + tile size: 1 x 1 diff --git a/testsuite/iff/run.py b/testsuite/iff/run.py index bf248d91eb..41ceabe185 100755 --- a/testsuite/iff/run.py +++ b/testsuite/iff/run.py @@ -8,3 +8,7 @@ command += diff_command (OIIO_TESTSUITE_IMAGEDIR+"/grid.tif", "gridscanline.iff") command += oiiotool (OIIO_TESTSUITE_IMAGEDIR+"/grid.tif --tile 64 64 -o gridtile.iff") command += diff_command (OIIO_TESTSUITE_IMAGEDIR+"/grid.tif", "gridtile.iff") + +# Regression test: verify reading of 16 bit rgba + float z (used to have a +# buffer overrun) +command += info_command("src//tiny_rgba16z.iff", hash=True) diff --git a/testsuite/iff/src/tiny_rgba16z.iff b/testsuite/iff/src/tiny_rgba16z.iff new file mode 100644 index 0000000000000000000000000000000000000000..48943093abb7decfeb2cc0d689481b6f88447ec5 GIT binary patch literal 108 zcmZ?s4>Dn3U`TQH^mPw$@^AsN6@Zu#j2Xc+JCFqN;lK@|#~{SXHz3H}$q^_a0F&fj Yz`cY00`rR~r%*Sb7!OR`{s0350Gulg4*&oF literal 0 HcmV?d00001