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