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