diff --git a/src/tiff.imageio/tiffinput.cpp b/src/tiff.imageio/tiffinput.cpp index f072135300..62bf5398d1 100644 --- a/src/tiff.imageio/tiffinput.cpp +++ b/src/tiff.imageio/tiffinput.cpp @@ -396,7 +396,7 @@ class TIFFInput final : public ImageInput { } } - void uncompress_one_strip(void* compressed_buf, unsigned long csize, + void uncompress_one_strip(const void* compressed_buf, unsigned long csize, void* uncompressed_buf, size_t strip_bytes, int channels, int width, int height, bool* ok) { @@ -1120,7 +1120,13 @@ TIFFInput::readspec(bool read_meta) } } } - if (m_spec.alpha_channel >= 0) { + if (m_photometric == PHOTOMETRIC_SEPARATED) + m_spec.alpha_channel = -1; // ignore alpha in CMYK + if (m_spec.alpha_channel >= 0 + && m_spec.alpha_channel < m_spec.nchannels) { + while (m_spec.channelnames.size() < size_t(m_spec.nchannels)) + m_spec.channelnames.push_back( + Strutil::fmt::format("channel{}", m_spec.nchannels)); m_spec.channelnames[m_spec.alpha_channel] = "A"; // Special case: "R","A" should really be named "Y","A", since // the first channel is luminance, not red. @@ -1972,8 +1978,8 @@ TIFFInput::read_native_tile(int subimage, int miplevel, int x, int y, int z, // We punted and used the RGBA image interface // libtiff has a call to read just one tile as RGBA. So that's all // we need to do, not buffer the whole image. - m_rgbadata.resize(m_spec.tile_pixels() * 4); - bool ok = TIFFReadRGBATile(m_tif, x, y, &m_rgbadata[0]); + m_rgbadata.resize(m_spec.tile_pixels()); + bool ok = TIFFReadRGBATile(m_tif, x, y, m_rgbadata.data()); if (!ok) { errorf("Unknown error trying to read TIFF as RGBA"); return false; @@ -2000,11 +2006,11 @@ TIFFInput::read_native_tile(int subimage, int miplevel, int x, int y, int z, } imagesize_t tile_pixels = m_spec.tile_pixels(); - imagesize_t nvals = tile_pixels * m_spec.nchannels; + imagesize_t nvals = tile_pixels * m_inputchannels; if (m_photometric == PHOTOMETRIC_PALETTE && m_bitspersample > 8) m_scratch.resize(nvals * 2); // special case for 16 bit palette else - m_scratch.resize(m_spec.tile_bytes()); + m_scratch.resize(nvals * m_spec.format.size()); bool no_bit_convert = (m_bitspersample == 8 || m_bitspersample == 16 || m_bitspersample == 32); if (m_photometric == PHOTOMETRIC_PALETTE) { @@ -2021,7 +2027,7 @@ TIFFInput::read_native_tile(int subimage, int miplevel, int x, int y, int z, } else { // Not palette imagesize_t plane_bytes = m_spec.tile_pixels() * m_spec.format.size(); - int planes = m_separate ? m_spec.nchannels : 1; + int planes = m_separate ? m_inputchannels : 1; std::vector scratch2(m_separate ? m_spec.tile_bytes() : 0); // Where to read? Directly into user data if no channel shuffling diff --git a/testsuite/tiff-misc/crash-1633.tif b/testsuite/tiff-misc/crash-1633.tif new file mode 100644 index 0000000000..ecd2085c1b Binary files /dev/null and b/testsuite/tiff-misc/crash-1633.tif differ diff --git a/testsuite/tiff-misc/crash-1643.tif b/testsuite/tiff-misc/crash-1643.tif new file mode 100644 index 0000000000..eaddca59ca Binary files /dev/null and b/testsuite/tiff-misc/crash-1643.tif differ diff --git a/testsuite/tiff-misc/ref/out-libtiff403.txt b/testsuite/tiff-misc/ref/out-libtiff403.txt index 0b853126dc..d72197c527 100644 --- a/testsuite/tiff-misc/ref/out-libtiff403.txt +++ b/testsuite/tiff-misc/ref/out-libtiff403.txt @@ -17,5 +17,11 @@ PASS oiiotool ERROR: read : "src/corrupt1.tif": Could not open file: IO error during reading of "StripOffsets" Full command line was: > oiiotool -colorconfig ../common/OpenColorIO/nuke-default/config.ocio --oiioattrib try_all_readers 0 --info -v src/corrupt1.tif +oiiotool ERROR: read : File does not exist: "src/crash-1633.tif" +Full command line was: +> oiiotool -colorconfig ../common/OpenColorIO/nuke-default/config.ocio --oiioattrib try_all_readers 0 --info -v src/crash-1633.tif +oiiotool ERROR: read : File does not exist: "src/crash-1643.tif" +Full command line was: +> oiiotool -colorconfig ../common/OpenColorIO/nuke-default/config.ocio --oiioattrib try_all_readers 0 --info -v src/crash-1643.tif 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 30d4ad1633..e742e7392f 100644 --- a/testsuite/tiff-misc/ref/out.txt +++ b/testsuite/tiff-misc/ref/out.txt @@ -17,5 +17,11 @@ PASS oiiotool ERROR: read : No support for data format of "src/corrupt1.tif" Full command line was: > oiiotool -colorconfig ../common/OpenColorIO/nuke-default/config.ocio --oiioattrib try_all_readers 0 --info -v src/corrupt1.tif +oiiotool ERROR: read : File does not exist: "src/crash-1633.tif" +Full command line was: +> oiiotool -colorconfig ../common/OpenColorIO/nuke-default/config.ocio --oiioattrib try_all_readers 0 --info -v src/crash-1633.tif +oiiotool ERROR: read : File does not exist: "src/crash-1643.tif" +Full command line was: +> oiiotool -colorconfig ../common/OpenColorIO/nuke-default/config.ocio --oiioattrib try_all_readers 0 --info -v src/crash-1643.tif Comparing "check1.tif" and "ref/check1.tif" PASS diff --git a/testsuite/tiff-misc/run.py b/testsuite/tiff-misc/run.py index f04b439dd7..6e3262d510 100755 --- a/testsuite/tiff-misc/run.py +++ b/testsuite/tiff-misc/run.py @@ -14,7 +14,9 @@ # to force compression in order to properly test: command += rw_command ("src", "separate.tif") -# Test bug we had until OIIO 2.4 for this corrupt file +# Test bugs we had until OIIO 2.4 for these corrupt file command += oiiotool ("--oiioattrib try_all_readers 0 --info -v src/corrupt1.tif", failureok = True) +command += oiiotool ("--oiioattrib try_all_readers 0 --info -v src/crash-1633.tif", failureok = True) +command += oiiotool ("--oiioattrib try_all_readers 0 --info -v src/crash-1643.tif", failureok = True) outputs = [ "check1.tif", "out.txt" ]