1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <unotools/configmgr.hxx>
24 #include <vcl/FilterConfigItem.hxx>
25 #include <vcl/graph.hxx>
26 #include <vcl/BitmapTools.hxx>
27 #include <vcl/animate/Animation.hxx>
28 #include <tools/fract.hxx>
29 #include <tools/stream.hxx>
30 #include "lzwdecom.hxx"
31 #include "ccidecom.hxx"
32 
33 #include <filter/TiffReader.hxx>
34 
35 namespace {
36 
BYTESWAP(T nByte)37 template< typename T > T BYTESWAP(T nByte) {
38     return ( nByte << 7 ) | ( ( nByte & 2 ) << 5 ) | ( ( nByte & 4 ) << 3 ) |
39         ( ( nByte & 8 ) << 1 ) | ( ( nByte & 16 ) >> 1 ) |
40         ( ( nByte & 32 ) >> 3 ) | ( ( nByte & 64 ) >> 5 ) |
41         ( ( nByte & 128 ) >> 7 );
42 }
43 
44 //============================ TIFFReader ==================================
45 
46 class TIFFReader
47 {
48 
49 private:
50 
51     bool                bStatus;                    // Whether until now no error occurred
52     Animation               aAnimation;
53 
54     SvStream*               pTIFF;                      // the TIFF file that should be read
55     std::vector<sal_uInt8>  maBitmap;
56     Size                    maBitmapPixelSize;
57     std::vector<Color>      mvPalette;
58     MapMode                 maBitmapPrefMapMode;
59     Size                    maBitmapPrefSize;
60     sal_uInt16              nDstBitsPerPixel;
61     int                     nLargestPixelIndex;
62 
63     sal_uInt64              nOrigPos;                   // start position in pTIFF
64     sal_uInt64              nEndOfFile;                 // end of file position in pTIFF
65 
66 
67     sal_uInt16              nDataType;
68     // Data taken from the TIFF tags:
69     bool                    bByteSwap;                  // sal_True if bits 0..7 -> 7..0 should get converted ( FILLORDER = 2 );
70 
71     sal_uInt32              nNewSubFile;
72     sal_uInt32              nSubFile;
73     sal_Int32               nImageWidth;                // picture width in pixels
74     sal_Int32               nImageLength;               // picture height in pixels
75     sal_uInt32              nBitsPerSample;             // bits per pixel per layer
76     sal_uInt32              nCompression;               // kind of compression
77     sal_uInt32              nPhotometricInterpretation;
78     sal_uInt32              nThresholding;
79     sal_uInt32              nCellWidth;
80     sal_uInt32              nCellLength;
81     sal_uInt32              nFillOrder;
82     std::vector<sal_uInt64> aStripOffsets;              // field of offsets to the Bitmap-Data-"Strips"
83     sal_uInt32              nOrientation;
84     sal_uInt32              nSamplesPerPixel;           // number of layers
85     sal_uInt32              nRowsPerStrip;              // if it's not compressed: number of rows per Strip
86     std::vector<sal_uInt32> aStripByteCounts;           // if compressed (in a certain way): size of the strips
87     sal_uInt32              nMinSampleValue;
88     sal_uInt32              nMaxSampleValue;
89     double                  fXResolution;               // X-resolution or 0.0
90     double                  fYResolution;               // Y-resolution or 0.0
91     sal_uInt32              nPlanarConfiguration;
92     sal_uInt32              nGroup3Options;
93     sal_uInt32              nGroup4Options;
94     sal_uInt32              nResolutionUnit;            // unit of fX/YResolution: 1=unknown, 2(default)=inch, 3=cm
95     sal_uInt32              nPredictor;
96     std::vector<sal_uInt32> aColorMap;                  // color palette
97     sal_uInt32              nNumColors;                 // number of colors within the color palette
98 
99     sal_uInt32              nPlanes;                    // number of layers within the Tiff file
100     sal_uInt32              nStripsPerPlane;            // number of Strips per layer
101     sal_uInt32              nBytesPerRow;               // Bytes per line per Layer in the Tiff file ( uncompressed )
102     std::vector<sal_uInt8>  aMap[4];                    // temporary Scanline
103 
104 
105     sal_uInt32 DataTypeSize();
106     sal_uInt32 ReadIntData();
107     double  ReadDoubleData();
108 
109     void    ReadHeader();
110     void    ReadTagData( sal_uInt16 nTagType, sal_uInt32 nDataLen );
111 
112     sal_uInt8* getMapData(sal_uInt32 np);
113 
114     bool    ReadMap();
115         // reads/decompress the bitmap data and fills aMap
116 
117     sal_uInt32 GetBits(const sal_uInt8 * pSrc, sal_uInt32 nBitsPos, sal_uInt32 nBitsCount);
118         // fetches BitsCount bits from pSrc[..] at the position nBitsPos
119 
120     void    MakePalCol();
121         // Create the bitmap from the temporary bitmap aMap
122         // and partly deletes aMap while doing this.
123 
124     bool    ConvertScanline(sal_Int32 nY);
125         // converts a Scanline to the Windows-BMP format
126 
127     bool HasAlphaChannel() const;
128 
129     void SetPixel(tools::Long nY, tools::Long nX, sal_uInt8 cIndex);
130     void SetPixel(tools::Long nY, tools::Long nX, Color c);
131     void SetPixelAlpha(tools::Long nY, tools::Long nX, sal_uInt8 nAlpha);
132 
133 public:
134 
TIFFReader()135     TIFFReader()
136         : bStatus(false)
137         , pTIFF(nullptr)
138         , nDstBitsPerPixel(0)
139         , nLargestPixelIndex(-1)
140         , nOrigPos(0)
141         , nEndOfFile(0)
142         , nDataType(0)
143         , bByteSwap(false)
144         , nNewSubFile(0)
145         , nSubFile(0)
146         , nImageWidth(0)
147         , nImageLength(0)
148         , nBitsPerSample(1)
149         , nCompression(1)
150         , nPhotometricInterpretation(0)
151         , nThresholding(1)
152         , nCellWidth(1)
153         , nCellLength(1)
154         , nFillOrder(1)
155         , nOrientation(1)
156         , nSamplesPerPixel(1)
157         , nRowsPerStrip(0xffffffff)
158         , nMinSampleValue(0)
159         , nMaxSampleValue(0)
160         , fXResolution(0.0)
161         , fYResolution(0.0)
162         , nPlanarConfiguration(1)
163         , nGroup3Options(0)
164         , nGroup4Options(0)
165         , nResolutionUnit(2)
166         , nPredictor(0)
167         , nNumColors(0)
168         , nPlanes(0)
169         , nStripsPerPlane(0)
170         , nBytesPerRow(0)
171     {
172     }
173 
GetRowsPerStrip() const174     sal_uInt32 GetRowsPerStrip() const
175     {
176         //Rows Per Strip:
177         //
178         //(TIFF format only) The number of rows of pixels per strip to use for
179         //encoding the TIFF image. A value greater than zero specifies the
180         //number of rows per strip. A value of 0 sets the rows per strip equal
181         //to the image length, resulting in a single strip. A value of -1 (the
182         //default) sets the rows per strip equal to infinity, resulting in a
183         //single strip.
184         return nRowsPerStrip == 0 ? nImageLength : nRowsPerStrip;
185     }
186 
187     bool ReadTIFF( SvStream & rTIFF, Graphic & rGraphic );
188 };
189 
190 }
191 
192 //=================== Methods of TIFFReader ==============================
193 
DataTypeSize()194 sal_uInt32 TIFFReader::DataTypeSize()
195 {
196     sal_uInt32 nSize;
197     switch ( nDataType )
198     {
199         case 1 :            // BYTE
200         case 2 :            // ASCII
201         case 6 :            // SIGNED Byte
202         case 7 :            // UNDEFINED
203             nSize = 1;
204             break;
205         case 3 :            // UINT16
206         case 8 :            // INT16
207             nSize = 2;
208             break;
209         case 4 :            // UINT32
210         case 9 :            // INT32
211         case 11 :           // FLOAT
212             nSize = 4;
213             break;
214         case 5 :            // RATIONAL
215         case 10 :           // SIGNED RATIONAL
216         case 12 :           // DOUBLE
217             nSize = 8;
218             break;
219         default:
220             pTIFF->SetError(SVSTREAM_FILEFORMAT_ERROR);
221             nSize=1;
222     }
223     return nSize;
224 }
225 
ReadIntData()226 sal_uInt32 TIFFReader::ReadIntData()
227 {
228     double  nDOUBLE(0.0);
229     float   nFLOAT(0);
230     sal_uInt32  nUINT32a(0), nUINT32b(0);
231     sal_Int32   nINT32(0);
232     sal_uInt16  nUINT16(0);
233     sal_Int16   nINT16(0);
234     sal_uInt8   nBYTE(0);
235     char    nCHAR(0);
236 
237     switch( nDataType )
238     {
239         case 0 :    //??
240         case 1 :
241         case 2 :
242         case 7 :
243             pTIFF->ReadUChar( nBYTE );
244             nUINT32a = nBYTE;
245         break;
246         case 3 :
247              pTIFF->ReadUInt16( nUINT16 );
248              nUINT32a = nUINT16;
249         break;
250         case 9 :
251         case 4 :
252             pTIFF->ReadUInt32( nUINT32a );
253         break;
254         case  5 :
255             pTIFF->ReadUInt32( nUINT32a ).ReadUInt32( nUINT32b );
256             if ( nUINT32b != 0 )
257                 nUINT32a /= nUINT32b;
258         break;
259         case 6 :
260             pTIFF->ReadChar( nCHAR );
261             nUINT32a = static_cast<sal_Int32>(nCHAR);
262         break;
263         case 8 :
264             pTIFF->ReadInt16( nINT16 );
265             nUINT32a = static_cast<sal_Int32>(nINT16);
266         break;
267         case 10 :
268             pTIFF->ReadUInt32( nUINT32a ).ReadInt32( nINT32 );
269             if ( nINT32 != 0 )
270                 nUINT32a /= nINT32;
271         break;
272         case 11 :
273             pTIFF->ReadFloat( nFLOAT );
274             if (!std::isnan(nFLOAT) && nFLOAT > SAL_MIN_INT32 - 1.0
275                 && nFLOAT < SAL_MAX_INT32 + 1.0)
276             {
277                 nUINT32a = static_cast<sal_Int32>(nFLOAT);
278             }
279             else
280             {
281                 SAL_INFO("filter.tiff", "float " << nFLOAT << " outsider of sal_Int32 range");
282             }
283         break;
284         case 12 :
285             pTIFF->ReadDouble( nDOUBLE );
286             if (!std::isnan(nDOUBLE) && nDOUBLE > SAL_MIN_INT32 - 1.0
287                 && nDOUBLE < SAL_MAX_INT32 + 1.0)
288             {
289                 nUINT32a = static_cast<sal_Int32>(nDOUBLE);
290             }
291             else
292             {
293                 SAL_INFO("filter.tiff", "double " << nDOUBLE << " outsider of sal_Int32 range");
294             }
295         break;
296         default:
297             pTIFF->ReadUInt32( nUINT32a );
298         break;
299     }
300     return nUINT32a;
301 }
302 
ReadDoubleData()303 double TIFFReader::ReadDoubleData()
304 {
305     switch (nDataType) {
306     case 5:
307         {
308             sal_uInt32 nulong(0);
309             pTIFF->ReadUInt32( nulong );
310             double nd = static_cast<double>(nulong);
311             nulong = 0;
312             pTIFF->ReadUInt32( nulong );
313             if ( nulong != 0 )
314                 nd /= static_cast<double>(nulong);
315             return nd;
316         }
317 
318     case 11:
319         {
320             float x = 0;
321             pTIFF->ReadFloat(x);
322             return x;
323         }
324 
325     case 12:
326         {
327             double x = 0;
328             pTIFF->ReadDouble(x);
329             return x;
330         }
331 
332     default:
333         return static_cast<double>(ReadIntData());
334     }
335 }
336 
ReadTagData(sal_uInt16 nTagType,sal_uInt32 nDataLen)337 void TIFFReader::ReadTagData( sal_uInt16 nTagType, sal_uInt32 nDataLen)
338 {
339     if ( !bStatus )
340         return;
341 
342     switch ( nTagType )
343     {
344         case 0x00fe:   // New Sub File
345             nNewSubFile = ReadIntData();
346             SAL_INFO("filter.tiff","NewSubFile: " << nNewSubFile);
347             break;
348 
349         case 0x00ff:   // Sub File
350             nSubFile = ReadIntData();
351             SAL_INFO("filter.tiff","SubFile: " << nSubFile);
352             break;
353 
354         case 0x0100:   // Image Width
355             nImageWidth = ReadIntData();
356             SAL_INFO("filter.tiff","ImageWidth: " << nImageWidth);
357             break;
358 
359         case 0x0101:   // Image Length
360             nImageLength = ReadIntData();
361             SAL_INFO("filter.tiff","ImageLength: " << nImageLength);
362             break;
363 
364         case 0x0102:   // Bits Per Sample
365             nBitsPerSample = ReadIntData();
366             SAL_INFO("filter.tiff","BitsPerSample: " << nBitsPerSample);
367             if ( nBitsPerSample >= 32 ) // 32 bit and larger samples are not supported
368                 bStatus = false;
369             break;
370 
371         case 0x0103:   // Compression
372             nCompression = ReadIntData();
373             SAL_INFO("filter.tiff","Compression: " << nCompression);
374             break;
375 
376         case 0x0106:   // Photometric Interpretation
377             nPhotometricInterpretation = ReadIntData();
378             SAL_INFO("filter.tiff","PhotometricInterpretation: " << nPhotometricInterpretation);
379             break;
380 
381         case 0x0107:   // Thresholding
382             nThresholding = ReadIntData();
383             SAL_INFO("filter.tiff","Thresholding: " << nThresholding);
384             break;
385 
386         case 0x0108:   // Cell Width
387             nCellWidth = ReadIntData();
388             break;
389 
390         case 0x0109:   // Cell Length
391             nCellLength = ReadIntData();
392             break;
393 
394         case 0x010a:   // Fill Order
395             nFillOrder = ReadIntData();
396             SAL_INFO("filter.tiff","FillOrder: " << nFillOrder);
397             break;
398 
399         case 0x0111: { // Strip Offset(s)
400             size_t nOldNumSO = aStripOffsets.size();
401             nDataLen += nOldNumSO;
402             size_t const nMaxAllocAllowed = SAL_MAX_UINT32 / sizeof(sal_uInt32);
403             size_t nMaxRecordsAvailable = pTIFF->remainingSize() / DataTypeSize();
404             if (nDataLen > nOldNumSO && nDataLen < nMaxAllocAllowed &&
405                 (nDataLen - nOldNumSO) <= nMaxRecordsAvailable)
406             {
407                 try
408                 {
409                     aStripOffsets.resize(nDataLen);
410                     if (nOrigPos)
411                     {
412                         for (size_t i = 0; i < nOldNumSO; ++i)
413                             aStripOffsets[i] += nOrigPos;
414                     }
415                     for (size_t i = nOldNumSO; i < aStripOffsets.size(); ++i)
416                         aStripOffsets[i] = ReadIntData() + nOrigPos;
417                 }
418                 catch (const std::bad_alloc &)
419                 {
420                     aStripOffsets.clear();
421                 }
422             }
423             SAL_INFO("filter.tiff","StripOffsets (Number:) " << nDataLen);
424             break;
425         }
426         case 0x0112:   // Orientation
427             nOrientation = ReadIntData();
428             SAL_INFO("filter.tiff","Orientation: " << nOrientation);
429             break;
430 
431         case 0x0115:   // Samples Per Pixel
432             nSamplesPerPixel = ReadIntData();
433             SAL_INFO("filter.tiff","SamplesPerPixel: " << nSamplesPerPixel);
434 
435             if (nSamplesPerPixel > USHRT_MAX) // ofz#15993 the expected type is SHORT
436                 bStatus = false;
437 
438             break;
439 
440         case 0x0116:   // Rows Per Strip
441             nRowsPerStrip = ReadIntData();
442             SAL_INFO("filter.tiff","RowsPerStrip: " << nRowsPerStrip);
443             break;
444 
445         case 0x0117: { // Strip Byte Counts
446             size_t nOldNumSBC = aStripByteCounts.size();
447             nDataLen += nOldNumSBC;
448             size_t const nMaxAllocAllowed = SAL_MAX_UINT32 / sizeof(sal_uInt32);
449             size_t nMaxRecordsAvailable = pTIFF->remainingSize() / DataTypeSize();
450             if (nDataLen > nOldNumSBC && nDataLen < nMaxAllocAllowed &&
451                 (nDataLen - nOldNumSBC) <= nMaxRecordsAvailable)
452             {
453                 try
454                 {
455                     aStripByteCounts.resize(nDataLen);
456                     for (size_t i = nOldNumSBC; i < aStripByteCounts.size(); ++i)
457                         aStripByteCounts[i] = ReadIntData();
458                 }
459                 catch (const std::bad_alloc &)
460                 {
461                     aStripByteCounts.clear();
462                 }
463             }
464             SAL_INFO("filter.tiff","StripByteCounts (Number:) " << nDataLen);
465             break;
466         }
467         case 0x0118:   // Min Sample Value
468             nMinSampleValue = ReadIntData();
469             SAL_INFO("filter.tiff","MinSampleValue: " << nMinSampleValue);
470             break;
471 
472         case 0x0119:   // Max Sample Value
473             nMaxSampleValue = ReadIntData();
474             SAL_INFO("filter.tiff","MaxSampleValue: " << nMaxSampleValue);
475             break;
476 
477         case 0x011a:   // X Resolution
478             fXResolution = ReadDoubleData();
479             break;
480 
481         case 0x011b:   // Y Resolution
482             fYResolution = ReadDoubleData();
483             break;
484 
485         case 0x011c:   // Planar Configuration
486             nPlanarConfiguration = ReadIntData();
487             SAL_INFO("filter.tiff","PlanarConfiguration: " << nPlanarConfiguration);
488             break;
489 
490         case 0x0124:   // Group 3 Options
491             nGroup3Options = ReadIntData();
492             SAL_INFO("filter.tiff","Group3Options: " << nGroup3Options);
493             break;
494 
495         case 0x0125:   // Group 4 Options
496             nGroup4Options = ReadIntData();
497             SAL_INFO("filter.tiff","Group4Options: " << nGroup4Options);
498             break;
499 
500         case 0x0128:   // Resolution Unit
501             nResolutionUnit = ReadIntData();
502             break;
503 
504         case 0x013d:   // Predictor
505             nPredictor = ReadIntData();
506             SAL_INFO("filter.tiff","Predictor: " << nPredictor);
507             break;
508 
509         case 0x0140: { // Color Map
510             sal_uInt16 nVal;
511             nNumColors = (sal_uInt32(1) << nBitsPerSample);
512             if ( nDataType == 3 && nNumColors <= 256)
513             {
514                 aColorMap.resize(256);
515                 for (sal_uInt32 i = 0; i < nNumColors; ++i)
516                     aColorMap[i] = 0;
517                 for (sal_uInt32 i = 0; i < nNumColors; ++i)
518                 {
519                     pTIFF->ReadUInt16( nVal );
520                     aColorMap[i] |= ( static_cast<sal_uInt32>(nVal) << 8 ) & 0x00ff0000;
521                 }
522                 for (sal_uInt32 i = 0; i < nNumColors; ++i)
523                 {
524                     pTIFF->ReadUInt16( nVal );
525                     aColorMap[i] |= static_cast<sal_uInt32>(nVal) & 0x0000ff00;
526                 }
527                 for (sal_uInt32 i = 0; i < nNumColors; ++i)
528                 {
529                     pTIFF->ReadUInt16( nVal );
530                     aColorMap[i] |= ( static_cast<sal_uInt32>(nVal) >> 8 ) & 0x000000ff;
531                 }
532             }
533             else
534                 bStatus = false;
535             SAL_INFO("filter.tiff","ColorMap (number of colors): " << nNumColors);
536             break;
537         }
538 
539         case 0x0153: { // SampleFormat
540             sal_uInt32 nSampleFormat = ReadIntData();
541             if ( nSampleFormat == 3 ) // IEEE floating point samples are not supported yet
542                 bStatus = false;
543             break;
544         }
545     }
546 
547     if ( pTIFF->GetError() )
548         bStatus = false;
549 }
550 
getMapData(sal_uInt32 np)551 sal_uInt8* TIFFReader::getMapData(sal_uInt32 np)
552 {
553     aMap[np].resize(nBytesPerRow);
554     return aMap[np].data();
555 }
556 
ReadMap()557 bool TIFFReader::ReadMap()
558 {
559     //when fuzzing with a max len set, max decompress to 250 times that limit
560     static size_t nMaxAllowedDecompression = [](const char* pEnv) { size_t nRet = pEnv ? std::atoi(pEnv) : 0; return nRet * 250; }(std::getenv("FUZZ_MAX_INPUT_LEN"));
561     size_t nTotalDataRead = 0;
562 
563     if ( nCompression == 1 || nCompression == 32771 )
564     {
565         sal_uInt32 nStripBytesPerRow;
566 
567         if ( nCompression == 1 )
568             nStripBytesPerRow = nBytesPerRow;
569         else
570             nStripBytesPerRow = ( nBytesPerRow + 1 ) & 0xfffffffe;
571         for (sal_Int32 ny = 0; ny < nImageLength; ++ny)
572         {
573             for (sal_uInt32 np = 0; np < nPlanes; ++np)
574             {
575                 if (np >= SAL_N_ELEMENTS(aMap))
576                     return false;
577                 sal_uInt32 nStrip = ny / GetRowsPerStrip() + np * nStripsPerPlane;
578                 if ( nStrip >= aStripOffsets.size())
579                     return false;
580                 pTIFF->Seek( aStripOffsets[ nStrip ] + ( ny % GetRowsPerStrip() ) * nStripBytesPerRow );
581                 // tdf#126147 allow a short incomplete read
582                 auto pDest = getMapData(np);
583                 auto nRead = pTIFF->ReadBytes(pDest, nBytesPerRow);
584                 if (nRead != nBytesPerRow)
585                     memset(pDest + nRead, 0, nBytesPerRow - nRead);
586             }
587             if ( !ConvertScanline( ny ) )
588                 return false;
589         }
590     }
591     else if ( nCompression == 2 || nCompression == 3 || nCompression == 4 )
592     {
593         sal_uInt32 nOptions;
594         if ( nCompression == 2 )
595         {
596             nOptions = CCI_OPTION_BYTEALIGNROW;
597         }
598         else if ( nCompression == 3 )
599         {
600             nOptions = CCI_OPTION_EOL;
601             if ( nGroup3Options & 0x00000001 )
602                 nOptions |= CCI_OPTION_2D;
603             if ( nGroup3Options & 0x00000004 )
604                 nOptions |= CCI_OPTION_BYTEALIGNEOL;
605             if ( nGroup3Options & 0xfffffffa )
606                 return false;
607         }
608         else
609         {   // nCompression==4
610             nOptions = CCI_OPTION_2D;
611             if ( nGroup4Options & 0xffffffff )
612                 return false;
613         }
614         if ( nFillOrder == 2 )
615         {
616             nOptions |= CCI_OPTION_INVERSEBITORDER;
617             bByteSwap = false;
618         }
619         sal_uInt32 nStrip = 0;
620         if (nStrip >= aStripOffsets.size())
621             return false;
622         sal_uInt64 nOffset = aStripOffsets[nStrip];
623         if (nOffset > nEndOfFile)
624             return false;
625         pTIFF->Seek(aStripOffsets[nStrip]);
626 
627         CCIDecompressor aCCIDecom( nOptions, nImageWidth );
628 
629         aCCIDecom.StartDecompression( *pTIFF );
630 
631         const bool bHasAlphaChannel = HasAlphaChannel();
632         for (sal_Int32 ny = 0; ny < nImageLength; ++ny)
633         {
634             bool bDifferentToPrev = ny == 0;
635             for (sal_uInt32 np = 0; np < nPlanes; ++np)
636             {
637                 if ( ny / GetRowsPerStrip() + np * nStripsPerPlane > nStrip )
638                 {
639                     nStrip=ny/GetRowsPerStrip()+np*nStripsPerPlane;
640                     if (nStrip >= aStripOffsets.size())
641                         return false;
642                     nOffset = aStripOffsets[nStrip];
643                     if (nOffset > nEndOfFile)
644                         return false;
645                     pTIFF->Seek(nOffset);
646                     aCCIDecom.StartDecompression( *pTIFF );
647                 }
648                 if (np >= SAL_N_ELEMENTS(aMap))
649                     return false;
650                 DecompressStatus aResult = aCCIDecom.DecompressScanline(getMapData(np), nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes, np + 1 == nPlanes);
651                 if (!aResult.m_bSuccess)
652                     return false;
653                 bDifferentToPrev |= !aResult.m_bBufferUnchanged;
654                 if ( pTIFF->GetError() )
655                     return false;
656                 nTotalDataRead += nBytesPerRow;
657                 if (nMaxAllowedDecompression && nTotalDataRead > nMaxAllowedDecompression)
658                     return false;
659             }
660             if (!bDifferentToPrev)
661             {
662                 //if the buffer for this line didn't change, then just copy the
663                 //previous scanline instead of painfully decoding and setting
664                 //each pixel one by one again
665                 const int nColorSize = bHasAlphaChannel ? 4 : 3;
666                 memcpy( maBitmap.data() + (ny * maBitmapPixelSize.Width()) * nColorSize,
667                         maBitmap.data() + ((ny-1) * maBitmapPixelSize.Width()) * nColorSize,
668                         maBitmapPixelSize.Width() * nColorSize);
669             }
670             else
671             {
672                 if (!ConvertScanline(ny))
673                     return false;
674             }
675         }
676     }
677     else if ( nCompression == 5 )
678     {
679         LZWDecompressor aLZWDecom;
680         sal_uInt32 nStrip(0);
681         if (nStrip >= aStripOffsets.size())
682             return false;
683         pTIFF->Seek(aStripOffsets[nStrip]);
684         aLZWDecom.StartDecompression(*pTIFF);
685         for (sal_Int32 ny = 0; ny < nImageLength; ++ny)
686         {
687             for (sal_uInt32 np = 0; np < nPlanes; ++np)
688             {
689                 if ( ny / GetRowsPerStrip() + np * nStripsPerPlane > nStrip )
690                 {
691                     nStrip = ny / GetRowsPerStrip() + np * nStripsPerPlane;
692                     if (nStrip >= aStripOffsets.size())
693                         return false;
694                     pTIFF->Seek(aStripOffsets[nStrip]);
695                     aLZWDecom.StartDecompression(*pTIFF);
696                 }
697                 if (np >= SAL_N_ELEMENTS(aMap))
698                     return false;
699                 if ( ( aLZWDecom.Decompress(getMapData(np), nBytesPerRow) != nBytesPerRow ) || pTIFF->GetError() )
700                     return false;
701             }
702 
703             nTotalDataRead += nBytesPerRow;
704             if (nMaxAllowedDecompression && nTotalDataRead > nMaxAllowedDecompression)
705                 return false;
706 
707             if ( !ConvertScanline( ny ) )
708                 return false;
709         }
710     }
711     else if ( nCompression == 32773 )
712     {
713         sal_uInt32 nStrip(0);
714         if (nStrip >= aStripOffsets.size())
715             return false;
716         pTIFF->Seek(aStripOffsets[nStrip]);
717         for (sal_Int32 ny = 0; ny < nImageLength; ++ny)
718         {
719             for (sal_uInt32 np = 0; np < nPlanes; ++np)
720             {
721                 if ( ny / GetRowsPerStrip() + np * nStripsPerPlane > nStrip )
722                 {
723                     nStrip=ny/GetRowsPerStrip()+np*nStripsPerPlane;
724                     if (nStrip >= aStripOffsets.size())
725                         return false;
726                     pTIFF->Seek(aStripOffsets[nStrip]);
727                 }
728                 sal_uInt32 nRowBytesLeft = nBytesPerRow;
729                 if (np >= SAL_N_ELEMENTS(aMap))
730                     return false;
731                 sal_uInt8* pdst = getMapData(np);
732                 do
733                 {
734                     sal_uInt8 nRecHeader(0);
735                     pTIFF->ReadUChar(nRecHeader);
736                     sal_uInt32 nRecCount;
737                     if ((nRecHeader&0x80)==0)
738                     {
739                         nRecCount=0x00000001 + static_cast<sal_uInt32>(nRecHeader);
740                         if ( nRecCount > nRowBytesLeft )
741                             return false;
742                         pTIFF->ReadBytes(pdst, nRecCount);
743                         if (!pTIFF->good())
744                             return false;
745                         pdst+=nRecCount;
746                         nRowBytesLeft-=nRecCount;
747                     }
748                     else if ( nRecHeader != 0x80 )
749                     {
750                         nRecCount = 0x000000101 - static_cast<sal_uInt32>(nRecHeader);
751                         if ( nRecCount > nRowBytesLeft )
752                         {
753                             nRecCount = nRowBytesLeft;
754                         }
755                         sal_uInt8 nRecData(0);
756                         pTIFF->ReadUChar( nRecData );
757                         for (sal_uInt32 i = 0; i < nRecCount; ++i)
758                             *(pdst++) = nRecData;
759                         nRowBytesLeft -= nRecCount;
760                     }
761                 } while ( nRowBytesLeft != 0 );
762                 if ( pTIFF->GetError() )
763                     return false;
764             }
765             if ( !ConvertScanline( ny ) )
766                 return false;
767         }
768     }
769     else
770         return false;
771     return true;
772 }
773 
GetBits(const sal_uInt8 * pSrc,sal_uInt32 nBitsPos,sal_uInt32 nBitsCount)774 sal_uInt32 TIFFReader::GetBits( const sal_uInt8 * pSrc, sal_uInt32 nBitsPos, sal_uInt32 nBitsCount)
775 {
776     sal_uInt32 nRes;
777     if ( bByteSwap )
778     {
779         pSrc += ( nBitsPos >> 3 );
780         nBitsPos &= 7;
781         sal_uInt8 nDat = *pSrc;
782         nRes = static_cast<sal_uInt32>( BYTESWAP( nDat ) & ( 0xff >> nBitsPos ) );
783 
784         if ( nBitsCount <= 8 - nBitsPos )
785         {
786             nRes >>= ( 8 - nBitsPos - nBitsCount );
787         }
788         else
789         {
790             pSrc++;
791             nBitsCount -= 8 - nBitsPos;
792             while ( nBitsCount >= 8 )
793             {
794                 nDat = *(pSrc++);
795                 nRes = ( nRes << 8 ) | static_cast<sal_uInt32>(BYTESWAP( nDat ));
796                 nBitsCount -= 8;
797             }
798             if ( nBitsCount > 0 )
799             {
800                 nDat = *pSrc;
801                 nRes = ( nRes << nBitsCount ) | (static_cast<sal_uInt32>(BYTESWAP(nDat))>>(8-nBitsCount));
802             }
803         }
804     }
805     else
806     {
807         pSrc += ( nBitsPos >> 3 );
808         nBitsPos &= 7;
809         nRes = static_cast<sal_uInt32>((*pSrc)&(0xff>>nBitsPos));
810         if ( nBitsCount <= 8 - nBitsPos )
811         {
812             nRes >>= ( 8 - nBitsPos - nBitsCount );
813         }
814         else
815         {
816             pSrc++;
817             nBitsCount -= 8 - nBitsPos;
818             while ( nBitsCount >= 8 )
819             {
820                 nRes = ( nRes << 8 ) | static_cast<sal_uInt32>(*(pSrc++));
821                 nBitsCount -= 8;
822             }
823             if ( nBitsCount > 0 )
824                 nRes = ( nRes << nBitsCount ) | (static_cast<sal_uInt32>(*pSrc)>>(8-nBitsCount));
825         }
826     }
827     return nRes;
828 }
829 
SetPixel(tools::Long nY,tools::Long nX,sal_uInt8 cIndex)830 void TIFFReader::SetPixel(tools::Long nY, tools::Long nX, sal_uInt8 cIndex)
831 {
832     maBitmap[(maBitmapPixelSize.Width() * nY + nX) * (HasAlphaChannel() ? 4 : 3)] = cIndex;
833     nLargestPixelIndex = std::max<int>(nLargestPixelIndex, cIndex);
834 }
835 
SetPixel(tools::Long nY,tools::Long nX,Color c)836 void TIFFReader::SetPixel(tools::Long nY, tools::Long nX, Color c)
837 {
838     auto p = maBitmap.data() + ((maBitmapPixelSize.Width() * nY + nX) * (HasAlphaChannel() ? 4 : 3));
839     *p = c.GetRed();
840     p++;
841     *p = c.GetGreen();
842     p++;
843     *p = c.GetBlue();
844     if (HasAlphaChannel())
845     {
846         p++;
847         *p = 0xff; // alpha
848     }
849 }
850 
SetPixelAlpha(tools::Long nY,tools::Long nX,sal_uInt8 nAlpha)851 void TIFFReader::SetPixelAlpha(tools::Long nY, tools::Long nX, sal_uInt8 nAlpha)
852 {
853     assert(HasAlphaChannel());
854     maBitmap[((maBitmapPixelSize.Width() * nY + nX) * 4) + 3] = nAlpha;
855 }
856 
ConvertScanline(sal_Int32 nY)857 bool TIFFReader::ConvertScanline(sal_Int32 nY)
858 {
859     sal_uInt32  nRed, nGreen, nBlue, ns, nVal;
860     sal_uInt8   nByteVal;
861 
862     if ( nDstBitsPerPixel == 24 )
863     {
864         if ( nBitsPerSample == 8 && nSamplesPerPixel >= 3 &&
865              nPlanes == 1 && nPhotometricInterpretation == 2 )
866         {
867             sal_uInt8* pt = getMapData(0);
868 
869             // are the values being saved as difference?
870             if ( 2 == nPredictor )
871             {
872                 sal_uInt8  nLRed = 0;
873                 sal_uInt8  nLGreen = 0;
874                 sal_uInt8  nLBlue = 0;
875                 sal_uInt8  nLAlpha = 0;
876                 for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel)
877                 {
878                     // The following computations rely on sal_uInt8 wrap-around when adding the
879                     // (unsigned) pt deltas; the "& 0xFF" is only conceptual, but helps prevent
880                     // sanitizer warnings:
881                     nLRed = (nLRed + pt[ 0 ]) & 0xFF;
882                     nLGreen = (nLGreen + pt[ 1 ]) & 0xFF;
883                     nLBlue = (nLBlue + pt[ 2 ]) & 0xFF;
884                     SetPixel(nY, nx, Color(nLRed, nLGreen, nLBlue));
885                     if (HasAlphaChannel())
886                     {
887                         nLAlpha = (nLAlpha + pt[ 3 ]) & 0xFF;
888                         SetPixelAlpha(nY, nx, ~nLAlpha);
889                     }
890                 }
891             }
892             else
893             {
894                 for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel)
895                 {
896                     SetPixel(nY, nx, Color(pt[0], pt[1], pt[2]));
897                     if (HasAlphaChannel())
898                     {
899                         sal_uInt8 nAlpha = pt[3];
900                         SetPixelAlpha(nY, nx, ~nAlpha);
901                     }
902                 }
903             }
904         }
905         else if ( nPhotometricInterpretation == 2 && nSamplesPerPixel >= 3 )
906         {
907             if ( nMaxSampleValue > nMinSampleValue )
908             {
909                 sal_uInt32 nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
910                 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
911                 {
912                     if ( nPlanes < 3 )
913                     {
914                         nRed = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
915                         nGreen = GetBits( getMapData(1), ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
916                         nBlue = GetBits( getMapData(2), ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
917                     }
918                     else
919                     {
920                         nRed = GetBits( getMapData(0), nx * nBitsPerSample, nBitsPerSample );
921                         nGreen = GetBits( getMapData(1), nx * nBitsPerSample, nBitsPerSample );
922                         nBlue = GetBits( getMapData(2), nx * nBitsPerSample, nBitsPerSample );
923                     }
924                     SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed - nMinMax), static_cast<sal_uInt8>(nGreen - nMinMax), static_cast<sal_uInt8>(nBlue - nMinMax)));
925                 }
926             }
927         }
928         else if ( nPhotometricInterpretation == 5 && nSamplesPerPixel == 3 )
929         {
930             if ( nMaxSampleValue > nMinSampleValue )
931             {
932                 sal_uInt32 nMinMax =  nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue );
933                 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
934                 {
935                     if ( nPlanes < 3 )
936                     {
937                         nRed = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample );
938                         nGreen = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample );
939                         nBlue = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample );
940                     }
941                     else
942                     {
943                         nRed = GetBits( getMapData(0), nx * nBitsPerSample, nBitsPerSample );
944                         nGreen = GetBits( getMapData(1), nx * nBitsPerSample, nBitsPerSample );
945                         nBlue = GetBits( getMapData(2), nx * nBitsPerSample, nBitsPerSample );
946                     }
947                     nRed = 255 - static_cast<sal_uInt8>( nRed - nMinMax );
948                     nGreen = 255 - static_cast<sal_uInt8>( nGreen - nMinMax );
949                     nBlue = 255 - static_cast<sal_uInt8>( nBlue - nMinMax );
950                     SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue)));
951                 }
952             }
953         }
954         else if( nPhotometricInterpretation == 5 && nSamplesPerPixel == 4 )
955         {
956             if ( nMaxSampleValue > nMinSampleValue )
957             {
958                 sal_uInt8   nSamp[ 4 ];
959                 sal_uInt8   nSampLast[ 4 ] = { 0, 0, 0, 0 };
960 
961                 for(sal_Int32 nx = 0; nx < nImageWidth; ++nx)
962                 {
963                     // are the values being saved as difference?
964                     if( 2 == nPredictor )
965                     {
966                         for( ns = 0; ns < 4; ns++ )
967                         {
968                             if( nPlanes < 3 )
969                                 nSampLast[ ns ] = nSampLast[ ns ] + static_cast<sal_uInt8>(GetBits( getMapData(0), ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample ));
970                             else
971                                 nSampLast[ ns ] = nSampLast[ ns ] + static_cast<sal_uInt8>(GetBits( getMapData(ns), nx * nBitsPerSample, nBitsPerSample ));
972                             nSamp[ ns ] = nSampLast[ ns ];
973                         }
974                     }
975                     else
976                     {
977                         for( ns = 0; ns < 4; ns++ )
978                         {
979                             if( nPlanes < 3 )
980                                 nSamp[ ns ] = static_cast<sal_uInt8>(GetBits( getMapData(0), ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample ));
981                             else
982                                 nSamp[ ns ]= static_cast<sal_uInt8>(GetBits( getMapData(ns), nx * nBitsPerSample, nBitsPerSample ));
983                         }
984                     }
985                     const tools::Long nBlack = nSamp[ 3 ];
986                     nRed = static_cast<sal_uInt8>(std::max<sal_Int32>( 0, 255 - ( ( static_cast<sal_Int32>(nSamp[ 0 ]) + nBlack - static_cast<sal_Int32>(nMinSampleValue << 1U ) ) *
987                                 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) ));
988                     nGreen = static_cast<sal_uInt8>(std::max<sal_Int32>( 0, 255 - ( ( static_cast<sal_Int32>(nSamp[ 1 ]) + nBlack - static_cast<sal_Int32>(nMinSampleValue << 1U ) ) *
989                                 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) ));
990                     nBlue = static_cast<sal_uInt8>(std::max<sal_Int32>( 0, 255 - ( ( static_cast<sal_Int32>(nSamp[ 2 ]) + nBlack - static_cast<sal_Int32>(nMinSampleValue << 1U ) ) *
991                                 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) ));
992                     SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue)));
993                 }
994             }
995         }
996     }
997     else if ( nSamplesPerPixel == 1 && ( nPhotometricInterpretation <= 1 || nPhotometricInterpretation == 3 ) )
998     {
999         if ( nMaxSampleValue > nMinSampleValue )
1000         {
1001             sal_uInt32 nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
1002             sal_uInt8* pt = getMapData(0);
1003             sal_uInt8* ptend = pt + nBytesPerRow;
1004             sal_uInt8 nShift;
1005 
1006             switch ( nDstBitsPerPixel )
1007             {
1008                 case 8 :
1009                 {
1010                     if (pt + nImageWidth > ptend)
1011                         return false;
1012 
1013                     if ( bByteSwap )
1014                     {
1015                         if ( nPredictor == 2 )
1016                         {
1017                             sal_uInt8 nLast = 0;
1018                             for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
1019                             {
1020                                 nLast += nx == 0 ? BYTESWAP( *pt++ ) : *pt++;
1021                                 SetPixel(nY, nx, nLast);
1022                             }
1023                         }
1024                         else
1025                         {
1026                             for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
1027                             {
1028                                 sal_uInt8 nLast = *pt++;
1029                                 SetPixel(nY, nx, static_cast<sal_uInt8>( (BYTESWAP(static_cast<sal_uInt32>(nLast)) - nMinSampleValue) * nMinMax ));
1030                             }
1031                         }
1032                     }
1033                     else
1034                     {
1035                         if ( nPredictor == 2 )
1036                         {
1037                             sal_uInt8 nLast = 0;
1038                             for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
1039                             {
1040                                 nLast += *pt++;
1041                                 SetPixel(nY, nx, nLast);
1042                             }
1043                         }
1044                         else
1045                         {
1046                             for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
1047                             {
1048                                 SetPixel(nY, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(*pt++) - nMinSampleValue) * nMinMax ));
1049                             }
1050                         }
1051                     }
1052                 }
1053                 break;
1054 
1055                 case 7 :
1056                 case 6 :
1057                 case 5 :
1058                 case 4 :
1059                 case 3 :
1060                 case 2 :
1061                 {
1062                     for (sal_Int32 nx = 0; nx < nImageWidth; ++nx)
1063                     {
1064                         nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax;
1065                         SetPixel(nY, nx, static_cast<sal_uInt8>(nVal));
1066                     }
1067                 }
1068                 break;
1069 
1070                 case 1 :
1071                 {
1072                     sal_uInt32 nByteCount = nImageWidth >> 3;
1073 
1074                     sal_uInt32 nBytesNeeded = nByteCount;
1075                     if (nImageWidth & 7)
1076                         ++nBytesNeeded;
1077                     if (pt + nBytesNeeded > ptend)
1078                         return false;
1079 
1080                     if ( bByteSwap )
1081                     {
1082                         sal_Int32 nx = 0;
1083                         while (nByteCount--)
1084                         {
1085                             nByteVal = *pt++;
1086                             SetPixel(nY, nx++, nByteVal & 1);
1087                             nByteVal >>= 1;
1088                             SetPixel(nY, nx++, nByteVal & 1);
1089                             nByteVal >>= 1;
1090                             SetPixel(nY, nx++, nByteVal & 1);
1091                             nByteVal >>= 1;
1092                             SetPixel(nY, nx++, nByteVal & 1);
1093                             nByteVal >>= 1;
1094                             SetPixel(nY, nx++, nByteVal & 1);
1095                             nByteVal >>= 1;
1096                             SetPixel(nY, nx++, nByteVal & 1);
1097                             nByteVal >>= 1;
1098                             SetPixel(nY, nx++, nByteVal & 1);
1099                             nByteVal >>= 1;
1100                             SetPixel(nY, nx++, nByteVal);
1101                         }
1102                         if ( nImageWidth & 7 )
1103                         {
1104                             nByteVal = *pt++;
1105                             while ( nx < nImageWidth )
1106                             {
1107                                 SetPixel(nY, nx++, nByteVal & 1);
1108                                 nByteVal >>= 1;
1109                             }
1110                         }
1111                     }
1112                     else
1113                     {
1114                         sal_Int32 nx = 7;
1115                         while (nByteCount--)
1116                         {
1117                             nByteVal = *pt++;
1118                             SetPixel(nY, nx, nByteVal & 1);
1119                             nByteVal >>= 1;
1120                             SetPixel(nY, --nx, nByteVal & 1);
1121                             nByteVal >>= 1;
1122                             SetPixel(nY, --nx, nByteVal & 1);
1123                             nByteVal >>= 1;
1124                             SetPixel(nY, --nx, nByteVal & 1);
1125                             nByteVal >>= 1;
1126                             SetPixel(nY, --nx, nByteVal & 1);
1127                             nByteVal >>= 1;
1128                             SetPixel(nY, --nx, nByteVal & 1);
1129                             nByteVal >>= 1;
1130                             SetPixel(nY, --nx, nByteVal & 1);
1131                             nByteVal >>= 1;
1132                             SetPixel(nY, --nx, nByteVal);
1133                             nx += 15;
1134                         }
1135                         if ( nImageWidth & 7 )
1136                         {
1137                             nx -= 7;
1138                             nByteVal = *pt++;
1139                             nShift = 7;
1140                             while ( nx < nImageWidth )
1141                             {
1142                                 SetPixel(nY, nx++, ( nByteVal >> nShift ) & 1);
1143                             }
1144                         }
1145                     }
1146                 }
1147                 break;
1148 
1149                 default :
1150                     return false;
1151             }
1152         }
1153     }
1154     else if ( ( nSamplesPerPixel == 2 ) && ( nBitsPerSample == 8 ) &&
1155         ( nPlanarConfiguration == 1 ) && aColorMap.empty() )               // grayscale + alpha
1156     {
1157         if ( nMaxSampleValue > nMinSampleValue )
1158         {
1159             sal_uInt8* pt = getMapData(0);
1160 
1161             if (nPredictor == 2)
1162             {
1163                 sal_uInt8 nLastPixel = 0;
1164                 sal_uInt8 nLastAlpha = 0;
1165                 for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += 2)
1166                 {
1167                     nLastPixel = (nLastPixel + pt[0]) & 0xFF;
1168                     SetPixel(nY, nx, nLastPixel);
1169 
1170                     nLastAlpha = (nLastAlpha + pt[1]) & 0xFF;
1171                     SetPixelAlpha(nY, nx, ~nLastAlpha);
1172                 }
1173             }
1174             else
1175             {
1176                 sal_uInt32 nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue );
1177                 for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += 2)
1178                 {
1179                     SetPixel(nY, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(pt[0]) - nMinSampleValue) * nMinMax ));
1180                     sal_uInt8 nAlpha = static_cast<sal_uInt8>( (static_cast<sal_uInt32>(pt[1]) - nMinSampleValue) * nMinMax );
1181                     SetPixelAlpha(nY, nx, ~nAlpha);
1182                 }
1183             }
1184         }
1185     }
1186     else
1187         return false;
1188     return true;
1189 }
1190 
MakePalCol()1191 void TIFFReader::MakePalCol()
1192 {
1193     if ( nDstBitsPerPixel <= 8 )
1194     {
1195         aColorMap.resize(256);
1196         if ( nPhotometricInterpretation <= 1 )
1197         {
1198             nNumColors = sal_uInt32(1) << nBitsPerSample;
1199             if ( nNumColors > 256 )
1200                 nNumColors = 256;
1201 
1202             if (nLargestPixelIndex >= static_cast<int>(nNumColors))
1203             {
1204                 SAL_WARN("filter.tiff", "palette has less entries that largest index used. Expanding palette to match");
1205                 nNumColors = nLargestPixelIndex + 1;
1206             }
1207 
1208             for (sal_uInt32 i = 0; i < nNumColors; ++i)
1209             {
1210                 sal_uInt32 nVal = ( i * 255 / ( nNumColors - 1 ) ) & 0xff;
1211                 sal_uInt32 n0RGB = nVal | ( nVal << 8 ) | ( nVal << 16 );
1212                 if ( nPhotometricInterpretation == 1 )
1213                     aColorMap[i] = n0RGB;
1214                 else
1215                     aColorMap[nNumColors - i - 1] = n0RGB;
1216             }
1217         }
1218         mvPalette.resize(std::max<sal_uInt16>(nNumColors, mvPalette.size()));
1219         for (sal_uInt32 i = 0; i < nNumColors; ++i)
1220         {
1221             mvPalette[i] = Color( static_cast<sal_uInt8>( aColorMap[ i ] >> 16 ),
1222                 static_cast<sal_uInt8>( aColorMap[ i ] >> 8 ), static_cast<sal_uInt8>(aColorMap[ i ]) );
1223         }
1224     }
1225 
1226     if ( !(fXResolution > 1.0 && fYResolution > 1.0 && ( nResolutionUnit == 2 || nResolutionUnit == 3 )) )
1227         return;
1228 
1229     sal_uInt32 nRX, nRY;
1230     if (nResolutionUnit==2)
1231     {
1232         nRX=static_cast<sal_uInt32>(fXResolution+0.5);
1233         nRY=static_cast<sal_uInt32>(fYResolution+0.5);
1234     }
1235     else
1236     {
1237         nRX=static_cast<sal_uInt32>(fXResolution*2.54+0.5);
1238         nRY=static_cast<sal_uInt32>(fYResolution*2.54+0.5);
1239     }
1240     MapMode aMapMode(MapUnit::MapInch,Point(0,0),Fraction(1,nRX),Fraction(1,nRY));
1241     maBitmapPrefMapMode = aMapMode;
1242     maBitmapPrefSize = Size(nImageWidth,nImageLength);
1243 }
1244 
1245 
ReadHeader()1246 void TIFFReader::ReadHeader()
1247 {
1248     sal_uInt8 nbyte1(0), nbyte2(0);
1249     sal_uInt16 nushort(0);
1250 
1251     pTIFF->ReadUChar( nbyte1 );
1252     if ( nbyte1 == 'I' )
1253         pTIFF->SetEndian( SvStreamEndian::LITTLE );
1254     else
1255         pTIFF->SetEndian( SvStreamEndian::BIG );
1256 
1257     pTIFF->ReadUChar( nbyte2 ).ReadUInt16( nushort );
1258     if ( nbyte1 != nbyte2 || ( nbyte1 != 'I' && nbyte1 != 'M' ) || nushort != 0x002a )
1259         bStatus = false;
1260 }
1261 
HasAlphaChannel() const1262 bool TIFFReader::HasAlphaChannel() const
1263 {
1264     /*There are undoubtedly more variants we could support, but keep it simple for now*/
1265     bool bRGBA = nDstBitsPerPixel == 24 &&
1266                  nBitsPerSample == 8 &&
1267                  nSamplesPerPixel >= 4 &&
1268                  nPlanes == 1 &&
1269                  nPhotometricInterpretation == 2;
1270     if (bRGBA)
1271         return true;
1272 
1273     // additionally support the format used in tdf#126460
1274     bool bGrayScaleAlpha = nDstBitsPerPixel == 8 &&
1275                            nBitsPerSample == 8 &&
1276                            nSamplesPerPixel == 2 &&
1277                            nPlanarConfiguration == 1;
1278 
1279     return bGrayScaleAlpha;
1280 }
1281 
1282 namespace
1283 {
SanitizePaletteIndex(sal_uInt8 nIndex,const std::vector<Color> & rPalette)1284     Color SanitizePaletteIndex(sal_uInt8 nIndex, const std::vector<Color>& rPalette)
1285     {
1286         const size_t nPaletteEntryCount = rPalette.size();
1287         if (nPaletteEntryCount && nIndex >= nPaletteEntryCount)
1288         {
1289             auto nSanitizedIndex = nIndex % nPaletteEntryCount;
1290             SAL_WARN_IF(nIndex != nSanitizedIndex, "vcl", "invalid colormap index: "
1291                         << static_cast<unsigned int>(nIndex) << ", colormap len is: "
1292                         << nPaletteEntryCount);
1293             nIndex = nSanitizedIndex;
1294         }
1295 
1296         return rPalette[nIndex];
1297     }
1298 }
1299 
ReadTIFF(SvStream & rTIFF,Graphic & rGraphic)1300 bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic )
1301 {
1302     sal_uInt16  i, nNumTags(0), nTagType(0);
1303     sal_uInt32 nFirstIfd(0), nDataLen;
1304 
1305     bStatus = true;
1306 
1307     pTIFF = &rTIFF;
1308     sal_uInt64 nMaxPos = nOrigPos = pTIFF->Tell();
1309     nEndOfFile = nOrigPos + pTIFF->remainingSize();
1310     // number format of pTIFF at the beginning
1311     SvStreamEndian nOrigNumberFormat = pTIFF->GetEndian();
1312 
1313     // read header:
1314     ReadHeader();
1315 
1316     // read first IFD:
1317     pTIFF->ReadUInt32( nFirstIfd );
1318 
1319     if( !nFirstIfd || pTIFF->GetError() )
1320         bStatus = false;
1321 
1322     if ( bStatus )
1323     {
1324         sal_uInt32 nOffset = nFirstIfd;
1325 
1326         std::vector<sal_uInt32> aSeenOffsets;
1327         // calculate length of TIFF file
1328         do
1329         {
1330             if (std::find(aSeenOffsets.begin(), aSeenOffsets.end(), nOffset) != aSeenOffsets.end())
1331             {
1332                 SAL_WARN("filter.tiff", "Parsing error: " << nOffset <<
1333                          " already processed, format loop");
1334                 bStatus = false;
1335                 break;
1336             }
1337             pTIFF->Seek(nOrigPos + nOffset);
1338             aSeenOffsets.push_back(nOffset);
1339 
1340             if( pTIFF->GetError() )
1341             {
1342                 pTIFF->ResetError();
1343                 break;
1344             }
1345             nMaxPos = std::max( pTIFF->Tell(), nMaxPos );
1346 
1347             pTIFF->ReadUInt16( nNumTags );
1348 
1349             const size_t nMinRecordSize = 12;
1350             const size_t nMaxRecords = pTIFF->remainingSize() / nMinRecordSize;
1351             if (nNumTags > nMaxRecords)
1352             {
1353                 SAL_WARN("filter.tiff", "Parsing error: " << nMaxRecords <<
1354                          " max possible entries, but " << nNumTags << " claimed, truncating");
1355                 nNumTags = nMaxRecords;
1356             }
1357 
1358             // loop through tags:
1359             for( i = 0; i < nNumTags; i++ )
1360             {
1361                 nTagType = 0;
1362                 nDataType = USHRT_MAX;
1363                 nDataLen = 0;
1364                 nOffset = 0;
1365                 pTIFF->ReadUInt16( nTagType ).ReadUInt16( nDataType ).ReadUInt32( nDataLen ).ReadUInt32( nOffset );
1366 
1367                 if( DataTypeSize() * nDataLen > 4 )
1368                     nMaxPos = std::max(nOrigPos + nOffset + DataTypeSize() * nDataLen, nMaxPos);
1369             }
1370             pTIFF->ReadUInt32( nOffset );
1371             if (!pTIFF->good())
1372                 nOffset = 0;
1373 
1374             nMaxPos = std::max( pTIFF->Tell(), nMaxPos );
1375             if ( !nOffset )
1376                 nMaxPos = std::max( pTIFF->Tell(), nMaxPos );
1377         }
1378         while( nOffset );
1379 
1380         std::vector<sal_uInt32> aSeenIfds;
1381 
1382         for ( sal_uInt32 nNextIfd = nFirstIfd; nNextIfd && bStatus; )
1383         {
1384             if (std::find(aSeenIfds.begin(), aSeenIfds.end(), nNextIfd) != aSeenIfds.end())
1385             {
1386                 SAL_WARN("filter.tiff", "Parsing error: " << nNextIfd <<
1387                          " already processed, format loop");
1388                 bStatus = false;
1389                 break;
1390             }
1391             pTIFF->Seek(nOrigPos + nNextIfd);
1392             aSeenIfds.push_back(nNextIfd);
1393             {
1394                 bByteSwap = false;
1395 
1396                 nNewSubFile = 0;
1397                 nSubFile = 0;
1398                 nImageWidth = 0;
1399                 nImageLength = 0;
1400                 nBitsPerSample = 1;                         // default value according to the documentation
1401                 nCompression = 1;
1402                 nPhotometricInterpretation = 0;
1403                 nThresholding = 1;                          // default value according to the documentation
1404                 nCellWidth = 1;
1405                 nCellLength = 1;
1406                 nFillOrder = 1;                             // default value according to the documentation
1407                 nOrientation = 1;
1408                 nSamplesPerPixel = 1;                       // default value according to the documentation
1409                 nRowsPerStrip = 0xffffffff;                 // default value according to the documentation
1410                 nMinSampleValue = 0;                        // default value according to the documentation
1411                 nMaxSampleValue = 0;
1412                 fXResolution = 0.0;
1413                 fYResolution = 0.0;
1414                 nPlanarConfiguration = 1;
1415                 nGroup3Options = 0;                         // default value according to the documentation
1416                 nGroup4Options = 0;                         // default value according to the documentation
1417                 nResolutionUnit = 2;                        // default value according to the documentation
1418                 nPredictor = 1;
1419                 nNumColors = 0;
1420 
1421                 aStripOffsets.clear();
1422                 aStripByteCounts.clear();
1423                 for (auto& j : aMap)
1424                     j.clear();
1425 
1426                 pTIFF->ReadUInt16( nNumTags );
1427                 sal_uInt64 nPos = pTIFF->Tell();
1428 
1429                 const size_t nMinRecordSize = 8;
1430                 const size_t nMaxRecords = pTIFF->remainingSize() / nMinRecordSize;
1431                 if (nNumTags > nMaxRecords)
1432                 {
1433                     SAL_WARN("filter.tiff", "Parsing error: " << nMaxRecords <<
1434                              " max possible entries, but " << nNumTags << " claimed, truncating");
1435                     nNumTags = nMaxRecords;
1436                 }
1437 
1438                 for( i = 0; i < nNumTags; i++ )
1439                 {
1440                     pTIFF->ReadUInt16( nTagType ).ReadUInt16( nDataType ).ReadUInt32( nDataLen );
1441 
1442                     if( DataTypeSize() * nDataLen > 4 )
1443                     {
1444                         pTIFF->ReadUInt32( nOffset );
1445                         if (!checkSeek(*pTIFF, nOrigPos + nOffset))
1446                         {
1447                             bStatus = false;
1448                             break;
1449                         }
1450                     }
1451                     ReadTagData( nTagType, nDataLen );
1452                     nPos += 12; pTIFF->Seek( nPos );
1453 
1454                     if ( pTIFF->GetError() )
1455                         bStatus = false;
1456 
1457                     if ( !bStatus )
1458                         break;
1459                 }
1460                 pTIFF->ReadUInt32( nNextIfd );
1461                 if (!pTIFF->good())
1462                     nNextIfd = 0;
1463             }
1464             if ( !nBitsPerSample || ( nBitsPerSample > 32 ) )
1465                 bStatus = false;
1466             if (nImageWidth <= 0 || nImageLength <= 0)
1467                 bStatus = false;
1468             if ( bStatus )
1469             {
1470                 nLargestPixelIndex = -1;
1471                 if ( nMaxSampleValue == 0 )
1472                 {
1473                     if ( nBitsPerSample == 32 )         // sj: i93300, compiler bug, 1 << 32 gives 1 one 32bit windows platforms,
1474                         nMaxSampleValue = 0xffffffff;   // (up from 80286 only the lower 5 bits are used when shifting a 32bit register)
1475                     else
1476                     {
1477                         nMaxSampleValue = (1U << nBitsPerSample) - 1;
1478                     }
1479                 }
1480                 if ( nPhotometricInterpretation == 2 || nPhotometricInterpretation == 5 || nPhotometricInterpretation == 6 )
1481                     nDstBitsPerPixel = 24;
1482                 else if ( nBitsPerSample*nSamplesPerPixel <= 1 )
1483                     nDstBitsPerPixel = 1;
1484                 else if ( nBitsPerSample*nSamplesPerPixel <= 4 )
1485                     nDstBitsPerPixel = 4;
1486                 else
1487                     nDstBitsPerPixel = 8;
1488 
1489                 if ( nPlanarConfiguration == 1 )
1490                     nPlanes = 1;
1491                 else
1492                     nPlanes = nSamplesPerPixel;
1493 
1494                 bStatus = nPlanes != 0;
1495             }
1496 
1497             sal_uInt32 nDiv = GetRowsPerStrip();
1498 
1499             if ( bStatus )
1500             {
1501                 bStatus = (nDiv != 0);
1502             }
1503 
1504             if ( bStatus )
1505             {
1506                 if ( ( nFillOrder == 2 ) && ( nCompression != 5 ) )     // in the LZW mode bits are already being inverted
1507                     bByteSwap = true;
1508                 nStripsPerPlane = ( nImageLength - 1 ) / nDiv + 1;
1509                 bStatus = nSamplesPerPixel != 0;
1510             }
1511 
1512             if ( bStatus )
1513             {
1514                 sal_uInt64 nRowSize = (static_cast<sal_uInt64>(nImageWidth) * nSamplesPerPixel / nPlanes * nBitsPerSample + 7) >> 3;
1515                 auto nMaxSize = SAL_MAX_INT32 / SAL_N_ELEMENTS(aMap);
1516                 if (utl::ConfigManager::IsFuzzing())
1517                     nMaxSize /= 2;
1518                 if (nRowSize > nMaxSize)
1519                 {
1520                     SAL_WARN("filter.tiff", "Ludicrous row size of: " << nRowSize << " required");
1521                     bStatus = false;
1522                 }
1523                 else
1524                     nBytesPerRow = nRowSize;
1525             }
1526 
1527             if (bStatus)
1528             {
1529                 //sanity check consider ReadMap condition for last row and
1530                 //last plane
1531                 if (nCompression == 1 || nCompression == 32771)
1532                 {
1533                     sal_uInt32 nStripBytesPerRow;
1534                     if (nCompression == 1)
1535                         nStripBytesPerRow = nBytesPerRow;
1536                     else
1537                         nStripBytesPerRow = ( nBytesPerRow + 1 ) & 0xfffffffe;
1538                     sal_uInt32 np = nPlanes - 1;
1539                     if (np >= SAL_N_ELEMENTS(aMap))
1540                         bStatus = false;
1541                     sal_Int32 ny = nImageLength - 1;
1542                     sal_uInt32 nStrip(0);
1543                     nDiv = GetRowsPerStrip();
1544                     if (bStatus)
1545                         bStatus = nDiv != 0;
1546                     if (bStatus)
1547                     {
1548                         nStrip = ny / nDiv + np * nStripsPerPlane;
1549                         if (nStrip >= aStripOffsets.size())
1550                             bStatus = false;
1551                     }
1552                     if (bStatus)
1553                     {
1554                         auto nStart = aStripOffsets[ nStrip ] + ( ny % GetRowsPerStrip() ) * nStripBytesPerRow;
1555                         if (nStart > nEndOfFile)
1556                             bStatus = false;
1557                     }
1558                 }
1559                 else if (nCompression == 2 || nCompression == 3 || nCompression == 4)
1560                 {
1561                     if (nCompression == 3 && nGroup3Options & 0xfffffffa)
1562                         bStatus = false;
1563                     else if (nCompression == 4 && nGroup4Options & 0xffffffff)
1564                         bStatus = false;
1565                     sal_uInt32 np = nPlanes - 1;
1566                     if (np >= SAL_N_ELEMENTS(aMap))
1567                         bStatus = false;
1568                     sal_Int32 ny = nImageLength - 1;
1569                     sal_uInt32 nStrip(0);
1570                     nDiv = GetRowsPerStrip();
1571                     if (bStatus)
1572                         bStatus = nDiv != 0;
1573                     if (bStatus)
1574                     {
1575                         nStrip = ny / nDiv + np * nStripsPerPlane;
1576                         if (nStrip >= aStripOffsets.size())
1577                             bStatus = false;
1578                     }
1579                     if (bStatus)
1580                     {
1581                         auto nStart = aStripOffsets[nStrip];
1582                         if (nStart > nEndOfFile)
1583                             bStatus = false;
1584                     }
1585 
1586                     if (bStatus)
1587                     {
1588                         sal_uInt64 nTargetBits = nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes;
1589                         if (nTargetBits > SAL_MAX_UINT16)
1590                             bStatus = false;
1591                     }
1592                 }
1593                 else if (nCompression == 5)
1594                 {
1595                     sal_uInt32 np = nPlanes - 1;
1596                     if (np >= SAL_N_ELEMENTS(aMap))
1597                         bStatus = false;
1598                     sal_Int32 ny = nImageLength - 1;
1599                     sal_uInt32 nStrip(0);
1600                     nDiv = GetRowsPerStrip();
1601                     if (bStatus)
1602                         bStatus = nDiv != 0;
1603                     if (bStatus)
1604                     {
1605                         nStrip = ny / nDiv + np * nStripsPerPlane;
1606                         if (nStrip >= aStripOffsets.size())
1607                             bStatus = false;
1608                     }
1609                     if (bStatus)
1610                     {
1611                         auto nStart = aStripOffsets[nStrip];
1612                         if (nStart > nEndOfFile)
1613                             bStatus = false;
1614                     }
1615                 }
1616                 else if (nCompression == 32773)
1617                 {
1618                 }
1619                 else
1620                 {
1621                     bStatus = false;
1622                 }
1623             }
1624 
1625             sal_Int32 nImageDataSize(0);
1626             if (bStatus)
1627             {
1628                 if (o3tl::checked_multiply<sal_Int32>(nImageWidth, nImageLength, nImageDataSize) ||
1629                     o3tl::checked_multiply<sal_Int32>(nImageDataSize, (HasAlphaChannel() ? 4 : 3), nImageDataSize) ||
1630                     nImageDataSize > SAL_MAX_INT32/4)
1631                 {
1632                     bStatus = false;
1633                 }
1634             }
1635 
1636             if (bStatus)
1637             {
1638                 sal_Int32 nResult = 0;
1639                 if (utl::ConfigManager::IsFuzzing() && (o3tl::checked_multiply(nImageWidth, nImageLength, nResult) || nResult > 4000000))
1640                     bStatus = false;
1641             }
1642 
1643             if ( bStatus )
1644             {
1645                 maBitmapPixelSize = Size(nImageWidth, nImageLength);
1646                 maBitmap.resize(nImageDataSize, 0);
1647 
1648                 if (bStatus && ReadMap())
1649                 {
1650                     nMaxPos = std::max( pTIFF->Tell(), nMaxPos );
1651                     MakePalCol();
1652                     nMaxPos = std::max( pTIFF->Tell(), nMaxPos );
1653                     // convert palette-ized images to 24-bit color
1654                     if (!mvPalette.empty())
1655                     {
1656                         for (sal_Int32 nY = 0; nY < nImageLength; ++nY)
1657                         {
1658                             for (sal_Int32 nX = 0; nX < nImageWidth; ++nX)
1659                             {
1660                                 auto p = maBitmap.data() + ((maBitmapPixelSize.Width() * nY + nX) * (HasAlphaChannel() ? 4 : 3));
1661                                 auto c = SanitizePaletteIndex(*p, mvPalette);
1662                                 *p = c.GetRed();
1663                                 p++;
1664                                 *p = c.GetGreen();
1665                                 p++;
1666                                 *p = c.GetBlue();
1667                             }
1668                         }
1669                     }
1670                 }
1671                 else
1672                     bStatus = false;
1673 
1674                 if ( bStatus )
1675                 {
1676                     BitmapEx aImage = vcl::bitmap::CreateFromData(maBitmap.data(), nImageWidth, nImageLength,
1677                             nImageWidth * (HasAlphaChannel() ? 4 : 3), // scanline bytes
1678                             HasAlphaChannel() ? vcl::PixelFormat::N32_BPP : vcl::PixelFormat::N24_BPP);
1679                     aImage.SetPrefMapMode(maBitmapPrefMapMode);
1680                     aImage.SetPrefSize(maBitmapPrefSize);
1681 
1682                     AnimationBitmap aAnimationBitmap( aImage, Point( 0, 0 ), maBitmapPixelSize,
1683                                                       ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back );
1684 
1685                     aAnimation.Insert( aAnimationBitmap );
1686                 }
1687             }
1688 
1689             // Clean up:
1690             for (auto& j : aMap)
1691                 j.clear();
1692             aColorMap.clear();
1693             aStripOffsets.clear();
1694             aStripByteCounts.clear();
1695         }
1696     }
1697 
1698     // seek to end of TIFF if succeeded
1699     pTIFF->SetEndian( nOrigNumberFormat );
1700     pTIFF->Seek(bStatus ? STREAM_SEEK_TO_END: nOrigPos);
1701 
1702     if ( aAnimation.Count() )
1703     {
1704         if ( aAnimation.Count() == 1 )
1705             rGraphic = aAnimation.GetBitmapEx();
1706         else
1707             rGraphic = aAnimation;  //aBitmap;
1708 
1709         return true;
1710     }
1711     else
1712         return false;
1713 }
1714 
ImportTiffGraphicImport(SvStream & rStream,Graphic & rGraphic)1715 bool ImportTiffGraphicImport(SvStream & rStream, Graphic & rGraphic)
1716 {
1717     TIFFReader aTIFFReader;
1718     try
1719     {
1720         return aTIFFReader.ReadTIFF(rStream, rGraphic);
1721     }
1722     catch (const std::bad_alloc &)
1723     {
1724         return false;
1725     }
1726 }
1727 
1728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1729