Makefile.fetch | 1 RepositoryExternal.mk | 51 bin/lo-all-static-libs | 1 config_host.mk.in | 3 configure.ac | 7 download.lst | 2 external/Module_external.mk | 1 external/libtiff/0001-add-16bit-cielab-support.patch | 164 + external/libtiff/ExternalProject_libtiff.mk | 72 external/libtiff/Makefile | 7 external/libtiff/Module_libtiff.mk | 17 external/libtiff/README | 3 external/libtiff/UnpackedTarball_libtiff.mk | 22 external/libtiff/include.patch | 10 external/libtiff/libtiff.linknolibs.patch | 11 readlicense_oo/license/license.xml | 18 solenv/clang-format/excludelist | 3 sw/source/filter/html/htmlplug.cxx | 3 vcl/Library_vcl.mk | 3 vcl/commonfuzzer.mk | 1 vcl/qa/cppunit/graphicfilter/data/tiff/fail/ofz47589.tiff |binary vcl/source/filter/itiff/ccidecom.cxx | 1100 -------- vcl/source/filter/itiff/ccidecom.hxx | 129 - vcl/source/filter/itiff/itiff.cxx | 1757 +------------- vcl/source/filter/itiff/lzwdecom.cxx | 218 - vcl/source/filter/itiff/lzwdecom.hxx | 73 26 files changed, 562 insertions(+), 3115 deletions(-)
New commits: commit 7b502405a816396193717dbc9eafa0e52622f049 Author: Caolán McNamara <[email protected]> AuthorDate: Sat May 21 20:37:23 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:55:18 2022 +0200 drop unused hxx files Change-Id: I68ea314f20b599c181f2ae9f264037918419d15c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134715 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index b6672e28d890..81a9baeabd67 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -14951,10 +14951,7 @@ vcl/source/filter/ixbm/xbmread.cxx vcl/source/filter/ixpm/rgbtable.hxx vcl/source/filter/ixpm/xpmread.cxx vcl/source/filter/itga/itga.cxx -vcl/source/filter/itiff/ccidecom.cxx -vcl/source/filter/itiff/ccidecom.hxx vcl/source/filter/itiff/itiff.cxx -vcl/source/filter/itiff/lzwdecom.cxx vcl/source/filter/jpeg/Exif.cxx vcl/source/filter/jpeg/Exif.hxx vcl/source/filter/jpeg/JpegReader.cxx diff --git a/vcl/source/filter/itiff/ccidecom.hxx b/vcl/source/filter/itiff/ccidecom.hxx deleted file mode 100644 index 89e23656b150..000000000000 --- a/vcl/source/filter/itiff/ccidecom.hxx +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ITIFF_CCIDECOM_HXX -#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ITIFF_CCIDECOM_HXX - -#include <sal/types.h> -#include <array> -#include <memory> - -#define CCI_OPTION_2D 1 // 2D compression (instead of 1D) -#define CCI_OPTION_EOL 2 // There are EOL-Codes at the end of each line. -#define CCI_OPTION_BYTEALIGNEOL 4 // Filling bits before each EOL-Code, so that - // the end of EOL is bytes aligned -#define CCI_OPTION_BYTEALIGNROW 8 // Rows always start byte aligned -#define CCI_OPTION_INVERSEBITORDER 16 - -// Entry in the Huffman table: -struct CCIHuffmanTableEntry { - sal_uInt16 nValue; // The data value. - sal_uInt16 nCode; // The code through which the data value is represented. - sal_uInt16 nCodeBits; // Size of the code in bits. -}; - -// Entry in a hash table for daft decoding. -struct CCILookUpTableEntry { - sal_uInt16 nValue; - sal_uInt16 nCodeBits; -}; - -class SvStream; - -struct DecompressStatus -{ - bool m_bSuccess; - bool m_bBufferUnchanged; - DecompressStatus(bool bSuccess, bool bBufferUnchanged) - : m_bSuccess(bSuccess), m_bBufferUnchanged(bBufferUnchanged) - { - } -}; - -class CCIDecompressor { - -public: - - CCIDecompressor( sal_uInt32 nOptions, sal_uInt32 nImageWidth ); - ~CCIDecompressor(); - - void StartDecompression( SvStream & rIStream ); - - DecompressStatus DecompressScanline(sal_uInt8 * pTarget, sal_uInt64 nTargetBits, bool bLastLine); - -private: - - void MakeLookUp(const CCIHuffmanTableEntry * pHufTab, - const CCIHuffmanTableEntry * pHufTabSave, - CCILookUpTableEntry * pLookUp, - sal_uInt16 nHuffmanTableSize, - sal_uInt16 nMaxCodeBits); - - bool ReadEOL(); - - bool Read2DTag(); - - sal_uInt8 ReadBlackOrWhite(); - - sal_uInt16 ReadCodeAndDecode(const CCILookUpTableEntry * pLookUp, - sal_uInt16 nMaxCodeBits); - - static void FillBits(sal_uInt8 * pTarget, sal_uInt16 nTargetBits, - sal_uInt16 nBitPos, sal_uInt16 nNumBits, - sal_uInt8 nBlackOrWhite); - - static sal_uInt16 CountBits(const sal_uInt8 * pData, sal_uInt16 nDataSizeBits, - sal_uInt16 nBitPos, sal_uInt8 nBlackOrWhite); - - //returns true if pTarget was unmodified - bool Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits); - bool Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits); - - bool bTableBad; - - bool bStatus; - - std::unique_ptr<sal_uInt8[]> pByteSwap; - - SvStream * pIStream; - - sal_uInt32 nEOLCount; - - sal_uInt32 nWidth; - - sal_uInt32 nOptions; - - bool bFirstEOL; - - std::array<CCILookUpTableEntry, 1<<13> pWhiteLookUp; - std::array<CCILookUpTableEntry, 1<<13> pBlackLookUp; - std::array<CCILookUpTableEntry, 1<<10> p2DModeLookUp; - std::array<CCILookUpTableEntry, 1<<11> pUncompLookUp; - - sal_uInt32 nInputBitsBuf; - sal_uInt16 nInputBitsBufSize; - - std::unique_ptr<sal_uInt8[]> pLastLine; - sal_uInt64 nLastLineSize; -}; - - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/filter/itiff/lzwdecom.hxx b/vcl/source/filter/itiff/lzwdecom.hxx deleted file mode 100644 index cd6590a6dc87..000000000000 --- a/vcl/source/filter/itiff/lzwdecom.hxx +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ITIFF_LZWDECOM_HXX -#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ITIFF_LZWDECOM_HXX - -#include <sal/types.h> -#include <array> - -#define MAX_TABLE_SIZE 4096 - -struct LZWTableEntry -{ - sal_uInt16 nPrevCode; - sal_uInt16 nDataCount; - sal_uInt8 nData; -}; - -class SvStream; - -class LZWDecompressor -{ -public: - LZWDecompressor(); - ~LZWDecompressor(); - - void StartDecompression(SvStream& rIStream); - - // Returns the number of written bytes. If < nMaxCount there is - // no more data to be unpacked or an error occurred. - sal_uInt64 Decompress(sal_uInt8* pTarget, sal_uInt32 nMaxCount); - -private: - sal_uInt16 GetNextCode(); - void AddToTable(sal_uInt16 nPrevCode, sal_uInt16 nCodeFirstData); - void DecompressSome(); - - SvStream* pIStream; - - std::array<LZWTableEntry, MAX_TABLE_SIZE> aTable; - sal_uInt16 nTableSize; - - bool bEOIFound, bInvert, bFirst; - - sal_uInt16 nOldCode; - - std::array<sal_uInt8, MAX_TABLE_SIZE> pOutBuf; - sal_uInt8* pOutBufData; - sal_uInt16 nOutBufDataLen; - - sal_uInt8 nInputBitsBuf; - sal_uInt16 nInputBitsBufSize; -}; - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 546bf38a7011be35bef8e37d8fc1fdeaa7f7120b Author: Caolán McNamara <[email protected]> AuthorDate: Fri Jun 3 15:53:24 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:53:31 2022 +0200 ofz#47781 Out of memory Change-Id: I6ebd284bb3fa2c220b6a09fa9875b97c79f4a239 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135364 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 92616ecbafba..db30ea2cac3c 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -159,7 +159,9 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) } uint32_t nPixelsRequired; - bool bOk = !o3tl::checked_multiply(w, h, nPixelsRequired) && nPixelsRequired <= SAL_MAX_INT32/4; + constexpr size_t nMaxPixelsAllowed = SAL_MAX_INT32/4; + // two buffers currently required, so limit further + bool bOk = !o3tl::checked_multiply(w, h, nPixelsRequired) && nPixelsRequired <= nMaxPixelsAllowed / 2; if (!bOk) { SAL_WARN("filter.tiff", "skipping oversized tiff image " << w << " x " << h); commit 4271bccdd7bb4718be25f762015a140c1b75752a Author: Caolán McNamara <[email protected]> AuthorDate: Mon May 30 15:17:04 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:53:26 2022 +0200 ofz#47664 OOM Change-Id: If0d1ea55a194961fdb05ed2023bcfdaa6f933bfa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135129 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 781e2b39bf4b..92616ecbafba 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -159,9 +159,10 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) } uint32_t nPixelsRequired; - if (o3tl::checked_multiply(w, h, nPixelsRequired)) + bool bOk = !o3tl::checked_multiply(w, h, nPixelsRequired) && nPixelsRequired <= SAL_MAX_INT32/4; + if (!bOk) { - SAL_WARN("filter.tiff", "skipping oversized tiff image"); + SAL_WARN("filter.tiff", "skipping oversized tiff image " << w << " x " << h); break; } commit a74fb56e7128855184c209393f98c00801c934e0 Author: Caolán McNamara <[email protected]> AuthorDate: Fri Jun 3 15:45:57 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:51:06 2022 +0200 ofz#47759 Timeout Change-Id: I8d6b1adb83963c229d71b9f593d39d8cd3e281e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135363 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index bca8021044ce..781e2b39bf4b 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -20,6 +20,7 @@ #include <sal/config.h> #include <sal/log.hxx> +#include <comphelper/scopeguard.hxx> #include <vcl/graph.hxx> #include <vcl/BitmapTools.hxx> #include <vcl/animate/Animation.hxx> @@ -105,6 +106,13 @@ static toff_t tiff_size(thandle_t handle) bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) { + auto origErrorHandler = TIFFSetErrorHandler(nullptr); + auto origWarningHandler = TIFFSetWarningHandler(nullptr); + comphelper::ScopeGuard restoreDefaultHandlers([&]() { + TIFFSetErrorHandler(origErrorHandler); + TIFFSetWarningHandler(origWarningHandler); + }); + Context aContext(rTIFF, rTIFF.remainingSize()); TIFF* tif = TIFFClientOpen("libtiff-svstream", "r", &aContext, tiff_read, tiff_write, commit 0494b2f17d3f35daa2a846b830f4448f6f1fb263 Author: Caolán McNamara <[email protected]> AuthorDate: Thu Jun 9 10:34:39 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:45:27 2022 +0200 ofz#47901 fix read overflow Change-Id: I707fe54e68ef548edcb8b69b83ba64c0674e44ce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135532 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/external/libtiff/0001-add-16bit-cielab-support.patch b/external/libtiff/0001-add-16bit-cielab-support.patch new file mode 100644 index 000000000000..3ee6c3f648ca --- /dev/null +++ b/external/libtiff/0001-add-16bit-cielab-support.patch @@ -0,0 +1,164 @@ +From 87cf58d0604e4bfd70da1044894c3e8f073133a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <[email protected]> +Date: Sun, 22 May 2022 14:20:21 +0100 +Subject: [PATCH] add 16bit-cielab support + +add an internal TIFFCIELab16ToXYZ that assumes 16bit encoding + +multiply the 8bit variant input to use that, keep TIFFCIELabToXYZ +unchanged so no different to existing potential consumers + +motivation: https://bugs.documentfoundation.org/show_bug.cgi?id=131199 +the "clavijo16bitlab.tiff" example where tiffinfo says: + + Image Width: 2601 Image Length: 3503 + Resolution: 96, 96 pixels/inch + Bits/Sample: 16 + Compression Scheme: AdobeDeflate + Photometric Interpretation: CIE L*a*b* + Orientation: row 0 top, col 0 lhs + Samples/Pixel: 3 + Rows/Strip: 1 + Planar Configuration: single image plane + DateTime: 2020:03:07 10:20:42 +--- + libtiff/tif_color.c | 19 ++++++++++++++++--- + libtiff/tif_getimage.c | 38 ++++++++++++++++++++++++++++++++++---- + libtiff/tiffiop.h | 2 ++ + 3 files changed, 52 insertions(+), 7 deletions(-) + +diff --git a/libtiff/tif_color.c b/libtiff/tif_color.c +index 20e41684..e0fc4bf0 100644 +--- libtiff/tif_color.c ++++ libtiff/tif_color.c +@@ -44,7 +44,20 @@ void + TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, + float *X, float *Y, float *Z) + { +- float L = (float)l * 100.0F / 255.0F; ++ TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z); ++} ++ ++/* ++ * For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535]. ++ * The a* and b* components are signed integers range [-32768,32767]. The 16 ++ * bit chrominance values are encoded as 256 times the 1976 CIE a* and b* ++ * values ++ */ ++void ++TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, ++ float *X, float *Y, float *Z) ++{ ++ float L = (float)l * 100.0F / 65535.0F; + float cby, tmp; + + if( L < 8.856F ) { +@@ -55,13 +68,13 @@ TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, + *Y = cielab->Y0 * cby * cby * cby; + } + +- tmp = (float)a / 500.0F + cby; ++ tmp = (float)a / 256.0F / 500.0F + cby; + if( tmp < 0.2069F ) + *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; + else + *X = cielab->X0 * tmp * tmp * tmp; + +- tmp = cby - (float)b / 200.0F; ++ tmp = cby - (float)b / 256.0F / 200.0F; + if( tmp < 0.2069F ) + *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; + else +diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c +index a1b6570b..9e2ac2c9 100644 +--- libtiff/tif_getimage.c ++++ libtiff/tif_getimage.c +@@ -194,7 +194,7 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) + } + break; + case PHOTOMETRIC_CIELAB: +- if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) { ++ if ( td->td_samplesperpixel != 3 || colorchannels != 3 || (td->td_bitspersample != 8 && td->td_bitspersample != 16) ) { + sprintf(emsg, + "Sorry, can not handle image with %s=%"PRIu16", %s=%d and %s=%"PRIu16, + "Samples/pixel", td->td_samplesperpixel, +@@ -1784,7 +1784,7 @@ DECLARESepPutFunc(putRGBUAseparate16bittile) + /* + * 8-bit packed CIE L*a*b 1976 samples => RGB + */ +-DECLAREContigPutFunc(putcontig8bitCIELab) ++DECLAREContigPutFunc(putcontig8bitCIELab8) + { + float X, Y, Z; + uint32_t r, g, b; +@@ -1806,6 +1806,32 @@ DECLAREContigPutFunc(putcontig8bitCIELab) + } + } + ++/* ++ * 16-bit packed CIE L*a*b 1976 samples => RGB ++ */ ++DECLAREContigPutFunc(putcontig8bitCIELab16) ++{ ++ float X, Y, Z; ++ uint32_t r, g, b; ++ uint16_t *wp = (uint16_t *)pp; ++ (void) y; ++ fromskew *= 3; ++ for( ; h > 0; --h) { ++ for (x = w; x > 0; --x) { ++ TIFFCIELab16ToXYZ(img->cielab, ++ (uint16_t)wp[0], ++ (int16_t)wp[1], ++ (int16_t)wp[2], ++ &X, &Y, &Z); ++ TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); ++ *cp++ = PACK(r, g, b); ++ wp += 3; ++ } ++ cp += toskew; ++ wp += fromskew; ++ } ++} ++ + /* + * YCbCr -> RGB conversion and packing routines. + */ +@@ -2395,7 +2421,11 @@ initCIELabConversion(TIFFRGBAImage* img) + return NULL; + } + +- return putcontig8bitCIELab; ++ if (img->bitspersample == 8) ++ return putcontig8bitCIELab8; ++ else if (img->bitspersample == 16) ++ return putcontig8bitCIELab16; ++ return NULL; + } + + /* +@@ -2777,7 +2807,7 @@ PickContigCase(TIFFRGBAImage* img) + break; + case PHOTOMETRIC_CIELAB: + if (img->samplesperpixel == 3 && buildMap(img)) { +- if (img->bitspersample == 8) ++ if (img->bitspersample == 8 || img->bitspersample == 16) + img->put.contig = initCIELabConversion(img); + break; + } +diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h +index e3af461d..7bd50514 100644 +--- libtiff/tiffiop.h ++++ libtiff/tiffiop.h +@@ -429,6 +429,8 @@ extern int TIFFInitZSTD(TIFF*, int); + extern int TIFFInitWebP(TIFF*, int); + #endif + extern const TIFFCodec _TIFFBuiltinCODECS[]; ++extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a, int32_t b, ++ float *, float *, float *); + + #if defined(__cplusplus) + } +-- +2.36.1 + diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk index 7776e7f88d75..3e7abee6aef2 100644 --- a/external/libtiff/UnpackedTarball_libtiff.mk +++ b/external/libtiff/UnpackedTarball_libtiff.mk @@ -15,7 +15,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0)) $(eval $(call gb_UnpackedTarball_add_patches,libtiff,\ external/libtiff/libtiff.linknolibs.patch \ - external/libtiff/libtiff.16bitcielab.patch \ + external/libtiff/0001-add-16bit-cielab-support.patch \ external/libtiff/include.patch \ )) diff --git a/external/libtiff/libtiff.16bitcielab.patch b/external/libtiff/libtiff.16bitcielab.patch deleted file mode 100644 index 968de975f641..000000000000 --- a/external/libtiff/libtiff.16bitcielab.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- libtiff/tif_getimage.c 2021-03-05 13:01:43.000000000 +0000 -+++ libtiff/tif_getimage.c 2022-05-22 14:05:56.320883484 +0100 -@@ -194,7 +194,7 @@ - } - break; - case PHOTOMETRIC_CIELAB: -- if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) { -+ if ( td->td_samplesperpixel != 3 || colorchannels != 3 || (td->td_bitspersample != 8 && td->td_bitspersample != 16) ) { - sprintf(emsg, - "Sorry, can not handle image with %s=%"PRIu16", %s=%d and %s=%"PRIu16, - "Samples/pixel", td->td_samplesperpixel, -@@ -1784,7 +1784,7 @@ - /* - * 8-bit packed CIE L*a*b 1976 samples => RGB - */ --DECLAREContigPutFunc(putcontig8bitCIELab) -+DECLAREContigPutFunc(putcontig8bitCIELab8) - { - float X, Y, Z; - uint32_t r, g, b; -@@ -1807,6 +1807,32 @@ - } - - /* -+ * 16-bit packed CIE L*a*b 1976 samples => RGB -+ */ -+DECLAREContigPutFunc(putcontig8bitCIELab16) -+{ -+ float X, Y, Z; -+ uint32_t r, g, b; -+ uint16_t *wp = (uint16_t *)pp; -+ (void) y; -+ fromskew = 3; -+ for( ; h > 0; --h) { -+ for (x = w; x > 0; --x) { -+ TIFFCIELabToXYZ(img->cielab, -+ (uint16_t)wp[0] / 257, -+ (int16_t)wp[1] / 256, -+ (int16_t)wp[2] / 256, -+ &X, &Y, &Z); -+ TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); -+ *cp++ = PACK(r, g, b); -+ wp += 3; -+ } -+ cp += toskew; -+ wp += fromskew; -+ } -+} -+ -+/* - * YCbCr -> RGB conversion and packing routines. - */ - -@@ -2395,7 +2421,11 @@ - return NULL; - } - -- return putcontig8bitCIELab; -+ if (img->bitspersample == 8) -+ return putcontig8bitCIELab8; -+ else if (img->bitspersample == 16) -+ return putcontig8bitCIELab16; -+ return NULL; - } - - /* -@@ -2777,7 +2807,7 @@ - break; - case PHOTOMETRIC_CIELAB: - if (img->samplesperpixel == 3 && buildMap(img)) { -- if (img->bitspersample == 8) -+ if (img->bitspersample == 8 || img->bitspersample == 16) - img->put.contig = initCIELabConversion(img); - break; - } commit 45df6ae18057332ff289ccba3ece04ba53702907 Author: Caolán McNamara <[email protected]> AuthorDate: Thu Oct 13 21:14:28 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:39:34 2022 +0200 Resolves: tdf#151468 honour tiff resolution fields Change-Id: I57d996f49c6ae7e60991ff53eae867144b56d89d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141346 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 7540239b5470..bca8021044ce 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -24,6 +24,7 @@ #include <vcl/BitmapTools.hxx> #include <vcl/animate/Animation.hxx> #include <bitmap/BitmapWriteAccess.hxx> +#include <tools/fract.hxx> #include <tools/stream.hxx> #include <unotools/configmgr.hxx> @@ -232,6 +233,25 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) break; } + MapMode aMapMode; + uint16_t ResolutionUnit = RESUNIT_NONE; + if (TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &ResolutionUnit) == 1 && ResolutionUnit != RESUNIT_NONE) + { + float xres = 0, yres = 0; + + if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) == 1 && + TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) == 1 && + xres != 0 && yres != 0) + { + if (ResolutionUnit == RESUNIT_INCH) + aMapMode = MapMode(MapUnit::MapInch, Point(0,0), Fraction(1/xres), Fraction(1/yres)); + else if (ResolutionUnit == RESUNIT_CENTIMETER) + aMapMode = MapMode(MapUnit::MapCM, Point(0,0), Fraction(1/xres), Fraction(1/yres)); + } + } + aBitmapEx.SetPrefMapMode(aMapMode); + aBitmapEx.SetPrefSize(Size(w, h)); + AnimationBitmap aAnimationBitmap(aBitmapEx, Point(0, 0), aBitmapEx.GetSizePixel(), ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back); aAnimation.Insert(aAnimationBitmap); commit 3a80ce4ff91058855f6e3d7c133499a62fee5716 Author: Stephan Bergmann <[email protected]> AuthorDate: Fri Jun 10 08:07:43 2022 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:39:28 2022 +0200 external/libtiff: Missing include for _byteswap_uint64 on Windows ...now causing a -Wimplicit-function-declaration error with Clang 15 trunk after <https://github.com/llvm/llvm-project/commit/7d644e1215b376ec5e915df9ea2eeb56e2d94626> "[C11/C2x] Change the behavior of the implicit function declaration warning". (Unconditionally including <stdlib.h> on all platforms even for those that don't need it should be harmless.) Change-Id: Ic2191308ea252cb4b88842a2767167ab2d23d9fb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135572 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk index ee3d4ab6cb27..7776e7f88d75 100644 --- a/external/libtiff/UnpackedTarball_libtiff.mk +++ b/external/libtiff/UnpackedTarball_libtiff.mk @@ -16,6 +16,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0)) $(eval $(call gb_UnpackedTarball_add_patches,libtiff,\ external/libtiff/libtiff.linknolibs.patch \ external/libtiff/libtiff.16bitcielab.patch \ + external/libtiff/include.patch \ )) # vim: set noet sw=4 ts=4: diff --git a/external/libtiff/include.patch b/external/libtiff/include.patch new file mode 100644 index 000000000000..0b6526234123 --- /dev/null +++ b/external/libtiff/include.patch @@ -0,0 +1,10 @@ +--- libtiff/tif_lzw.c ++++ libtiff/tif_lzw.c +@@ -39,6 +39,7 @@ + + #include <stdbool.h> + #include <stdio.h> ++#include <stdlib.h> + + /* Select the plausible largest natural integer type for the architecture */ + #define SIZEOF_WORDTYPE SIZEOF_SIZE_T commit 2728fe2051ceaedaeabb2a5efd69638f268bb1ee Author: Caolán McNamara <[email protected]> AuthorDate: Tue Jun 7 20:34:48 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:38:01 2022 +0200 add LIBTIFF to cross-compiling targets with an eye to win_arm64 cross build failure Change-Id: I6872859f288168352e3e70c1d559f4d318439958 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135479 Tested-by: Jenkins Reviewed-by: Julien Nabet <[email protected]> diff --git a/configure.ac b/configure.ac index 155f29fae282..27248dde59ce 100644 --- a/configure.ac +++ b/configure.ac @@ -5651,6 +5651,7 @@ if test "$cross_compiling" = "yes"; then LibO LIBFFI LIBPN + LIBTIFF LIBXML2 LIBXSLT MDDS commit cf813d0f16c41193b0e9ce633d85e0c75f17b171 Author: Caolán McNamara <[email protected]> AuthorDate: Fri Jun 3 14:09:11 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:36:09 2022 +0200 upgrade libtiff to 4.4.0 dropping ubsan.patch which was fixed upstream in this release Change-Id: Ic2e35b24f7a9c7c3e2a00da8bc5b5b7d500746fd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135359 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/download.lst b/download.lst index dd463076f5c7..3a3e299f7c26 100644 --- a/download.lst +++ b/download.lst @@ -238,8 +238,8 @@ export PIXMAN_SHA256SUM := 6d200dec3740d9ec4ec8d1180e25779c00bc749f94278c8b9021f export PIXMAN_TARBALL := pixman-0.40.0.tar.gz export LIBPNG_SHA256SUM := b3683e8b8111ebf6f1ac004ebb6b0c975cd310ec469d98364388e9cedbfa68be export LIBPNG_TARBALL := libpng-1.6.38.tar.xz -export LIBTIFF_SHA256SUM := 0e46e5acb087ce7d1ac53cf4f56a09b221537fc86dfc5daaad1c2e89e1b37ac8 -export LIBTIFF_TARBALL := tiff-4.3.0.tar.gz +export LIBTIFF_SHA256SUM := 49307b510048ccc7bc40f2cba6e8439182fe6e654057c1a1683139bf2ecb1dc1 +export LIBTIFF_TARBALL := tiff-4.4.0.tar.xz export POPPLER_SHA256SUM := d7a8f748211359cadb774ba3e18ecda6464b34027045c0648eb30d5852a41e2e export POPPLER_TARBALL := poppler-22.09.0.tar.xz export POPPLER_DATA_SHA256SUM := 2cec05cd1bb03af98a8b06a1e22f6e6e1a65b1e2f3816cb3069bb0874825f08c diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk index f874d6d61743..ee3d4ab6cb27 100644 --- a/external/libtiff/UnpackedTarball_libtiff.mk +++ b/external/libtiff/UnpackedTarball_libtiff.mk @@ -16,7 +16,6 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0)) $(eval $(call gb_UnpackedTarball_add_patches,libtiff,\ external/libtiff/libtiff.linknolibs.patch \ external/libtiff/libtiff.16bitcielab.patch \ - external/libtiff/ubsan.patch \ )) # vim: set noet sw=4 ts=4: diff --git a/external/libtiff/ubsan.patch b/external/libtiff/ubsan.patch deleted file mode 100644 index 853d069ad795..000000000000 --- a/external/libtiff/ubsan.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- libtiff/tif_dirread.c -+++ libtiff/tif_dirread.c -@@ -4173,7 +4173,7 @@ - goto bad; - } - -- memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); -+ if (old_extrasamples != 0) memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); - _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); - _TIFFfree(new_sampleinfo); - } commit 45d3d7132beefc7ba8fa5ebf4f0de8ee3efe9a9f Author: Caolán McNamara <[email protected]> AuthorDate: Wed Jun 1 20:24:22 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:35:40 2022 +0200 tdf#149418 the expectation is on success the tiff stream pos is at EOF which is what the old one did, so do that here as well, libtiff will leave the stream some other pos by default, presumably the directory. which explains the testTdf138818 mystery Change-Id: I574700f81a21ee164d9911e05e2023aa48d10370 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135279 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx b/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx index 5697ca97ef28..d3e7dec94d6f 100644 --- a/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx +++ b/vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx @@ -107,7 +107,6 @@ 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"; @@ -120,9 +119,9 @@ void TiffFilterTest::testTdf138818() CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, bResult); // Without the fix in place, this test would have failed with - // - Expected: 45953 + // - Expected: 46428 // - Actual : 45951 - CPPUNIT_ASSERT_EQUAL(sal_uInt32(45953), aGraphic.GetGfxLink().GetDataSize()); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(46428), aGraphic.GetGfxLink().GetDataSize()); } void TiffFilterTest::testRoundtrip() diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index b01e769a7d46..7540239b5470 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -113,6 +113,8 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) if (!tif) return false; + const auto nOrigPos = rTIFF.Tell(); + Animation aAnimation; do @@ -245,9 +247,14 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) rGraphic = aAnimation.GetBitmapEx(); else rGraphic = aAnimation; + + // seek to end of TIFF if succeeded + rTIFF.Seek(STREAM_SEEK_TO_END); + return true; } + rTIFF.Seek(nOrigPos); return false; } commit f2ed852ecb58ef6a580c3683f38e99a20a34c9c8 Author: Caolán McNamara <[email protected]> AuthorDate: Wed Jun 1 12:40:23 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:35:27 2022 +0200 Resolves: tdf#149417 allow one short read in tiff import as not a failure Change-Id: I77bff41abd51cfd3050836fff04e9644b0828c09 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135239 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 6f81dffd08ef..b01e769a7d46 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -37,9 +37,11 @@ namespace { SvStream& rStream; tsize_t nSize; + int nShortReads; Context(SvStream& rInStream, tsize_t nInSize) : rStream(rInStream) , nSize(nInSize) + , nShortReads(0) { } }; @@ -48,7 +50,16 @@ namespace 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); + tsize_t nRead = pContext->rStream.ReadBytes(buf, size); + // tdf#149417 allow one short read, which is similar to what + // we do for jpeg since tdf#138950 + if (nRead < size && !pContext->nShortReads) + { + memset(static_cast<char*>(buf) + nRead, 0, size - nRead); + ++pContext->nShortReads; + return size; + } + return nRead; } static tsize_t tiff_write(thandle_t, tdata_t, tsize_t) commit 4aa9b8520248479ceb2ba97e223f75f2969a28f8 Author: Caolán McNamara <[email protected]> AuthorDate: Sun May 29 12:40:36 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:35:17 2022 +0200 crashtesting: failure on loading gnome635181-1.tiff Change-Id: I5dd9552eb267ffb67aa0aae36b474eb28790b5c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135091 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 59021b8c4999..6f81dffd08ef 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -120,7 +120,7 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) break; } - if (w > SAL_MAX_INT32 / 8 || h > SAL_MAX_INT32 / 8) + if (w > SAL_MAX_INT32 / 32 || h > SAL_MAX_INT32 / 32) { SAL_WARN("filter.tiff", "image too large"); break; @@ -147,10 +147,20 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) if (TIFFReadRGBAImageOriented(tif, w, h, raster.data(), ORIENTATION_TOPLEFT, 1)) { Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); - AlphaMask bitmapAlpha(Size(w, h)); - BitmapScopedWriteAccess access(bitmap); + if (!access) + { + SAL_WARN("filter.tiff", "cannot create image " << w << " x " << h); + break; + } + + AlphaMask bitmapAlpha(Size(w, h)); AlphaScopedWriteAccess accessAlpha(bitmapAlpha); + if (!accessAlpha) + { + SAL_WARN("filter.tiff", "cannot create alpha " << w << " x " << h); + break; + } /* ORIENTATION_TOPLEFT = 1 commit 7ad225b445d0acb3ee026a4fe3dc24e176f60d2d Author: Caolán McNamara <[email protected]> AuthorDate: Fri May 27 14:14:06 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:35:05 2022 +0200 ofz#47673 skip oversized tiff images Change-Id: I78727819b7c440855f89240f396dad845a295d61 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135041 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 6eac698121f0..59021b8c4999 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -136,8 +136,14 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) } } - size_t npixels = w * h; - std::vector<uint32_t> raster(npixels); + uint32_t nPixelsRequired; + if (o3tl::checked_multiply(w, h, nPixelsRequired)) + { + SAL_WARN("filter.tiff", "skipping oversized tiff image"); + break; + } + + std::vector<uint32_t> raster(nPixelsRequired); if (TIFFReadRGBAImageOriented(tif, w, h, raster.data(), ORIENTATION_TOPLEFT, 1)) { Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); commit aad932882403598b49b7e650deceaea02bac0db3 Author: Caolán McNamara <[email protected]> AuthorDate: Wed May 25 09:07:16 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:34:12 2022 +0200 ofz#47617 don't skip TIFFClose on error condition Change-Id: Ie5a84488312b9f17733747942e45d767cd5d4966 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134928 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index b682d759f115..6eac698121f0 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -25,6 +25,7 @@ #include <vcl/animate/Animation.hxx> #include <bitmap/BitmapWriteAccess.hxx> #include <tools/stream.hxx> +#include <unotools/configmgr.hxx> #include <tiffio.h> @@ -125,6 +126,16 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) break; } + if (utl::ConfigManager::IsFuzzing()) + { + const uint64_t MAX_SIZE = 500000000; + if (TIFFTileSize64(tif) > MAX_SIZE) + { + SAL_WARN("filter.tiff", "skipping large tiffs"); + break; + } + } + size_t npixels = w * h; std::vector<uint32_t> raster(npixels); if (TIFFReadRGBAImageOriented(tif, w, h, raster.data(), ORIENTATION_TOPLEFT, 1)) commit d7ad92e5796ba86ce0b0172a1df58aa2e7fd8288 Author: Caolán McNamara <[email protected]> AuthorDate: Tue May 24 12:09:51 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:20:36 2022 +0200 ofz#47589 can't avoid passing in an output in the general case after all there's a flip case which assumes the dest buffer is available, so the 'ALTERNATE RASTER FORMATS' case of man TIFFRGBAImageGet isn't as useful as it looked initially. This reverts commit e912a446210fdae61be3fc04d20d90488cedcdf6, etc Change-Id: I09a614a5469c8996f93af103581099242747fd7d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134866 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/qa/cppunit/graphicfilter/data/tiff/fail/ofz47589.tiff b/vcl/qa/cppunit/graphicfilter/data/tiff/fail/ofz47589.tiff new file mode 100644 index 000000000000..936afbd992e4 Binary files /dev/null and b/vcl/qa/cppunit/graphicfilter/data/tiff/fail/ofz47589.tiff differ diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 4514ce916959..b682d759f115 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -36,83 +36,10 @@ namespace { SvStream& rStream; tsize_t nSize; - /* - ORIENTATION_TOPLEFT = 1 - ORIENTATION_TOPRIGHT = 2 - ORIENTATION_BOTRIGHT = 3 - ORIENTATION_BOTLEFT = 4 - ORIENTATION_LEFTTOP = 5 - ORIENTATION_RIGHTTOP = 6 - ORIENTATION_RIGHTBOT = 7 - ORIENTATION_LEFTBOT = 8 - */ - uint16_t nOrientation; - - tileContigRoutine pOrigContig; - tileSeparateRoutine pOrigSeparate; - BitmapWriteAccess* pWriteAccess; - BitmapWriteAccess* pAlphaAccess; - std::vector<uint32_t> aBuffer; - Context(SvStream& rInStream, tsize_t nInSize) : rStream(rInStream) , nSize(nInSize) - , nOrientation(0) - , pOrigContig(nullptr) - , pOrigSeparate(nullptr) - , pWriteAccess(nullptr) - , pAlphaAccess(nullptr) - { - } - - uint32_t* GetBuffer(uint32_t w, uint32_t h, int32_t toskew) { - uint32_t nExtraPerRow; - if (toskew >= 0) - nExtraPerRow = toskew; - else - { - int32_t nExtraNeg = w + toskew + w; - nExtraPerRow = std::abs(nExtraNeg); - } - uint32_t nScanLine = w + nExtraPerRow; - aBuffer.resize(nScanLine * h); - uint32_t* pBuffer = aBuffer.data(); - if (toskew < 0) - pBuffer += h * nScanLine - nScanLine; - - return pBuffer; - } - - void SetPixels(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const uint32_t* pSrc, int32_t skew) - { - uint32_t nDestRow = y; - for (uint32_t nRow = 0; nRow < h; ++nRow) - { - for (uint32_t nCol = 0; nCol < w; ++nCol) - { - uint32_t nDestCol; - switch (nOrientation) - { - case ORIENTATION_LEFTBOT: - nDestCol = x + w - 1 - nCol; - break; - default: - nDestCol = x + nCol; - break; - } - - pWriteAccess->SetPixel(nDestRow, nDestCol, - Color(TIFFGetR(*pSrc), TIFFGetG(*pSrc), TIFFGetB(*pSrc))); - pAlphaAccess->SetPixelIndex(nDestRow, nDestCol, 255 - TIFFGetA(*pSrc)); - ++pSrc; - } - pSrc += skew; - if (skew >= 0) - ++nDestRow; - else - --nDestRow; - } } }; } @@ -163,36 +90,6 @@ static toff_t tiff_size(thandle_t handle) return pContext->nSize; } -static void putContigPixel(TIFFRGBAImage* img, uint32_t* /*raster*/, - uint32_t x, uint32_t y, uint32_t w, uint32_t h, - int32_t fromskew, int32_t toskew, - unsigned char* cp) -{ - Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); - - uint32_t* pBuffer = pContext->GetBuffer(w, h, toskew); - - (pContext->pOrigContig)(img, pBuffer, 0, 0, w, h, - fromskew, toskew, cp); - - pContext->SetPixels(x, y, w, h, pBuffer, toskew); -} - -static void putSeparatePixel(TIFFRGBAImage* img, uint32_t* /*raster*/, - uint32_t x, uint32_t y, uint32_t w, uint32_t h, - int32_t fromskew, int32_t toskew, - unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) -{ - Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); - - uint32_t* pBuffer = pContext->GetBuffer(w, h, toskew); - - (pContext->pOrigSeparate)(img, pBuffer, 0, 0, w, h, - fromskew, toskew, r, g, b, a); - - pContext->SetPixels(x, y, w, h, pBuffer, toskew); -} - bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) { Context aContext(rTIFF, rTIFF.remainingSize()); @@ -228,68 +125,65 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) break; } - aContext.nOrientation = 0; - TIFFGetField(tif, TIFFTAG_ORIENTATION, &aContext.nOrientation); - - Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); - AlphaMask bitmapAlpha(Size(w, h)); - - BitmapScopedWriteAccess access(bitmap); - AlphaScopedWriteAccess accessAlpha(bitmapAlpha); - - if (!access || !accessAlpha) + size_t npixels = w * h; + std::vector<uint32_t> raster(npixels); + if (TIFFReadRGBAImageOriented(tif, w, h, raster.data(), ORIENTATION_TOPLEFT, 1)) { - SAL_WARN("filter.tiff", "could not create bitmaps"); - break; - } + Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); + AlphaMask bitmapAlpha(Size(w, h)); + + BitmapScopedWriteAccess access(bitmap); + AlphaScopedWriteAccess accessAlpha(bitmapAlpha); + + /* + ORIENTATION_TOPLEFT = 1 + ORIENTATION_TOPRIGHT = 2 + ORIENTATION_BOTRIGHT = 3 + ORIENTATION_BOTLEFT = 4 + ORIENTATION_LEFTTOP = 5 + ORIENTATION_RIGHTTOP = 6 + ORIENTATION_RIGHTBOT = 7 + ORIENTATION_LEFTBOT = 8 + */ + uint16_t nOrientation; + if (TIFFGetField(tif, TIFFTAG_ORIENTATION, &nOrientation) != 1) + nOrientation = 0; + + for (uint32_t y = 0; y < h; ++y) + { + const uint32_t* src = raster.data() + w * y; + for (uint32_t x = 0; x < w; ++x) + { + sal_uInt8 r = TIFFGetR(*src); + sal_uInt8 g = TIFFGetG(*src); + sal_uInt8 b = TIFFGetB(*src); + sal_uInt8 a = TIFFGetA(*src); - aContext.pWriteAccess = access.get(); - aContext.pAlphaAccess = accessAlpha.get(); + uint32_t dest; + switch (nOrientation) + { + case ORIENTATION_LEFTBOT: + dest = w - 1 - x; + break; + default: + dest = x; + break; + } - char emsg[1024] = ""; - TIFFRGBAImage img; - bool bOk = false; - // Expanded out TIFFReadRGBAImageOriented to create this block then - // inserted custom "put" methods to write (via a limited size buffer) - // into the final Bitmap incrementally - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 1, emsg)) - { - img.req_orientation = ORIENTATION_TOPLEFT; - assert(img.isContig); - if (img.isContig) - { - aContext.pOrigContig = img.put.contig; - img.put.contig = putContigPixel; - } - else - { - aContext.pOrigSeparate = img.put.separate; - img.put.separate = putSeparatePixel; + access->SetPixel(y, dest, Color(r, g, b)); + accessAlpha->SetPixelIndex(y, dest, 255 - a); + ++src; + } } - // we don't access TIFFRGBAImageGet's raster argument in our custom putContigPixel/ - // putSeparatePixel functions, but TIFFRGBAImageGet nevertheless internally - // advances that pointer, so passing nullptr would cause UBSan nullptr-with-offset - // errors; while technically still UB, this HACK of passing a non-null pointer keeps - // UBSan happy for now (and better use an artificial pointer value which would - // hopefully cause SIGSEGV if it should erroneously be dereferenced after all) - uint32_t* unused_raster = reinterpret_cast<uint32_t *>(sizeof (uint32_t)); - bOk = TIFFRGBAImageGet(&img, unused_raster, w, img.height); - TIFFRGBAImageEnd(&img); - } - else - { - SAL_WARN("filter.tiff", "cannot import tiff, error is: " << emsg); - } + raster.clear(); - access.reset(); - accessAlpha.reset(); + access.reset(); + accessAlpha.reset(); - if (bOk) - { BitmapEx aBitmapEx(bitmap, bitmapAlpha); - switch (aContext.nOrientation) + switch (nOrientation) { case ORIENTATION_LEFTBOT: aBitmapEx.Rotate(2700_deg10, COL_BLACK); @@ -302,7 +196,6 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back); aAnimation.Insert(aAnimationBitmap); } - } while (TIFFReadDirectory(tif)); TIFFClose(tif); commit 845fdd34ceb30a460a3c60ae63bfd66f13426743 Author: Caolán McNamara <[email protected]> AuthorDate: Mon May 23 17:24:06 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:20:31 2022 +0200 move the comment around a bit Change-Id: I784534285baa5e68f8d8877c6a5fe8c10e5eb429 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134843 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 9f51e28df0a9..4514ce916959 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -267,14 +267,14 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) img.put.separate = putSeparatePixel; } - bOk = TIFFRGBAImageGet( - &img, reinterpret_cast<uint32_t *>(sizeof (uint32_t)), w, img.height); - // we don't access TIFFRGBAImageGet's raster argument in our custom putContigPixel/ - // putSeparatePixel functions, but TIFFRGBAImageGet nevertheless internally - // advances that pointer, so passing nullptr would cause UBSan nullptr-with-offset - // errors; while technically still UB, this HACK of passing a non-null pointer keeps - // UBSan happy for now (and better use an artificial pointer value which would - // hopefully cause SIGSEGV if it should erroneously be dereferenced after all) + // we don't access TIFFRGBAImageGet's raster argument in our custom putContigPixel/ + // putSeparatePixel functions, but TIFFRGBAImageGet nevertheless internally + // advances that pointer, so passing nullptr would cause UBSan nullptr-with-offset + // errors; while technically still UB, this HACK of passing a non-null pointer keeps + // UBSan happy for now (and better use an artificial pointer value which would + // hopefully cause SIGSEGV if it should erroneously be dereferenced after all) + uint32_t* unused_raster = reinterpret_cast<uint32_t *>(sizeof (uint32_t)); + bOk = TIFFRGBAImageGet(&img, unused_raster, w, img.height); TIFFRGBAImageEnd(&img); } else commit f1a662f7c27b57a749b5998de1567da3534434a4 Author: Stephan Bergmann <[email protected]> AuthorDate: Tue May 24 09:18:38 2022 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:19:02 2022 +0200 workdir/UnpackedTarball/libtiff/libtiff/tiff.h is generated ...and included via vcl/source/filter/itiff/itiff.cxx -> workdir/UnpackedTarball/libtiff/libtiff/tiffio.h -> workdir/UnpackedTarball/libtiff/libtiff/tiff.h Change-Id: I717e23946d7d14572c5e9de9f7319d553a76364a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134851 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index a86c1e60addb..c3f14a38d831 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -2770,7 +2770,7 @@ $(call gb_LinkTarget_add_libs,$(1),\ -L$(call gb_UnpackedTarball_get_dir,libtiff)/libtiff/.libs -ltiff \ ) endif -$(call gb_LinkTarget_use_external_project,$(1),libtiff) +$(call gb_LinkTarget_use_external_project,$(1),libtiff,full) endef commit ca9c0b90a0116f830b9eb052bb28c65338059b09 Author: Caolán McNamara <[email protected]> AuthorDate: Mon May 23 21:01:24 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:18:48 2022 +0200 We actually want to divide by 257 here follow the * 257 suggestion at https://gitlab.com/libtiff/libtiff/-/merge_requests/336 I did think it looked a tiny bit different than the others Change-Id: I92306ae22d2acc485a4162160a8c0464a32591d9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134844 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/external/libtiff/libtiff.16bitcielab.patch b/external/libtiff/libtiff.16bitcielab.patch index cecce9cd8402..968de975f641 100644 --- a/external/libtiff/libtiff.16bitcielab.patch +++ b/external/libtiff/libtiff.16bitcielab.patch @@ -34,9 +34,9 @@ + for( ; h > 0; --h) { + for (x = w; x > 0; --x) { + TIFFCIELabToXYZ(img->cielab, -+ wp[0] / 256, -+ wp[1] / 256, -+ wp[2] / 256, ++ (uint16_t)wp[0] / 257, ++ (int16_t)wp[1] / 256, ++ (int16_t)wp[2] / 256, + &X, &Y, &Z); + TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); + *cp++ = PACK(r, g, b); commit 874a6f008fe32be8ef25a96ae404d62925364ade Author: Miklos Vajna <[email protected]> AuthorDate: Mon May 23 16:24:00 2022 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:18:33 2022 +0200 sw HTML import: extend list of MIME types recognized as image objects The HTML import sometimes imports <object> elements as embedded objects and sometimes as Writer images. This MIME-type based approach works great to differentiate plain images (with PNG fallback) from real embedded objects, but analysis on some larger document corpus pointed out a few missing entries in this allow-list. Fix the problem by adding a 2nd variant for BMP, TIFF and WMF, which should also count as image, not object. This could be improved further in a later commit by getting a full list of image MIME types we support from VCL. Change-Id: Idb2485012e44b4c7db396b5062e7173f3c85495e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134826 Tested-by: Jenkins Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/source/filter/html/htmlplug.cxx b/sw/source/filter/html/htmlplug.cxx index 76e07d63073d..46b1b8952b45 100644 --- a/sw/source/filter/html/htmlplug.cxx +++ b/sw/source/filter/html/htmlplug.cxx @@ -444,6 +444,9 @@ bool SwHTMLParser::InsertEmbed() u"image/svg+xml", u"image/tiff", u"image/x-emf", + u"image/bmp", + u"image/tif", + u"image/wmf", }; if (vAllowlist.find(aType) != vAllowlist.end() && m_aEmbeds.empty()) commit ed14c4548809006c1ec02661c2066c0361290bf6 Author: Stephan Bergmann <[email protected]> AuthorDate: Mon May 23 15:05:47 2022 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:18:11 2022 +0200 external/libtiff: Silence invalid-null-argument ...during CppunitTest_vcl_filters_test, > tif_dirread.c:4176:40: runtime error: null pointer passed as argument 2, which is declared to never be null > /usr/include/string.h:44:28: note: nonnull attribute specified here > #0 in TIFFReadDirectory at workdir/UnpackedTarball/libtiff/libtiff/tif_dirread.c:4176:17 (instdir/program/libvcllo.so +0xc4dbb6d) > #1 in ImportTiffGraphicImport(SvStream&, Graphic&) at vcl/source/filter/itiff/itiff.cxx:238:14 (instdir/program/libvcllo.so +0xa691680) > #2 in TiffFilterTest::load(rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int) at vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx:70:12 (workdir/LinkTarget/CppunitTest/libtest_vcl_filters_test.so +0x16dc48) > #3 in test::FiltersTest::recursiveScan(test::filterStatus, rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int, bool) at unotest/source/cpp/filters-test.cxx:132:20 (workdir/LinkTarget/CppunitTest/../Library/libunotest.so +0xd8d5c) > #4 in test::FiltersTest::testDir(rtl::OUString const&, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int, bool) at unotest/source/cpp/filters-test.cxx:160:5 (workdir/LinkTarget/CppunitTest/../Library/libunotest.so +0xdcc71) > #5 in TiffFilterTest::testCVEs() at vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx:76:5 (workdir/LinkTarget/CppunitTest/libtest_vcl_filters_test.so +0x16e1c5) Change-Id: I2de4363ff0f5552e89fd0af84b7b88e38b7bb209 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134823 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk index ee3d4ab6cb27..f874d6d61743 100644 --- a/external/libtiff/UnpackedTarball_libtiff.mk +++ b/external/libtiff/UnpackedTarball_libtiff.mk @@ -16,6 +16,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0)) $(eval $(call gb_UnpackedTarball_add_patches,libtiff,\ external/libtiff/libtiff.linknolibs.patch \ external/libtiff/libtiff.16bitcielab.patch \ + external/libtiff/ubsan.patch \ )) # vim: set noet sw=4 ts=4: diff --git a/external/libtiff/ubsan.patch b/external/libtiff/ubsan.patch new file mode 100644 index 000000000000..853d069ad795 --- /dev/null +++ b/external/libtiff/ubsan.patch @@ -0,0 +1,11 @@ +--- libtiff/tif_dirread.c ++++ libtiff/tif_dirread.c +@@ -4173,7 +4173,7 @@ + goto bad; + } + +- memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); ++ if (old_extrasamples != 0) memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); + _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); + _TIFFfree(new_sampleinfo); + } commit c0795ad2c3a0a3a7264f94cdbd0fd42fde699c78 Author: Stephan Bergmann <[email protected]> AuthorDate: Mon May 23 14:57:18 2022 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:18:00 2022 +0200 Bad hack to silence UBSan nullptr-with-offset ...since e912a446210fdae61be3fc04d20d90488cedcdf6 "tiff: use more complicated apis to need a smaller buffer during read" in CppunitTest_vcl_filters_test, > [_RUN_____] TiffFilterTest::testCVEs [...] > tif_getimage.c:998:21: runtime error: applying zero offset to null pointer > #0 0x7f487da9d408 in gtStripContig /workdir/UnpackedTarball/libtiff/libtiff/tif_getimage.c:998:21 > #1 0x7f487da97c27 in TIFFRGBAImageGet /workdir/UnpackedTarball/libtiff/libtiff/tif_getimage.c:512:12 > #2 0x7f487bd1a56c in ImportTiffGraphicImport(SvStream&, Graphic&) /vcl/source/filter/itiff/itiff.cxx:219:19 > #3 0x7f485d820126 in TiffFilterTest::load(rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int) /vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx:70:12 > #4 0x7f485a49ffa0 in test::FiltersTest::recursiveScan(test::filterStatus, rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int, bool) /unotest/source/cpp/filters-test.cxx:132:20 > #5 0x7f485a4a3a52 in test::FiltersTest::testDir(rtl::OUString const&, std::basic_string_view<char16_t, std::char_traits<char16_t> >, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int, bool) /unotest/source/cpp/filters-test.cxx:157:5 > #6 0x7f485d8206f9 in TiffFilterTest::testCVEs() /vcl/qa/cppunit/graphicfilter/filters-tiff-test.cxx:76:5 (<https://ci.libreoffice.org/job/lo_ubsan/2406/>). (If UBSan or some other tool starts to flag this too, we'll probably need to pass in a nullptr after all and teach libtiff to treat that case specially and not advance it.) Change-Id: I4477e6c7036c3c5f2782c2c90c612d98fee60468 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134822 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 292621ed0b83..9f51e28df0a9 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -267,7 +267,14 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) img.put.separate = putSeparatePixel; } - bOk = TIFFRGBAImageGet(&img, nullptr, w, img.height); + bOk = TIFFRGBAImageGet( + &img, reinterpret_cast<uint32_t *>(sizeof (uint32_t)), w, img.height); + // we don't access TIFFRGBAImageGet's raster argument in our custom putContigPixel/ + // putSeparatePixel functions, but TIFFRGBAImageGet nevertheless internally + // advances that pointer, so passing nullptr would cause UBSan nullptr-with-offset + // errors; while technically still UB, this HACK of passing a non-null pointer keeps + // UBSan happy for now (and better use an artificial pointer value which would + // hopefully cause SIGSEGV if it should erroneously be dereferenced after all) TIFFRGBAImageEnd(&img); } else commit 7c15c269a4a303e2acf2cb2b6d5f715c9acb9963 Author: Julien Nabet <[email protected]> AuthorDate: Mon May 23 13:40:15 2022 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:17:48 2022 +0200 README libtiff Change-Id: Icece0daad46896334cba7dc66435351a347bd2cb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134819 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/external/libtiff/README b/external/libtiff/README new file mode 100644 index 000000000000..a650ea584a6a --- /dev/null +++ b/external/libtiff/README @@ -0,0 +1,3 @@ +libtiff is a library to encode and decode images in TIFF format, from [http://download.osgeo.org/libtiff/] + +For the moment we use it only for decoding part. commit 1b5cccdaa3e50de0d4d794fcc705f764d1ffb4de Author: Caolán McNamara <[email protected]> AuthorDate: Mon May 23 11:57:17 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:17:24 2022 +0200 tiff: reverse row pixels for ORIENTATION_LEFTBOT and rotate e.g. novell600797-1.tiff Change-Id: I03edcc44f86a40f3e005bec1d8b82a0a89cad276 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134817 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 90c7bf5f3422..292621ed0b83 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -36,6 +36,17 @@ namespace { SvStream& rStream; tsize_t nSize; + /* + ORIENTATION_TOPLEFT = 1 + ORIENTATION_TOPRIGHT = 2 + ORIENTATION_BOTRIGHT = 3 + ORIENTATION_BOTLEFT = 4 + ORIENTATION_LEFTTOP = 5 + ORIENTATION_RIGHTTOP = 6 + ORIENTATION_RIGHTBOT = 7 + ORIENTATION_LEFTBOT = 8 + */ + uint16_t nOrientation; tileContigRoutine pOrigContig; tileSeparateRoutine pOrigSeparate; @@ -46,6 +57,7 @@ namespace Context(SvStream& rInStream, tsize_t nInSize) : rStream(rInStream) , nSize(nInSize) + , nOrientation(0) , pOrigContig(nullptr) , pOrigSeparate(nullptr) , pWriteAccess(nullptr) @@ -79,9 +91,20 @@ namespace { for (uint32_t nCol = 0; nCol < w; ++nCol) { - pWriteAccess->SetPixel(nDestRow, x + nCol, + uint32_t nDestCol; + switch (nOrientation) + { + case ORIENTATION_LEFTBOT: + nDestCol = x + w - 1 - nCol; + break; + default: + nDestCol = x + nCol; + break; + } + + pWriteAccess->SetPixel(nDestRow, nDestCol, Color(TIFFGetR(*pSrc), TIFFGetG(*pSrc), TIFFGetB(*pSrc))); - pAlphaAccess->SetPixelIndex(nDestRow, x + nCol, 255 - TIFFGetA(*pSrc)); + pAlphaAccess->SetPixelIndex(nDestRow, nDestCol, 255 - TIFFGetA(*pSrc)); ++pSrc; } pSrc += skew; @@ -205,6 +228,9 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) break; } + aContext.nOrientation = 0; + TIFFGetField(tif, TIFFTAG_ORIENTATION, &aContext.nOrientation); + Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); AlphaMask bitmapAlpha(Size(w, h)); @@ -255,6 +281,16 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) if (bOk) { BitmapEx aBitmapEx(bitmap, bitmapAlpha); + + switch (aContext.nOrientation) + { + case ORIENTATION_LEFTBOT: + aBitmapEx.Rotate(2700_deg10, COL_BLACK); + break; + default: + break; + } + AnimationBitmap aAnimationBitmap(aBitmapEx, Point(0, 0), aBitmapEx.GetSizePixel(), ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back); aAnimation.Insert(aAnimationBitmap); commit b474b670234287a04e756322f749baf1bb943da1 Author: Caolán McNamara <[email protected]> AuthorDate: Mon May 23 10:47:03 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:17:15 2022 +0200 crashtesting: we can have negative skew which is used to fill rows backwards Change-Id: I07543a622b9566a1a4a8e85c72302545600916c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134816 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index cb512d58577d..90c7bf5f3422 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -53,20 +53,42 @@ namespace { } - void SetPixels(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t skew) + uint32_t* GetBuffer(uint32_t w, uint32_t h, int32_t toskew) { - const uint32_t* pSrc = aBuffer.data(); + uint32_t nExtraPerRow; + if (toskew >= 0) + nExtraPerRow = toskew; + else + { + int32_t nExtraNeg = w + toskew + w; + nExtraPerRow = std::abs(nExtraNeg); + } + uint32_t nScanLine = w + nExtraPerRow; + aBuffer.resize(nScanLine * h); + uint32_t* pBuffer = aBuffer.data(); + if (toskew < 0) + pBuffer += h * nScanLine - nScanLine; + + return pBuffer; + } + void SetPixels(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const uint32_t* pSrc, int32_t skew) + { + uint32_t nDestRow = y; for (uint32_t nRow = 0; nRow < h; ++nRow) { for (uint32_t nCol = 0; nCol < w; ++nCol) { - pWriteAccess->SetPixel(y + nRow, x + nCol, + pWriteAccess->SetPixel(nDestRow, x + nCol, Color(TIFFGetR(*pSrc), TIFFGetG(*pSrc), TIFFGetB(*pSrc))); - pAlphaAccess->SetPixelIndex(y + nRow, x + nCol, 255 - TIFFGetA(*pSrc)); + pAlphaAccess->SetPixelIndex(nDestRow, x + nCol, 255 - TIFFGetA(*pSrc)); ++pSrc; } pSrc += skew; + if (skew >= 0) + ++nDestRow; + else + --nDestRow; } } }; @@ -125,11 +147,12 @@ static void putContigPixel(TIFFRGBAImage* img, uint32_t* /*raster*/, { Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); - pContext->aBuffer.resize((w + toskew) * h); - (pContext->pOrigContig)(img, pContext->aBuffer.data(), 0, 0, w, h, + uint32_t* pBuffer = pContext->GetBuffer(w, h, toskew); + + (pContext->pOrigContig)(img, pBuffer, 0, 0, w, h, fromskew, toskew, cp); - pContext->SetPixels(x, y, w, h, toskew); + pContext->SetPixels(x, y, w, h, pBuffer, toskew); } static void putSeparatePixel(TIFFRGBAImage* img, uint32_t* /*raster*/, @@ -139,11 +162,12 @@ static void putSeparatePixel(TIFFRGBAImage* img, uint32_t* /*raster*/, { Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); - pContext->aBuffer.resize((w + toskew) * h); - (pContext->pOrigSeparate)(img, pContext->aBuffer.data(), 0, 0, w, h, + uint32_t* pBuffer = pContext->GetBuffer(w, h, toskew); + + (pContext->pOrigSeparate)(img, pBuffer, 0, 0, w, h, fromskew, toskew, r, g, b, a); - pContext->SetPixels(x, y, w, h, toskew); + pContext->SetPixels(x, y, w, h, pBuffer, toskew); } bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) commit 1dc0f4b05ba67901ec6a4008b0b8ca159db67f7c Author: Caolán McNamara <[email protected]> AuthorDate: Mon May 23 08:54:04 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:13:34 2022 +0200 tiled tiff found at rhbz552360-2.tiff fix up wrt skew and buffer size and the right put function Change-Id: Iff93876c39213668f38ba341e597741b695b47bf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134759 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index f919cda526dc..cb512d58577d 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -53,7 +53,7 @@ namespace { } - void SetPixels(uint32_t x, uint32_t y, uint32_t w, uint32_t h) + void SetPixels(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t skew) { const uint32_t* pSrc = aBuffer.data(); @@ -66,6 +66,7 @@ namespace pAlphaAccess->SetPixelIndex(y + nRow, x + nCol, 255 - TIFFGetA(*pSrc)); ++pSrc; } + pSrc += skew; } } }; @@ -124,11 +125,11 @@ static void putContigPixel(TIFFRGBAImage* img, uint32_t* /*raster*/, { Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); - pContext->aBuffer.resize(w * h); + pContext->aBuffer.resize((w + toskew) * h); (pContext->pOrigContig)(img, pContext->aBuffer.data(), 0, 0, w, h, fromskew, toskew, cp); - pContext->SetPixels(x, y, w, h); + pContext->SetPixels(x, y, w, h, toskew); } static void putSeparatePixel(TIFFRGBAImage* img, uint32_t* /*raster*/, @@ -138,11 +139,11 @@ static void putSeparatePixel(TIFFRGBAImage* img, uint32_t* /*raster*/, { Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); - pContext->aBuffer.resize(w * h); + pContext->aBuffer.resize((w + toskew) * h); (pContext->pOrigSeparate)(img, pContext->aBuffer.data(), 0, 0, w, h, fromskew, toskew, r, g, b, a); - pContext->SetPixels(x, y, w, h); + pContext->SetPixels(x, y, w, h, toskew); } bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) @@ -204,8 +205,8 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 1, emsg)) { img.req_orientation = ORIENTATION_TOPLEFT; - assert(!TIFFIsTiled(img.tif)); - if (!TIFFIsTiled(img.tif)) + assert(img.isContig); + if (img.isContig) { aContext.pOrigContig = img.put.contig; img.put.contig = putContigPixel; commit 900a7f57f42e15818b9bd97029950fab58016a8b Author: Caolán McNamara <[email protected]> AuthorDate: Sun May 22 21:23:05 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:13:28 2022 +0200 for fuzzers add libtiff to common externals, not just tiffuzzer Change-Id: I747a39a26c446000924a1d48c5d650fac330216e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134746 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/Executable_tiffuzzer.mk b/vcl/Executable_tiffuzzer.mk index 0b3613a2eeba..79bb4ad2c8f5 100644 --- a/vcl/Executable_tiffuzzer.mk +++ b/vcl/Executable_tiffuzzer.mk @@ -19,7 +19,6 @@ $(eval $(call gb_Executable_use_api,tiffuzzer,\ $(eval $(call gb_Executable_use_externals,tiffuzzer,\ $(fuzzer_externals) \ - libtiff \ )) $(eval $(call gb_Executable_set_include,tiffuzzer,\ diff --git a/vcl/commonfuzzer.mk b/vcl/commonfuzzer.mk index 8688894f544f..b1f6c18f9448 100644 --- a/vcl/commonfuzzer.mk +++ b/vcl/commonfuzzer.mk @@ -35,6 +35,7 @@ fuzzer_externals = \ libxml2 \ libjpeg \ libpng \ + libtiff \ openssl \ expat \ mythes \ commit 721160d0b95ff9cf5cc666af4003420cae212869 Author: Caolán McNamara <[email protected]> AuthorDate: Sun May 22 14:12:13 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:12:14 2022 +0200 tdf#131199 add some basic 16bitcielab support to get that final tiff loadable Change-Id: Ia772c06521c93ac860e9d3014706d677f16c8d4e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134734 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk index ce5a3a53d36a..ee3d4ab6cb27 100644 --- a/external/libtiff/UnpackedTarball_libtiff.mk +++ b/external/libtiff/UnpackedTarball_libtiff.mk @@ -15,6 +15,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0)) $(eval $(call gb_UnpackedTarball_add_patches,libtiff,\ external/libtiff/libtiff.linknolibs.patch \ + external/libtiff/libtiff.16bitcielab.patch \ )) # vim: set noet sw=4 ts=4: diff --git a/external/libtiff/libtiff.16bitcielab.patch b/external/libtiff/libtiff.16bitcielab.patch new file mode 100644 index 000000000000..cecce9cd8402 --- /dev/null +++ b/external/libtiff/libtiff.16bitcielab.patch @@ -0,0 +1,75 @@ +--- libtiff/tif_getimage.c 2021-03-05 13:01:43.000000000 +0000 ++++ libtiff/tif_getimage.c 2022-05-22 14:05:56.320883484 +0100 +@@ -194,7 +194,7 @@ + } + break; + case PHOTOMETRIC_CIELAB: +- if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) { ++ if ( td->td_samplesperpixel != 3 || colorchannels != 3 || (td->td_bitspersample != 8 && td->td_bitspersample != 16) ) { + sprintf(emsg, + "Sorry, can not handle image with %s=%"PRIu16", %s=%d and %s=%"PRIu16, + "Samples/pixel", td->td_samplesperpixel, +@@ -1784,7 +1784,7 @@ + /* + * 8-bit packed CIE L*a*b 1976 samples => RGB + */ +-DECLAREContigPutFunc(putcontig8bitCIELab) ++DECLAREContigPutFunc(putcontig8bitCIELab8) + { + float X, Y, Z; + uint32_t r, g, b; +@@ -1807,6 +1807,32 @@ + } + + /* ++ * 16-bit packed CIE L*a*b 1976 samples => RGB ++ */ ++DECLAREContigPutFunc(putcontig8bitCIELab16) ++{ ++ float X, Y, Z; ++ uint32_t r, g, b; ++ uint16_t *wp = (uint16_t *)pp; ++ (void) y; ++ fromskew = 3; ++ for( ; h > 0; --h) { ++ for (x = w; x > 0; --x) { ++ TIFFCIELabToXYZ(img->cielab, ++ wp[0] / 256, ++ wp[1] / 256, ++ wp[2] / 256, ++ &X, &Y, &Z); ++ TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); ++ *cp++ = PACK(r, g, b); ++ wp += 3; ++ } ++ cp += toskew; ++ wp += fromskew; ++ } ++} ++ ++/* + * YCbCr -> RGB conversion and packing routines. + */ + +@@ -2395,7 +2421,11 @@ + return NULL; + } + +- return putcontig8bitCIELab; ++ if (img->bitspersample == 8) ++ return putcontig8bitCIELab8; ++ else if (img->bitspersample == 16) ++ return putcontig8bitCIELab16; ++ return NULL; + } + + /* +@@ -2777,7 +2807,7 @@ + break; + case PHOTOMETRIC_CIELAB: + if (img->samplesperpixel == 3 && buildMap(img)) { +- if (img->bitspersample == 8) ++ if (img->bitspersample == 8 || img->bitspersample == 16) + img->put.contig = initCIELabConversion(img); + break; + } commit 87eea116243563d095b2add404653625b81b7878 Author: Caolán McNamara <[email protected]> AuthorDate: Sun May 22 19:41:31 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:12:00 2022 +0200 move fuzzer to libtiff Change-Id: Ib2a3da65f13a239076981473410a0e3240cab670 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134744 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/Executable_tiffuzzer.mk b/vcl/Executable_tiffuzzer.mk index 79bb4ad2c8f5..0b3613a2eeba 100644 --- a/vcl/Executable_tiffuzzer.mk +++ b/vcl/Executable_tiffuzzer.mk @@ -19,6 +19,7 @@ $(eval $(call gb_Executable_use_api,tiffuzzer,\ $(eval $(call gb_Executable_use_externals,tiffuzzer,\ $(fuzzer_externals) \ + libtiff \ )) $(eval $(call gb_Executable_set_include,tiffuzzer,\ commit 818b66ed761ebe007b0b7f9851a1bdd259e41298 Author: Caolán McNamara <[email protected]> AuthorDate: Sat May 21 20:48:54 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:11:41 2022 +0200 tiff: output libtiff error via SAL_WARN for failures Change-Id: Iff62f8081d5d7b1971940775bd72722f376bf3d0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134716 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index dde8a1f996b7..f919cda526dc 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -219,6 +219,10 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) bOk = TIFFRGBAImageGet(&img, nullptr, w, img.height); TIFFRGBAImageEnd(&img); } + else + { + SAL_WARN("filter.tiff", "cannot import tiff, error is: " << emsg); + } access.reset(); accessAlpha.reset(); commit d71e9279357c8c1c2bed62a65b7573df863fac0f Author: Caolán McNamara <[email protected]> AuthorDate: Sat May 21 16:30:59 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:11:21 2022 +0200 tiff: enable webp Change-Id: Ifd277fd89393f964817bf58dead53074321252d8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134711 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk index dc1a42b96277..a86c1e60addb 100644 --- a/RepositoryExternal.mk +++ b/RepositoryExternal.mk @@ -2775,9 +2775,7 @@ $(call gb_LinkTarget_use_external_project,$(1),libtiff) endef define gb_ExternalProject__use_libtiff -$(call gb_ExternalProject_use_external_project,$(1),\ - libtiff \ -) +$(call gb_ExternalProject_use_external_project,$(1),libtiff) endef @@ -2825,9 +2823,7 @@ $(call gb_LinkTarget_use_external_project,$(1),libwebp) endef define gb_ExternalProject__use_libwebp -$(call gb_ExternalProject_use_external_project,$(1),\ - libwebp \ -) +$(call gb_ExternalProject_use_external_project,$(1),libwebp) endef diff --git a/external/libtiff/ExternalProject_libtiff.mk b/external/libtiff/ExternalProject_libtiff.mk index e9ecbdf86765..04af18322541 100644 --- a/external/libtiff/ExternalProject_libtiff.mk +++ b/external/libtiff/ExternalProject_libtiff.mk @@ -15,6 +15,7 @@ $(eval $(call gb_ExternalProject_register_targets,libtiff,\ $(eval $(call gb_ExternalProject_use_externals,libtiff,\ libjpeg \ + libwebp \ zlib \ )) @@ -36,6 +37,7 @@ $(call gb_ExternalProject_get_state_target,libtiff,build) : --enable-static \ --enable-jpeg \ --enable-zlib \ + --enable-webp \ --disable-shared \ --disable-cxx \ --disable-libdeflate \ @@ -43,7 +45,6 @@ $(call gb_ExternalProject_get_state_target,libtiff,build) : --disable-lerc \ --disable-lzma \ --disable-mdi \ - --disable-webp \ --disable-win32-io \ --disable-zstd \ --with-pic \ @@ -54,10 +55,15 @@ $(call gb_ExternalProject_get_state_target,libtiff,build) : $(if $(SYSTEM_ZLIB),,--with-zlib-lib-dir="$(gb_StaticLibrary_WORKDIR)") \ $(if $(SYSTEM_LIBJPEG),,--with-jpeg-include-dir="$(call gb_UnpackedTarball_get_dir,libjpeg-turbo)") \ $(if $(SYSTEM_LIBJPEG),,--with-jpeg-lib-dir="$(gb_StaticLibrary_WORKDIR)") \ + $(if $(SYSTEM_LIBWEBP),,--with-webp-include-dir="$(call gb_UnpackedTarball_get_dir,libwebp/src)") \ + $(if $(SYSTEM_LIBWEBP),,$(if $(filter WNT,$(OS_FOR_BUILD)),\ + --with-webp-lib-dir="$(call gb_UnpackedTarball_get_dir,libwebp)/output/lib/libwebp$(if $(MSVC_USE_DEBUG_RUNTIME),_debug)$(gb_StaticLibrary_PLAINEXT)", \ + --with-webp-lib-dir="$(call gb_UnpackedTarball_get_dir,libwebp)/src/.libs")) \ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libtiff)" \ ac_cv_lib_z_inflateEnd=yes \ ac_cv_lib_jpeg_jpeg_read_scanlines=yes \ + ac_cv_lib_webp_WebPDecode=yes \ $(gb_CONFIGURE_PLATFORMS) \ && cd libtiff && $(MAKE) libtiff.la \ ) commit 3a1307001d5d9c20087739943aed35206cedc766 Author: Rene Engelhard <[email protected]> AuthorDate: Sat May 21 15:48:57 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:11:08 2022 +0200 fix system libtiff detection Change-Id: I9cd29a48a0b46bae9d265b502b250709ec8a3247 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134710 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/configure.ac b/configure.ac index 91a450681616..155f29fae282 100644 --- a/configure.ac +++ b/configure.ac @@ -13599,7 +13599,7 @@ dnl =================================================================== dnl Test whether to build libtiff or rely on the system version dnl =================================================================== -libo_CHECK_SYSTEM_MODULE([libtiff],[LIBTIFF],[libtiff]) +libo_CHECK_SYSTEM_MODULE([libtiff],[LIBTIFF],[libtiff-4]) dnl =================================================================== dnl Test whether to build libwebp or rely on the system version commit ab000227ea216a3789f9971ecb001e6ef15c094e Author: Caolán McNamara <[email protected]> AuthorDate: Fri May 20 20:16:17 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:10:55 2022 +0200 tiff: add some error checks Change-Id: I55ca42f637c802bc917eeba5c08cc82074edd523 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134697 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 8fa61c4509b5..dde8a1f996b7 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -162,8 +162,23 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) { uint32_t w, h; - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + if (TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w) != 1) + { + SAL_WARN("filter.tiff", "missing width"); + break; + } + + if (TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h) != 1) + { + SAL_WARN("filter.tiff", "missing height"); + break; + } + + if (w > SAL_MAX_INT32 / 8 || h > SAL_MAX_INT32 / 8) + { + SAL_WARN("filter.tiff", "image too large"); + break; + } Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); AlphaMask bitmapAlpha(Size(w, h)); @@ -171,6 +186,12 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) BitmapScopedWriteAccess access(bitmap); AlphaScopedWriteAccess accessAlpha(bitmapAlpha); + if (!access || !accessAlpha) + { + SAL_WARN("filter.tiff", "could not create bitmaps"); + break; + } + aContext.pWriteAccess = access.get(); aContext.pAlphaAccess = accessAlpha.get(); commit 519a5adf7d2d7dd5f895e59896fbbcc52210dfa7 Author: Caolán McNamara <[email protected]> AuthorDate: Fri May 20 09:51:19 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:10:34 2022 +0200 libtiff: enable jpeg and zlib Change-Id: Ied6ab75342f5cdaadefbff7f75fbe63e9d67e992 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134667 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/external/libtiff/ExternalProject_libtiff.mk b/external/libtiff/ExternalProject_libtiff.mk index 9933a4cf947c..e9ecbdf86765 100644 --- a/external/libtiff/ExternalProject_libtiff.mk +++ b/external/libtiff/ExternalProject_libtiff.mk @@ -13,31 +13,53 @@ $(eval $(call gb_ExternalProject_register_targets,libtiff,\ build \ )) +$(eval $(call gb_ExternalProject_use_externals,libtiff,\ + libjpeg \ + zlib \ +)) + $(eval $(call gb_ExternalProject_use_autoconf,libtiff,build)) +# using ac_cv_lib_z_inflateEnd=yes to skip test for our +# static windows lib where the name is zlib not z +# using ac_cv_lib_jpeg_jpeg_read_scanlines to skip test +# for our static windows lib where the name is libjpeg-turbo.lib +# not libjpeg.lib +# we're building this statically anyway so the lib isn't +# used during the link done here + $(call gb_ExternalProject_get_state_target,libtiff,build) : $(call gb_Trace_StartRange,libtiff,EXTERNAL) $(call gb_ExternalProject_run,build,\ export PKG_CONFIG="" \ && MAKE=$(MAKE) $(gb_RUN_CONFIGURE) ./configure \ --enable-static \ - --with-pic \ + --enable-jpeg \ + --enable-zlib \ --disable-shared \ --disable-cxx \ + --disable-libdeflate \ --disable-jbig \ - --disable-jpeg \ + --disable-lerc \ --disable-lzma \ --disable-mdi \ --disable-webp \ --disable-win32-io \ --disable-zstd \ + --with-pic \ --without-x \ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \ CFLAGS="$(CFLAGS) $(call gb_ExternalProject_get_build_flags,libtiff)" \ + $(if $(SYSTEM_ZLIB),,--with-zlib-include-dir="$(call gb_UnpackedTarball_get_dir,zlib)") \ + $(if $(SYSTEM_ZLIB),,--with-zlib-lib-dir="$(gb_StaticLibrary_WORKDIR)") \ + $(if $(SYSTEM_LIBJPEG),,--with-jpeg-include-dir="$(call gb_UnpackedTarball_get_dir,libjpeg-turbo)") \ + $(if $(SYSTEM_LIBJPEG),,--with-jpeg-lib-dir="$(gb_StaticLibrary_WORKDIR)") \ CPPFLAGS="$(CPPFLAGS) $(BOOST_CPPFLAGS)" \ LDFLAGS="$(call gb_ExternalProject_get_link_flags,libtiff)" \ + ac_cv_lib_z_inflateEnd=yes \ + ac_cv_lib_jpeg_jpeg_read_scanlines=yes \ $(gb_CONFIGURE_PLATFORMS) \ - && $(MAKE) \ + && cd libtiff && $(MAKE) libtiff.la \ ) $(call gb_Trace_EndRange,libtiff,EXTERNAL) diff --git a/external/libtiff/UnpackedTarball_libtiff.mk b/external/libtiff/UnpackedTarball_libtiff.mk index 30701edc56cf..ce5a3a53d36a 100644 --- a/external/libtiff/UnpackedTarball_libtiff.mk +++ b/external/libtiff/UnpackedTarball_libtiff.mk @@ -13,4 +13,8 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libtiff,$(LIBTIFF_TARBALL))) $(eval $(call gb_UnpackedTarball_set_patchlevel,libtiff,0)) +$(eval $(call gb_UnpackedTarball_add_patches,libtiff,\ + external/libtiff/libtiff.linknolibs.patch \ +)) + # vim: set noet sw=4 ts=4: diff --git a/external/libtiff/libtiff.linknolibs.patch b/external/libtiff/libtiff.linknolibs.patch new file mode 100644 index 000000000000..0017ca9ca345 --- /dev/null +++ b/external/libtiff/libtiff.linknolibs.patch @@ -0,0 +1,11 @@ +--- libtiff/Makefile.in 2022-05-21 15:32:48.069999327 +0100 ++++ libtiff/Makefile.in 2022-05-21 15:32:59.051499293 +0100 +@@ -372,7 +372,7 @@ + LDFLAGS = @LDFLAGS@ + LIBDIR = @LIBDIR@ + LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ ++#LIBS = @LIBS@ + LIBTIFF_ALPHA_VERSION = @LIBTIFF_ALPHA_VERSION@ + LIBTIFF_DOCDIR = @LIBTIFF_DOCDIR@ + LIBTIFF_MAJOR_VERSION = @LIBTIFF_MAJOR_VERSION@ commit 4ae463bbe74239137e0a1c1093d583f0100d9cc1 Author: Caolán McNamara <[email protected]> AuthorDate: Fri May 20 17:30:49 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:09:46 2022 +0200 tiff: use more complicated apis to need a smaller buffer during read while the split alpha persists as a thing Change-Id: I17b37650e66ae8bd4aa42b953cd39fcfe7ac80ee Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134696 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/source/filter/itiff/itiff.cxx b/vcl/source/filter/itiff/itiff.cxx index 8bce9e705b35..8fa61c4509b5 100644 --- a/vcl/source/filter/itiff/itiff.cxx +++ b/vcl/source/filter/itiff/itiff.cxx @@ -36,11 +36,38 @@ namespace { SvStream& rStream; tsize_t nSize; + + tileContigRoutine pOrigContig; + tileSeparateRoutine pOrigSeparate; + BitmapWriteAccess* pWriteAccess; + BitmapWriteAccess* pAlphaAccess; + std::vector<uint32_t> aBuffer; + Context(SvStream& rInStream, tsize_t nInSize) : rStream(rInStream) , nSize(nInSize) + , pOrigContig(nullptr) + , pOrigSeparate(nullptr) + , pWriteAccess(nullptr) + , pAlphaAccess(nullptr) { } + + void SetPixels(uint32_t x, uint32_t y, uint32_t w, uint32_t h) + { + const uint32_t* pSrc = aBuffer.data(); + + for (uint32_t nRow = 0; nRow < h; ++nRow) + { + for (uint32_t nCol = 0; nCol < w; ++nCol) + { + pWriteAccess->SetPixel(y + nRow, x + nCol, + Color(TIFFGetR(*pSrc), TIFFGetG(*pSrc), TIFFGetB(*pSrc))); + pAlphaAccess->SetPixelIndex(y + nRow, x + nCol, 255 - TIFFGetA(*pSrc)); + ++pSrc; + } + } + } }; } @@ -90,6 +117,34 @@ static toff_t tiff_size(thandle_t handle) return pContext->nSize; } +static void putContigPixel(TIFFRGBAImage* img, uint32_t* /*raster*/, + uint32_t x, uint32_t y, uint32_t w, uint32_t h, + int32_t fromskew, int32_t toskew, + unsigned char* cp) +{ + Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); + + pContext->aBuffer.resize(w * h); + (pContext->pOrigContig)(img, pContext->aBuffer.data(), 0, 0, w, h, + fromskew, toskew, cp); + + pContext->SetPixels(x, y, w, h); +} + +static void putSeparatePixel(TIFFRGBAImage* img, uint32_t* /*raster*/, + uint32_t x, uint32_t y, uint32_t w, uint32_t h, + int32_t fromskew, int32_t toskew, + unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) +{ + Context* pContext = static_cast<Context*>(TIFFClientdata(img->tif)); + + pContext->aBuffer.resize(w * h); + (pContext->pOrigSeparate)(img, pContext->aBuffer.data(), 0, 0, w, h, + fromskew, toskew, r, g, b, a); + + pContext->SetPixels(x, y, w, h); +} + bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) { Context aContext(rTIFF, rTIFF.remainingSize()); @@ -110,43 +165,51 @@ bool ImportTiffGraphicImport(SvStream& rTIFF, Graphic& rGraphic) 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) + Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); + AlphaMask bitmapAlpha(Size(w, h)); + + BitmapScopedWriteAccess access(bitmap); + AlphaScopedWriteAccess accessAlpha(bitmapAlpha); + + aContext.pWriteAccess = access.get(); + aContext.pAlphaAccess = accessAlpha.get(); + + char emsg[1024] = ""; + TIFFRGBAImage img; + bool bOk = false; + // Expanded out TIFFReadRGBAImageOriented to create this block then + // inserted custom "put" methods to write (via a limited size buffer) + // into the final Bitmap incrementally + if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 1, emsg)) { - if (TIFFReadRGBAImageOriented(tif, w, h, raster, ORIENTATION_TOPLEFT, 1)) + img.req_orientation = ORIENTATION_TOPLEFT; + assert(!TIFFIsTiled(img.tif)); + if (!TIFFIsTiled(img.tif)) { - Bitmap bitmap(Size(w, h), vcl::PixelFormat::N24_BPP); - AlphaMask bitmapAlpha(Size(w, h)); - - BitmapScopedWriteAccess access(bitmap); - AlphaScopedWriteAccess accessAlpha(bitmapAlpha); + aContext.pOrigContig = img.put.contig; + img.put.contig = putContigPixel; + } + else + { + aContext.pOrigSeparate = img.put.separate; + img.put.separate = putSeparatePixel; + } - 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; - } - } + bOk = TIFFRGBAImageGet(&img, nullptr, w, img.height); + TIFFRGBAImageEnd(&img); + } - access.reset(); - accessAlpha.reset(); + 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); + if (bOk) + { + BitmapEx aBitmapEx(bitmap, bitmapAlpha); + AnimationBitmap aAnimationBitmap(aBitmapEx, Point(0, 0), aBitmapEx.GetSizePixel(), + ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back); + aAnimation.Insert(aAnimationBitmap); } + } while (TIFFReadDirectory(tif)); TIFFClose(tif); commit 98c9de286314926185c7e5c40b529532bcff16a2 Author: Caolán McNamara <[email protected]> AuthorDate: Fri May 20 10:00:14 2022 +0100 Commit: Andras Timar <[email protected]> CommitDate: Sun Oct 16 16:09:26 2022 +0200 drop old tiff filter Change-Id: I3bfeae4751cb9173fbe2efdbda531a9a1a491c8e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134695 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index c9e9aabc6da8..b0a6ee533133 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -454,9 +454,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/ipdf/pdfdocument \ vcl/source/filter/iras/iras \ vcl/source/filter/itga/itga \ - vcl/source/filter/itiff/ccidecom \ vcl/source/filter/itiff/itiff \ - vcl/source/filter/itiff/lzwdecom \ vcl/source/filter/ixbm/xbmread \ vcl/source/filter/ixpm/xpmread \ vcl/source/filter/jpeg/Exif \ diff --git a/vcl/source/filter/itiff/ccidecom.cxx b/vcl/source/filter/itiff/ccidecom.cxx deleted file mode 100644 index c558fdea7fc9..000000000000 --- a/vcl/source/filter/itiff/ccidecom.cxx +++ /dev/null @@ -1,1100 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - - -#include "ccidecom.hxx" -#include <tools/stream.hxx> - -//=============================== Huffman tables ======================== - -//---------------------------- White-Run ------------------------------ - -#define CCIWhiteTableSize 105 - -const CCIHuffmanTableEntry CCIWhiteTable[CCIWhiteTableSize]={ - { 0, 0x0035, 8 }, - { 1, 0x0007, 6 }, - { 2, 0x0007, 4 }, - { 3, 0x0008, 4 }, - { 4, 0x000b, 4 }, - { 5, 0x000c, 4 }, - { 6, 0x000e, 4 }, - { 7, 0x000f, 4 }, - { 8, 0x0013, 5 }, - { 9, 0x0014, 5 }, - { 10, 0x0007, 5 }, - { 11, 0x0008, 5 }, - { 12, 0x0008, 6 }, - { 13, 0x0003, 6 }, - { 14, 0x0034, 6 }, - { 15, 0x0035, 6 }, - { 16, 0x002a, 6 }, - { 17, 0x002b, 6 }, - { 18, 0x0027, 7 }, - { 19, 0x000c, 7 }, - { 20, 0x0008, 7 }, - { 21, 0x0017, 7 }, - { 22, 0x0003, 7 }, - { 23, 0x0004, 7 }, - { 24, 0x0028, 7 }, - { 25, 0x002b, 7 }, - { 26, 0x0013, 7 }, - { 27, 0x0024, 7 }, - { 28, 0x0018, 7 }, - { 29, 0x0002, 8 }, - { 30, 0x0003, 8 }, - { 31, 0x001a, 8 }, - { 32, 0x001b, 8 }, - { 33, 0x0012, 8 }, - { 34, 0x0013, 8 }, - { 35, 0x0014, 8 }, - { 36, 0x0015, 8 }, - { 37, 0x0016, 8 }, - { 38, 0x0017, 8 }, - { 39, 0x0028, 8 }, - { 40, 0x0029, 8 }, - { 41, 0x002a, 8 }, - { 42, 0x002b, 8 }, - { 43, 0x002c, 8 }, - { 44, 0x002d, 8 }, - { 45, 0x0004, 8 }, - { 46, 0x0005, 8 }, - { 47, 0x000a, 8 }, - { 48, 0x000b, 8 }, - { 49, 0x0052, 8 }, - { 50, 0x0053, 8 }, - { 51, 0x0054, 8 }, - { 52, 0x0055, 8 }, - { 53, 0x0024, 8 }, - { 54, 0x0025, 8 }, - { 55, 0x0058, 8 }, - { 56, 0x0059, 8 }, - { 57, 0x005a, 8 }, - { 58, 0x005b, 8 }, - { 59, 0x004a, 8 }, - { 60, 0x004b, 8 }, - { 61, 0x0032, 8 }, - { 62, 0x0033, 8 }, - { 63, 0x0034, 8 }, - { 64, 0x001b, 5 }, - { 128, 0x0012, 5 }, - { 192, 0x0017, 6 }, - { 256, 0x0037, 7 }, - { 320, 0x0036, 8 }, - { 384, 0x0037, 8 }, - { 448, 0x0064, 8 }, - { 512, 0x0065, 8 }, - { 576, 0x0068, 8 }, - { 640, 0x0067, 8 }, - { 704, 0x00cc, 9 }, - { 768, 0x00cd, 9 }, ... etc. - the rest is truncated
