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: */