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