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))

Reply via email to