vcl/Library_vcl.mk | 1 vcl/source/filter/itiff/itiff.cxx | 64 +++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-)
New commits: commit f0d3727322207b3a547313e14305440ad7009079 Author: Julien Nabet <serval2...@yahoo.fr> AuthorDate: Tue May 17 17:25:58 2022 +0200 Commit: Julien Nabet <serval2...@yahoo.fr> CommitDate: Tue May 17 20:53:01 2022 +0200 tdf#122057: read tiff with deflate compression (code 32946 only) tiff format is more a multiformat container with different combination of parameters, above all compression and photometric interpretation. For this one, the only pb was deflate compression wasn't dealt with. So just use existing LO wrapper for deflate lib in package part. Remark: for the moment only decompression 32946 (legacy deflate) is managed not Adobe deflate (code 8). I expected the same behaviour but some tests with tdf#131199 showed it didn't work. Change-Id: I2c8d244fa89a2378bfe3b87d3d3262810c9952be Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134485 Tested-by: Jenkins Reviewed-by: Julien Nabet <serval2...@yahoo.fr> diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index a141e22348dd..626134894bd0 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -69,6 +69,7 @@ $(eval $(call gb_Library_use_libraries,vcl,\ i18nutil \ $(if $(ENABLE_JAVA),jvmaccess) \ $(if $(filter OPENCL,$(BUILD_TYPE)),opencl) \ + package2 \ sal \ salhelper \ sot \ diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index cff68f9e6ec9..894241a68d38 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -20,6 +20,10 @@ #include <sal/config.h> #include <sal/log.hxx> +#include <comphelper/sequence.hxx> +#include <optional> +#include <package/Inflater.hxx> + #include <unotools/configmgr.hxx> #include <vcl/FilterConfigItem.hxx> #include <vcl/graph.hxx> @@ -708,6 +712,64 @@ bool TIFFReader::ReadMap() return false; } } + else if ( nCompression == 32946 ) // deflate compression (legacy code) + { + sal_uInt32 nStrip(0); + if (nStrip >= aStripOffsets.size()) + return false; + pTIFF->Seek(aStripOffsets[nStrip]); + + + sal_Int32 nRowSize = (static_cast<sal_uInt64>(nImageWidth) * nSamplesPerPixel / nPlanes * nBitsPerSample + 7) >> 3; + + for (sal_Int32 ny = 0; ny < nImageLength; ++ny) + { + for (sal_uInt32 np = 0; np < nPlanes; ++np) + { + if ( ny / GetRowsPerStrip() + np * nStripsPerPlane > nStrip ) + { + nStrip = ny / GetRowsPerStrip() + np * nStripsPerPlane; + if (nStrip >= aStripOffsets.size()) + return false; + pTIFF->Seek(aStripOffsets[nStrip]); + } + if (np >= SAL_N_ELEMENTS(aMap)) + return false; + + // Inflater uses in and out sequences + // 1) Preparation: read in nBytesPerRow from the stream, put it on the sequence and initialize decompresser with it + css::uno::Sequence<sal_Int8> aInput(nBytesPerRow); + sal_uInt8* aInputArray = reinterpret_cast< sal_uInt8* >( aInput.getArray( ) ); + for (size_t i = 0; i < nBytesPerRow ; ++i) + { + pTIFF->ReadUChar(aInputArray[i]); + } + std::optional< ::ZipUtils::Inflater> decompresser(std::in_place, false); + decompresser->setInput(aInput); + + // 2) Decompression + css::uno::Sequence<sal_Int8> aOutput(nRowSize); + decompresser->doInflateSegment(aOutput, 0, nRowSize); + decompresser->end(); + decompresser.reset(); + + // 3) Result retrieving: put the read row in the aMap which will be read by ConvertScanline later + auto pDest = getMapData(np); + for (sal_Int32 i = 0; i < nRowSize; ++i) + *pDest++ = aInput[i]; + + if ( pTIFF->GetError() ) + return false; + } + + nTotalDataRead += nBytesPerRow; + if (nMaxAllowedDecompression && nTotalDataRead > nMaxAllowedDecompression) + return false; + + if ( !ConvertScanline( ny ) ) + return false; + } + } else if ( nCompression == 32773 ) { sal_uInt32 nStrip(0); @@ -1584,7 +1646,7 @@ bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic ) bStatus = false; } } - else if (nCompression == 5) + else if (nCompression == 5 || nCompression == 32946) { sal_uInt32 np = nPlanes - 1; if (np >= SAL_N_ELEMENTS(aMap))