Home | History | Annotate | Download | only in source
      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 
     47 static 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 
     78 static 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 
    109 static 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 
    140 inline 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 
    241 static 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 
    328 bool 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 
    383 class 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 
    447 dng_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 
    469 void 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 
    493 void 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 
    524 bool 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 
    602 bool 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 
    809 dng_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 
    825 int32 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 
    858 void 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 
    882 void 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 
    906 static 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 
    984 class 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 
   1039 dng_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 
   1085 dng_image_spooler::~dng_image_spooler ()
   1086 	{
   1087 
   1088 	}
   1089 
   1090 /*****************************************************************************/
   1091 
   1092 void 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 
   1157 dng_read_image::dng_read_image ()
   1158 
   1159 	:	fJPEGTables ()
   1160 
   1161 	{
   1162 
   1163 	}
   1164 
   1165 /*****************************************************************************/
   1166 
   1167 dng_read_image::~dng_read_image ()
   1168 	{
   1169 
   1170 	}
   1171 
   1172 /*****************************************************************************/
   1173 
   1174 bool 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 
   1466 static 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 
   1495 static 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 
   1516 void 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 
   1660 static 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 
   1746 bool 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 
   1807 bool 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 
   1886 bool 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 
   2014 bool 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 
   2031 void 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 
   2069 void 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 
   2160 void 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 
   2612 bool 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 
   2716 class 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 
   2914 void 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