RepositoryExternal.mk                              |    2 
 vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx |    5 
 vcl/source/filter/itiff/itiff.cxx                  |  140 +++++++++++++++++++++
 3 files changed, 144 insertions(+), 3 deletions(-)

New commits:
commit 22b50f1937de67e4ad9e692d6964aa5b8d33af7a
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu May 19 17:11:23 2022 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sat May 21 11:52:30 2022 +0200

    use libtiff for tiff import
    
    TODO: check testTdf138818 change is acceptable/meaningful
    
    Change-Id: Ia72f2e7ec49a9f8fc23b178fe61cbc3d0e1287c3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134647
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index fa97dc350597..1e2329d69339 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -2632,7 +2632,7 @@ $(call gb_LinkTarget_set_include,$(1),\
 )
 
 $(call gb_LinkTarget_set_include,$(1),\
-       -I$(call gb_UnpackedTarball_get_dir,libtiff)/src \
+       -I$(call gb_UnpackedTarball_get_dir,libtiff)/libtiff \
        $$(INCLUDE) \
 )
 ifeq ($(OS),WNT)
diff --git a/vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2007-2217-1.tiff 
b/vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2007-2217-1.tiff
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2007-2217-1.tiff
rename to vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2007-2217-1.tiff
diff --git a/vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2013-5575-1.tiff 
b/vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2013-5575-1.tiff
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2013-5575-1.tiff
rename to vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2013-5575-1.tiff
diff --git a/vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2012-0276-1.tiff 
b/vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2012-0276-1.tiff
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2012-0276-1.tiff
rename to vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2012-0276-1.tiff
diff --git a/vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2012-0276-2.tiff 
b/vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2012-0276-2.tiff
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2012-0276-2.tiff
rename to vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2012-0276-2.tiff
diff --git a/vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2012-2027-1.tiff 
b/vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2012-2027-1.tiff
similarity index 100%
rename from vcl/qa/cppunit/graphicfilter/data/tiff/fail/CVE-2012-2027-1.tiff
rename to vcl/qa/cppunit/graphicfilter/data/tiff/pass/CVE-2012-2027-1.tiff
diff --git a/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx 
b/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx
index 72f12ca565f5..d4fdeea43524 100644
--- a/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx
+++ b/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx
@@ -113,6 +113,7 @@ void TiffFilterTest::testTdf115863()
     CPPUNIT_ASSERT_EQUAL(tools::Long(618), aSize.Height());
 }
 
+//TODO-check if this is still correct, looks ok, but what was it testing 
exactly
 void TiffFilterTest::testTdf138818()
 {
     OUString aURL = getUrl() + "tdf138818.tif";
@@ -125,9 +126,9 @@ void TiffFilterTest::testTdf138818()
     CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult);
 
     // Without the fix in place, this test would have failed with
-    // - Expected: 46428
+    // - Expected: 45953
     // - Actual  : 45951
-    CPPUNIT_ASSERT_EQUAL(sal_uInt32(46428), 
aGraphic.GetGfxLink().GetDataSize());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt32(45953), 
aGraphic.GetGfxLink().GetDataSize());
 }
 
 void TiffFilterTest::testTdf74331()
diff --git a/vcl/source/filter/itiff/itiff.cxx 
b/vcl/source/filter/itiff/itiff.cxx
index cff68f9e6ec9..b434471b2317 100644
--- a/vcl/source/filter/itiff/itiff.cxx
+++ b/vcl/source/filter/itiff/itiff.cxx
@@ -25,13 +25,152 @@
 #include <vcl/graph.hxx>
 #include <vcl/BitmapTools.hxx>
 #include <vcl/animate/Animation.hxx>
+#include <bitmap/BitmapWriteAccess.hxx>
 #include <tools/fract.hxx>
 #include <tools/stream.hxx>
 #include "lzwdecom.hxx"
 #include "ccidecom.hxx"
 
+#include <tiffio.h>
+
 #include <filter/TiffReader.hxx>
 
+#if 1
+namespace
+{
+    struct Context
+    {
+        SvStream& rStream;
+        tsize_t nSize;
+        Context(SvStream& rInStream, tsize_t nInSize)
+            : rStream(rInStream)
+            , nSize(nInSize)
+        {
+        }
+    };
+}
+
+static tsize_t tiff_read(thandle_t handle, tdata_t buf, tsize_t size)
+{
+    Context* pContext = static_cast<Context*>(handle);
+    return pContext->rStream.ReadBytes(buf, size);
+}
+
+static tsize_t tiff_write(thandle_t, tdata_t, tsize_t)
+{
+    return -1;
+}
+
+static toff_t tiff_seek(thandle_t handle, toff_t offset, int whence)
+{
+    Context* pContext = static_cast<Context*>(handle);
+
+    switch (whence)
+    {
+        case SEEK_SET:
+            pContext->rStream.Seek(offset);
+            break;
+        case SEEK_CUR:
+            pContext->rStream.SeekRel(offset);
+            break;
+        case SEEK_END:
+            pContext->rStream.Seek(STREAM_SEEK_TO_END);
+            pContext->rStream.SeekRel(offset);
+            break;
+        default:
+            assert(false && "unknown seek type");
+            break;
+    }
+
+    return pContext->rStream.Tell();
+}
+
+static int tiff_close(thandle_t)
+{
+    return 0;
+}
+
+static toff_t tiff_size(thandle_t handle)
+{
+    Context* pContext = static_cast<Context*>(handle);
+    return pContext->nSize;
+}
+
+bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic)
+{
+    Context aContext(rTIFF, rTIFF.remainingSize());
+    TIFF* tif = TIFFClientOpen("libtiff-svstream", "r", &aContext,
+                               tiff_read, tiff_write,
+                               tiff_seek, tiff_close,
+                               tiff_size, nullptr, nullptr);
+
+    if (!tif)
+        return false;
+
+    Animation aAnimation;
+
+    do
+    {
+        uint32_t w, h;
+
+        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
+        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
+
+        size_t npixels = w * h;
+        uint32_t* raster = static_cast<uint32_t*>(_TIFFmalloc(npixels * sizeof 
(uint32_t)));
+        if (raster)
+        {
+            if (TIFFReadRGBAImageOriented(tif, w, h, raster, 
ORIENTATION_TOPLEFT, 1))
+            {
+                Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP);
+                AlphaMask bitmapAlpha(Size(w, h));
+
+                BitmapScopedWriteAccess access(bitmap);
+                AlphaScopedWriteAccess accessAlpha(bitmapAlpha);
+
+                for (tools::Long y = 0; y < access->Height(); ++y)
+                {
+                    const uint32_t* src = raster + w * y;
+                    for (tools::Long x = 0; x < access->Width(); ++x)
+                    {
+                        sal_uInt8 r = TIFFGetR(*src);
+                        sal_uInt8 g = TIFFGetG(*src);
+                        sal_uInt8 b = TIFFGetB(*src);
+                        sal_uInt8 a = TIFFGetA(*src);
+                        access->SetPixel(y, x, Color(r, g, b));
+                        accessAlpha->SetPixelIndex(y, x, 255 - a);
+                        ++src;
+                    }
+                }
+
+                access.reset();
+                accessAlpha.reset();
+
+                BitmapEx aBitmapEx(bitmap, bitmapAlpha);
+                AnimationBitmap aAnimationBitmap(aBitmapEx, Point(0, 0), 
aBitmapEx.GetSizePixel(),
+                                                 ANIMATION_TIMEOUT_ON_CLICK, 
Disposal::Back);
+                aAnimation.Insert(aAnimationBitmap);
+            }
+            _TIFFfree(raster);
+        }
+    } while (TIFFReadDirectory(tif));
+
+    TIFFClose(tif);
+
+    const auto nImages = aAnimation.Count();
+    if (nImages)
+    {
+        if (nImages == 1)
+            rGraphic = aAnimation.GetBitmapEx();
+        else
+            rGraphic = aAnimation;
+        return true;
+    }
+
+    return false;
+}
+#else
+
 namespace {
 
 template< typename T > T BYTESWAP(T nByte) {
@@ -1718,5 +1857,6 @@ bool ImportTiffGraphicImport(SvStream & rStream, Graphic 
& rGraphic)
         return false;
     }
 }
+#endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to