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 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_INT32 / 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_INT32 / 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 ( 906 ( nPhotometricInterpretation == 2 && nSamplesPerPixel >= 3 ) || 907 ( nPhotometricInterpretation == 5 && nSamplesPerPixel == 3 ) 908 ) 909 { 910 if ( nMaxSampleValue > nMinSampleValue ) 911 { 912 sal_uInt32 nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue ); 913 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 914 { 915 if ( nPlanes < 3 ) 916 { 917 nRed = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 0 ) * nBitsPerSample, nBitsPerSample ); 918 nGreen = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 1 ) * nBitsPerSample, nBitsPerSample ); 919 nBlue = GetBits( getMapData(0), ( nx * nSamplesPerPixel + 2 ) * nBitsPerSample, nBitsPerSample ); 920 } 921 else 922 { 923 nRed = GetBits( getMapData(0), nx * nBitsPerSample, nBitsPerSample ); 924 nGreen = GetBits( getMapData(1), nx * nBitsPerSample, nBitsPerSample ); 925 nBlue = GetBits( getMapData(2), nx * nBitsPerSample, nBitsPerSample ); 926 } 927 if (nPhotometricInterpretation == 2) 928 SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed - nMinMax), static_cast<sal_uInt8>(nGreen - nMinMax), static_cast<sal_uInt8>(nBlue - nMinMax))); 929 else 930 SetPixel(nY, nx, Color(255 - static_cast<sal_uInt8>(nRed - nMinMax), 255 - static_cast<sal_uInt8>(nGreen - nMinMax), 255 - static_cast<sal_uInt8>(nBlue - nMinMax))); 931 } 932 } 933 } 934 else if( nPhotometricInterpretation == 5 && nSamplesPerPixel == 4 ) 935 { 936 if ( nMaxSampleValue > nMinSampleValue ) 937 { 938 sal_uInt8 nSamp[ 4 ]; 939 sal_uInt8 nSampLast[ 4 ] = { 0, 0, 0, 0 }; 940 941 for(sal_Int32 nx = 0; nx < nImageWidth; ++nx) 942 { 943 // are the values being saved as difference? 944 if( 2 == nPredictor ) 945 { 946 for( ns = 0; ns < 4; ns++ ) 947 { 948 if( nPlanes < 3 ) 949 nSampLast[ ns ] = nSampLast[ ns ] + static_cast<sal_uInt8>(GetBits( getMapData(0), ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample )); 950 else 951 nSampLast[ ns ] = nSampLast[ ns ] + static_cast<sal_uInt8>(GetBits( getMapData(ns), nx * nBitsPerSample, nBitsPerSample )); 952 nSamp[ ns ] = nSampLast[ ns ]; 953 } 954 } 955 else 956 { 957 for( ns = 0; ns < 4; ns++ ) 958 { 959 if( nPlanes < 3 ) 960 nSamp[ ns ] = static_cast<sal_uInt8>(GetBits( getMapData(0), ( nx * nSamplesPerPixel + ns ) * nBitsPerSample, nBitsPerSample )); 961 else 962 nSamp[ ns ]= static_cast<sal_uInt8>(GetBits( getMapData(ns), nx * nBitsPerSample, nBitsPerSample )); 963 } 964 } 965 const tools::Long nBlack = nSamp[ 3 ]; 966 nRed = static_cast<sal_uInt8>(std::max<sal_Int32>( 0, 255 - ( ( static_cast<sal_Int32>(nSamp[ 0 ]) + nBlack - static_cast<sal_Int32>(nMinSampleValue << 1U ) ) * 967 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) )); 968 nGreen = static_cast<sal_uInt8>(std::max<sal_Int32>( 0, 255 - ( ( static_cast<sal_Int32>(nSamp[ 1 ]) + nBlack - static_cast<sal_Int32>(nMinSampleValue << 1U ) ) * 969 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) )); 970 nBlue = static_cast<sal_uInt8>(std::max<sal_Int32>( 0, 255 - ( ( static_cast<sal_Int32>(nSamp[ 2 ]) + nBlack - static_cast<sal_Int32>(nMinSampleValue << 1U ) ) * 971 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) )); 972 SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue))); 973 } 974 } 975 } 976 } 977 else if ( nSamplesPerPixel == 1 && ( nPhotometricInterpretation <= 1 || nPhotometricInterpretation == 3 ) ) 978 { 979 if ( nMaxSampleValue > nMinSampleValue ) 980 { 981 sal_uInt8* pt = getMapData(0); 982 sal_uInt8* ptend = pt + nBytesPerRow; 983 984 if (nBitsPerSample > 8) 985 { 986 sal_uInt32 nMinMax = nMinSampleValue * 255 / ( nMaxSampleValue - nMinSampleValue ); 987 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 988 { 989 nVal = GetBits(pt, nx * nSamplesPerPixel * nBitsPerSample, nBitsPerSample); 990 SetPixel(nY, nx, static_cast<sal_uInt8>(nVal - nMinMax)); 991 } 992 } 993 else 994 { 995 sal_uInt32 nMinMax = ( ( 1 << nDstBitsPerPixel ) - 1 ) / ( nMaxSampleValue - nMinSampleValue ); 996 sal_uInt8 nShift; 997 998 switch ( nDstBitsPerPixel ) 999 { 1000 case 8 : 1001 { 1002 if (pt + nImageWidth > ptend) 1003 return false; 1004 1005 if ( bByteSwap ) 1006 { 1007 if ( nPredictor == 2 ) 1008 { 1009 sal_uInt8 nLast = 0; 1010 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 1011 { 1012 nLast += nx == 0 ? BYTESWAP( *pt++ ) : *pt++; 1013 SetPixel(nY, nx, nLast); 1014 } 1015 } 1016 else 1017 { 1018 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 1019 { 1020 sal_uInt8 nLast = *pt++; 1021 SetPixel(nY, nx, static_cast<sal_uInt8>( (BYTESWAP(static_cast<sal_uInt32>(nLast)) - nMinSampleValue) * nMinMax )); 1022 } 1023 } 1024 } 1025 else 1026 { 1027 if ( nPredictor == 2 ) 1028 { 1029 sal_uInt8 nLast = 0; 1030 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 1031 { 1032 nLast += *pt++; 1033 SetPixel(nY, nx, nLast); 1034 } 1035 } 1036 else 1037 { 1038 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 1039 { 1040 SetPixel(nY, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(*pt++) - nMinSampleValue) * nMinMax )); 1041 } 1042 } 1043 } 1044 } 1045 break; 1046 1047 case 7 : 1048 case 6 : 1049 case 5 : 1050 case 4 : 1051 case 3 : 1052 case 2 : 1053 { 1054 for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) 1055 { 1056 nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax; 1057 SetPixel(nY, nx, static_cast<sal_uInt8>(nVal)); 1058 } 1059 } 1060 break; 1061 1062 case 1 : 1063 { 1064 sal_uInt32 nByteCount = nImageWidth >> 3; 1065 1066 sal_uInt32 nBytesNeeded = nByteCount; 1067 if (nImageWidth & 7) 1068 ++nBytesNeeded; 1069 if (pt + nBytesNeeded > ptend) 1070 return false; 1071 1072 if ( bByteSwap ) 1073 { 1074 sal_Int32 nx = 0; 1075 while (nByteCount--) 1076 { 1077 nByteVal = *pt++; 1078 SetPixel(nY, nx++, nByteVal & 1); 1079 nByteVal >>= 1; 1080 SetPixel(nY, nx++, nByteVal & 1); 1081 nByteVal >>= 1; 1082 SetPixel(nY, nx++, nByteVal & 1); 1083 nByteVal >>= 1; 1084 SetPixel(nY, nx++, nByteVal & 1); 1085 nByteVal >>= 1; 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); 1093 } 1094 if ( nImageWidth & 7 ) 1095 { 1096 nByteVal = *pt++; 1097 while ( nx < nImageWidth ) 1098 { 1099 SetPixel(nY, nx++, nByteVal & 1); 1100 nByteVal >>= 1; 1101 } 1102 } 1103 } 1104 else 1105 { 1106 sal_Int32 nx = 7; 1107 while (nByteCount--) 1108 { 1109 nByteVal = *pt++; 1110 SetPixel(nY, nx, nByteVal & 1); 1111 nByteVal >>= 1; 1112 SetPixel(nY, --nx, nByteVal & 1); 1113 nByteVal >>= 1; 1114 SetPixel(nY, --nx, nByteVal & 1); 1115 nByteVal >>= 1; 1116 SetPixel(nY, --nx, nByteVal & 1); 1117 nByteVal >>= 1; 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); 1125 nx += 15; 1126 } 1127 if ( nImageWidth & 7 ) 1128 { 1129 nx -= 7; 1130 nByteVal = *pt++; 1131 nShift = 7; 1132 while ( nx < nImageWidth ) 1133 { 1134 SetPixel(nY, nx++, ( nByteVal >> nShift ) & 1); 1135 --nShift; 1136 } 1137 } 1138 } 1139 } 1140 break; 1141 1142 default : 1143 return false; 1144 } 1145 } 1146 } 1147 } 1148 else if ( ( nSamplesPerPixel == 2 ) && ( nBitsPerSample == 8 ) && 1149 ( nPlanarConfiguration == 1 ) && aColorMap.empty() ) // grayscale + alpha 1150 { 1151 if ( nMaxSampleValue > nMinSampleValue ) 1152 { 1153 sal_uInt8* pt = getMapData(0); 1154 1155 if (nPredictor == 2) 1156 { 1157 sal_uInt8 nLastPixel = 0; 1158 sal_uInt8 nLastAlpha = 0; 1159 for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += 2) 1160 { 1161 nLastPixel = (nLastPixel + pt[0]) & 0xFF; 1162 SetPixel(nY, nx, nLastPixel); 1163 1164 nLastAlpha = (nLastAlpha + pt[1]) & 0xFF; 1165 SetPixelAlpha(nY, nx, ~nLastAlpha); 1166 } 1167 } 1168 else 1169 { 1170 sal_uInt32 nMinMax = ( ( 1 << 8 /*nDstBitsPerPixel*/ ) - 1 ) / ( nMaxSampleValue - nMinSampleValue ); 1171 for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += 2) 1172 { 1173 SetPixel(nY, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(pt[0]) - nMinSampleValue) * nMinMax )); 1174 sal_uInt8 nAlpha = static_cast<sal_uInt8>( (static_cast<sal_uInt32>(pt[1]) - nMinSampleValue) * nMinMax ); 1175 SetPixelAlpha(nY, nx, ~nAlpha); 1176 } 1177 } 1178 } 1179 } 1180 else 1181 return false; 1182 return true; 1183 } 1184 1185 void TIFFReader::MakePalCol() 1186 { 1187 if ( nDstBitsPerPixel <= 8 ) 1188 { 1189 aColorMap.resize(256); 1190 if ( nPhotometricInterpretation <= 1 ) 1191 { 1192 nNumColors = sal_uInt32(1) << nBitsPerSample; 1193 if ( nNumColors > 256 ) 1194 nNumColors = 256; 1195 1196 if (nLargestPixelIndex >= static_cast<int>(nNumColors)) 1197 { 1198 SAL_WARN("filter.tiff", "palette has less entries that largest index used. Expanding palette to match"); 1199 nNumColors = nLargestPixelIndex + 1; 1200 } 1201 1202 for (sal_uInt32 i = 0; i < nNumColors; ++i) 1203 { 1204 sal_uInt32 nVal = ( i * 255 / ( nNumColors - 1 ) ) & 0xff; 1205 sal_uInt32 n0RGB = nVal | ( nVal << 8 ) | ( nVal << 16 ); 1206 if ( nPhotometricInterpretation == 1 ) 1207 aColorMap[i] = n0RGB; 1208 else 1209 aColorMap[nNumColors - i - 1] = n0RGB; 1210 } 1211 } 1212 mvPalette.resize(std::max<sal_uInt16>(nNumColors, mvPalette.size())); 1213 for (sal_uInt32 i = 0; i < nNumColors; ++i) 1214 { 1215 mvPalette[i] = Color( static_cast<sal_uInt8>( aColorMap[ i ] >> 16 ), 1216 static_cast<sal_uInt8>( aColorMap[ i ] >> 8 ), static_cast<sal_uInt8>(aColorMap[ i ]) ); 1217 } 1218 } 1219 1220 if ( !(fXResolution > 1.0 && fYResolution > 1.0 && ( nResolutionUnit == 2 || nResolutionUnit == 3 )) ) 1221 return; 1222 1223 sal_uInt32 nRX, nRY; 1224 if (nResolutionUnit==2) 1225 { 1226 nRX=static_cast<sal_uInt32>(fXResolution+0.5); 1227 nRY=static_cast<sal_uInt32>(fYResolution+0.5); 1228 } 1229 else 1230 { 1231 nRX=static_cast<sal_uInt32>(fXResolution*2.54+0.5); 1232 nRY=static_cast<sal_uInt32>(fYResolution*2.54+0.5); 1233 } 1234 MapMode aMapMode(MapUnit::MapInch,Point(0,0),Fraction(1,nRX),Fraction(1,nRY)); 1235 maBitmapPrefMapMode = aMapMode; 1236 maBitmapPrefSize = Size(nImageWidth,nImageLength); 1237 } 1238 1239 1240 void TIFFReader::ReadHeader() 1241 { 1242 sal_uInt8 nbyte1(0), nbyte2(0); 1243 sal_uInt16 nushort(0); 1244 1245 pTIFF->ReadUChar( nbyte1 ); 1246 if ( nbyte1 == 'I' ) 1247 pTIFF->SetEndian( SvStreamEndian::LITTLE ); 1248 else 1249 pTIFF->SetEndian( SvStreamEndian::BIG ); 1250 1251 pTIFF->ReadUChar( nbyte2 ).ReadUInt16( nushort ); 1252 if ( nbyte1 != nbyte2 || ( nbyte1 != 'I' && nbyte1 != 'M' ) || nushort != 0x002a ) 1253 bStatus = false; 1254 } 1255 1256 bool TIFFReader::HasAlphaChannel() const 1257 { 1258 /*There are undoubtedly more variants we could support, but keep it simple for now*/ 1259 bool bRGBA = nDstBitsPerPixel == 24 && 1260 nBitsPerSample == 8 && 1261 nSamplesPerPixel >= 4 && 1262 nPlanes == 1 && 1263 nPhotometricInterpretation == 2; 1264 if (bRGBA) 1265 return true; 1266 1267 // additionally support the format used in tdf#126460 1268 bool bGrayScaleAlpha = nDstBitsPerPixel == 8 && 1269 nBitsPerSample == 8 && 1270 nSamplesPerPixel == 2 && 1271 nPlanarConfiguration == 1; 1272 1273 return bGrayScaleAlpha; 1274 } 1275 1276 namespace 1277 { 1278 Color SanitizePaletteIndex(sal_uInt8 nIndex, const std::vector<Color>& rPalette) 1279 { 1280 const size_t nPaletteEntryCount = rPalette.size(); 1281 if (nPaletteEntryCount && nIndex >= nPaletteEntryCount) 1282 { 1283 auto nSanitizedIndex = nIndex % nPaletteEntryCount; 1284 SAL_WARN_IF(nIndex != nSanitizedIndex, "vcl", "invalid colormap index: " 1285 << static_cast<unsigned int>(nIndex) << ", colormap len is: " 1286 << nPaletteEntryCount); 1287 nIndex = nSanitizedIndex; 1288 } 1289 1290 return rPalette[nIndex]; 1291 } 1292 } 1293 1294 bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic ) 1295 { 1296 sal_uInt16 i, nNumTags(0), nTagType(0); 1297 sal_uInt32 nFirstIfd(0), nDataLen; 1298 1299 bStatus = true; 1300 1301 pTIFF = &rTIFF; 1302 sal_uInt64 nMaxPos = nOrigPos = pTIFF->Tell(); 1303 nEndOfFile = nOrigPos + pTIFF->remainingSize(); 1304 // number format of pTIFF at the beginning 1305 SvStreamEndian nOrigNumberFormat = pTIFF->GetEndian(); 1306 1307 // read header: 1308 ReadHeader(); 1309 1310 // read first IFD: 1311 pTIFF->ReadUInt32( nFirstIfd ); 1312 1313 if( !nFirstIfd || pTIFF->GetError() ) 1314 bStatus = false; 1315 1316 if ( bStatus ) 1317 { 1318 sal_uInt32 nOffset = nFirstIfd; 1319 1320 std::vector<sal_uInt32> aSeenOffsets; 1321 // calculate length of TIFF file 1322 do 1323 { 1324 if (std::find(aSeenOffsets.begin(), aSeenOffsets.end(), nOffset) != aSeenOffsets.end()) 1325 { 1326 SAL_WARN("filter.tiff", "Parsing error: " << nOffset << 1327 " already processed, format loop"); 1328 bStatus = false; 1329 break; 1330 } 1331 pTIFF->Seek(nOrigPos + nOffset); 1332 aSeenOffsets.push_back(nOffset); 1333 1334 if( pTIFF->GetError() ) 1335 { 1336 pTIFF->ResetError(); 1337 break; 1338 } 1339 nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); 1340 1341 pTIFF->ReadUInt16( nNumTags ); 1342 1343 const size_t nMinRecordSize = 12; 1344 const size_t nMaxRecords = pTIFF->remainingSize() / nMinRecordSize; 1345 if (nNumTags > nMaxRecords) 1346 { 1347 SAL_WARN("filter.tiff", "Parsing error: " << nMaxRecords << 1348 " max possible entries, but " << nNumTags << " claimed, truncating"); 1349 nNumTags = nMaxRecords; 1350 } 1351 1352 // loop through tags: 1353 for( i = 0; i < nNumTags; i++ ) 1354 { 1355 nTagType = 0; 1356 nDataType = USHRT_MAX; 1357 nDataLen = 0; 1358 nOffset = 0; 1359 pTIFF->ReadUInt16( nTagType ).ReadUInt16( nDataType ).ReadUInt32( nDataLen ).ReadUInt32( nOffset ); 1360 1361 if( DataTypeSize() * nDataLen > 4 ) 1362 nMaxPos = std::max(nOrigPos + nOffset + DataTypeSize() * nDataLen, nMaxPos); 1363 } 1364 pTIFF->ReadUInt32( nOffset ); 1365 if (!pTIFF->good()) 1366 nOffset = 0; 1367 1368 nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); 1369 if ( !nOffset ) 1370 nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); 1371 } 1372 while( nOffset ); 1373 1374 std::vector<sal_uInt32> aSeenIfds; 1375 1376 for ( sal_uInt32 nNextIfd = nFirstIfd; nNextIfd && bStatus; ) 1377 { 1378 if (std::find(aSeenIfds.begin(), aSeenIfds.end(), nNextIfd) != aSeenIfds.end()) 1379 { 1380 SAL_WARN("filter.tiff", "Parsing error: " << nNextIfd << 1381 " already processed, format loop"); 1382 bStatus = false; 1383 break; 1384 } 1385 pTIFF->Seek(nOrigPos + nNextIfd); 1386 aSeenIfds.push_back(nNextIfd); 1387 { 1388 bByteSwap = false; 1389 1390 nNewSubFile = 0; 1391 nSubFile = 0; 1392 nImageWidth = 0; 1393 nImageLength = 0; 1394 nBitsPerSample = 1; // default value according to the documentation 1395 nCompression = 1; 1396 nPhotometricInterpretation = 0; 1397 nThresholding = 1; // default value according to the documentation 1398 nCellWidth = 1; 1399 nCellLength = 1; 1400 nFillOrder = 1; // default value according to the documentation 1401 nOrientation = 1; 1402 nSamplesPerPixel = 1; // default value according to the documentation 1403 nRowsPerStrip = 0xffffffff; // default value according to the documentation 1404 nMinSampleValue = 0; // default value according to the documentation 1405 nMaxSampleValue = 0; 1406 fXResolution = 0.0; 1407 fYResolution = 0.0; 1408 nPlanarConfiguration = 1; 1409 nGroup3Options = 0; // default value according to the documentation 1410 nGroup4Options = 0; // default value according to the documentation 1411 nResolutionUnit = 2; // default value according to the documentation 1412 nPredictor = 1; 1413 nNumColors = 0; 1414 1415 aStripOffsets.clear(); 1416 aStripByteCounts.clear(); 1417 for (auto& j : aMap) 1418 j.clear(); 1419 1420 pTIFF->ReadUInt16( nNumTags ); 1421 sal_uInt64 nPos = pTIFF->Tell(); 1422 1423 const size_t nMinRecordSize = 8; 1424 const size_t nMaxRecords = pTIFF->remainingSize() / nMinRecordSize; 1425 if (nNumTags > nMaxRecords) 1426 { 1427 SAL_WARN("filter.tiff", "Parsing error: " << nMaxRecords << 1428 " max possible entries, but " << nNumTags << " claimed, truncating"); 1429 nNumTags = nMaxRecords; 1430 } 1431 1432 for( i = 0; i < nNumTags; i++ ) 1433 { 1434 pTIFF->ReadUInt16( nTagType ).ReadUInt16( nDataType ).ReadUInt32( nDataLen ); 1435 1436 if( DataTypeSize() * nDataLen > 4 ) 1437 { 1438 pTIFF->ReadUInt32( nOffset ); 1439 if (!checkSeek(*pTIFF, nOrigPos + nOffset)) 1440 { 1441 bStatus = false; 1442 break; 1443 } 1444 } 1445 ReadTagData( nTagType, nDataLen ); 1446 nPos += 12; pTIFF->Seek( nPos ); 1447 1448 if ( pTIFF->GetError() ) 1449 bStatus = false; 1450 1451 if ( !bStatus ) 1452 break; 1453 } 1454 pTIFF->ReadUInt32( nNextIfd ); 1455 if (!pTIFF->good()) 1456 nNextIfd = 0; 1457 } 1458 if ( !nBitsPerSample || ( nBitsPerSample > 32 ) ) 1459 bStatus = false; 1460 if (nImageWidth <= 0 || nImageLength <= 0) 1461 bStatus = false; 1462 if ( bStatus ) 1463 { 1464 nLargestPixelIndex = -1; 1465 if ( nMaxSampleValue == 0 ) 1466 { 1467 if ( nBitsPerSample == 32 ) // sj: i93300, compiler bug, 1 << 32 gives 1 one 32bit windows platforms, 1468 nMaxSampleValue = 0xffffffff; // (up from 80286 only the lower 5 bits are used when shifting a 32bit register) 1469 else 1470 { 1471 nMaxSampleValue = (1U << nBitsPerSample) - 1; 1472 } 1473 } 1474 if ( nPhotometricInterpretation == 2 || nPhotometricInterpretation == 5 || nPhotometricInterpretation == 6 ) 1475 nDstBitsPerPixel = 24; 1476 else if ( nBitsPerSample*nSamplesPerPixel <= 1 ) 1477 nDstBitsPerPixel = 1; 1478 else if ( nBitsPerSample*nSamplesPerPixel <= 4 ) 1479 nDstBitsPerPixel = 4; 1480 else 1481 nDstBitsPerPixel = 8; 1482 1483 if ( nPlanarConfiguration == 1 ) 1484 nPlanes = 1; 1485 else 1486 nPlanes = nSamplesPerPixel; 1487 1488 bStatus = nPlanes != 0; 1489 } 1490 1491 sal_uInt32 nDiv = GetRowsPerStrip(); 1492 1493 if ( bStatus ) 1494 { 1495 bStatus = (nDiv != 0); 1496 } 1497 1498 if ( bStatus ) 1499 { 1500 if ( ( nFillOrder == 2 ) && ( nCompression != 5 ) ) // in the LZW mode bits are already being inverted 1501 bByteSwap = true; 1502 nStripsPerPlane = ( nImageLength - 1 ) / nDiv + 1; 1503 bStatus = nSamplesPerPixel != 0; 1504 } 1505 1506 if ( bStatus ) 1507 { 1508 sal_uInt64 nRowSize = (static_cast<sal_uInt64>(nImageWidth) * nSamplesPerPixel / nPlanes * nBitsPerSample + 7) >> 3; 1509 auto nMaxSize = SAL_MAX_INT32 / SAL_N_ELEMENTS(aMap); 1510 if (utl::ConfigManager::IsFuzzing()) 1511 nMaxSize /= 2; 1512 if (nRowSize > nMaxSize) 1513 { 1514 SAL_WARN("filter.tiff", "Ludicrous row size of: " << nRowSize << " required"); 1515 bStatus = false; 1516 } 1517 else 1518 nBytesPerRow = nRowSize; 1519 } 1520 1521 if (bStatus) 1522 { 1523 //sanity check consider ReadMap condition for last row and 1524 //last plane 1525 if (nCompression == 1 || nCompression == 32771) 1526 { 1527 sal_uInt32 nStripBytesPerRow; 1528 if (nCompression == 1) 1529 nStripBytesPerRow = nBytesPerRow; 1530 else 1531 nStripBytesPerRow = ( nBytesPerRow + 1 ) & 0xfffffffe; 1532 sal_uInt32 np = nPlanes - 1; 1533 if (np >= SAL_N_ELEMENTS(aMap)) 1534 bStatus = false; 1535 sal_Int32 ny = nImageLength - 1; 1536 sal_uInt32 nStrip(0); 1537 nDiv = GetRowsPerStrip(); 1538 if (bStatus) 1539 bStatus = nDiv != 0; 1540 if (bStatus) 1541 { 1542 nStrip = ny / nDiv + np * nStripsPerPlane; 1543 if (nStrip >= aStripOffsets.size()) 1544 bStatus = false; 1545 } 1546 if (bStatus) 1547 { 1548 auto nStart = aStripOffsets[ nStrip ] + ( ny % GetRowsPerStrip() ) * nStripBytesPerRow; 1549 if (nStart > nEndOfFile) 1550 bStatus = false; 1551 } 1552 } 1553 else if (nCompression == 2 || nCompression == 3 || nCompression == 4) 1554 { 1555 if (nCompression == 3 && nGroup3Options & 0xfffffffa) 1556 bStatus = false; 1557 else if (nCompression == 4 && nGroup4Options & 0xffffffff) 1558 bStatus = false; 1559 sal_uInt32 np = nPlanes - 1; 1560 if (np >= SAL_N_ELEMENTS(aMap)) 1561 bStatus = false; 1562 sal_Int32 ny = nImageLength - 1; 1563 sal_uInt32 nStrip(0); 1564 nDiv = GetRowsPerStrip(); 1565 if (bStatus) 1566 bStatus = nDiv != 0; 1567 if (bStatus) 1568 { 1569 nStrip = ny / nDiv + np * nStripsPerPlane; 1570 if (nStrip >= aStripOffsets.size()) 1571 bStatus = false; 1572 } 1573 if (bStatus) 1574 { 1575 auto nStart = aStripOffsets[nStrip]; 1576 if (nStart > nEndOfFile) 1577 bStatus = false; 1578 } 1579 1580 if (bStatus) 1581 { 1582 sal_uInt64 nTargetBits = nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes; 1583 if (nTargetBits > SAL_MAX_UINT16) 1584 bStatus = false; 1585 } 1586 } 1587 else if (nCompression == 5) 1588 { 1589 sal_uInt32 np = nPlanes - 1; 1590 if (np >= SAL_N_ELEMENTS(aMap)) 1591 bStatus = false; 1592 sal_Int32 ny = nImageLength - 1; 1593 sal_uInt32 nStrip(0); 1594 nDiv = GetRowsPerStrip(); 1595 if (bStatus) 1596 bStatus = nDiv != 0; 1597 if (bStatus) 1598 { 1599 nStrip = ny / nDiv + np * nStripsPerPlane; 1600 if (nStrip >= aStripOffsets.size()) 1601 bStatus = false; 1602 } 1603 if (bStatus) 1604 { 1605 auto nStart = aStripOffsets[nStrip]; 1606 if (nStart > nEndOfFile) 1607 bStatus = false; 1608 } 1609 } 1610 else if (nCompression == 32773) 1611 { 1612 } 1613 else 1614 { 1615 bStatus = false; 1616 } 1617 } 1618 1619 sal_Int32 nImageDataSize(0); 1620 if (bStatus) 1621 { 1622 if (o3tl::checked_multiply<sal_Int32>(nImageWidth, nImageLength, nImageDataSize) || 1623 o3tl::checked_multiply<sal_Int32>(nImageDataSize, (HasAlphaChannel() ? 4 : 3), nImageDataSize) || 1624 nImageDataSize > SAL_MAX_INT32/4) 1625 { 1626 bStatus = false; 1627 } 1628 } 1629 1630 if (bStatus) 1631 { 1632 sal_Int32 nResult = 0; 1633 if (utl::ConfigManager::IsFuzzing() && (o3tl::checked_multiply(nImageWidth, nImageLength, nResult) || nResult > 4000000)) 1634 bStatus = false; 1635 } 1636 1637 if ( bStatus ) 1638 { 1639 maBitmapPixelSize = Size(nImageWidth, nImageLength); 1640 maBitmap.resize(nImageDataSize, 0); 1641 1642 if (bStatus && ReadMap()) 1643 { 1644 nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); 1645 MakePalCol(); 1646 nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); 1647 // convert palette-ized images to 24-bit color 1648 if (!mvPalette.empty()) 1649 { 1650 for (sal_Int32 nY = 0; nY < nImageLength; ++nY) 1651 { 1652 for (sal_Int32 nX = 0; nX < nImageWidth; ++nX) 1653 { 1654 auto p = maBitmap.data() + ((maBitmapPixelSize.Width() * nY + nX) * (HasAlphaChannel() ? 4 : 3)); 1655 auto c = SanitizePaletteIndex(*p, mvPalette); 1656 *p = c.GetRed(); 1657 p++; 1658 *p = c.GetGreen(); 1659 p++; 1660 *p = c.GetBlue(); 1661 } 1662 } 1663 } 1664 } 1665 else 1666 bStatus = false; 1667 1668 if ( bStatus ) 1669 { 1670 BitmapEx aImage = vcl::bitmap::CreateFromData(maBitmap.data(), nImageWidth, nImageLength, 1671 nImageWidth * (HasAlphaChannel() ? 4 : 3), // scanline bytes 1672 HasAlphaChannel() ? vcl::PixelFormat::N32_BPP : vcl::PixelFormat::N24_BPP); 1673 aImage.SetPrefMapMode(maBitmapPrefMapMode); 1674 aImage.SetPrefSize(maBitmapPrefSize); 1675 1676 AnimationBitmap aAnimationBitmap( aImage, Point( 0, 0 ), maBitmapPixelSize, 1677 ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back ); 1678 1679 aAnimation.Insert( aAnimationBitmap ); 1680 } 1681 } 1682 1683 // Clean up: 1684 for (auto& j : aMap) 1685 j.clear(); 1686 aColorMap.clear(); 1687 aStripOffsets.clear(); 1688 aStripByteCounts.clear(); 1689 } 1690 } 1691 1692 // seek to end of TIFF if succeeded 1693 pTIFF->SetEndian( nOrigNumberFormat ); 1694 pTIFF->Seek(bStatus ? STREAM_SEEK_TO_END: nOrigPos); 1695 1696 if ( aAnimation.Count() ) 1697 { 1698 if ( aAnimation.Count() == 1 ) 1699 rGraphic = aAnimation.GetBitmapEx(); 1700 else 1701 rGraphic = aAnimation; //aBitmap; 1702 1703 return true; 1704 } 1705 else 1706 return false; 1707 } 1708 1709 bool ImportTiffGraphicImport(SvStream & rStream, Graphic & rGraphic) 1710 { 1711 TIFFReader aTIFFReader; 1712 try 1713 { 1714 return aTIFFReader.ReadTIFF(rStream, rGraphic); 1715 } 1716 catch (const std::bad_alloc &) 1717 { 1718 return false; 1719 } 1720 } 1721 1722 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1723
