From b800f1980761d87837bd54805ea8bef58f74dfc1 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Mon, 14 Sep 2026 08:22:54 -0700 Subject: [PATCH 1/2] fix(tiff): handle CMYK and odd bit depths in the tiled reader Fixes 5315 This is essentially the same fix as PR 5296, but for the tile path (we had only fixed scanline). For CMYK (photometric=separated) files, readspec_photometric() drops m_spec.nchannels to 3 for the CMYK->RGB conversion while m_inputchannels stays 4, and the tiled path was unaware of the difference: - sub-8-bit and 9-15 bit samples were unpacked straight into the caller's 3-channel buffer, writing tile_pixels*4 values into room for tile_pixels*3 (heap buffer overflow write) - planarconfig=separate overflowed the same way in separate_to_contig - at 8 and 16 bits the tile was read into scratch and never copied out, so the caller got back uninitialized heap - 17-31 bit samples were never unpacked at all, likewise leaving the caller's buffer uninitialized Assisted-by: Claude Code / Claude Opus 5 Signed-off-by: Larry Gritz --- src/tiff.imageio/tiffinput.cpp | 77 +++++++++++++----- testsuite/tiff-misc/ref/out-libtiff403-b.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff403-c.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff403.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff409.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff410.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff430.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff470-b.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff470-c.txt | 6 ++ testsuite/tiff-misc/ref/out-libtiff470.txt | 6 ++ testsuite/tiff-misc/ref/out.txt | 6 ++ testsuite/tiff-misc/run.py | 11 +++ testsuite/tiff-misc/src/cmyk-1bit-strip.tif | Bin 0 -> 282 bytes testsuite/tiff-misc/src/cmyk-1bit-tiled.tif | Bin 0 -> 294 bytes .../tiff-misc/src/cmyk-4bit-planar-strip.tif | Bin 0 -> 698 bytes .../tiff-misc/src/cmyk-4bit-planar-tiled.tif | Bin 0 -> 710 bytes testsuite/tiff-misc/src/rgb-24bit-strip.tif | Bin 0 -> 2444 bytes testsuite/tiff-misc/src/rgb-24bit-tiled.tif | Bin 0 -> 2456 bytes 18 files changed, 126 insertions(+), 22 deletions(-) create mode 100644 testsuite/tiff-misc/src/cmyk-1bit-strip.tif create mode 100644 testsuite/tiff-misc/src/cmyk-1bit-tiled.tif create mode 100644 testsuite/tiff-misc/src/cmyk-4bit-planar-strip.tif create mode 100644 testsuite/tiff-misc/src/cmyk-4bit-planar-tiled.tif create mode 100644 testsuite/tiff-misc/src/rgb-24bit-strip.tif create mode 100644 testsuite/tiff-misc/src/rgb-24bit-tiled.tif diff --git a/src/tiff.imageio/tiffinput.cpp b/src/tiff.imageio/tiffinput.cpp index 14f295abdc..9ef753ea43 100644 --- a/src/tiff.imageio/tiffinput.cpp +++ b/src/tiff.imageio/tiffinput.cpp @@ -2461,13 +2461,19 @@ TIFFInput::read_native_tile_locked(int subimage, int miplevel, int x, int y, span_cast(data)); } else { // Not palette - imagesize_t plane_bytes = m_spec.tile_pixels() * m_spec.format.size(); + imagesize_t plane_bytes = tile_pixels * m_spec.format.size(); int planes = m_separate ? m_inputchannels : 1; - std::vector scratch2(m_separate ? plane_bytes * planes - : 0); - // Where to read? Directly into user data if no channel shuffling - // or bit shifting is needed, otherwise into scratch space. - unsigned char* readbuf = (no_bit_convert && !m_separate + imagesize_t input_bytes = plane_bytes * m_inputchannels; + // CMYK->RGB consumes more channels than it produces, so it can't be + // done in place in the user's buffer. + bool cmyk_convert = (m_photometric == PHOTOMETRIC_SEPARATED + && !m_raw_color); + std::vector scratch2( + (m_separate || cmyk_convert) ? input_bytes : 0); + // Where to read? Directly into user data if no channel shuffling, + // bit shifting, or CMYK conversion is needed, otherwise into + // scratch space. + unsigned char* readbuf = (no_bit_convert && !m_separate && !cmyk_convert && m_inputchannels == m_spec.nchannels) ? (unsigned char*)data.data() : m_scratch.data(); @@ -2479,33 +2485,60 @@ TIFFInput::read_native_tile_locked(int subimage, int miplevel, int x, int y, errorfmt("{}", oiio_tiff_last_error()); return false; } - if (m_bitspersample < 8) { + // Handle less-than-full bit depths + bool use_scratch_dest = m_separate || cmyk_convert; + int outbits = 0; + if (m_bitspersample < 8) + outbits = 8; + else if (m_bitspersample > 8 && m_bitspersample < 16) + outbits = 16; + else if (m_bitspersample > 16 && m_bitspersample < 32) + outbits = 32; + if (outbits) { // m_scratch now holds nvals n-bit values, contig or separate - std::swap(m_scratch, scratch2); + scratch2.resize(input_bytes); + m_scratch.swap(scratch2); for (int c = 0; c < planes; ++c) /* planes==1 for contig */ bit_convert(m_separate ? tile_pixels : nvals, &scratch2[plane_bytes * c], m_bitspersample, - m_separate + use_scratch_dest ? m_scratch.data() + plane_bytes * c : (unsigned char*)data.data() + plane_bytes * c, - 8); - } else if (m_bitspersample > 8 && m_bitspersample < 16) { - // m_scratch now holds nvals n-bit values, contig or separate - std::swap(m_scratch, scratch2); - for (int c = 0; c < planes; ++c) /* planes==1 for contig */ - bit_convert(m_separate ? tile_pixels : nvals, - &scratch2[plane_bytes * c], m_bitspersample, - m_separate - ? m_scratch.data() + plane_bytes * c - : (unsigned char*)data.data() + plane_bytes * c, - 16); + outbits); } if (m_separate) { // Convert from separate (RRRGGGBBB) to contiguous (RGBRGBRGB). // We know the data is in m_scratch at this point, so // contiguize it into the user data area. - separate_to_contig(planes, tile_pixels, - as_bytes(make_span(m_scratch)), data); + if (cmyk_convert) { + // CMYK->RGB means we need temp storage. + scratch2.resize(input_bytes); + separate_to_contig(planes, tile_pixels, + as_bytes(make_span(m_scratch)), + as_writable_bytes(make_span(scratch2))); + m_scratch.swap(scratch2); + } else { + // If no CMYK->RGB conversion is necessary, we can "separate" + // straight into the data area. + separate_to_contig(planes, tile_pixels, + as_bytes(make_span(m_scratch)), data); + } + } + // Handle CMYK + if (cmyk_convert) { + // The CMYK will be in m_scratch. + if (m_spec.format == TypeDesc::UINT8) { + cmyk_to_rgb(int(tile_pixels), (unsigned char*)m_scratch.data(), + m_inputchannels, (unsigned char*)data.data(), + m_spec.nchannels); + } else if (m_spec.format == TypeDesc::UINT16) { + cmyk_to_rgb(int(tile_pixels), (unsigned short*)m_scratch.data(), + m_inputchannels, (unsigned short*)data.data(), + m_spec.nchannels); + } else { + errorfmt("CMYK only supported for UINT8, UINT16"); + return false; + } } } diff --git a/testsuite/tiff-misc/ref/out-libtiff403-b.txt b/testsuite/tiff-misc/ref/out-libtiff403-b.txt index 32c82dcbbc..79f8a7c865 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403-b.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403-b.txt @@ -64,5 +64,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff403-c.txt b/testsuite/tiff-misc/ref/out-libtiff403-c.txt index 396aebf181..d160ecf3af 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403-c.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403-c.txt @@ -64,5 +64,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff403.txt b/testsuite/tiff-misc/ref/out-libtiff403.txt index ac1ce73af1..321822f1ad 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403.txt @@ -64,5 +64,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff409.txt b/testsuite/tiff-misc/ref/out-libtiff409.txt index 344efd57ff..04e955e589 100644 --- a/testsuite/tiff-misc/ref/out-libtiff409.txt +++ b/testsuite/tiff-misc/ref/out-libtiff409.txt @@ -64,5 +64,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff410.txt b/testsuite/tiff-misc/ref/out-libtiff410.txt index a5efaa756a..b2be4305d9 100644 --- a/testsuite/tiff-misc/ref/out-libtiff410.txt +++ b/testsuite/tiff-misc/ref/out-libtiff410.txt @@ -64,5 +64,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff430.txt b/testsuite/tiff-misc/ref/out-libtiff430.txt index ec76c79fef..0baf52ee51 100644 --- a/testsuite/tiff-misc/ref/out-libtiff430.txt +++ b/testsuite/tiff-misc/ref/out-libtiff430.txt @@ -79,5 +79,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff470-b.txt b/testsuite/tiff-misc/ref/out-libtiff470-b.txt index 32bac79d4f..f6c696a93b 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470-b.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470-b.txt @@ -79,5 +79,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff470-c.txt b/testsuite/tiff-misc/ref/out-libtiff470-c.txt index 1be4fe8ab2..5fce6e7cff 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470-c.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470-c.txt @@ -79,5 +79,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out-libtiff470.txt b/testsuite/tiff-misc/ref/out-libtiff470.txt index 2eb1295620..752413f396 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470.txt @@ -79,5 +79,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/ref/out.txt b/testsuite/tiff-misc/ref/out.txt index ec15e58273..f947b897be 100644 --- a/testsuite/tiff-misc/ref/out.txt +++ b/testsuite/tiff-misc/ref/out.txt @@ -64,5 +64,11 @@ src/crash-cmyk-1bit.tif : 73 x 43, 3 channel, uint1 tiff oiiotool ERROR: read : "src/crash-rawstrip-offset-past-eof.tif": TIFFReadRawStrip failed reading line y=0: Read error at scanline 4294967295; got 0 bytes, expected 28 Full command line was: > oiiotool --oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr +Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" +PASS +Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" +PASS +Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" +PASS Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/run.py b/testsuite/tiff-misc/run.py index 4dd434f37c..2efd24d4a8 100755 --- a/testsuite/tiff-misc/run.py +++ b/testsuite/tiff-misc/run.py @@ -45,4 +45,15 @@ # last so its output appends at the tail of every libtiff-version ref variant. command += oiiotool ("--oiioattrib try_all_readers 0 src/crash-rawstrip-offset-past-eof.tif -o out.exr", failureok = True) +# Regression test: the tiled reader did not do the channel shuffling and bit +# unpacking that the strip reader does. Sub-8-bit CMYK tiles unpacked all 4 +# input channels straight into the 3-channel RGB buffer and overflowed it, +# "separate" CMYK tiles overflowed in separate_to_contig, and 17-31 bit tiles +# were never unpacked at all, leaving the caller's buffer uninitialized. Each +# pair below holds identical pixels, stored tiled and in strips, so the two +# must decode the same. Also placed at the end so the output appends to the +# tail of every libtiff-version ref variant. +for base in [ "cmyk-1bit", "cmyk-4bit-planar", "rgb-24bit" ] : + command += oiiotool ("src/{0}-tiled.tif src/{0}-strip.tif --diff".format(base)) + outputs = [ "check1.tif", "out.txt" ] diff --git a/testsuite/tiff-misc/src/cmyk-1bit-strip.tif b/testsuite/tiff-misc/src/cmyk-1bit-strip.tif new file mode 100644 index 0000000000000000000000000000000000000000..00a6d45d9880bc77d5c349c27d92c8458b509ef8 GIT binary patch literal 282 zcmebD)MDUZU|`^8U|?inU<9%RfS3`9&BVyezycJT1jNihHb@N!vq9OcK(-)M{VX6` m6ePWSKJ|vQ-x#vJc%MvJv}0dO;dMdO;eX#xX;U ptAZN$5Nccm*fO97uw_6Ev@(}if0625V$CJiU$AhXwz%#{i061K5@D$_YnBzR;aKg#YCh>9dEbqwUvGWkmaeIF<&uRNy z{wHH+`OU1o13yrj<9GNKa{vFy$vGaLnc&y13GmLskO%IG@XdzP56>p>Ukg_V-pvuX z0q!V#TOoKeJPG)>Md&to(+KQ<@SX7G5ZoD&d*Cl3v>T%LBTzwjPsAQVu#U(+h(C%@ z3(@_Ncmm-rVh17lG$MV(4@K%ZM8_d<1kx|UF$JzK;9C+yQ{ny^{$=2t2G4g0EDzUo zcz;B2CAeq6_X|Q}g6;nu;nf8@@E0O$33l*bMAsGU@DO6_3wFef_=bWV^&zpbV8?<; zZYJ3A2vS=Lb|Q}SHiDf@A+x<;r?SZI1m|4v90~tRaLo(vF$la0_X6-8hu|CVEDZmN z2)zyOVhEg!@Oy$CJPnZ#1v_*mqMrzM_#DJO7wpJ+h<_#6(F>6HRKLtB=6|(;bcKRCR9dJEts@;#7YR{9V+WU;D_C0T^iLI)Mt*VKw zs)-$&2g#!aJ3c>BlLR}l5Yi_Ic5+cXAJNr6{ zqk^4#3#GZO5USQfs9Fo5YAuASwGgV-La15`p=vFJsS+XBrS1-rgATDO4MjqT9BeXz^O4N=wH5LL|$QPtcK z7E)VWHiU)Lm$E_{%UU7L6|9if%7R`074208yYUA)Yk=6zztLTLu*;~0P_-69)!YzO z%?)88^%rDASV-e#E2R0F71Das3TeM1*v(VWd0((wr=$B3h}}L5y-x?bj9Lg)Yavw4 z4N=wH5EjzhQ8t8yw05yV+PhmJoxQA(?!JQEZliaAV0U^LJ{ZLAj-Y?oV3$z~p=vFJ zs<|Pmnj6AG+K>%lAswd`()Cy&J--z)91`r#UFb&zyL&H25+HW(0gR>xyNp^0Rcj$s y%?(l2+z=MhnIap)Lb_9}klr*aWO%w2(w`yNz3~{CDcHjkFggpw?oY(H+5Z7t^}{d# literal 0 HcmV?d00001 diff --git a/testsuite/tiff-misc/src/rgb-24bit-tiled.tif b/testsuite/tiff-misc/src/rgb-24bit-tiled.tif new file mode 100644 index 0000000000000000000000000000000000000000..469f544f2e691a12990c495e1a8e5ca7f63ab4ee GIT binary patch literal 2456 zcmb7^WpJEj6h@z9-QC?c+Z1=F0tAObp}4!dyE{c%3WY+UP$=&1?(XjHuFvJ(ANjk< zd^2x$zU-VibKYlUqz5m605IUh08ddq1EbD^0}eR&*;GCbp5+~R+;$%1Ib~;guQ=+R zadwvP96#zj!M=YwKc8r4`1l8Zvj6|e$uSA;IpDuJC&M!rgKoH{z&j5PAKaV3cP*Sj zcs7Us2Dl>dZiT?jaL3`>7Qx%#Nx{DZLU+QOMPO%y?}4v?;BJWA4}Te|MC;Q0}OmEf8U?=J|B2)6HcgjN@9|6d5NCD?&~5m{HTLxYH}FW6xhVjBu}#EbaG zf*lPYv6*1U!bol@*zp)r+X!|diS+h@oy;J!6CCrweI$G@!MPwj$H4z8T#LYaJOXdP zy*PX)A^0{tOTm9CLhlK7;0%O66zt$xhq-aT(HCEA@-GEM=n78TfvTAgv1Ym z9lHd{p9MR98B)IqcH#=8{}k-xRml7!*r{uf8-Vj+Q|)@pRJ)%v)t+ZewfA{bO>9+7 zY*kHcRZZ;Z0!SP!*s+C?JWjCViy?KQU?-MD`V_%VE`!YJf}L6(*{On^9*5jHf}NR& z{B$dXs#dN?O;$+uRx2cT zhZT~)8^q4;io$&$c5V+89|W=Ud!zJ-6++co2vut#RIPsTSh^+4>r6QvD6?1Bg7jX><8AC*n}yNp^0Rcj$st%Xpv7Lt3{ z3dw(9g%m!vLW-YRA*C-t?85mde*Na+wOqNmwD(v=vgz33mB$)Qf^$c?yjRh+Taa&3b>AksG3_xgn~W8=|VY zAuObPscZ-fsa$S_RIju`YFAq!_3H$?x&<0H3U+O4G;aa1>)WAqdw-Xa8=|VYA*z}i zqN=$eETp=$YzPafEoX()SF}PJ6ReQt%7R_{6|GeTyZ#5-Yk=5|ztLH{zssnFP_-69 z)!YzO%?)88wHIVVSV;Y4E2Qz771Dgu3TeF~*p1WBeqXSgXQJ~Fh}}9H-B0_wj9Lg) zYavw44N=wH5EjzdQ8t8yG+S8LfQ^1q~o?ix;`spC@9$NyU>dWcIRG Date: Sun, 20 Sep 2026 22:17:25 -0700 Subject: [PATCH 2/2] testing(tiff): cover CMYK tiles at native 8/16 bits and 9-15 bit samples The tiled/strip regression matrix was missing two of the four bugs the previous commit fixed: CMYK at native 8 and 16 bits (read into scratch and never copied out) and 9-15 bit samples. Adds cmyk-8bit, cmyk-12bit and cmyk-16bit pairs. All three fail against the pre-fix reader. Assisted-by: Claude Code / Claude Opus 5 Signed-off-by: Larry Gritz --- testsuite/tiff-misc/ref/out-libtiff403-b.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff403-c.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff403.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff409.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff410.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff430.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff470-b.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff470-c.txt | 6 ++++++ testsuite/tiff-misc/ref/out-libtiff470.txt | 6 ++++++ testsuite/tiff-misc/ref/out.txt | 6 ++++++ testsuite/tiff-misc/run.py | 17 +++++++++++------ testsuite/tiff-misc/src/cmyk-12bit-strip.tif | Bin 0 -> 1690 bytes testsuite/tiff-misc/src/cmyk-12bit-tiled.tif | Bin 0 -> 1702 bytes testsuite/tiff-misc/src/cmyk-16bit-strip.tif | Bin 0 -> 2202 bytes testsuite/tiff-misc/src/cmyk-16bit-tiled.tif | Bin 0 -> 2214 bytes testsuite/tiff-misc/src/cmyk-8bit-strip.tif | Bin 0 -> 1178 bytes testsuite/tiff-misc/src/cmyk-8bit-tiled.tif | Bin 0 -> 1190 bytes 17 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 testsuite/tiff-misc/src/cmyk-12bit-strip.tif create mode 100644 testsuite/tiff-misc/src/cmyk-12bit-tiled.tif create mode 100644 testsuite/tiff-misc/src/cmyk-16bit-strip.tif create mode 100644 testsuite/tiff-misc/src/cmyk-16bit-tiled.tif create mode 100644 testsuite/tiff-misc/src/cmyk-8bit-strip.tif create mode 100644 testsuite/tiff-misc/src/cmyk-8bit-tiled.tif diff --git a/testsuite/tiff-misc/ref/out-libtiff403-b.txt b/testsuite/tiff-misc/ref/out-libtiff403-b.txt index 79f8a7c865..27ac1c16a6 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403-b.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403-b.txt @@ -68,6 +68,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff403-c.txt b/testsuite/tiff-misc/ref/out-libtiff403-c.txt index d160ecf3af..afb71b1d0f 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403-c.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403-c.txt @@ -68,6 +68,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff403.txt b/testsuite/tiff-misc/ref/out-libtiff403.txt index 321822f1ad..f8b67eedb2 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403.txt @@ -68,6 +68,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff409.txt b/testsuite/tiff-misc/ref/out-libtiff409.txt index 04e955e589..1d640a4630 100644 --- a/testsuite/tiff-misc/ref/out-libtiff409.txt +++ b/testsuite/tiff-misc/ref/out-libtiff409.txt @@ -68,6 +68,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff410.txt b/testsuite/tiff-misc/ref/out-libtiff410.txt index b2be4305d9..17499fb717 100644 --- a/testsuite/tiff-misc/ref/out-libtiff410.txt +++ b/testsuite/tiff-misc/ref/out-libtiff410.txt @@ -68,6 +68,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff430.txt b/testsuite/tiff-misc/ref/out-libtiff430.txt index 0baf52ee51..32495c8f52 100644 --- a/testsuite/tiff-misc/ref/out-libtiff430.txt +++ b/testsuite/tiff-misc/ref/out-libtiff430.txt @@ -83,6 +83,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff470-b.txt b/testsuite/tiff-misc/ref/out-libtiff470-b.txt index f6c696a93b..d1e4e65ec4 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470-b.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470-b.txt @@ -83,6 +83,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff470-c.txt b/testsuite/tiff-misc/ref/out-libtiff470-c.txt index 5fce6e7cff..19548ca002 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470-c.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470-c.txt @@ -83,6 +83,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out-libtiff470.txt b/testsuite/tiff-misc/ref/out-libtiff470.txt index 752413f396..938d0ba37e 100644 --- a/testsuite/tiff-misc/ref/out-libtiff470.txt +++ b/testsuite/tiff-misc/ref/out-libtiff470.txt @@ -83,6 +83,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/ref/out.txt b/testsuite/tiff-misc/ref/out.txt index f947b897be..10c06fddc0 100644 --- a/testsuite/tiff-misc/ref/out.txt +++ b/testsuite/tiff-misc/ref/out.txt @@ -68,6 +68,12 @@ Computing diff of "src/cmyk-1bit-tiled.tif" vs "src/cmyk-1bit-strip.tif" PASS Computing diff of "src/cmyk-4bit-planar-tiled.tif" vs "src/cmyk-4bit-planar-strip.tif" PASS +Computing diff of "src/cmyk-8bit-tiled.tif" vs "src/cmyk-8bit-strip.tif" +PASS +Computing diff of "src/cmyk-12bit-tiled.tif" vs "src/cmyk-12bit-strip.tif" +PASS +Computing diff of "src/cmyk-16bit-tiled.tif" vs "src/cmyk-16bit-strip.tif" +PASS Computing diff of "src/rgb-24bit-tiled.tif" vs "src/rgb-24bit-strip.tif" PASS Comparing "check1.tif" and "ref/check1.tif" diff --git a/testsuite/tiff-misc/run.py b/testsuite/tiff-misc/run.py index 2efd24d4a8..4e5ea550ba 100755 --- a/testsuite/tiff-misc/run.py +++ b/testsuite/tiff-misc/run.py @@ -48,12 +48,17 @@ # Regression test: the tiled reader did not do the channel shuffling and bit # unpacking that the strip reader does. Sub-8-bit CMYK tiles unpacked all 4 # input channels straight into the 3-channel RGB buffer and overflowed it, -# "separate" CMYK tiles overflowed in separate_to_contig, and 17-31 bit tiles -# were never unpacked at all, leaving the caller's buffer uninitialized. Each -# pair below holds identical pixels, stored tiled and in strips, so the two -# must decode the same. Also placed at the end so the output appends to the -# tail of every libtiff-version ref variant. -for base in [ "cmyk-1bit", "cmyk-4bit-planar", "rgb-24bit" ] : +# "separate" CMYK tiles overflowed in separate_to_contig, CMYK tiles at native +# 8 and 16 bits were read into scratch and never copied out, and 17-31 bit +# tiles were never unpacked at all, both leaving the caller's buffer +# uninitialized. Each pair below holds identical pixels, stored tiled and in +# strips, so the two must decode the same. Between them they cover every +# unpacking case the tiled reader has: <8, 9-15, 17-31, and native 8 and 16 +# bits, contig and "separate", with and without CMYK->RGB conversion. Also +# placed at the end so the output appends to the tail of every +# libtiff-version ref variant. +for base in [ "cmyk-1bit", "cmyk-4bit-planar", "cmyk-8bit", "cmyk-12bit", + "cmyk-16bit", "rgb-24bit" ] : command += oiiotool ("src/{0}-tiled.tif src/{0}-strip.tif --diff".format(base)) outputs = [ "check1.tif", "out.txt" ] diff --git a/testsuite/tiff-misc/src/cmyk-12bit-strip.tif b/testsuite/tiff-misc/src/cmyk-12bit-strip.tif new file mode 100644 index 0000000000000000000000000000000000000000..843a917a5a85f32a5a123158f86d1b396ca968f7 GIT binary patch literal 1690 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 Dd*sr3 literal 0 HcmV?d00001 diff --git a/testsuite/tiff-misc/src/cmyk-16bit-strip.tif b/testsuite/tiff-misc/src/cmyk-16bit-strip.tif new file mode 100644 index 0000000000000000000000000000000000000000..1a22c66235bb61c3a659a1173fe59a5270ec0d5f GIT binary patch literal 2202 zcmYjSL2DFA7_DfGQKP0pbVm&#TLv7$3Zo@Dhk&CLVZ>ENuwc;3uq(v~B7Iq^_p%Hk zY#kOH_8?Q@VJ^a0r#XlO>JrdH4s{5gycFooQ{g|T?Z@WeH#B_obob+Z-+Qla-P$1Y zgpgx|%*>LRs#~nCnIHNCGY83Rb?@KmI#~612G`tvf2iu|{`0S@{?z_`ymNZL$2Wi4 ze+FvorxoMWul zTVD2_v3~#b=@1wzidrp3#>(>S*_0R?3|3ZhX3Ut?RZJRlrj&E=WsGy+@~Rq*BS(bb zyxCk>kdpIO>*PtLIB&O?mbB))(>Zm@7|y%hTFqL{d%bh#oa4OTUtRT{^P>3q=MXqA z%k}jbIUfuzTu6y?V>UK&=6pE3co7@Mekm0Kb7o8k@a0?x;EJkRt;Iztg=n{zmz5Ht z)2Y?87NXl-SusY4UTycjD2jUBdm+m5mtR5I-N6Tl#;UBU0u~$%3kmMd1IvP_v>|Q zr7Vhz7oC%`EH7X7UdqAX+O-g*G-h)%Mk$BG8#hvtax~i7%2~?s`1Wlm8hWNwDd>tZ zrLbSlmBO5bPzrpdR0_DNs$Oq>U2CQK{f!M{lq!lw!&;@v^6FLRlo|{+H@#QNn4334 zP--}Aw_{XlG`f2?C8fsW`}cEJYBG8708WCBDAgKzW=w17igT^8Um>){oTbzne3jA~ zxVoyMxOB-Ft;@36v{viE;QDpvv^HjI%X_Vd!#j6E(0Vkwe?La8$K!_&Q_^}e`R%uy zwVqBNKZb+hUrLREkDyBE87hIUur=%#Q^cIX3VeYATvOFx&}vzWuHAOdnBlO~@!pux zsM`&}nDMyRi_w_Lq~A};nCY}AayDjr8wp@7a)VN9;a|qAg^xJ57J3%KTIfnjYq4LY zti_zQwibMi0dl)-s~QgP-E+>`(dfYg@2wq=fB!uMYbTQ@PhzxoI{o91l&sy}{_C%t zt=-xA`)?!`@`_UDkQhT3XRSkku8au*`?WR% z%-OjRz}Nc_fE%jX*%=OF3}JWo_3M;E*xQ>-at`71=XdXLGT>aGG)CkzV=*EpIgb%} zB?Odn<%*Os!oNzz2p?%3BlK)cjL?;}F=D^Y#fUk3A0zmN5F>D7ReO7H-=-Af=g;ro z=N#jgFCRYOM8bJQX-YU37)uHH%sG_0u^~iC$SWyRLT)IP68x)mO7M{}DM8QHrUYF% zmlF2teM*>f2q}SYj41&(RrTe|$B#Lu^zGZHPdEwT0!nkndBhl;vAW86&d6sWaz;){ znKSZAshp7;TIUS^8j~}8WNpsSvvWB^SKjB0{f3Y;<{V?r;G0s;z|B>C|Niysf2A>E AG5`Po literal 0 HcmV?d00001 diff --git a/testsuite/tiff-misc/src/cmyk-16bit-tiled.tif b/testsuite/tiff-misc/src/cmyk-16bit-tiled.tif new file mode 100644 index 0000000000000000000000000000000000000000..1d81c3f1f97d0c1d5fb462e2b6a2534b4a59f1d3 GIT binary patch literal 2214 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 DJDakw literal 0 HcmV?d00001 diff --git a/testsuite/tiff-misc/src/cmyk-8bit-tiled.tif b/testsuite/tiff-misc/src/cmyk-8bit-tiled.tif new file mode 100644 index 0000000000000000000000000000000000000000..460735cd864e865fc31760aeb6126c1dec7e2788 GIT binary patch literal 1190 zcmYk$ziU)U902fdej4MNWI~iZ4PhMvF2TT_Bf3SvH8&TYc*;A-z#}#fJ%%TUyhi3- zBM%XrLhx0xBXVrxu{YHgA`8oMjD6w6$91cxYPL^&JoBehrYH0N9Or*N z@$r&hPW6tz#+Uv7j*Z5~h@B z0HLJ`jOvpFHKr(PPBYY+;ix?;Q0I(9(VRl@S&fo;gVJ*rWi^NL^Bxro0hNn@mjL1V zB*u+tf}67xx8@jb&vV?V2^=j*94{%HENh&u7@S?SIIlZgT=KYF4Op%LsRJU7DNLHP zgtX35(ylSmS>z;I79_qPNm5rNy{t*LW=MX;l49MF@|q`dBamtnXaf*!PGj1dBeY$k zw6nx$w8Cjz7c^OwG;JuFt!tV$4K1!)TDBaOH$AP|fp)imH36~K3})?l!a9qTMJtTO zKX8_;36@@!ENd#3Z)#TDFs!_7ncQ-$y6ahYC$Qdq;4MJBJ&Sp#MtHPLd0b~aS>rri z7d+dLJZ~vp+|s<~A9~)~4ZObxq76uN&R`KO5D{OXB3Wf3y~;(lAw>S8 z6h&K!@{SgA$B62I72RDYdXK#5KMrE>6l4dGjOMV6mxxU2RHh9kvnH2$OUR-vW!X_u zMp{;}k=?|~Ug~5&^Ky^}IV?a$fK+@It7Ms|^fFc1I#c;3SH&%%$~#iYNU7>qt-5v!>@-{beTbSyBG~Gm*-V<&5&y5-UZq4wu zGoyFj?0*R6;1k#skj-k?=5=C=b!y8NvvP~uDiXH4D{U`Tw*O4qL1FChwY8(l+5L~+ z9`u7f{0uGwXAN?Kt z_iqpiK%rd3L9UTdZPL))Vxf1RhyI=jgQqeK3l&Chbl87y!oepS4nMna^wo#&-$MBJ GpZ@@HzO$|X literal 0 HcmV?d00001