LibreOffice Module vcl (master)  1
itiff.cxx
Go to the documentation of this file.
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>
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 
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) const;
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 
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 
174  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 
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 
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 
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 
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 
551 sal_uInt8* TIFFReader::getMapData(sal_uInt32 np)
552 {
553  aMap[np].resize(nBytesPerRow);
554  return aMap[np].data();
555 }
556 
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 
774 sal_uInt32 TIFFReader::GetBits( const sal_uInt8 * pSrc, sal_uInt32 nBitsPos, sal_uInt32 nBitsCount) const
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 
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 
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 
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 
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 
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 
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 
1262 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 {
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 
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);
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
1679  aImage.SetPrefMapMode(maBitmapPrefMapMode);
1680  aImage.SetPrefSize(maBitmapPrefSize);
1681 
1682  AnimationBitmap aAnimationBitmap( aImage, Point( 0, 0 ), maBitmapPixelSize,
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 
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: */
sal_uInt8 GetRed() const
bool ImportTiffGraphicImport(SvStream &rStream, Graphic &rGraphic)
Definition: itiff.cxx:1715
void ReadHeader(SvStream &rStream, ODbaseIndex::NDXHeader &rHeader)
tuple ns
double ny
long Long
void SetPrefMapMode(const MapMode &rPrefMapMode)
Definition: bitmapex.hxx:80
#define CCI_OPTION_BYTEALIGNROW
Definition: ccidecom.hxx:31
float x
#define CCI_OPTION_2D
Definition: ccidecom.hxx:27
#define SAL_MAX_UINT32
HashMap_OWString_Interface aMap
static bool IsFuzzing()
sal_uInt8 GetBlue() const
#define SAL_N_ELEMENTS(arr)
bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
#define SAL_MAX_INT32
void StartDecompression(SvStream &rIStream)
Definition: lzwdecom.cxx:52
int i
const sal_Int32 nCellWidth
std::enable_if< std::is_signed< T >::value, bool >::type checked_multiply(T a, T b, T &result)
bool m_bBufferUnchanged
Definition: ccidecom.hxx:52
#define ANIMATION_TIMEOUT_ON_CLICK
Definition: Animation.hxx:27
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
Definition: graph.cxx:329
sal_uInt8 GetGreen() const
double nx
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
sal_Int32 nDataType
#define CCI_OPTION_BYTEALIGNEOL
Definition: ccidecom.hxx:29
#define SAL_INFO(area, stream)
#define SVSTREAM_FILEFORMAT_ERROR
Definition: errcode.hxx:260
#define CCI_OPTION_INVERSEBITORDER
Definition: ccidecom.hxx:32
void SetPrefSize(const Size &rPrefSize)
Definition: bitmapex.hxx:77
sal_uInt64 Decompress(sal_uInt8 *pTarget, sal_uInt32 nMaxCount)
Definition: lzwdecom.cxx:77
sal_uInt64 Tell() const
void * p
BitmapEx CreateFromData(sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, vcl::PixelFormat ePixelFormat, bool bReversColors, bool bReverseAlpha)
Copy block of image data into the bitmap.
#define CCI_OPTION_EOL
Definition: ccidecom.hxx:28
#define SAL_WARN(area, stream)
SvStreamEndian
sal_uInt16 nPos