1/*****************************************************************************/ 2// Copyright 2006-2012 Adobe Systems Incorporated 3// All Rights Reserved. 4// 5// NOTICE: Adobe permits you to use, modify, and distribute this file in 6// accordance with the terms of the Adobe license agreement accompanying it. 7/*****************************************************************************/ 8 9/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_read_image.cpp#7 $ */ 10/* $DateTime: 2012/07/31 22:04:34 $ */ 11/* $Change: 840853 $ */ 12/* $Author: tknoll $ */ 13 14/*****************************************************************************/ 15 16#include "dng_read_image.h" 17 18#include "dng_abort_sniffer.h" 19#include "dng_area_task.h" 20#include "dng_bottlenecks.h" 21#include "dng_exceptions.h" 22#include "dng_flags.h" 23#include "dng_host.h" 24#include "dng_image.h" 25#include "dng_ifd.h" 26#include "dng_jpeg_image.h" 27#include "dng_lossless_jpeg.h" 28#include "dng_mutex.h" 29#include "dng_memory.h" 30#include "dng_pixel_buffer.h" 31#include "dng_safe_arithmetic.h" 32#include "dng_tag_types.h" 33#include "dng_tag_values.h" 34#include "dng_utils.h" 35 36#include "zlib.h" 37 38#if qDNGUseLibJPEG 39#include "dng_jpeg_memory_source.h" 40#include "dng_jpeglib.h" 41#endif 42 43#include <limits> 44 45/******************************************************************************/ 46 47static void DecodeDelta8 (uint8 *dPtr, 48 uint32 rows, 49 uint32 cols, 50 uint32 channels) 51 { 52 53 const uint32 dRowStep = cols * channels; 54 55 for (uint32 row = 0; row < rows; row++) 56 { 57 58 for (uint32 col = 1; col < cols; col++) 59 { 60 61 for (uint32 channel = 0; channel < channels; channel++) 62 { 63 64 dPtr [col * channels + channel] += dPtr [(col - 1) * channels + channel]; 65 66 } 67 68 } 69 70 dPtr += dRowStep; 71 72 } 73 74 } 75 76/******************************************************************************/ 77 78static void DecodeDelta16 (uint16 *dPtr, 79 uint32 rows, 80 uint32 cols, 81 uint32 channels) 82 { 83 84 const uint32 dRowStep = cols * channels; 85 86 for (uint32 row = 0; row < rows; row++) 87 { 88 89 for (uint32 col = 1; col < cols; col++) 90 { 91 92 for (uint32 channel = 0; channel < channels; channel++) 93 { 94 95 dPtr [col * channels + channel] += dPtr [(col - 1) * channels + channel]; 96 97 } 98 99 } 100 101 dPtr += dRowStep; 102 103 } 104 105 } 106 107/******************************************************************************/ 108 109static void DecodeDelta32 (uint32 *dPtr, 110 uint32 rows, 111 uint32 cols, 112 uint32 channels) 113 { 114 115 const uint32 dRowStep = cols * channels; 116 117 for (uint32 row = 0; row < rows; row++) 118 { 119 120 for (uint32 col = 1; col < cols; col++) 121 { 122 123 for (uint32 channel = 0; channel < channels; channel++) 124 { 125 126 dPtr [col * channels + channel] += dPtr [(col - 1) * channels + channel]; 127 128 } 129 130 } 131 132 dPtr += dRowStep; 133 134 } 135 136 } 137 138/*****************************************************************************/ 139 140inline void DecodeDeltaBytes (uint8 *bytePtr, int32 cols, int32 channels) 141 { 142 143 if (channels == 1) 144 { 145 146 uint8 b0 = bytePtr [0]; 147 148 bytePtr += 1; 149 150 for (int32 col = 1; col < cols; ++col) 151 { 152 153 b0 += bytePtr [0]; 154 155 bytePtr [0] = b0; 156 157 bytePtr += 1; 158 159 } 160 161 } 162 163 else if (channels == 3) 164 { 165 166 uint8 b0 = bytePtr [0]; 167 uint8 b1 = bytePtr [1]; 168 uint8 b2 = bytePtr [2]; 169 170 bytePtr += 3; 171 172 for (int32 col = 1; col < cols; ++col) 173 { 174 175 b0 += bytePtr [0]; 176 b1 += bytePtr [1]; 177 b2 += bytePtr [2]; 178 179 bytePtr [0] = b0; 180 bytePtr [1] = b1; 181 bytePtr [2] = b2; 182 183 bytePtr += 3; 184 185 } 186 187 } 188 189 else if (channels == 4) 190 { 191 192 uint8 b0 = bytePtr [0]; 193 uint8 b1 = bytePtr [1]; 194 uint8 b2 = bytePtr [2]; 195 uint8 b3 = bytePtr [3]; 196 197 bytePtr += 4; 198 199 for (int32 col = 1; col < cols; ++col) 200 { 201 202 b0 += bytePtr [0]; 203 b1 += bytePtr [1]; 204 b2 += bytePtr [2]; 205 b3 += bytePtr [3]; 206 207 bytePtr [0] = b0; 208 bytePtr [1] = b1; 209 bytePtr [2] = b2; 210 bytePtr [3] = b3; 211 212 bytePtr += 4; 213 214 } 215 216 } 217 218 else 219 { 220 221 for (int32 col = 1; col < cols; ++col) 222 { 223 224 for (int32 chan = 0; chan < channels; ++chan) 225 { 226 227 bytePtr [chan + channels] += bytePtr [chan]; 228 229 } 230 231 bytePtr += channels; 232 233 } 234 235 } 236 237 } 238 239/*****************************************************************************/ 240 241static void DecodeFPDelta (uint8 *input, 242 uint8 *output, 243 int32 cols, 244 int32 channels, 245 int32 bytesPerSample) 246 { 247 248 DecodeDeltaBytes (input, cols * bytesPerSample, channels); 249 250 int32 rowIncrement = cols * channels; 251 252 if (bytesPerSample == 2) 253 { 254 255 #if qDNGBigEndian 256 const uint8 *input0 = input; 257 const uint8 *input1 = input + rowIncrement; 258 #else 259 const uint8 *input1 = input; 260 const uint8 *input0 = input + rowIncrement; 261 #endif 262 263 for (int32 col = 0; col < rowIncrement; ++col) 264 { 265 266 output [0] = input0 [col]; 267 output [1] = input1 [col]; 268 269 output += 2; 270 271 } 272 273 } 274 275 else if (bytesPerSample == 3) 276 { 277 278 const uint8 *input0 = input; 279 const uint8 *input1 = input + rowIncrement; 280 const uint8 *input2 = input + rowIncrement * 2; 281 282 for (int32 col = 0; col < rowIncrement; ++col) 283 { 284 285 output [0] = input0 [col]; 286 output [1] = input1 [col]; 287 output [2] = input2 [col]; 288 289 output += 3; 290 291 } 292 293 } 294 295 else 296 { 297 298 #if qDNGBigEndian 299 const uint8 *input0 = input; 300 const uint8 *input1 = input + rowIncrement; 301 const uint8 *input2 = input + rowIncrement * 2; 302 const uint8 *input3 = input + rowIncrement * 3; 303 #else 304 const uint8 *input3 = input; 305 const uint8 *input2 = input + rowIncrement; 306 const uint8 *input1 = input + rowIncrement * 2; 307 const uint8 *input0 = input + rowIncrement * 3; 308 #endif 309 310 for (int32 col = 0; col < rowIncrement; ++col) 311 { 312 313 output [0] = input0 [col]; 314 output [1] = input1 [col]; 315 output [2] = input2 [col]; 316 output [3] = input3 [col]; 317 318 output += 4; 319 320 } 321 322 } 323 324 } 325 326/*****************************************************************************/ 327 328bool DecodePackBits (dng_stream &stream, 329 uint8 *dPtr, 330 int32 dstCount) 331 { 332 333 while (dstCount > 0) 334 { 335 336 int32 runCount = (int8) stream.Get_uint8 (); 337 338 if (runCount >= 0) 339 { 340 341 ++runCount; 342 343 dstCount -= runCount; 344 345 if (dstCount < 0) 346 return false; 347 348 stream.Get (dPtr, runCount); 349 350 dPtr += runCount; 351 352 } 353 354 else 355 { 356 357 runCount = -runCount + 1; 358 359 dstCount -= runCount; 360 361 if (dstCount < 0) 362 return false; 363 364 uint8 x = stream.Get_uint8 (); 365 366 while (runCount--) 367 { 368 369 *(dPtr++) = x; 370 371 } 372 373 } 374 375 } 376 377 return true; 378 379 } 380 381/******************************************************************************/ 382 383class dng_lzw_expander 384 { 385 386 private: 387 388 enum 389 { 390 kResetCode = 256, 391 kEndCode = 257, 392 kTableSize = 4096 393 }; 394 395 struct LZWExpanderNode 396 { 397 int16 prefix; 398 int16 final; 399 int16 depth; 400 int16 fake_for_padding; 401 }; 402 403 dng_memory_data fBuffer; 404 405 LZWExpanderNode *fTable; 406 407 const uint8 *fSrcPtr; 408 409 int32 fSrcCount; 410 411 int32 fByteOffset; 412 413 uint32 fBitBuffer; 414 int32 fBitBufferCount; 415 416 int32 fNextCode; 417 418 int32 fCodeSize; 419 420 public: 421 422 dng_lzw_expander (); 423 424 bool Expand (const uint8 *sPtr, 425 uint8 *dPtr, 426 int32 sCount, 427 int32 dCount); 428 429 private: 430 431 void InitTable (); 432 433 void AddTable (int32 w, int32 k); 434 435 bool GetCodeWord (int32 &code); 436 437 // Hidden copy constructor and assignment operator. 438 439 dng_lzw_expander (const dng_lzw_expander &expander); 440 441 dng_lzw_expander & operator= (const dng_lzw_expander &expander); 442 443 }; 444 445/******************************************************************************/ 446 447dng_lzw_expander::dng_lzw_expander () 448 449 : fBuffer () 450 , fTable (NULL) 451 , fSrcPtr (NULL) 452 , fSrcCount (0) 453 , fByteOffset (0) 454 , fBitBuffer (0) 455 , fBitBufferCount (0) 456 , fNextCode (0) 457 , fCodeSize (0) 458 459 { 460 461 fBuffer.Allocate (kTableSize * sizeof (LZWExpanderNode)); 462 463 fTable = (LZWExpanderNode *) fBuffer.Buffer (); 464 465 } 466 467/******************************************************************************/ 468 469void dng_lzw_expander::InitTable () 470 { 471 472 fCodeSize = 9; 473 474 fNextCode = 258; 475 476 LZWExpanderNode *node = &fTable [0]; 477 478 for (int32 code = 0; code < 256; code++) 479 { 480 481 node->prefix = -1; 482 node->final = (int16) code; 483 node->depth = 1; 484 485 node++; 486 487 } 488 489 } 490 491/******************************************************************************/ 492 493void dng_lzw_expander::AddTable (int32 w, int32 k) 494 { 495 496 DNG_ASSERT ((w >= 0) && (w <= kTableSize), 497 "bad w value in dng_lzw_expander::AddTable"); 498 499 LZWExpanderNode *parentNode = &fTable [w]; 500 501 int32 nextCode = fNextCode; 502 503 fNextCode++; 504 505 DNG_ASSERT ((nextCode >= 0) && (nextCode <= kTableSize), 506 "bad fNextCode value in dng_lzw_expander::AddTable"); 507 508 LZWExpanderNode *node = &fTable [nextCode]; 509 510 node->prefix = (int16) w; 511 node->final = (int16) k; 512 node->depth = 1 + parentNode->depth; 513 514 if (nextCode + 1 == (1 << fCodeSize) - 1) 515 { 516 if (fCodeSize != 12) 517 fCodeSize++; 518 } 519 520 } 521 522/******************************************************************************/ 523 524bool dng_lzw_expander::GetCodeWord (int32 &code) 525 { 526 527 // The bit buffer has the current code in the most significant bits, 528 // so shift off the low orders. 529 530 int32 codeSize = fCodeSize; 531 532 code = fBitBuffer >> (32 - codeSize); 533 534 if (fBitBufferCount >= codeSize) 535 { 536 537 // Typical case; get the code from the bit buffer. 538 539 fBitBuffer <<= codeSize; 540 fBitBufferCount -= codeSize; 541 542 } 543 544 else 545 { 546 547 // The buffer needs to be refreshed. 548 549 const int32 bitsSoFar = fBitBufferCount; 550 551 if (fByteOffset >= fSrcCount) 552 return false; 553 554 // Buffer a long word 555 556 const uint8 *ptr = fSrcPtr + fByteOffset; 557 558 #if qDNGBigEndian 559 560 fBitBuffer = *((const uint32 *) ptr); 561 562 #else 563 564 { 565 566 uint32 b0 = ptr [0]; 567 uint32 b1 = ptr [1]; 568 uint32 b2 = ptr [2]; 569 uint32 b3 = ptr [3]; 570 571 fBitBuffer = (((((b0 << 8) | b1) << 8) | b2) << 8) | b3; 572 573 } 574 575 #endif 576 577 fBitBufferCount = 32; 578 579 fByteOffset += 4; 580 581 // Number of additional bits we need 582 583 const int32 bitsUsed = codeSize - bitsSoFar; 584 585 // Number of low order bits in the current buffer we don't care about 586 587 const int32 bitsNotUsed = 32 - bitsUsed; 588 589 code |= fBitBuffer >> bitsNotUsed; 590 591 fBitBuffer <<= bitsUsed; 592 fBitBufferCount -= bitsUsed; 593 594 } 595 596 return true; 597 598 } 599 600/******************************************************************************/ 601 602bool dng_lzw_expander::Expand (const uint8 *sPtr, 603 uint8 *dPtr, 604 int32 sCount, 605 int32 dCount) 606 { 607 608 void *dStartPtr = dPtr; 609 610 fSrcPtr = sPtr; 611 612 fSrcCount = sCount; 613 614 fByteOffset = 0; 615 616 /* the master decode loop */ 617 618 while (true) 619 { 620 621 InitTable (); 622 623 int32 code; 624 625 do 626 { 627 628 if (!GetCodeWord (code)) 629 return false; 630 631 DNG_ASSERT (code <= fNextCode, 632 "Unexpected LZW code in dng_lzw_expander::Expand"); 633 634 } 635 while (code == kResetCode); 636 637 if (code == kEndCode) 638 return true; 639 640 if (code > kEndCode) 641 return false; 642 643 int32 oldCode = code; 644 int32 inChar = code; 645 646 *(dPtr++) = (uint8) code; 647 648 if (--dCount == 0) 649 return true; 650 651 while (true) 652 { 653 654 if (!GetCodeWord (code)) 655 return false; 656 657 if (code == kResetCode) 658 break; 659 660 if (code == kEndCode) 661 return true; 662 663 const int32 inCode = code; 664 665 bool repeatLastPixel = false; 666 667 if (code >= fNextCode) 668 { 669 670 // This is either a bad file or our code table is not big enough; we 671 // are going to repeat the last code seen and attempt to muddle thru. 672 673 code = oldCode; 674 675 repeatLastPixel = true; 676 677 } 678 679 // this can only happen if we hit 2 bad codes in a row 680 681 if (code > fNextCode) 682 return false; 683 684 const int32 depth = fTable [code].depth; 685 686 if (depth < dCount) 687 { 688 689 dCount -= depth; 690 691 dPtr += depth; 692 693 uint8 *ptr = dPtr; 694 695 // give the compiler an extra hint to optimize these as registers 696 697 const LZWExpanderNode *localTable = fTable; 698 699 int32 localCode = code; 700 701 // this is usually the hottest loop in LZW expansion 702 703 while (localCode >= kResetCode) 704 { 705 706 if (ptr <= dStartPtr) 707 return false; // about to trash memory 708 709 const LZWExpanderNode &node = localTable [localCode]; 710 711 uint8 tempFinal = (uint8) node.final; 712 713 localCode = node.prefix; 714 715 // Check for bogus table entry 716 717 if (localCode < 0 || localCode > kTableSize) 718 return false; 719 720 *(--ptr) = tempFinal; 721 722 } 723 724 code = localCode; 725 726 inChar = localCode; 727 728 if (ptr <= dStartPtr) 729 return false; // about to trash memory 730 731 *(--ptr) = (uint8) inChar; 732 733 } 734 735 else 736 { 737 738 // There might not be enough room for the full code 739 // so skip the end of it. 740 741 const int32 skip = depth - dCount; 742 743 for (int32 i = 0; i < skip ; i++) 744 { 745 const LZWExpanderNode &node = fTable [code]; 746 code = node.prefix; 747 } 748 749 int32 depthUsed = depth - skip; 750 751 dCount -= depthUsed; 752 753 dPtr += depthUsed; 754 755 uint8 *ptr = dPtr; 756 757 while (code >= 0) 758 { 759 760 if (ptr <= dStartPtr) 761 return false; // about to trash memory 762 763 const LZWExpanderNode &node = fTable [code]; 764 765 *(--ptr) = (uint8) node.final; 766 767 code = node.prefix; 768 769 // Check for bogus table entry 770 771 if (code > kTableSize) 772 return false; 773 774 } 775 776 return true; 777 778 } 779 780 if (repeatLastPixel) 781 { 782 783 *(dPtr++) = (uint8) inChar; 784 785 if (--dCount == 0) 786 return true; 787 788 } 789 790 if (fNextCode < kTableSize) 791 { 792 793 AddTable (oldCode, code); 794 795 } 796 797 oldCode = inCode; 798 799 } 800 801 } 802 803 return false; 804 805 } 806 807/*****************************************************************************/ 808 809dng_row_interleaved_image::dng_row_interleaved_image (dng_image &image, 810 uint32 factor) 811 812 : dng_image (image.Bounds (), 813 image.Planes (), 814 image.PixelType ()) 815 816 , fImage (image ) 817 , fFactor (factor) 818 819 { 820 821 } 822 823/*****************************************************************************/ 824 825int32 dng_row_interleaved_image::MapRow (int32 row) const 826 { 827 828 uint32 rows = Height (); 829 830 int32 top = Bounds ().t; 831 832 uint32 fieldRow = row - top; 833 834 for (uint32 field = 0; true; field++) 835 { 836 837 uint32 fieldRows = (rows - field + fFactor - 1) / fFactor; 838 839 if (fieldRow < fieldRows) 840 { 841 842 return fieldRow * fFactor + field + top; 843 844 } 845 846 fieldRow -= fieldRows; 847 848 } 849 850 ThrowProgramError (); 851 852 return 0; 853 854 } 855 856/*****************************************************************************/ 857 858void dng_row_interleaved_image::DoGet (dng_pixel_buffer &buffer) const 859 { 860 861 dng_pixel_buffer tempBuffer (buffer); 862 863 for (int32 row = buffer.fArea.t; row < buffer.fArea.b; row++) 864 { 865 866 tempBuffer.fArea.t = MapRow (row); 867 868 tempBuffer.fArea.b = tempBuffer.fArea.t + 1; 869 870 tempBuffer.fData = (void *) buffer.DirtyPixel (row, 871 buffer.fArea.l, 872 buffer.fPlane); 873 874 fImage.Get (tempBuffer); 875 876 } 877 878 } 879 880/*****************************************************************************/ 881 882void dng_row_interleaved_image::DoPut (const dng_pixel_buffer &buffer) 883 { 884 885 dng_pixel_buffer tempBuffer (buffer); 886 887 for (int32 row = buffer.fArea.t; row < buffer.fArea.b; row++) 888 { 889 890 tempBuffer.fArea.t = MapRow (row); 891 892 tempBuffer.fArea.b = tempBuffer.fArea.t + 1; 893 894 tempBuffer.fData = (void *) buffer.ConstPixel (row, 895 buffer.fArea.l, 896 buffer.fPlane); 897 898 fImage.Put (tempBuffer); 899 900 } 901 902 } 903 904/*****************************************************************************/ 905 906static void ReorderSubTileBlocks (dng_host &host, 907 const dng_ifd &ifd, 908 dng_pixel_buffer &buffer, 909 AutoPtr<dng_memory_block> &tempBuffer) 910 { 911 912 uint32 tempBufferSize = ComputeBufferSize(buffer.fPixelType, 913 buffer.fArea.Size(), 914 buffer.fPlanes, padNone); 915 916 if (!tempBuffer.Get () || tempBuffer->LogicalSize () < tempBufferSize) 917 { 918 919 tempBuffer.Reset (host.Allocate (tempBufferSize)); 920 921 } 922 923 uint32 blockRows = ifd.fSubTileBlockRows; 924 uint32 blockCols = ifd.fSubTileBlockCols; 925 926 uint32 rowBlocks = buffer.fArea.H () / blockRows; 927 uint32 colBlocks = buffer.fArea.W () / blockCols; 928 929 int32 rowStep = buffer.fRowStep * buffer.fPixelSize; 930 int32 colStep = buffer.fColStep * buffer.fPixelSize; 931 932 int32 rowBlockStep = rowStep * blockRows; 933 int32 colBlockStep = colStep * blockCols; 934 935 uint32 blockColBytes = blockCols * buffer.fPlanes * buffer.fPixelSize; 936 937 const uint8 *s0 = (const uint8 *) buffer.fData; 938 uint8 *d0 = tempBuffer->Buffer_uint8 (); 939 940 for (uint32 rowBlock = 0; rowBlock < rowBlocks; rowBlock++) 941 { 942 943 uint8 *d1 = d0; 944 945 for (uint32 colBlock = 0; colBlock < colBlocks; colBlock++) 946 { 947 948 uint8 *d2 = d1; 949 950 for (uint32 blockRow = 0; blockRow < blockRows; blockRow++) 951 { 952 953 for (uint32 j = 0; j < blockColBytes; j++) 954 { 955 956 d2 [j] = s0 [j]; 957 958 } 959 960 s0 += blockColBytes; 961 962 d2 += rowStep; 963 964 } 965 966 d1 += colBlockStep; 967 968 } 969 970 d0 += rowBlockStep; 971 972 } 973 974 // Copy back reordered pixels. 975 976 DoCopyBytes (tempBuffer->Buffer (), 977 buffer.fData, 978 tempBufferSize); 979 980 } 981 982/*****************************************************************************/ 983 984class dng_image_spooler: public dng_spooler 985 { 986 987 private: 988 989 dng_host &fHost; 990 991 const dng_ifd &fIFD; 992 993 dng_image &fImage; 994 995 dng_rect fTileArea; 996 997 uint32 fPlane; 998 uint32 fPlanes; 999 1000 dng_memory_block &fBlock; 1001 1002 AutoPtr<dng_memory_block> &fSubTileBuffer; 1003 1004 dng_rect fTileStrip; 1005 1006 uint8 *fBuffer; 1007 1008 uint32 fBufferCount; 1009 uint32 fBufferSize; 1010 1011 public: 1012 1013 dng_image_spooler (dng_host &host, 1014 const dng_ifd &ifd, 1015 dng_image &image, 1016 const dng_rect &tileArea, 1017 uint32 plane, 1018 uint32 planes, 1019 dng_memory_block &block, 1020 AutoPtr<dng_memory_block> &subTileBuffer); 1021 1022 virtual ~dng_image_spooler (); 1023 1024 virtual void Spool (const void *data, 1025 uint32 count); 1026 1027 private: 1028 1029 // Hidden copy constructor and assignment operator. 1030 1031 dng_image_spooler (const dng_image_spooler &spooler); 1032 1033 dng_image_spooler & operator= (const dng_image_spooler &spooler); 1034 1035 }; 1036 1037/*****************************************************************************/ 1038 1039dng_image_spooler::dng_image_spooler (dng_host &host, 1040 const dng_ifd &ifd, 1041 dng_image &image, 1042 const dng_rect &tileArea, 1043 uint32 plane, 1044 uint32 planes, 1045 dng_memory_block &block, 1046 AutoPtr<dng_memory_block> &subTileBuffer) 1047 1048 : fHost (host) 1049 , fIFD (ifd) 1050 , fImage (image) 1051 , fTileArea (tileArea) 1052 , fPlane (plane) 1053 , fPlanes (planes) 1054 , fBlock (block) 1055 , fSubTileBuffer (subTileBuffer) 1056 1057 , fTileStrip () 1058 , fBuffer (NULL) 1059 , fBufferCount (0) 1060 , fBufferSize (0) 1061 1062 { 1063 1064 uint32 bytesPerRow = fTileArea.W () * fPlanes * (uint32) sizeof (uint16); 1065 1066 uint32 stripLength = Pin_uint32 (ifd.fSubTileBlockRows, 1067 fBlock.LogicalSize () / bytesPerRow, 1068 fTileArea.H ()); 1069 1070 stripLength = stripLength / ifd.fSubTileBlockRows 1071 * ifd.fSubTileBlockRows; 1072 1073 fTileStrip = fTileArea; 1074 fTileStrip.b = fTileArea.t + stripLength; 1075 1076 fBuffer = (uint8 *) fBlock.Buffer (); 1077 1078 fBufferCount = 0; 1079 fBufferSize = bytesPerRow * stripLength; 1080 1081 } 1082 1083/*****************************************************************************/ 1084 1085dng_image_spooler::~dng_image_spooler () 1086 { 1087 1088 } 1089 1090/*****************************************************************************/ 1091 1092void dng_image_spooler::Spool (const void *data, 1093 uint32 count) 1094 { 1095 1096 while (count) 1097 { 1098 1099 uint32 block = Min_uint32 (count, fBufferSize - fBufferCount); 1100 1101 if (block == 0) 1102 { 1103 return; 1104 } 1105 1106 DoCopyBytes (data, 1107 fBuffer + fBufferCount, 1108 block); 1109 1110 data = ((const uint8 *) data) + block; 1111 1112 count -= block; 1113 1114 fBufferCount += block; 1115 1116 if (fBufferCount == fBufferSize) 1117 { 1118 1119 fHost.SniffForAbort (); 1120 1121 dng_pixel_buffer buffer (fTileStrip, fPlane, fPlanes, ttShort, 1122 pcInterleaved, fBuffer); 1123 1124 if (fIFD.fSubTileBlockRows > 1) 1125 { 1126 1127 ReorderSubTileBlocks (fHost, 1128 fIFD, 1129 buffer, 1130 fSubTileBuffer); 1131 1132 } 1133 1134 fImage.Put (buffer); 1135 1136 uint32 stripLength = fTileStrip.H (); 1137 1138 fTileStrip.t = fTileStrip.b; 1139 1140 fTileStrip.b = Min_int32 (fTileStrip.t + stripLength, 1141 fTileArea.b); 1142 1143 fBufferCount = 0; 1144 1145 fBufferSize = fTileStrip.W () * 1146 fTileStrip.H () * 1147 fPlanes * (uint32) sizeof (uint16); 1148 1149 } 1150 1151 } 1152 1153 } 1154 1155/*****************************************************************************/ 1156 1157dng_read_image::dng_read_image () 1158 1159 : fJPEGTables () 1160 1161 { 1162 1163 } 1164 1165/*****************************************************************************/ 1166 1167dng_read_image::~dng_read_image () 1168 { 1169 1170 } 1171 1172/*****************************************************************************/ 1173 1174bool dng_read_image::ReadUncompressed (dng_host &host, 1175 const dng_ifd &ifd, 1176 dng_stream &stream, 1177 dng_image &image, 1178 const dng_rect &tileArea, 1179 uint32 plane, 1180 uint32 planes, 1181 AutoPtr<dng_memory_block> &uncompressedBuffer, 1182 AutoPtr<dng_memory_block> &subTileBlockBuffer) 1183 { 1184 1185 uint32 rows = tileArea.H (); 1186 uint32 samplesPerRow = tileArea.W (); 1187 1188 if (ifd.fPlanarConfiguration == pcRowInterleaved) 1189 { 1190 rows = SafeUint32Mult(rows, planes); 1191 } 1192 else 1193 { 1194 samplesPerRow = SafeUint32Mult(samplesPerRow, planes); 1195 } 1196 1197 uint32 samplesPerTile = SafeUint32Mult(samplesPerRow, rows); 1198 1199 if (uncompressedBuffer.Get () == NULL) 1200 { 1201 1202 #if qDNGValidate 1203 1204 ReportError ("Fuzz: Missing uncompressed buffer"); 1205 1206 #endif 1207 1208 ThrowBadFormat (); 1209 1210 } 1211 1212 uint32 bitDepth = ifd.fBitsPerSample [plane]; 1213 1214 uint32 pixelType = ttUndefined; 1215 1216 if (bitDepth == 8) 1217 { 1218 1219 pixelType = ttByte; 1220 1221 stream.Get (uncompressedBuffer->Buffer (), samplesPerTile); 1222 1223 } 1224 1225 else if (bitDepth == 16 && ifd.fSampleFormat [0] == sfFloatingPoint) 1226 { 1227 1228 pixelType = ttFloat; 1229 1230 uint32 *p_uint32 = (uint32 *) uncompressedBuffer->Buffer (); 1231 1232 for (uint32 j = 0; j < samplesPerTile; j++) 1233 { 1234 1235 p_uint32 [j] = DNG_HalfToFloat (stream.Get_uint16 ()); 1236 1237 } 1238 1239 } 1240 1241 else if (bitDepth == 24 && ifd.fSampleFormat [0] == sfFloatingPoint) 1242 { 1243 1244 pixelType = ttFloat; 1245 1246 uint32 *p_uint32 = (uint32 *) uncompressedBuffer->Buffer (); 1247 1248 for (uint32 j = 0; j < samplesPerTile; j++) 1249 { 1250 1251 uint8 input [3]; 1252 1253 if (stream.LittleEndian ()) 1254 { 1255 input [2] = stream.Get_uint8 (); 1256 input [1] = stream.Get_uint8 (); 1257 input [0] = stream.Get_uint8 (); 1258 } 1259 1260 else 1261 { 1262 input [0] = stream.Get_uint8 (); 1263 input [1] = stream.Get_uint8 (); 1264 input [2] = stream.Get_uint8 (); 1265 } 1266 1267 p_uint32 [j] = DNG_FP24ToFloat (input); 1268 1269 } 1270 1271 } 1272 1273 else if (bitDepth == 16) 1274 { 1275 1276 pixelType = ttShort; 1277 1278 stream.Get (uncompressedBuffer->Buffer (), samplesPerTile * 2); 1279 1280 if (stream.SwapBytes ()) 1281 { 1282 1283 DoSwapBytes16 ((uint16 *) uncompressedBuffer->Buffer (), 1284 samplesPerTile); 1285 1286 } 1287 1288 } 1289 1290 else if (bitDepth == 32) 1291 { 1292 1293 pixelType = image.PixelType (); 1294 1295 stream.Get (uncompressedBuffer->Buffer (), samplesPerTile * 4); 1296 1297 if (stream.SwapBytes ()) 1298 { 1299 1300 DoSwapBytes32 ((uint32 *) uncompressedBuffer->Buffer (), 1301 samplesPerTile); 1302 1303 } 1304 1305 } 1306 1307 else if (bitDepth == 12) 1308 { 1309 1310 pixelType = ttShort; 1311 1312 uint16 *p = (uint16 *) uncompressedBuffer->Buffer (); 1313 1314 uint32 evenSamples = samplesPerRow >> 1; 1315 1316 for (uint32 row = 0; row < rows; row++) 1317 { 1318 1319 for (uint32 j = 0; j < evenSamples; j++) 1320 { 1321 1322 uint32 b0 = stream.Get_uint8 (); 1323 uint32 b1 = stream.Get_uint8 (); 1324 uint32 b2 = stream.Get_uint8 (); 1325 1326 p [0] = (uint16) ((b0 << 4) | (b1 >> 4)); 1327 p [1] = (uint16) (((b1 << 8) | b2) & 0x0FFF); 1328 1329 p += 2; 1330 1331 } 1332 1333 if (samplesPerRow & 1) 1334 { 1335 1336 uint32 b0 = stream.Get_uint8 (); 1337 uint32 b1 = stream.Get_uint8 (); 1338 1339 p [0] = (uint16) ((b0 << 4) | (b1 >> 4)); 1340 1341 p += 1; 1342 1343 } 1344 1345 } 1346 1347 } 1348 1349 else if (bitDepth > 8 && bitDepth < 16) 1350 { 1351 1352 pixelType = ttShort; 1353 1354 uint16 *p = (uint16 *) uncompressedBuffer->Buffer (); 1355 1356 uint32 bitMask = (1 << bitDepth) - 1; 1357 1358 for (uint32 row = 0; row < rows; row++) 1359 { 1360 1361 uint32 bitBuffer = 0; 1362 uint32 bufferBits = 0; 1363 1364 for (uint32 j = 0; j < samplesPerRow; j++) 1365 { 1366 1367 while (bufferBits < bitDepth) 1368 { 1369 1370 bitBuffer = (bitBuffer << 8) | stream.Get_uint8 (); 1371 1372 bufferBits += 8; 1373 1374 } 1375 1376 p [j] = (uint16) ((bitBuffer >> (bufferBits - bitDepth)) & bitMask); 1377 1378 bufferBits -= bitDepth; 1379 1380 } 1381 1382 p += samplesPerRow; 1383 1384 } 1385 1386 } 1387 1388 else if (bitDepth > 16 && bitDepth < 32) 1389 { 1390 1391 pixelType = ttLong; 1392 1393 uint32 *p = (uint32 *) uncompressedBuffer->Buffer (); 1394 1395 uint32 bitMask = ((uint32) 1 << bitDepth) - 1; 1396 1397 for (uint32 row = 0; row < rows; row++) 1398 { 1399 1400 uint64 bitBuffer = 0; 1401 uint32 bufferBits = 0; 1402 1403 for (uint32 j = 0; j < samplesPerRow; j++) 1404 { 1405 1406 while (bufferBits < bitDepth) 1407 { 1408 1409 bitBuffer = (bitBuffer << 8) | stream.Get_uint8 (); 1410 1411 bufferBits += 8; 1412 1413 } 1414 1415 p [j] = ((uint32) (bitBuffer >> (bufferBits - bitDepth))) & bitMask; 1416 1417 bufferBits -= bitDepth; 1418 1419 } 1420 1421 p += samplesPerRow; 1422 1423 } 1424 1425 } 1426 1427 else 1428 { 1429 1430 return false; 1431 1432 } 1433 1434 dng_pixel_buffer buffer (tileArea, plane, planes, pixelType, 1435 ifd.fPlanarConfiguration, uncompressedBuffer->Buffer ()); 1436 1437 if (ifd.fSampleBitShift) 1438 { 1439 1440 buffer.ShiftRight (ifd.fSampleBitShift); 1441 1442 } 1443 1444 if (ifd.fSubTileBlockRows > 1) 1445 { 1446 1447 ReorderSubTileBlocks (host, 1448 ifd, 1449 buffer, 1450 subTileBlockBuffer); 1451 1452 } 1453 1454 image.Put (buffer); 1455 1456 return true; 1457 1458 } 1459 1460/*****************************************************************************/ 1461 1462#if qDNGUseLibJPEG 1463 1464/*****************************************************************************/ 1465 1466static void dng_error_exit (j_common_ptr cinfo) 1467 { 1468 1469 // Output message. 1470 1471 (*cinfo->err->output_message) (cinfo); 1472 1473 // Convert to a dng_exception. 1474 1475 switch (cinfo->err->msg_code) 1476 { 1477 1478 case JERR_OUT_OF_MEMORY: 1479 { 1480 ThrowMemoryFull (); 1481 break; 1482 } 1483 1484 default: 1485 { 1486 ThrowBadFormat (); 1487 } 1488 1489 } 1490 1491 } 1492 1493/*****************************************************************************/ 1494 1495static void dng_output_message (j_common_ptr cinfo) 1496 { 1497 1498 // Format message to string. 1499 1500 char buffer [JMSG_LENGTH_MAX]; 1501 1502 (*cinfo->err->format_message) (cinfo, buffer); 1503 1504 // Report the libjpeg message as a warning. 1505 1506 ReportWarning ("libjpeg", buffer); 1507 1508 } 1509 1510/*****************************************************************************/ 1511 1512#endif 1513 1514/*****************************************************************************/ 1515 1516void dng_read_image::DecodeLossyJPEG (dng_host &host, 1517 dng_image &image, 1518 const dng_rect &tileArea, 1519 uint32 plane, 1520 uint32 planes, 1521 uint32 /* photometricInterpretation */, 1522 uint32 jpegDataSize, 1523 uint8 *jpegDataInMemory) 1524 { 1525 1526 #if qDNGUseLibJPEG 1527 1528 struct jpeg_decompress_struct cinfo; 1529 1530 // Setup the error manager. 1531 1532 struct jpeg_error_mgr jerr; 1533 1534 cinfo.err = jpeg_std_error (&jerr); 1535 1536 jerr.error_exit = dng_error_exit; 1537 jerr.output_message = dng_output_message; 1538 1539 try 1540 { 1541 1542 // Create the decompression context. 1543 1544 jpeg_create_decompress (&cinfo); 1545 1546 // Set up the memory data source manager. 1547 1548 size_t jpegDataSizeAsSizet = 0; 1549 ConvertUnsigned(jpegDataSize, &jpegDataSizeAsSizet); 1550 jpeg_source_mgr memorySource = 1551 CreateJpegMemorySource(jpegDataInMemory, 1552 jpegDataSizeAsSizet); 1553 cinfo.src = &memorySource; 1554 1555 // Read the JPEG header. 1556 1557 jpeg_read_header (&cinfo, TRUE); 1558 1559 // Check header. 1560 1561 { 1562 // Number of components may not be negative. 1563 if (cinfo.num_components < 0) 1564 { 1565 ThrowBadFormat(); 1566 } 1567 1568 // Convert relevant values from header to uint32. 1569 uint32 imageWidthAsUint32 = 0; 1570 uint32 imageHeightAsUint32 = 0; 1571 uint32 numComponentsAsUint32 = 0; 1572 ConvertUnsigned(cinfo.image_width, &imageWidthAsUint32); 1573 ConvertUnsigned(cinfo.image_height, &imageHeightAsUint32); 1574 // num_components is an int. Casting to unsigned is safe because the 1575 // test above guarantees num_components is not negative. 1576 ConvertUnsigned(static_cast<unsigned>(cinfo.num_components), 1577 &numComponentsAsUint32); 1578 1579 // Check that dimensions of JPEG correspond to dimensions of tile. 1580 if (imageWidthAsUint32 != tileArea.W () || 1581 imageHeightAsUint32 != tileArea.H () || 1582 numComponentsAsUint32 != planes ) 1583 { 1584 ThrowBadFormat (); 1585 } 1586 } 1587 1588 // Start the compression. 1589 1590 jpeg_start_decompress (&cinfo); 1591 1592 // Setup a one-scanline size buffer. 1593 1594 dng_pixel_buffer buffer(tileArea, plane, planes, ttByte, pcInterleaved, 1595 NULL); 1596 buffer.fArea.b = tileArea.t + 1; 1597 1598 buffer.fDirty = true; 1599 1600 AutoPtr<dng_memory_block> bufferData (host.Allocate (buffer.fRowStep)); 1601 1602 buffer.fData = bufferData->Buffer (); 1603 1604 uint8 *sampArray [1]; 1605 1606 sampArray [0] = bufferData->Buffer_uint8 (); 1607 1608 // Read each scanline and save to image. 1609 1610 while (buffer.fArea.t < tileArea.b) 1611 { 1612 1613 jpeg_read_scanlines (&cinfo, sampArray, 1); 1614 1615 image.Put (buffer); 1616 1617 buffer.fArea.t = buffer.fArea.b; 1618 buffer.fArea.b = buffer.fArea.t + 1; 1619 1620 } 1621 1622 // Cleanup. 1623 1624 jpeg_finish_decompress (&cinfo); 1625 1626 jpeg_destroy_decompress (&cinfo); 1627 1628 } 1629 1630 catch (...) 1631 { 1632 1633 jpeg_destroy_decompress (&cinfo); 1634 1635 throw; 1636 1637 } 1638 1639 #else 1640 1641 // The dng_sdk does not include a lossy JPEG decoder. Override this 1642 // this method to add lossy JPEG support. 1643 1644 (void) host; 1645 (void) image; 1646 (void) tileArea; 1647 (void) plane; 1648 (void) planes; 1649 (void) jpegDataSize; 1650 (void) jpegDataInMemory; 1651 1652 ThrowProgramError ("Missing lossy JPEG decoder"); 1653 1654 #endif 1655 1656 } 1657 1658/*****************************************************************************/ 1659 1660static dng_memory_block * ReadJPEGDataToBlock (dng_host &host, 1661 dng_stream &stream, 1662 dng_memory_block *tablesBlock, 1663 uint64 tileOffset, 1664 uint32 tileByteCount, 1665 bool patchFirstByte) 1666 { 1667 1668 // This ensures that the "tileByteCount -= 2" operation below will not wrap 1669 // around. 1670 if (tileByteCount <= 2) 1671 { 1672 ThrowEndOfFile (); 1673 } 1674 1675 uint32 tablesByteCount = tablesBlock ? tablesBlock->LogicalSize () : 0; 1676 1677 // This ensures that the "tablesByteCount -= 2" operation below will not 1678 // wrap around. 1679 if (tablesByteCount && tablesByteCount < 4) 1680 { 1681 ThrowEndOfFile (); 1682 } 1683 1684 // The JPEG tables start with a two byte SOI marker, and 1685 // and end with a two byte EOI marker. The JPEG tile 1686 // data also starts with a two byte SOI marker. We can 1687 // convert this combination a normal JPEG stream removing 1688 // the last two bytes of the JPEG tables and the first two 1689 // bytes of the tile data, and then concatenating them. 1690 1691 if (tablesByteCount) 1692 { 1693 1694 // Ensure the "tileOffset += 2" operation below will not wrap around. 1695 if (tileOffset > std::numeric_limits<uint64>::max () - 2) 1696 { 1697 ThrowEndOfFile(); 1698 } 1699 1700 tablesByteCount -= 2; 1701 1702 tileOffset += 2; 1703 tileByteCount -= 2; 1704 1705 } 1706 1707 // Allocate buffer. 1708 1709 AutoPtr<dng_memory_block> buffer (host.Allocate ( 1710 SafeUint32Add(tablesByteCount, tileByteCount))); 1711 1712 // Read in table. 1713 1714 if (tablesByteCount) 1715 { 1716 1717 DoCopyBytes (tablesBlock->Buffer (), 1718 buffer->Buffer (), 1719 tablesByteCount); 1720 1721 } 1722 1723 // Read in tile data. 1724 1725 stream.SetReadPosition (tileOffset); 1726 1727 stream.Get (buffer->Buffer_uint8 () + tablesByteCount, tileByteCount); 1728 1729 // Patch first byte, if required. 1730 1731 if (patchFirstByte) 1732 { 1733 1734 buffer->Buffer_uint8 () [0] = 0xFF; 1735 1736 } 1737 1738 // Return buffer. 1739 1740 return buffer.Release (); 1741 1742 } 1743 1744/*****************************************************************************/ 1745 1746bool dng_read_image::ReadBaselineJPEG (dng_host &host, 1747 const dng_ifd &ifd, 1748 dng_stream &stream, 1749 dng_image &image, 1750 const dng_rect &tileArea, 1751 uint32 plane, 1752 uint32 planes, 1753 uint32 tileByteCount, 1754 uint8 *jpegDataInMemory) 1755 { 1756 1757 // Setup the data source. 1758 1759 if (fJPEGTables.Get () || !jpegDataInMemory) 1760 { 1761 1762 AutoPtr<dng_memory_block> jpegDataBlock; 1763 1764 jpegDataBlock.Reset (ReadJPEGDataToBlock (host, 1765 stream, 1766 fJPEGTables.Get (), 1767 stream.Position (), 1768 tileByteCount, 1769 ifd.fPatchFirstJPEGByte)); 1770 1771 DecodeLossyJPEG (host, 1772 image, 1773 tileArea, 1774 plane, 1775 planes, 1776 ifd.fPhotometricInterpretation, 1777 jpegDataBlock->LogicalSize (), 1778 jpegDataBlock->Buffer_uint8 ()); 1779 1780 } 1781 1782 else 1783 { 1784 1785 if (ifd.fPatchFirstJPEGByte && tileByteCount) 1786 { 1787 jpegDataInMemory [0] = 0xFF; 1788 } 1789 1790 DecodeLossyJPEG (host, 1791 image, 1792 tileArea, 1793 plane, 1794 planes, 1795 ifd.fPhotometricInterpretation, 1796 tileByteCount, 1797 jpegDataInMemory); 1798 1799 } 1800 1801 return true; 1802 1803 } 1804 1805/*****************************************************************************/ 1806 1807bool dng_read_image::ReadLosslessJPEG (dng_host &host, 1808 const dng_ifd &ifd, 1809 dng_stream &stream, 1810 dng_image &image, 1811 const dng_rect &tileArea, 1812 uint32 plane, 1813 uint32 planes, 1814 uint32 tileByteCount, 1815 AutoPtr<dng_memory_block> &uncompressedBuffer, 1816 AutoPtr<dng_memory_block> &subTileBlockBuffer) 1817 { 1818 1819 // If the tile area is empty, there's nothing to read. 1820 if (tileArea.IsEmpty ()) 1821 { 1822 return true; 1823 } 1824 1825 uint32 bytesPerRow = SafeUint32Mult (tileArea.W(), planes, 1826 static_cast<uint32> (sizeof (uint16))); 1827 1828 uint32 rowsPerStrip = Pin_uint32 (ifd.fSubTileBlockRows, 1829 kImageBufferSize / bytesPerRow, 1830 tileArea.H ()); 1831 1832 rowsPerStrip = rowsPerStrip / ifd.fSubTileBlockRows 1833 * ifd.fSubTileBlockRows; 1834 1835 uint32 bufferSize = SafeUint32Mult (bytesPerRow, rowsPerStrip); 1836 1837 if (uncompressedBuffer.Get () && 1838 uncompressedBuffer->LogicalSize () < bufferSize) 1839 { 1840 1841 uncompressedBuffer.Reset (); 1842 1843 } 1844 1845 if (uncompressedBuffer.Get () == NULL) 1846 { 1847 1848 uncompressedBuffer.Reset (host.Allocate (bufferSize)); 1849 1850 } 1851 1852 dng_image_spooler spooler (host, 1853 ifd, 1854 image, 1855 tileArea, 1856 plane, 1857 planes, 1858 *uncompressedBuffer.Get (), 1859 subTileBlockBuffer); 1860 1861 uint32 decodedSize = SafeUint32Mult(tileArea.W (), 1862 tileArea.H (), 1863 planes, (uint32) sizeof (uint16)); 1864 1865 bool bug16 = ifd.fLosslessJPEGBug16; 1866 1867 uint64 tileOffset = stream.Position (); 1868 1869 DecodeLosslessJPEG (stream, 1870 spooler, 1871 decodedSize, 1872 decodedSize, 1873 bug16); 1874 1875 if (stream.Position () > tileOffset + tileByteCount) 1876 { 1877 ThrowBadFormat (); 1878 } 1879 1880 return true; 1881 1882 } 1883 1884/*****************************************************************************/ 1885 1886bool dng_read_image::CanReadTile (const dng_ifd &ifd) 1887 { 1888 1889 if (ifd.fSampleFormat [0] != sfUnsignedInteger && 1890 ifd.fSampleFormat [0] != sfFloatingPoint) 1891 { 1892 return false; 1893 } 1894 1895 switch (ifd.fCompression) 1896 { 1897 1898 case ccUncompressed: 1899 { 1900 1901 if (ifd.fSampleFormat [0] == sfFloatingPoint) 1902 { 1903 1904 return (ifd.fBitsPerSample [0] == 16 || 1905 ifd.fBitsPerSample [0] == 24 || 1906 ifd.fBitsPerSample [0] == 32); 1907 1908 } 1909 1910 return ifd.fBitsPerSample [0] >= 8 && 1911 ifd.fBitsPerSample [0] <= 32; 1912 1913 } 1914 1915 case ccJPEG: 1916 { 1917 1918 if (ifd.fSampleFormat [0] != sfUnsignedInteger) 1919 { 1920 return false; 1921 } 1922 1923 if (ifd.IsBaselineJPEG ()) 1924 { 1925 1926 // Baseline JPEG. 1927 1928 return true; 1929 1930 } 1931 1932 else 1933 { 1934 1935 // Lossless JPEG. 1936 1937 return ifd.fBitsPerSample [0] >= 8 && 1938 ifd.fBitsPerSample [0] <= 16; 1939 1940 } 1941 1942 break; 1943 1944 } 1945 1946 case ccLZW: 1947 case ccDeflate: 1948 case ccOldDeflate: 1949 case ccPackBits: 1950 { 1951 1952 if (ifd.fSampleFormat [0] == sfFloatingPoint) 1953 { 1954 1955 if (ifd.fCompression == ccPackBits) 1956 { 1957 return false; 1958 } 1959 1960 if (ifd.fPredictor != cpNullPredictor && 1961 ifd.fPredictor != cpFloatingPoint && 1962 ifd.fPredictor != cpFloatingPointX2 && 1963 ifd.fPredictor != cpFloatingPointX4) 1964 { 1965 return false; 1966 } 1967 1968 if (ifd.fBitsPerSample [0] != 16 && 1969 ifd.fBitsPerSample [0] != 24 && 1970 ifd.fBitsPerSample [0] != 32) 1971 { 1972 return false; 1973 } 1974 1975 } 1976 1977 else 1978 { 1979 1980 if (ifd.fPredictor != cpNullPredictor && 1981 ifd.fPredictor != cpHorizontalDifference && 1982 ifd.fPredictor != cpHorizontalDifferenceX2 && 1983 ifd.fPredictor != cpHorizontalDifferenceX4) 1984 { 1985 return false; 1986 } 1987 1988 if (ifd.fBitsPerSample [0] != 8 && 1989 ifd.fBitsPerSample [0] != 16 && 1990 ifd.fBitsPerSample [0] != 32) 1991 { 1992 return false; 1993 } 1994 1995 } 1996 1997 return true; 1998 1999 } 2000 2001 default: 2002 { 2003 break; 2004 } 2005 2006 } 2007 2008 return false; 2009 2010 } 2011 2012/*****************************************************************************/ 2013 2014bool dng_read_image::NeedsCompressedBuffer (const dng_ifd &ifd) 2015 { 2016 2017 if (ifd.fCompression == ccLZW || 2018 ifd.fCompression == ccDeflate || 2019 ifd.fCompression == ccOldDeflate || 2020 ifd.fCompression == ccPackBits) 2021 { 2022 return true; 2023 } 2024 2025 return false; 2026 2027 } 2028 2029/*****************************************************************************/ 2030 2031void dng_read_image::ByteSwapBuffer (dng_host & /* host */, 2032 dng_pixel_buffer &buffer) 2033 { 2034 2035 uint32 pixels = buffer.fRowStep * buffer.fArea.H (); 2036 2037 switch (buffer.fPixelSize) 2038 { 2039 2040 case 2: 2041 { 2042 2043 DoSwapBytes16 ((uint16 *) buffer.fData, 2044 pixels); 2045 2046 break; 2047 2048 } 2049 2050 case 4: 2051 { 2052 2053 DoSwapBytes32 ((uint32 *) buffer.fData, 2054 pixels); 2055 2056 break; 2057 2058 } 2059 2060 default: 2061 break; 2062 2063 } 2064 2065 } 2066 2067/*****************************************************************************/ 2068 2069void dng_read_image::DecodePredictor (dng_host & /* host */, 2070 const dng_ifd &ifd, 2071 dng_pixel_buffer &buffer) 2072 { 2073 2074 switch (ifd.fPredictor) 2075 { 2076 2077 case cpNullPredictor: 2078 { 2079 2080 return; 2081 2082 } 2083 2084 case cpHorizontalDifference: 2085 case cpHorizontalDifferenceX2: 2086 case cpHorizontalDifferenceX4: 2087 { 2088 2089 int32 xFactor = 1; 2090 2091 if (ifd.fPredictor == cpHorizontalDifferenceX2) 2092 { 2093 xFactor = 2; 2094 } 2095 2096 else if (ifd.fPredictor == cpHorizontalDifferenceX4) 2097 { 2098 xFactor = 4; 2099 } 2100 2101 switch (buffer.fPixelType) 2102 { 2103 2104 case ttByte: 2105 { 2106 2107 DecodeDelta8 ((uint8 *) buffer.fData, 2108 buffer.fArea.H (), 2109 buffer.fArea.W () / xFactor, 2110 buffer.fPlanes * xFactor); 2111 2112 return; 2113 2114 } 2115 2116 case ttShort: 2117 { 2118 2119 DecodeDelta16 ((uint16 *) buffer.fData, 2120 buffer.fArea.H (), 2121 buffer.fArea.W () / xFactor, 2122 buffer.fPlanes * xFactor); 2123 2124 return; 2125 2126 } 2127 2128 case ttLong: 2129 { 2130 2131 DecodeDelta32 ((uint32 *) buffer.fData, 2132 buffer.fArea.H (), 2133 buffer.fArea.W () / xFactor, 2134 buffer.fPlanes * xFactor); 2135 2136 return; 2137 2138 } 2139 2140 default: 2141 break; 2142 2143 } 2144 2145 break; 2146 2147 } 2148 2149 default: 2150 break; 2151 2152 } 2153 2154 ThrowBadFormat (); 2155 2156 } 2157 2158/*****************************************************************************/ 2159 2160void dng_read_image::ReadTile (dng_host &host, 2161 const dng_ifd &ifd, 2162 dng_stream &stream, 2163 dng_image &image, 2164 const dng_rect &tileArea, 2165 uint32 plane, 2166 uint32 planes, 2167 uint32 tileByteCount, 2168 AutoPtr<dng_memory_block> &compressedBuffer, 2169 AutoPtr<dng_memory_block> &uncompressedBuffer, 2170 AutoPtr<dng_memory_block> &subTileBlockBuffer) 2171 { 2172 2173 switch (ifd.fCompression) 2174 { 2175 2176 case ccLZW: 2177 case ccDeflate: 2178 case ccOldDeflate: 2179 case ccPackBits: 2180 { 2181 2182 // Figure out uncompressed size. 2183 2184 uint32 bytesPerSample = (ifd.fBitsPerSample [0] >> 3); 2185 2186 uint32 rowStep = 0; 2187 2188 uint32 sampleCount = 0; 2189 2190 if (!SafeUint32Mult (planes, tileArea.W (), &rowStep) || 2191 !SafeUint32Mult (rowStep, tileArea.H (), &sampleCount)) 2192 { 2193 2194 ThrowMemoryFull ("Arithmetic overflow computing sample count."); 2195 2196 } 2197 2198 // Setup pixel buffer to hold uncompressed data. 2199 2200 uint32 pixelType = ttUndefined; 2201 2202 if (ifd.fSampleFormat [0] == sfFloatingPoint) 2203 { 2204 pixelType = ttFloat; 2205 } 2206 2207 else if (ifd.fBitsPerSample [0] == 8) 2208 { 2209 pixelType = ttByte; 2210 } 2211 2212 else if (ifd.fBitsPerSample [0] == 16) 2213 { 2214 pixelType = ttShort; 2215 } 2216 2217 else if (ifd.fBitsPerSample [0] == 32) 2218 { 2219 pixelType = ttLong; 2220 } 2221 2222 else 2223 { 2224 ThrowBadFormat (); 2225 } 2226 2227 uint32 uncompressedSize = ComputeBufferSize (pixelType, tileArea.Size(), 2228 planes, padNone); 2229 2230 dng_pixel_buffer buffer (tileArea, plane, planes, pixelType, pcInterleaved, 2231 NULL); 2232 2233 uint32 bufferSize = uncompressedSize; 2234 2235 // If we are using the floating point predictor, we need an extra 2236 // buffer row. 2237 2238 if (ifd.fPredictor == cpFloatingPoint || 2239 ifd.fPredictor == cpFloatingPointX2 || 2240 ifd.fPredictor == cpFloatingPointX4) 2241 { 2242 uint32 rowSize = 0; 2243 if (!SafeUint32Mult (rowStep, buffer.fPixelSize, &rowSize) || 2244 !SafeUint32Add (bufferSize, rowSize, &bufferSize)) 2245 { 2246 2247 ThrowMemoryFull ("Arithmetic overflow computing buffer size."); 2248 2249 } 2250 } 2251 2252 // If are processing less than full size floating point data, 2253 // we need space to expand the data to full floating point size. 2254 2255 if (buffer.fPixelType == ttFloat) 2256 { 2257 bufferSize = Max_uint32 (bufferSize, 2258 SafeUint32Mult(sampleCount, 4)); 2259 } 2260 2261 // Sometimes with multi-threading and planar image using strips, 2262 // we can process a small tile before a large tile on a thread. 2263 // Simple fix is to just reallocate the buffer if it is too small. 2264 2265 if (uncompressedBuffer.Get () && 2266 uncompressedBuffer->LogicalSize () < bufferSize) 2267 { 2268 2269 uncompressedBuffer.Reset (); 2270 2271 } 2272 2273 if (uncompressedBuffer.Get () == NULL) 2274 { 2275 2276 uncompressedBuffer.Reset (host.Allocate (bufferSize)); 2277 2278 } 2279 2280 buffer.fData = uncompressedBuffer->Buffer (); 2281 2282 // If using floating point predictor, move buffer pointer to second row. 2283 2284 if (ifd.fPredictor == cpFloatingPoint || 2285 ifd.fPredictor == cpFloatingPointX2 || 2286 ifd.fPredictor == cpFloatingPointX4) 2287 { 2288 2289 buffer.fData = (uint8 *) buffer.fData + 2290 buffer.fRowStep * buffer.fPixelSize; 2291 2292 } 2293 2294 // Decompress the data. 2295 2296 if (ifd.fCompression == ccLZW) 2297 { 2298 2299 dng_lzw_expander expander; 2300 2301 if (!expander.Expand (compressedBuffer->Buffer_uint8 (), 2302 (uint8 *) buffer.fData, 2303 tileByteCount, 2304 uncompressedSize)) 2305 { 2306 ThrowBadFormat (); 2307 } 2308 2309 } 2310 2311 else if (ifd.fCompression == ccPackBits) 2312 { 2313 2314 dng_stream subStream (compressedBuffer->Buffer_uint8 (), 2315 tileByteCount); 2316 2317 if (!DecodePackBits (subStream, 2318 (uint8 *) buffer.fData, 2319 uncompressedSize)) 2320 { 2321 ThrowBadFormat (); 2322 } 2323 2324 } 2325 2326 else 2327 { 2328 2329 uLongf dstLen = uncompressedSize; 2330 2331 int err = uncompress ((Bytef *) buffer.fData, 2332 &dstLen, 2333 (const Bytef *) compressedBuffer->Buffer (), 2334 tileByteCount); 2335 2336 if (err != Z_OK) 2337 { 2338 2339 if (err == Z_MEM_ERROR) 2340 { 2341 ThrowMemoryFull (); 2342 } 2343 2344 else if (err == Z_DATA_ERROR) 2345 { 2346 // Most other TIFF readers do not fail for this error 2347 // so we should not either, even if it means showing 2348 // a corrupted image to the user. Watson #2530216 2349 // - tknoll 12/20/11 2350 } 2351 2352 else 2353 { 2354 ThrowBadFormat (); 2355 } 2356 2357 } 2358 2359 if (dstLen != uncompressedSize) 2360 { 2361 ThrowBadFormat (); 2362 } 2363 2364 } 2365 2366 // The floating point predictor is byte order independent. 2367 2368 if (ifd.fPredictor == cpFloatingPoint || 2369 ifd.fPredictor == cpFloatingPointX2 || 2370 ifd.fPredictor == cpFloatingPointX4) 2371 { 2372 2373 int32 xFactor = 1; 2374 2375 if (ifd.fPredictor == cpFloatingPointX2) 2376 { 2377 xFactor = 2; 2378 } 2379 2380 else if (ifd.fPredictor == cpFloatingPointX4) 2381 { 2382 xFactor = 4; 2383 } 2384 2385 for (int32 row = tileArea.t; row < tileArea.b; row++) 2386 { 2387 2388 uint8 *srcPtr = (uint8 *) buffer.DirtyPixel (row , tileArea.l, plane); 2389 // Destination is previous row. 2390 // Subtracting buffer.fRowStep * buffer.fPixelSize will 2391 // always result in a pointer that lies inside the buffer 2392 // because above, we added exactly the same offset to 2393 // buffer.fData (see the piece of code commented "move 2394 // buffer pointer to second row"). 2395 uint8 *dstPtr = srcPtr - 2396 buffer.fRowStep * buffer.fPixelSize; 2397 2398 DecodeFPDelta (srcPtr, 2399 dstPtr, 2400 tileArea.W () / xFactor, 2401 planes * xFactor, 2402 bytesPerSample); 2403 2404 } 2405 2406 buffer.fData = (uint8 *) buffer.fData - 2407 buffer.fRowStep * buffer.fPixelSize; 2408 2409 } 2410 2411 else 2412 { 2413 2414 // Both these compression algorithms are byte based. 2415 2416 if (stream.SwapBytes ()) 2417 { 2418 2419 ByteSwapBuffer (host, 2420 buffer); 2421 2422 } 2423 2424 // Undo the predictor. 2425 2426 DecodePredictor (host, 2427 ifd, 2428 buffer); 2429 2430 } 2431 2432 // Expand floating point data, if needed. 2433 2434 if (buffer.fPixelType == ttFloat && buffer.fPixelSize == 2) 2435 { 2436 2437 uint16 *srcPtr = (uint16 *) buffer.fData; 2438 uint32 *dstPtr = (uint32 *) buffer.fData; 2439 2440 for (int32 index = sampleCount - 1; index >= 0; index--) 2441 { 2442 2443 dstPtr [index] = DNG_HalfToFloat (srcPtr [index]); 2444 2445 } 2446 2447 buffer.fPixelSize = 4; 2448 2449 } 2450 2451 else if (buffer.fPixelType == ttFloat && buffer.fPixelSize == 3) 2452 { 2453 2454 uint8 *srcPtr = ((uint8 *) buffer.fData) + (sampleCount - 1) * 3; 2455 uint32 *dstPtr = ((uint32 *) buffer.fData) + (sampleCount - 1); 2456 2457 if (stream.BigEndian () || ifd.fPredictor == cpFloatingPoint || 2458 ifd.fPredictor == cpFloatingPointX2 || 2459 ifd.fPredictor == cpFloatingPointX4) 2460 { 2461 2462 for (uint32 index = 0; index < sampleCount; index++) 2463 { 2464 2465 *(dstPtr--) = DNG_FP24ToFloat (srcPtr); 2466 2467 srcPtr -= 3; 2468 2469 } 2470 2471 } 2472 2473 else 2474 { 2475 2476 for (uint32 index = 0; index < sampleCount; index++) 2477 { 2478 2479 uint8 input [3]; 2480 2481 input [2] = srcPtr [0]; 2482 input [1] = srcPtr [1]; 2483 input [0] = srcPtr [2]; 2484 2485 *(dstPtr--) = DNG_FP24ToFloat (input); 2486 2487 srcPtr -= 3; 2488 2489 } 2490 2491 } 2492 2493 buffer.fPixelSize = 4; 2494 2495 } 2496 2497 // Save the data. 2498 2499 image.Put (buffer); 2500 2501 return; 2502 2503 } 2504 2505 case ccUncompressed: 2506 { 2507 2508 if (ReadUncompressed (host, 2509 ifd, 2510 stream, 2511 image, 2512 tileArea, 2513 plane, 2514 planes, 2515 uncompressedBuffer, 2516 subTileBlockBuffer)) 2517 { 2518 2519 return; 2520 2521 } 2522 2523 break; 2524 2525 } 2526 2527 case ccJPEG: 2528 { 2529 2530 if (ifd.IsBaselineJPEG ()) 2531 { 2532 2533 // Baseline JPEG. 2534 2535 if (ReadBaselineJPEG (host, 2536 ifd, 2537 stream, 2538 image, 2539 tileArea, 2540 plane, 2541 planes, 2542 tileByteCount, 2543 compressedBuffer.Get () ? compressedBuffer->Buffer_uint8 () : NULL)) 2544 { 2545 2546 return; 2547 2548 } 2549 2550 } 2551 2552 else 2553 { 2554 2555 // Otherwise is should be lossless JPEG. 2556 2557 if (ReadLosslessJPEG (host, 2558 ifd, 2559 stream, 2560 image, 2561 tileArea, 2562 plane, 2563 planes, 2564 tileByteCount, 2565 uncompressedBuffer, 2566 subTileBlockBuffer)) 2567 { 2568 2569 return; 2570 2571 } 2572 2573 } 2574 2575 break; 2576 2577 } 2578 2579 case ccLossyJPEG: 2580 { 2581 2582 if (ReadBaselineJPEG (host, 2583 ifd, 2584 stream, 2585 image, 2586 tileArea, 2587 plane, 2588 planes, 2589 tileByteCount, 2590 compressedBuffer.Get () ? compressedBuffer->Buffer_uint8 () : NULL)) 2591 { 2592 2593 return; 2594 2595 } 2596 2597 break; 2598 2599 } 2600 2601 default: 2602 break; 2603 2604 } 2605 2606 ThrowBadFormat (); 2607 2608 } 2609 2610/*****************************************************************************/ 2611 2612bool dng_read_image::CanRead (const dng_ifd &ifd) 2613 { 2614 2615 if (ifd.fImageWidth < 1 || 2616 ifd.fImageLength < 1) 2617 { 2618 return false; 2619 } 2620 2621 if (ifd.fSamplesPerPixel < 1) 2622 { 2623 return false; 2624 } 2625 2626 if (ifd.fBitsPerSample [0] < 1) 2627 { 2628 return false; 2629 } 2630 2631 for (uint32 j = 1; j < Min_uint32 (ifd.fSamplesPerPixel, 2632 kMaxSamplesPerPixel); j++) 2633 { 2634 2635 if (ifd.fBitsPerSample [j] != 2636 ifd.fBitsPerSample [0]) 2637 { 2638 return false; 2639 } 2640 2641 if (ifd.fSampleFormat [j] != 2642 ifd.fSampleFormat [0]) 2643 { 2644 return false; 2645 } 2646 2647 } 2648 2649 if ((ifd.fPlanarConfiguration != pcInterleaved ) && 2650 (ifd.fPlanarConfiguration != pcPlanar ) && 2651 (ifd.fPlanarConfiguration != pcRowInterleaved)) 2652 { 2653 return false; 2654 } 2655 2656 if (ifd.fUsesStrips == ifd.fUsesTiles) 2657 { 2658 return false; 2659 } 2660 2661 uint32 tileCount = ifd.TilesPerImage (); 2662 2663 if (tileCount < 1) 2664 { 2665 return false; 2666 } 2667 2668 bool needTileByteCounts = (ifd.TileByteCount (ifd.TileArea (0, 0)) == 0); 2669 2670 if (tileCount == 1) 2671 { 2672 2673 if (needTileByteCounts) 2674 { 2675 2676 if (ifd.fTileByteCount [0] < 1) 2677 { 2678 return false; 2679 } 2680 2681 } 2682 2683 } 2684 2685 else 2686 { 2687 2688 if (ifd.fTileOffsetsCount != tileCount) 2689 { 2690 return false; 2691 } 2692 2693 if (needTileByteCounts) 2694 { 2695 2696 if (ifd.fTileByteCountsCount != tileCount) 2697 { 2698 return false; 2699 } 2700 2701 } 2702 2703 } 2704 2705 if (!CanReadTile (ifd)) 2706 { 2707 return false; 2708 } 2709 2710 return true; 2711 2712 } 2713 2714/*****************************************************************************/ 2715 2716class dng_read_tiles_task : public dng_area_task 2717 { 2718 2719 private: 2720 2721 dng_read_image &fReadImage; 2722 2723 dng_host &fHost; 2724 2725 const dng_ifd &fIFD; 2726 2727 dng_stream &fStream; 2728 2729 dng_image &fImage; 2730 2731 dng_jpeg_image *fJPEGImage; 2732 2733 dng_fingerprint *fJPEGTileDigest; 2734 2735 uint32 fOuterSamples; 2736 2737 uint32 fInnerSamples; 2738 2739 uint32 fTilesDown; 2740 2741 uint32 fTilesAcross; 2742 2743 uint64 *fTileOffset; 2744 2745 uint32 *fTileByteCount; 2746 2747 uint32 fCompressedSize; 2748 2749 uint32 fUncompressedSize; 2750 2751 dng_mutex fMutex; 2752 2753 uint32 fNextTileIndex; 2754 2755 public: 2756 2757 dng_read_tiles_task (dng_read_image &readImage, 2758 dng_host &host, 2759 const dng_ifd &ifd, 2760 dng_stream &stream, 2761 dng_image &image, 2762 dng_jpeg_image *jpegImage, 2763 dng_fingerprint *jpegTileDigest, 2764 uint32 outerSamples, 2765 uint32 innerSamples, 2766 uint32 tilesDown, 2767 uint32 tilesAcross, 2768 uint64 *tileOffset, 2769 uint32 *tileByteCount, 2770 uint32 compressedSize, 2771 uint32 uncompressedSize) 2772 2773 : fReadImage (readImage) 2774 , fHost (host) 2775 , fIFD (ifd) 2776 , fStream (stream) 2777 , fImage (image) 2778 , fJPEGImage (jpegImage) 2779 , fJPEGTileDigest (jpegTileDigest) 2780 , fOuterSamples (outerSamples) 2781 , fInnerSamples (innerSamples) 2782 , fTilesDown (tilesDown) 2783 , fTilesAcross (tilesAcross) 2784 , fTileOffset (tileOffset) 2785 , fTileByteCount (tileByteCount) 2786 , fCompressedSize (compressedSize) 2787 , fUncompressedSize (uncompressedSize) 2788 , fMutex ("dng_read_tiles_task") 2789 , fNextTileIndex (0) 2790 2791 { 2792 2793 fMinTaskArea = 16 * 16; 2794 fUnitCell = dng_point (16, 16); 2795 fMaxTileSize = dng_point (16, 16); 2796 2797 } 2798 2799 void Process (uint32 /* threadIndex */, 2800 const dng_rect & /* tile */, 2801 dng_abort_sniffer *sniffer) 2802 { 2803 2804 AutoPtr<dng_memory_block> compressedBuffer; 2805 AutoPtr<dng_memory_block> uncompressedBuffer; 2806 AutoPtr<dng_memory_block> subTileBlockBuffer; 2807 2808 if (!fJPEGImage) 2809 { 2810 compressedBuffer.Reset (fHost.Allocate (fCompressedSize)); 2811 } 2812 2813 if (fUncompressedSize) 2814 { 2815 uncompressedBuffer.Reset (fHost.Allocate (fUncompressedSize)); 2816 } 2817 2818 while (true) 2819 { 2820 2821 uint32 tileIndex; 2822 uint32 byteCount; 2823 2824 { 2825 2826 dng_lock_mutex lock (&fMutex); 2827 2828 if (fNextTileIndex == fOuterSamples * fTilesDown * fTilesAcross) 2829 { 2830 return; 2831 } 2832 2833 tileIndex = fNextTileIndex++; 2834 2835 TempStreamSniffer noSniffer (fStream, NULL); 2836 2837 fStream.SetReadPosition (fTileOffset [tileIndex]); 2838 2839 byteCount = fTileByteCount [tileIndex]; 2840 2841 if (fJPEGImage) 2842 { 2843 2844 fJPEGImage->fJPEGData [tileIndex] . Reset (fHost.Allocate (byteCount)); 2845 2846 } 2847 2848 fStream.Get (fJPEGImage ? fJPEGImage->fJPEGData [tileIndex]->Buffer () 2849 : compressedBuffer->Buffer (), 2850 byteCount); 2851 2852 } 2853 2854 dng_abort_sniffer::SniffForAbort (sniffer); 2855 2856 if (fJPEGTileDigest) 2857 { 2858 2859 dng_md5_printer printer; 2860 2861 printer.Process (compressedBuffer->Buffer (), 2862 byteCount); 2863 2864 fJPEGTileDigest [tileIndex] = printer.Result (); 2865 2866 } 2867 2868 dng_stream tileStream (fJPEGImage ? fJPEGImage->fJPEGData [tileIndex]->Buffer () 2869 : compressedBuffer->Buffer (), 2870 byteCount); 2871 2872 tileStream.SetLittleEndian (fStream.LittleEndian ()); 2873 2874 uint32 plane = tileIndex / (fTilesDown * fTilesAcross); 2875 2876 uint32 rowIndex = (tileIndex - plane * fTilesDown * fTilesAcross) / fTilesAcross; 2877 2878 uint32 colIndex = tileIndex - (plane * fTilesDown + rowIndex) * fTilesAcross; 2879 2880 dng_rect tileArea = fIFD.TileArea (rowIndex, colIndex); 2881 2882 dng_host host (&fHost.Allocator (), 2883 sniffer); // Cannot use sniffer attached to main host 2884 2885 fReadImage.ReadTile (host, 2886 fIFD, 2887 tileStream, 2888 fImage, 2889 tileArea, 2890 plane, 2891 fInnerSamples, 2892 byteCount, 2893 fJPEGImage ? fJPEGImage->fJPEGData [tileIndex] 2894 : compressedBuffer, 2895 uncompressedBuffer, 2896 subTileBlockBuffer); 2897 2898 } 2899 2900 } 2901 2902 private: 2903 2904 // Hidden copy constructor and assignment operator. 2905 2906 dng_read_tiles_task (const dng_read_tiles_task &); 2907 2908 dng_read_tiles_task & operator= (const dng_read_tiles_task &); 2909 2910 }; 2911 2912/*****************************************************************************/ 2913 2914void dng_read_image::Read (dng_host &host, 2915 const dng_ifd &ifd, 2916 dng_stream &stream, 2917 dng_image &image, 2918 dng_jpeg_image *jpegImage, 2919 dng_fingerprint *jpegDigest) 2920 { 2921 2922 uint32 tileIndex; 2923 2924 // Deal with row interleaved images. 2925 2926 if (ifd.fRowInterleaveFactor > 1 && 2927 ifd.fRowInterleaveFactor < ifd.fImageLength) 2928 { 2929 2930 dng_ifd tempIFD (ifd); 2931 2932 tempIFD.fRowInterleaveFactor = 1; 2933 2934 dng_row_interleaved_image tempImage (image, 2935 ifd.fRowInterleaveFactor); 2936 2937 Read (host, 2938 tempIFD, 2939 stream, 2940 tempImage, 2941 jpegImage, 2942 jpegDigest); 2943 2944 return; 2945 2946 } 2947 2948 // Figure out inner and outer samples. 2949 2950 uint32 innerSamples = 1; 2951 uint32 outerSamples = 1; 2952 2953 if (ifd.fPlanarConfiguration == pcPlanar) 2954 { 2955 outerSamples = ifd.fSamplesPerPixel; 2956 } 2957 else 2958 { 2959 innerSamples = ifd.fSamplesPerPixel; 2960 } 2961 2962 // Calculate number of tiles to read. 2963 2964 uint32 tilesAcross = ifd.TilesAcross (); 2965 uint32 tilesDown = ifd.TilesDown (); 2966 2967 uint32 tileCount = SafeUint32Mult (tilesAcross, tilesDown, outerSamples); 2968 2969 // Find the tile offsets. 2970 2971 dng_memory_data tileOffsetData (tileCount, sizeof (uint64)); 2972 2973 uint64 *tileOffset = tileOffsetData.Buffer_uint64 (); 2974 2975 if (tileCount <= dng_ifd::kMaxTileInfo) 2976 { 2977 2978 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 2979 { 2980 2981 tileOffset [tileIndex] = ifd.fTileOffset [tileIndex]; 2982 2983 } 2984 2985 } 2986 2987 else 2988 { 2989 2990 stream.SetReadPosition (ifd.fTileOffsetsOffset); 2991 2992 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 2993 { 2994 2995 tileOffset [tileIndex] = stream.TagValue_uint32 (ifd.fTileOffsetsType); 2996 2997 } 2998 2999 } 3000 3001 // Quick validity check on tile offsets. 3002 3003 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 3004 { 3005 3006 #if qDNGValidate 3007 3008 if (tileOffset [tileIndex] < 8) 3009 { 3010 3011 ReportWarning ("Tile/Strip offset less than 8"); 3012 3013 } 3014 3015 #endif 3016 3017 if (tileOffset [tileIndex] >= stream.Length ()) 3018 { 3019 3020 ThrowBadFormat (); 3021 3022 } 3023 3024 } 3025 3026 // Buffer to hold the tile byte counts, if needed. 3027 3028 dng_memory_data tileByteCountData; 3029 3030 uint32 *tileByteCount = NULL; 3031 3032 // If we can compute the number of bytes needed to store the 3033 // data, we can split the read for each tile into sub-tiles. 3034 3035 uint32 uncompressedSize = 0; 3036 3037 uint32 subTileLength = ifd.fTileLength; 3038 3039 if (ifd.TileByteCount (ifd.TileArea (0, 0)) != 0) 3040 { 3041 3042 uint32 bytesPerPixel = TagTypeSize (ifd.PixelType ()); 3043 3044 uint32 bytesPerRow = SafeUint32Mult (ifd.fTileWidth, innerSamples, 3045 bytesPerPixel); 3046 3047 subTileLength = Pin_uint32 (ifd.fSubTileBlockRows, 3048 kImageBufferSize / bytesPerRow, 3049 ifd.fTileLength); 3050 3051 subTileLength = subTileLength / ifd.fSubTileBlockRows 3052 * ifd.fSubTileBlockRows; 3053 3054 uncompressedSize = SafeUint32Mult (subTileLength, bytesPerRow); 3055 3056 } 3057 3058 // Else we need to know the byte counts. 3059 3060 else 3061 { 3062 3063 tileByteCountData.Allocate (tileCount, sizeof (uint32)); 3064 3065 tileByteCount = tileByteCountData.Buffer_uint32 (); 3066 3067 if (tileCount <= dng_ifd::kMaxTileInfo) 3068 { 3069 3070 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 3071 { 3072 3073 tileByteCount [tileIndex] = ifd.fTileByteCount [tileIndex]; 3074 3075 } 3076 3077 } 3078 3079 else 3080 { 3081 3082 stream.SetReadPosition (ifd.fTileByteCountsOffset); 3083 3084 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 3085 { 3086 3087 tileByteCount [tileIndex] = stream.TagValue_uint32 (ifd.fTileByteCountsType); 3088 3089 } 3090 3091 } 3092 3093 // Quick validity check on tile byte counts. 3094 3095 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 3096 { 3097 3098 if (tileByteCount [tileIndex] < 1 || 3099 tileByteCount [tileIndex] > stream.Length ()) 3100 { 3101 3102 ThrowBadFormat (); 3103 3104 } 3105 3106 } 3107 3108 } 3109 3110 // Find maximum tile size, if possible. 3111 3112 uint32 maxTileByteCount = 0; 3113 3114 if (tileByteCount) 3115 { 3116 3117 for (tileIndex = 0; tileIndex < tileCount; tileIndex++) 3118 { 3119 3120 maxTileByteCount = Max_uint32 (maxTileByteCount, 3121 tileByteCount [tileIndex]); 3122 3123 } 3124 3125 } 3126 3127 // Do we need a compressed data buffer? 3128 3129 uint32 compressedSize = 0; 3130 3131 bool needsCompressedBuffer = NeedsCompressedBuffer (ifd); 3132 3133 if (needsCompressedBuffer) 3134 { 3135 3136 if (!tileByteCount) 3137 { 3138 ThrowBadFormat (); 3139 } 3140 3141 compressedSize = maxTileByteCount; 3142 3143 } 3144 3145 // Are we keeping the compressed JPEG image data? 3146 3147 if (jpegImage) 3148 { 3149 3150 if (ifd.IsBaselineJPEG ()) 3151 { 3152 3153 jpegImage->fImageSize.h = ifd.fImageWidth; 3154 jpegImage->fImageSize.v = ifd.fImageLength; 3155 3156 jpegImage->fTileSize.h = ifd.fTileWidth; 3157 jpegImage->fTileSize.v = ifd.fTileLength; 3158 3159 jpegImage->fUsesStrips = ifd.fUsesStrips; 3160 3161 jpegImage->fJPEGData.Reset (tileCount); 3162 3163 } 3164 3165 else 3166 { 3167 3168 jpegImage = NULL; 3169 3170 } 3171 3172 } 3173 3174 // Do we need to read the JPEG tables? 3175 3176 if (ifd.fJPEGTablesOffset && ifd.fJPEGTablesCount) 3177 { 3178 3179 if (ifd.IsBaselineJPEG ()) 3180 { 3181 3182 fJPEGTables.Reset (host.Allocate (ifd.fJPEGTablesCount)); 3183 3184 stream.SetReadPosition (ifd.fJPEGTablesOffset); 3185 3186 stream.Get (fJPEGTables->Buffer (), 3187 fJPEGTables->LogicalSize ()); 3188 3189 } 3190 3191 } 3192 3193 AutoArray<dng_fingerprint> jpegTileDigest; 3194 3195 if (jpegDigest) 3196 { 3197 3198 jpegTileDigest.Reset ( 3199 SafeUint32Add(tileCount, (fJPEGTables.Get () ? 1 : 0))); 3200 3201 } 3202 3203 // Don't read planes we are not actually saving. 3204 3205 outerSamples = Min_uint32 (image.Planes (), outerSamples); 3206 3207 // See if we can do this read using multiple threads. 3208 3209 bool useMultipleThreads = (outerSamples * tilesDown * tilesAcross >= 2) && 3210 (host.PerformAreaTaskThreads () > 1) && 3211 (maxTileByteCount > 0 && maxTileByteCount <= 1024 * 1024) && 3212 (subTileLength == ifd.fTileLength) && 3213 (ifd.fCompression != ccUncompressed); 3214 3215#if qImagecore 3216 useMultipleThreads = false; 3217#endif 3218 3219 if (useMultipleThreads) 3220 { 3221 3222 uint32 threadCount = Min_uint32 (outerSamples * tilesDown * tilesAcross, 3223 host.PerformAreaTaskThreads ()); 3224 3225 dng_read_tiles_task task (*this, 3226 host, 3227 ifd, 3228 stream, 3229 image, 3230 jpegImage, 3231 jpegTileDigest.Get (), 3232 outerSamples, 3233 innerSamples, 3234 tilesDown, 3235 tilesAcross, 3236 tileOffset, 3237 tileByteCount, 3238 maxTileByteCount, 3239 uncompressedSize); 3240 3241 host.PerformAreaTask (task, 3242 dng_rect (0, 0, 16, 16 * threadCount)); 3243 3244 } 3245 3246 // Else use a single thread to read all the tiles. 3247 3248 else 3249 { 3250 3251 AutoPtr<dng_memory_block> compressedBuffer; 3252 AutoPtr<dng_memory_block> uncompressedBuffer; 3253 AutoPtr<dng_memory_block> subTileBlockBuffer; 3254 3255 if (uncompressedSize) 3256 { 3257 uncompressedBuffer.Reset (host.Allocate (uncompressedSize)); 3258 } 3259 3260 if (compressedSize && !jpegImage) 3261 { 3262 compressedBuffer.Reset (host.Allocate (compressedSize)); 3263 } 3264 3265 else if (jpegDigest) 3266 { 3267 compressedBuffer.Reset (host.Allocate (maxTileByteCount)); 3268 } 3269 3270 tileIndex = 0; 3271 3272 for (uint32 plane = 0; plane < outerSamples; plane++) 3273 { 3274 3275 for (uint32 rowIndex = 0; rowIndex < tilesDown; rowIndex++) 3276 { 3277 3278 for (uint32 colIndex = 0; colIndex < tilesAcross; colIndex++) 3279 { 3280 3281 stream.SetReadPosition (tileOffset [tileIndex]); 3282 3283 dng_rect tileArea = ifd.TileArea (rowIndex, colIndex); 3284 3285 uint32 subTileCount = (tileArea.H () + subTileLength - 1) / 3286 subTileLength; 3287 3288 for (uint32 subIndex = 0; subIndex < subTileCount; subIndex++) 3289 { 3290 3291 host.SniffForAbort (); 3292 3293 dng_rect subArea (tileArea); 3294 3295 subArea.t = tileArea.t + subIndex * subTileLength; 3296 3297 subArea.b = Min_int32 (subArea.t + subTileLength, 3298 tileArea.b); 3299 3300 uint32 subByteCount; 3301 3302 if (tileByteCount) 3303 { 3304 subByteCount = tileByteCount [tileIndex]; 3305 } 3306 else 3307 { 3308 subByteCount = ifd.TileByteCount (subArea); 3309 } 3310 3311 if (jpegImage) 3312 { 3313 3314 jpegImage->fJPEGData [tileIndex].Reset (host.Allocate (subByteCount)); 3315 3316 stream.Get (jpegImage->fJPEGData [tileIndex]->Buffer (), subByteCount); 3317 3318 stream.SetReadPosition (tileOffset [tileIndex]); 3319 3320 } 3321 3322 else if ((needsCompressedBuffer || jpegDigest) && subByteCount) 3323 { 3324 3325 stream.Get (compressedBuffer->Buffer (), subByteCount); 3326 3327 if (jpegDigest) 3328 { 3329 3330 dng_md5_printer printer; 3331 3332 printer.Process (compressedBuffer->Buffer (), 3333 subByteCount); 3334 3335 jpegTileDigest [tileIndex] = printer.Result (); 3336 3337 } 3338 3339 } 3340 3341 ReadTile (host, 3342 ifd, 3343 stream, 3344 image, 3345 subArea, 3346 plane, 3347 innerSamples, 3348 subByteCount, 3349 jpegImage ? jpegImage->fJPEGData [tileIndex] : compressedBuffer, 3350 uncompressedBuffer, 3351 subTileBlockBuffer); 3352 3353 } 3354 3355 tileIndex++; 3356 3357 } 3358 3359 } 3360 3361 } 3362 3363 } 3364 3365 // Finish up JPEG digest computation, if needed. 3366 3367 if (jpegDigest) 3368 { 3369 3370 if (fJPEGTables.Get ()) 3371 { 3372 3373 dng_md5_printer printer; 3374 3375 printer.Process (fJPEGTables->Buffer (), 3376 fJPEGTables->LogicalSize ()); 3377 3378 jpegTileDigest [tileCount] = printer.Result (); 3379 3380 } 3381 3382 dng_md5_printer printer2; 3383 3384 for (uint32 j = 0; j < tileCount + (fJPEGTables.Get () ? 1 : 0); j++) 3385 { 3386 3387 printer2.Process (jpegTileDigest [j].data, 3388 dng_fingerprint::kDNGFingerprintSize); 3389 3390 } 3391 3392 *jpegDigest = printer2.Result (); 3393 3394 } 3395 3396 // Keep the JPEG table in the jpeg image, if any. 3397 3398 if (jpegImage) 3399 { 3400 3401 jpegImage->fJPEGTables.Reset (fJPEGTables.Release ()); 3402 3403 } 3404 3405 } 3406 3407/*****************************************************************************/ 3408