xref: /aosp_15_r20/external/dng_sdk/source/dng_jpeg_image.cpp (revision fd1fabb72dbdf09ea7034f531e6f8e9f57334c8d)
1*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2*fd1fabb7SAndroid Build Coastguard Worker // Copyright 2011 Adobe Systems Incorporated
3*fd1fabb7SAndroid Build Coastguard Worker // All Rights Reserved.
4*fd1fabb7SAndroid Build Coastguard Worker //
5*fd1fabb7SAndroid Build Coastguard Worker // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6*fd1fabb7SAndroid Build Coastguard Worker // accordance with the terms of the Adobe license agreement accompanying it.
7*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
8*fd1fabb7SAndroid Build Coastguard Worker 
9*fd1fabb7SAndroid Build Coastguard Worker /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_jpeg_image.cpp#1 $ */
10*fd1fabb7SAndroid Build Coastguard Worker /* $DateTime: 2012/05/30 13:28:51 $ */
11*fd1fabb7SAndroid Build Coastguard Worker /* $Change: 832332 $ */
12*fd1fabb7SAndroid Build Coastguard Worker /* $Author: tknoll $ */
13*fd1fabb7SAndroid Build Coastguard Worker 
14*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
15*fd1fabb7SAndroid Build Coastguard Worker 
16*fd1fabb7SAndroid Build Coastguard Worker #include "dng_jpeg_image.h"
17*fd1fabb7SAndroid Build Coastguard Worker 
18*fd1fabb7SAndroid Build Coastguard Worker #include "dng_abort_sniffer.h"
19*fd1fabb7SAndroid Build Coastguard Worker #include "dng_area_task.h"
20*fd1fabb7SAndroid Build Coastguard Worker #include "dng_assertions.h"
21*fd1fabb7SAndroid Build Coastguard Worker #include "dng_host.h"
22*fd1fabb7SAndroid Build Coastguard Worker #include "dng_ifd.h"
23*fd1fabb7SAndroid Build Coastguard Worker #include "dng_image.h"
24*fd1fabb7SAndroid Build Coastguard Worker #include "dng_image_writer.h"
25*fd1fabb7SAndroid Build Coastguard Worker #include "dng_memory_stream.h"
26*fd1fabb7SAndroid Build Coastguard Worker #include "dng_mutex.h"
27*fd1fabb7SAndroid Build Coastguard Worker #include "dng_safe_arithmetic.h"
28*fd1fabb7SAndroid Build Coastguard Worker 
29*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
30*fd1fabb7SAndroid Build Coastguard Worker 
dng_jpeg_image()31*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_image::dng_jpeg_image ()
32*fd1fabb7SAndroid Build Coastguard Worker 
33*fd1fabb7SAndroid Build Coastguard Worker 	:	fImageSize  ()
34*fd1fabb7SAndroid Build Coastguard Worker 	,	fTileSize   ()
35*fd1fabb7SAndroid Build Coastguard Worker 	,	fUsesStrips (false)
36*fd1fabb7SAndroid Build Coastguard Worker 	,	fJPEGTables ()
37*fd1fabb7SAndroid Build Coastguard Worker 	,	fJPEGData   ()
38*fd1fabb7SAndroid Build Coastguard Worker 
39*fd1fabb7SAndroid Build Coastguard Worker 	{
40*fd1fabb7SAndroid Build Coastguard Worker 
41*fd1fabb7SAndroid Build Coastguard Worker 	}
42*fd1fabb7SAndroid Build Coastguard Worker 
43*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
44*fd1fabb7SAndroid Build Coastguard Worker 
45*fd1fabb7SAndroid Build Coastguard Worker class dng_jpeg_image_encode_task : public dng_area_task
46*fd1fabb7SAndroid Build Coastguard Worker 	{
47*fd1fabb7SAndroid Build Coastguard Worker 
48*fd1fabb7SAndroid Build Coastguard Worker 	private:
49*fd1fabb7SAndroid Build Coastguard Worker 
50*fd1fabb7SAndroid Build Coastguard Worker 		dng_host &fHost;
51*fd1fabb7SAndroid Build Coastguard Worker 
52*fd1fabb7SAndroid Build Coastguard Worker 		dng_image_writer &fWriter;
53*fd1fabb7SAndroid Build Coastguard Worker 
54*fd1fabb7SAndroid Build Coastguard Worker 		const dng_image &fImage;
55*fd1fabb7SAndroid Build Coastguard Worker 
56*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image &fJPEGImage;
57*fd1fabb7SAndroid Build Coastguard Worker 
58*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fTileCount;
59*fd1fabb7SAndroid Build Coastguard Worker 
60*fd1fabb7SAndroid Build Coastguard Worker 		const dng_ifd &fIFD;
61*fd1fabb7SAndroid Build Coastguard Worker 
62*fd1fabb7SAndroid Build Coastguard Worker 		dng_mutex fMutex;
63*fd1fabb7SAndroid Build Coastguard Worker 
64*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fNextTileIndex;
65*fd1fabb7SAndroid Build Coastguard Worker 
66*fd1fabb7SAndroid Build Coastguard Worker 	public:
67*fd1fabb7SAndroid Build Coastguard Worker 
dng_jpeg_image_encode_task(dng_host & host,dng_image_writer & writer,const dng_image & image,dng_jpeg_image & jpegImage,uint32 tileCount,const dng_ifd & ifd)68*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_encode_task (dng_host &host,
69*fd1fabb7SAndroid Build Coastguard Worker 									dng_image_writer &writer,
70*fd1fabb7SAndroid Build Coastguard Worker 									const dng_image &image,
71*fd1fabb7SAndroid Build Coastguard Worker 									dng_jpeg_image &jpegImage,
72*fd1fabb7SAndroid Build Coastguard Worker 									uint32 tileCount,
73*fd1fabb7SAndroid Build Coastguard Worker 									const dng_ifd &ifd)
74*fd1fabb7SAndroid Build Coastguard Worker 
75*fd1fabb7SAndroid Build Coastguard Worker 			:	fHost			  (host)
76*fd1fabb7SAndroid Build Coastguard Worker 			,	fWriter			  (writer)
77*fd1fabb7SAndroid Build Coastguard Worker 			,	fImage			  (image)
78*fd1fabb7SAndroid Build Coastguard Worker 			,	fJPEGImage        (jpegImage)
79*fd1fabb7SAndroid Build Coastguard Worker 			,	fTileCount		  (tileCount)
80*fd1fabb7SAndroid Build Coastguard Worker 			,	fIFD		      (ifd)
81*fd1fabb7SAndroid Build Coastguard Worker 			,	fMutex			  ("dng_jpeg_image_encode_task")
82*fd1fabb7SAndroid Build Coastguard Worker 			,	fNextTileIndex	  (0)
83*fd1fabb7SAndroid Build Coastguard Worker 
84*fd1fabb7SAndroid Build Coastguard Worker 			{
85*fd1fabb7SAndroid Build Coastguard Worker 
86*fd1fabb7SAndroid Build Coastguard Worker 			fMinTaskArea = 16 * 16;
87*fd1fabb7SAndroid Build Coastguard Worker 			fUnitCell    = dng_point (16, 16);
88*fd1fabb7SAndroid Build Coastguard Worker 			fMaxTileSize = dng_point (16, 16);
89*fd1fabb7SAndroid Build Coastguard Worker 
90*fd1fabb7SAndroid Build Coastguard Worker 			}
91*fd1fabb7SAndroid Build Coastguard Worker 
Process(uint32,const dng_rect &,dng_abort_sniffer * sniffer)92*fd1fabb7SAndroid Build Coastguard Worker 		void Process (uint32 /* threadIndex */,
93*fd1fabb7SAndroid Build Coastguard Worker 					  const dng_rect & /* tile */,
94*fd1fabb7SAndroid Build Coastguard Worker 					  dng_abort_sniffer *sniffer)
95*fd1fabb7SAndroid Build Coastguard Worker 			{
96*fd1fabb7SAndroid Build Coastguard Worker 
97*fd1fabb7SAndroid Build Coastguard Worker 			AutoPtr<dng_memory_block> compressedBuffer;
98*fd1fabb7SAndroid Build Coastguard Worker 			AutoPtr<dng_memory_block> uncompressedBuffer;
99*fd1fabb7SAndroid Build Coastguard Worker 			AutoPtr<dng_memory_block> subTileBlockBuffer;
100*fd1fabb7SAndroid Build Coastguard Worker 			AutoPtr<dng_memory_block> tempBuffer;
101*fd1fabb7SAndroid Build Coastguard Worker 
102*fd1fabb7SAndroid Build Coastguard Worker 			uint32 uncompressedSize = SafeUint32Mult (
103*fd1fabb7SAndroid Build Coastguard Worker 				fIFD.fTileLength, fIFD.fTileWidth, fIFD.fSamplesPerPixel);
104*fd1fabb7SAndroid Build Coastguard Worker 
105*fd1fabb7SAndroid Build Coastguard Worker 			uncompressedBuffer.Reset (fHost.Allocate (uncompressedSize));
106*fd1fabb7SAndroid Build Coastguard Worker 
107*fd1fabb7SAndroid Build Coastguard Worker 			uint32 tilesAcross = fIFD.TilesAcross ();
108*fd1fabb7SAndroid Build Coastguard Worker 
109*fd1fabb7SAndroid Build Coastguard Worker 			while (true)
110*fd1fabb7SAndroid Build Coastguard Worker 				{
111*fd1fabb7SAndroid Build Coastguard Worker 
112*fd1fabb7SAndroid Build Coastguard Worker 				uint32 tileIndex;
113*fd1fabb7SAndroid Build Coastguard Worker 
114*fd1fabb7SAndroid Build Coastguard Worker 					{
115*fd1fabb7SAndroid Build Coastguard Worker 
116*fd1fabb7SAndroid Build Coastguard Worker 					dng_lock_mutex lock (&fMutex);
117*fd1fabb7SAndroid Build Coastguard Worker 
118*fd1fabb7SAndroid Build Coastguard Worker 					if (fNextTileIndex == fTileCount)
119*fd1fabb7SAndroid Build Coastguard Worker 						{
120*fd1fabb7SAndroid Build Coastguard Worker 						return;
121*fd1fabb7SAndroid Build Coastguard Worker 						}
122*fd1fabb7SAndroid Build Coastguard Worker 
123*fd1fabb7SAndroid Build Coastguard Worker 					tileIndex = fNextTileIndex++;
124*fd1fabb7SAndroid Build Coastguard Worker 
125*fd1fabb7SAndroid Build Coastguard Worker 					}
126*fd1fabb7SAndroid Build Coastguard Worker 
127*fd1fabb7SAndroid Build Coastguard Worker 				dng_abort_sniffer::SniffForAbort (sniffer);
128*fd1fabb7SAndroid Build Coastguard Worker 
129*fd1fabb7SAndroid Build Coastguard Worker 				uint32 rowIndex = tileIndex / tilesAcross;
130*fd1fabb7SAndroid Build Coastguard Worker 				uint32 colIndex = tileIndex % tilesAcross;
131*fd1fabb7SAndroid Build Coastguard Worker 
132*fd1fabb7SAndroid Build Coastguard Worker 				dng_rect tileArea = fIFD.TileArea (rowIndex, colIndex);
133*fd1fabb7SAndroid Build Coastguard Worker 
134*fd1fabb7SAndroid Build Coastguard Worker 				dng_memory_stream stream (fHost.Allocator ());
135*fd1fabb7SAndroid Build Coastguard Worker 
136*fd1fabb7SAndroid Build Coastguard Worker 				fWriter.WriteTile (fHost,
137*fd1fabb7SAndroid Build Coastguard Worker 								   fIFD,
138*fd1fabb7SAndroid Build Coastguard Worker 								   stream,
139*fd1fabb7SAndroid Build Coastguard Worker 								   fImage,
140*fd1fabb7SAndroid Build Coastguard Worker 								   tileArea,
141*fd1fabb7SAndroid Build Coastguard Worker 								   1,
142*fd1fabb7SAndroid Build Coastguard Worker 								   compressedBuffer,
143*fd1fabb7SAndroid Build Coastguard Worker 								   uncompressedBuffer,
144*fd1fabb7SAndroid Build Coastguard Worker 								   subTileBlockBuffer,
145*fd1fabb7SAndroid Build Coastguard Worker 								   tempBuffer);
146*fd1fabb7SAndroid Build Coastguard Worker 
147*fd1fabb7SAndroid Build Coastguard Worker 				fJPEGImage.fJPEGData [tileIndex].Reset (stream.AsMemoryBlock (fHost.Allocator ()));
148*fd1fabb7SAndroid Build Coastguard Worker 
149*fd1fabb7SAndroid Build Coastguard Worker 				}
150*fd1fabb7SAndroid Build Coastguard Worker 
151*fd1fabb7SAndroid Build Coastguard Worker 			}
152*fd1fabb7SAndroid Build Coastguard Worker 
153*fd1fabb7SAndroid Build Coastguard Worker 	private:
154*fd1fabb7SAndroid Build Coastguard Worker 
155*fd1fabb7SAndroid Build Coastguard Worker 		// Hidden copy constructor and assignment operator.
156*fd1fabb7SAndroid Build Coastguard Worker 
157*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_encode_task (const dng_jpeg_image_encode_task &);
158*fd1fabb7SAndroid Build Coastguard Worker 
159*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_encode_task & operator= (const dng_jpeg_image_encode_task &);
160*fd1fabb7SAndroid Build Coastguard Worker 
161*fd1fabb7SAndroid Build Coastguard Worker 	};
162*fd1fabb7SAndroid Build Coastguard Worker 
163*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
164*fd1fabb7SAndroid Build Coastguard Worker 
Encode(dng_host & host,const dng_negative & negative,dng_image_writer & writer,const dng_image & image)165*fd1fabb7SAndroid Build Coastguard Worker void dng_jpeg_image::Encode (dng_host &host,
166*fd1fabb7SAndroid Build Coastguard Worker 							 const dng_negative &negative,
167*fd1fabb7SAndroid Build Coastguard Worker 							 dng_image_writer &writer,
168*fd1fabb7SAndroid Build Coastguard Worker 							 const dng_image &image)
169*fd1fabb7SAndroid Build Coastguard Worker 	{
170*fd1fabb7SAndroid Build Coastguard Worker 
171*fd1fabb7SAndroid Build Coastguard Worker 	#if qDNGValidate
172*fd1fabb7SAndroid Build Coastguard Worker 	dng_timer timer ("Encode JPEG Proxy time");
173*fd1fabb7SAndroid Build Coastguard Worker 	#endif
174*fd1fabb7SAndroid Build Coastguard Worker 
175*fd1fabb7SAndroid Build Coastguard Worker 	DNG_ASSERT (image.PixelType () == ttByte, "Cannot JPEG encode non-byte image");
176*fd1fabb7SAndroid Build Coastguard Worker 
177*fd1fabb7SAndroid Build Coastguard Worker 	fImageSize = image.Bounds ().Size ();
178*fd1fabb7SAndroid Build Coastguard Worker 
179*fd1fabb7SAndroid Build Coastguard Worker 	dng_ifd ifd;
180*fd1fabb7SAndroid Build Coastguard Worker 
181*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fImageWidth  = fImageSize.h;
182*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fImageLength = fImageSize.v;
183*fd1fabb7SAndroid Build Coastguard Worker 
184*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fSamplesPerPixel = image.Planes ();
185*fd1fabb7SAndroid Build Coastguard Worker 
186*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fBitsPerSample [0] = 8;
187*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fBitsPerSample [1] = 8;
188*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fBitsPerSample [2] = 8;
189*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fBitsPerSample [3] = 8;
190*fd1fabb7SAndroid Build Coastguard Worker 
191*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fPhotometricInterpretation = piLinearRaw;
192*fd1fabb7SAndroid Build Coastguard Worker 
193*fd1fabb7SAndroid Build Coastguard Worker 	ifd.fCompression = ccLossyJPEG;
194*fd1fabb7SAndroid Build Coastguard Worker 
195*fd1fabb7SAndroid Build Coastguard Worker 	ifd.FindTileSize (512 * 512 * ifd.fSamplesPerPixel);
196*fd1fabb7SAndroid Build Coastguard Worker 
197*fd1fabb7SAndroid Build Coastguard Worker 	fTileSize.h = ifd.fTileWidth;
198*fd1fabb7SAndroid Build Coastguard Worker 	fTileSize.v = ifd.fTileLength;
199*fd1fabb7SAndroid Build Coastguard Worker 
200*fd1fabb7SAndroid Build Coastguard Worker 	// Need a higher quality for raw proxies than non-raw proxies,
201*fd1fabb7SAndroid Build Coastguard Worker 	// since users often perform much greater color changes.  Also, use
202*fd1fabb7SAndroid Build Coastguard Worker 	// we are targeting a "large" size proxy (larger than 5MP pixels), or this
203*fd1fabb7SAndroid Build Coastguard Worker 	// is a full size proxy, then use a higher quality.
204*fd1fabb7SAndroid Build Coastguard Worker 
205*fd1fabb7SAndroid Build Coastguard Worker 	bool useHigherQuality = (uint64) ifd.fImageWidth *
206*fd1fabb7SAndroid Build Coastguard Worker 							(uint64) ifd.fImageLength > 5000000 ||
207*fd1fabb7SAndroid Build Coastguard Worker 							image.Bounds ().Size () == negative.OriginalDefaultFinalSize ();
208*fd1fabb7SAndroid Build Coastguard Worker 
209*fd1fabb7SAndroid Build Coastguard Worker 	if (negative.ColorimetricReference () == crSceneReferred)
210*fd1fabb7SAndroid Build Coastguard Worker 		{
211*fd1fabb7SAndroid Build Coastguard Worker 		ifd.fCompressionQuality = useHigherQuality ? 11 : 10;
212*fd1fabb7SAndroid Build Coastguard Worker 		}
213*fd1fabb7SAndroid Build Coastguard Worker 	else
214*fd1fabb7SAndroid Build Coastguard Worker 		{
215*fd1fabb7SAndroid Build Coastguard Worker 		ifd.fCompressionQuality = useHigherQuality ? 10 : 8;
216*fd1fabb7SAndroid Build Coastguard Worker 		}
217*fd1fabb7SAndroid Build Coastguard Worker 
218*fd1fabb7SAndroid Build Coastguard Worker 	uint32 tilesAcross = ifd.TilesAcross ();
219*fd1fabb7SAndroid Build Coastguard Worker 	uint32 tilesDown   = ifd.TilesDown   ();
220*fd1fabb7SAndroid Build Coastguard Worker 
221*fd1fabb7SAndroid Build Coastguard Worker 	uint32 tileCount = tilesAcross * tilesDown;
222*fd1fabb7SAndroid Build Coastguard Worker 
223*fd1fabb7SAndroid Build Coastguard Worker 	fJPEGData.Reset (tileCount);
224*fd1fabb7SAndroid Build Coastguard Worker 
225*fd1fabb7SAndroid Build Coastguard Worker 	uint32 threadCount = Min_uint32 (tileCount,
226*fd1fabb7SAndroid Build Coastguard Worker 									 host.PerformAreaTaskThreads ());
227*fd1fabb7SAndroid Build Coastguard Worker 
228*fd1fabb7SAndroid Build Coastguard Worker 	dng_jpeg_image_encode_task task (host,
229*fd1fabb7SAndroid Build Coastguard Worker 									 writer,
230*fd1fabb7SAndroid Build Coastguard Worker 									 image,
231*fd1fabb7SAndroid Build Coastguard Worker 									 *this,
232*fd1fabb7SAndroid Build Coastguard Worker 									 tileCount,
233*fd1fabb7SAndroid Build Coastguard Worker 									 ifd);
234*fd1fabb7SAndroid Build Coastguard Worker 
235*fd1fabb7SAndroid Build Coastguard Worker 	host.PerformAreaTask (task,
236*fd1fabb7SAndroid Build Coastguard Worker 						  dng_rect (0, 0, 16, 16 * threadCount));
237*fd1fabb7SAndroid Build Coastguard Worker 
238*fd1fabb7SAndroid Build Coastguard Worker 	}
239*fd1fabb7SAndroid Build Coastguard Worker 
240*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
241*fd1fabb7SAndroid Build Coastguard Worker 
242*fd1fabb7SAndroid Build Coastguard Worker class dng_jpeg_image_find_digest_task : public dng_area_task
243*fd1fabb7SAndroid Build Coastguard Worker 	{
244*fd1fabb7SAndroid Build Coastguard Worker 
245*fd1fabb7SAndroid Build Coastguard Worker 	private:
246*fd1fabb7SAndroid Build Coastguard Worker 
247*fd1fabb7SAndroid Build Coastguard Worker 		const dng_jpeg_image &fJPEGImage;
248*fd1fabb7SAndroid Build Coastguard Worker 
249*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fTileCount;
250*fd1fabb7SAndroid Build Coastguard Worker 
251*fd1fabb7SAndroid Build Coastguard Worker 		dng_fingerprint *fDigests;
252*fd1fabb7SAndroid Build Coastguard Worker 
253*fd1fabb7SAndroid Build Coastguard Worker 		dng_mutex fMutex;
254*fd1fabb7SAndroid Build Coastguard Worker 
255*fd1fabb7SAndroid Build Coastguard Worker 		uint32 fNextTileIndex;
256*fd1fabb7SAndroid Build Coastguard Worker 
257*fd1fabb7SAndroid Build Coastguard Worker 	public:
258*fd1fabb7SAndroid Build Coastguard Worker 
dng_jpeg_image_find_digest_task(const dng_jpeg_image & jpegImage,uint32 tileCount,dng_fingerprint * digests)259*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_find_digest_task (const dng_jpeg_image &jpegImage,
260*fd1fabb7SAndroid Build Coastguard Worker 										 uint32 tileCount,
261*fd1fabb7SAndroid Build Coastguard Worker 										 dng_fingerprint *digests)
262*fd1fabb7SAndroid Build Coastguard Worker 
263*fd1fabb7SAndroid Build Coastguard Worker 			:	fJPEGImage        (jpegImage)
264*fd1fabb7SAndroid Build Coastguard Worker 			,	fTileCount		  (tileCount)
265*fd1fabb7SAndroid Build Coastguard Worker 			,	fDigests		  (digests)
266*fd1fabb7SAndroid Build Coastguard Worker 			,	fMutex			  ("dng_jpeg_image_find_digest_task")
267*fd1fabb7SAndroid Build Coastguard Worker 			,	fNextTileIndex	  (0)
268*fd1fabb7SAndroid Build Coastguard Worker 
269*fd1fabb7SAndroid Build Coastguard Worker 			{
270*fd1fabb7SAndroid Build Coastguard Worker 
271*fd1fabb7SAndroid Build Coastguard Worker 			fMinTaskArea = 16 * 16;
272*fd1fabb7SAndroid Build Coastguard Worker 			fUnitCell    = dng_point (16, 16);
273*fd1fabb7SAndroid Build Coastguard Worker 			fMaxTileSize = dng_point (16, 16);
274*fd1fabb7SAndroid Build Coastguard Worker 
275*fd1fabb7SAndroid Build Coastguard Worker 			}
276*fd1fabb7SAndroid Build Coastguard Worker 
Process(uint32,const dng_rect &,dng_abort_sniffer * sniffer)277*fd1fabb7SAndroid Build Coastguard Worker 		void Process (uint32 /* threadIndex */,
278*fd1fabb7SAndroid Build Coastguard Worker 					  const dng_rect & /* tile */,
279*fd1fabb7SAndroid Build Coastguard Worker 					  dng_abort_sniffer *sniffer)
280*fd1fabb7SAndroid Build Coastguard Worker 			{
281*fd1fabb7SAndroid Build Coastguard Worker 
282*fd1fabb7SAndroid Build Coastguard Worker 			while (true)
283*fd1fabb7SAndroid Build Coastguard Worker 				{
284*fd1fabb7SAndroid Build Coastguard Worker 
285*fd1fabb7SAndroid Build Coastguard Worker 				uint32 tileIndex;
286*fd1fabb7SAndroid Build Coastguard Worker 
287*fd1fabb7SAndroid Build Coastguard Worker 					{
288*fd1fabb7SAndroid Build Coastguard Worker 
289*fd1fabb7SAndroid Build Coastguard Worker 					dng_lock_mutex lock (&fMutex);
290*fd1fabb7SAndroid Build Coastguard Worker 
291*fd1fabb7SAndroid Build Coastguard Worker 					if (fNextTileIndex == fTileCount)
292*fd1fabb7SAndroid Build Coastguard Worker 						{
293*fd1fabb7SAndroid Build Coastguard Worker 						return;
294*fd1fabb7SAndroid Build Coastguard Worker 						}
295*fd1fabb7SAndroid Build Coastguard Worker 
296*fd1fabb7SAndroid Build Coastguard Worker 					tileIndex = fNextTileIndex++;
297*fd1fabb7SAndroid Build Coastguard Worker 
298*fd1fabb7SAndroid Build Coastguard Worker 					}
299*fd1fabb7SAndroid Build Coastguard Worker 
300*fd1fabb7SAndroid Build Coastguard Worker 				dng_abort_sniffer::SniffForAbort (sniffer);
301*fd1fabb7SAndroid Build Coastguard Worker 
302*fd1fabb7SAndroid Build Coastguard Worker 				dng_md5_printer printer;
303*fd1fabb7SAndroid Build Coastguard Worker 
304*fd1fabb7SAndroid Build Coastguard Worker 				printer.Process (fJPEGImage.fJPEGData [tileIndex]->Buffer      (),
305*fd1fabb7SAndroid Build Coastguard Worker 								 fJPEGImage.fJPEGData [tileIndex]->LogicalSize ());
306*fd1fabb7SAndroid Build Coastguard Worker 
307*fd1fabb7SAndroid Build Coastguard Worker 				fDigests [tileIndex] = printer.Result ();
308*fd1fabb7SAndroid Build Coastguard Worker 
309*fd1fabb7SAndroid Build Coastguard Worker 				}
310*fd1fabb7SAndroid Build Coastguard Worker 
311*fd1fabb7SAndroid Build Coastguard Worker 			}
312*fd1fabb7SAndroid Build Coastguard Worker 
313*fd1fabb7SAndroid Build Coastguard Worker 	private:
314*fd1fabb7SAndroid Build Coastguard Worker 
315*fd1fabb7SAndroid Build Coastguard Worker 		// Hidden copy constructor and assignment operator.
316*fd1fabb7SAndroid Build Coastguard Worker 
317*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_find_digest_task (const dng_jpeg_image_find_digest_task &);
318*fd1fabb7SAndroid Build Coastguard Worker 
319*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_find_digest_task & operator= (const dng_jpeg_image_find_digest_task &);
320*fd1fabb7SAndroid Build Coastguard Worker 
321*fd1fabb7SAndroid Build Coastguard Worker 	};
322*fd1fabb7SAndroid Build Coastguard Worker 
323*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
324*fd1fabb7SAndroid Build Coastguard Worker 
FindDigest(dng_host & host) const325*fd1fabb7SAndroid Build Coastguard Worker dng_fingerprint dng_jpeg_image::FindDigest (dng_host &host) const
326*fd1fabb7SAndroid Build Coastguard Worker 	{
327*fd1fabb7SAndroid Build Coastguard Worker 
328*fd1fabb7SAndroid Build Coastguard Worker 	uint32 tileCount = TileCount ();
329*fd1fabb7SAndroid Build Coastguard Worker 
330*fd1fabb7SAndroid Build Coastguard Worker 	uint32 arrayCount = tileCount + (fJPEGTables.Get () ? 1 : 0);
331*fd1fabb7SAndroid Build Coastguard Worker 
332*fd1fabb7SAndroid Build Coastguard Worker 	AutoArray<dng_fingerprint> digests (arrayCount);
333*fd1fabb7SAndroid Build Coastguard Worker 
334*fd1fabb7SAndroid Build Coastguard Worker 	// Compute digest of each compressed tile.
335*fd1fabb7SAndroid Build Coastguard Worker 
336*fd1fabb7SAndroid Build Coastguard Worker 		{
337*fd1fabb7SAndroid Build Coastguard Worker 
338*fd1fabb7SAndroid Build Coastguard Worker 		uint32 threadCount = Min_uint32 (tileCount,
339*fd1fabb7SAndroid Build Coastguard Worker 										 host.PerformAreaTaskThreads ());
340*fd1fabb7SAndroid Build Coastguard Worker 
341*fd1fabb7SAndroid Build Coastguard Worker 		dng_jpeg_image_find_digest_task task (*this,
342*fd1fabb7SAndroid Build Coastguard Worker 											  tileCount,
343*fd1fabb7SAndroid Build Coastguard Worker 											  digests.Get ());
344*fd1fabb7SAndroid Build Coastguard Worker 
345*fd1fabb7SAndroid Build Coastguard Worker 		host.PerformAreaTask (task,
346*fd1fabb7SAndroid Build Coastguard Worker 							  dng_rect (0, 0, 16, 16 * threadCount));
347*fd1fabb7SAndroid Build Coastguard Worker 
348*fd1fabb7SAndroid Build Coastguard Worker 		}
349*fd1fabb7SAndroid Build Coastguard Worker 
350*fd1fabb7SAndroid Build Coastguard Worker 	// Compute digest of JPEG tables, if any.
351*fd1fabb7SAndroid Build Coastguard Worker 
352*fd1fabb7SAndroid Build Coastguard Worker 	if (fJPEGTables.Get ())
353*fd1fabb7SAndroid Build Coastguard Worker 		{
354*fd1fabb7SAndroid Build Coastguard Worker 
355*fd1fabb7SAndroid Build Coastguard Worker 		dng_md5_printer printer;
356*fd1fabb7SAndroid Build Coastguard Worker 
357*fd1fabb7SAndroid Build Coastguard Worker 		printer.Process (fJPEGTables->Buffer      (),
358*fd1fabb7SAndroid Build Coastguard Worker 						 fJPEGTables->LogicalSize ());
359*fd1fabb7SAndroid Build Coastguard Worker 
360*fd1fabb7SAndroid Build Coastguard Worker 		digests [tileCount] = printer.Result ();
361*fd1fabb7SAndroid Build Coastguard Worker 
362*fd1fabb7SAndroid Build Coastguard Worker 		}
363*fd1fabb7SAndroid Build Coastguard Worker 
364*fd1fabb7SAndroid Build Coastguard Worker 	// Combine digests into a single digest.
365*fd1fabb7SAndroid Build Coastguard Worker 
366*fd1fabb7SAndroid Build Coastguard Worker 		{
367*fd1fabb7SAndroid Build Coastguard Worker 
368*fd1fabb7SAndroid Build Coastguard Worker 		dng_md5_printer printer;
369*fd1fabb7SAndroid Build Coastguard Worker 
370*fd1fabb7SAndroid Build Coastguard Worker 		for (uint32 k = 0; k < arrayCount; k++)
371*fd1fabb7SAndroid Build Coastguard Worker 			{
372*fd1fabb7SAndroid Build Coastguard Worker 
373*fd1fabb7SAndroid Build Coastguard Worker 			printer.Process (digests [k].data,
374*fd1fabb7SAndroid Build Coastguard Worker 							 dng_fingerprint::kDNGFingerprintSize);
375*fd1fabb7SAndroid Build Coastguard Worker 
376*fd1fabb7SAndroid Build Coastguard Worker 			}
377*fd1fabb7SAndroid Build Coastguard Worker 
378*fd1fabb7SAndroid Build Coastguard Worker 		return printer.Result ();
379*fd1fabb7SAndroid Build Coastguard Worker 
380*fd1fabb7SAndroid Build Coastguard Worker 		}
381*fd1fabb7SAndroid Build Coastguard Worker 
382*fd1fabb7SAndroid Build Coastguard Worker 	}
383*fd1fabb7SAndroid Build Coastguard Worker 
384*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
385*fd1fabb7SAndroid Build Coastguard Worker 
386