1*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2*fd1fabb7SAndroid Build Coastguard Worker // Copyright 2006-2012 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_image_writer.cpp#4 $ */
10*fd1fabb7SAndroid Build Coastguard Worker /* $DateTime: 2012/06/14 20:24:41 $ */
11*fd1fabb7SAndroid Build Coastguard Worker /* $Change: 835078 $ */
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_image_writer.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_bottlenecks.h"
21*fd1fabb7SAndroid Build Coastguard Worker #include "dng_camera_profile.h"
22*fd1fabb7SAndroid Build Coastguard Worker #include "dng_color_space.h"
23*fd1fabb7SAndroid Build Coastguard Worker #include "dng_exif.h"
24*fd1fabb7SAndroid Build Coastguard Worker #include "dng_flags.h"
25*fd1fabb7SAndroid Build Coastguard Worker #include "dng_exceptions.h"
26*fd1fabb7SAndroid Build Coastguard Worker #include "dng_host.h"
27*fd1fabb7SAndroid Build Coastguard Worker #include "dng_ifd.h"
28*fd1fabb7SAndroid Build Coastguard Worker #include "dng_image.h"
29*fd1fabb7SAndroid Build Coastguard Worker #include "dng_jpeg_image.h"
30*fd1fabb7SAndroid Build Coastguard Worker #include "dng_lossless_jpeg.h"
31*fd1fabb7SAndroid Build Coastguard Worker #include "dng_memory.h"
32*fd1fabb7SAndroid Build Coastguard Worker #include "dng_memory_stream.h"
33*fd1fabb7SAndroid Build Coastguard Worker #include "dng_negative.h"
34*fd1fabb7SAndroid Build Coastguard Worker #include "dng_pixel_buffer.h"
35*fd1fabb7SAndroid Build Coastguard Worker #include "dng_preview.h"
36*fd1fabb7SAndroid Build Coastguard Worker #include "dng_read_image.h"
37*fd1fabb7SAndroid Build Coastguard Worker #include "dng_safe_arithmetic.h"
38*fd1fabb7SAndroid Build Coastguard Worker #include "dng_stream.h"
39*fd1fabb7SAndroid Build Coastguard Worker #include "dng_string_list.h"
40*fd1fabb7SAndroid Build Coastguard Worker #include "dng_tag_codes.h"
41*fd1fabb7SAndroid Build Coastguard Worker #include "dng_tag_values.h"
42*fd1fabb7SAndroid Build Coastguard Worker #include "dng_utils.h"
43*fd1fabb7SAndroid Build Coastguard Worker
44*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
45*fd1fabb7SAndroid Build Coastguard Worker #include "dng_xmp.h"
46*fd1fabb7SAndroid Build Coastguard Worker #endif
47*fd1fabb7SAndroid Build Coastguard Worker
48*fd1fabb7SAndroid Build Coastguard Worker #include "zlib.h"
49*fd1fabb7SAndroid Build Coastguard Worker
50*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseLibJPEG
51*fd1fabb7SAndroid Build Coastguard Worker #include "dng_jpeglib.h"
52*fd1fabb7SAndroid Build Coastguard Worker #endif
53*fd1fabb7SAndroid Build Coastguard Worker
54*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
55*fd1fabb7SAndroid Build Coastguard Worker
56*fd1fabb7SAndroid Build Coastguard Worker // Defines for testing DNG 1.2 features.
57*fd1fabb7SAndroid Build Coastguard Worker
58*fd1fabb7SAndroid Build Coastguard Worker //#define qTestRowInterleave 2
59*fd1fabb7SAndroid Build Coastguard Worker
60*fd1fabb7SAndroid Build Coastguard Worker //#define qTestSubTileBlockRows 2
61*fd1fabb7SAndroid Build Coastguard Worker //#define qTestSubTileBlockCols 2
62*fd1fabb7SAndroid Build Coastguard Worker
63*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
64*fd1fabb7SAndroid Build Coastguard Worker
dng_resolution()65*fd1fabb7SAndroid Build Coastguard Worker dng_resolution::dng_resolution ()
66*fd1fabb7SAndroid Build Coastguard Worker
67*fd1fabb7SAndroid Build Coastguard Worker : fXResolution ()
68*fd1fabb7SAndroid Build Coastguard Worker , fYResolution ()
69*fd1fabb7SAndroid Build Coastguard Worker
70*fd1fabb7SAndroid Build Coastguard Worker , fResolutionUnit (0)
71*fd1fabb7SAndroid Build Coastguard Worker
72*fd1fabb7SAndroid Build Coastguard Worker {
73*fd1fabb7SAndroid Build Coastguard Worker
74*fd1fabb7SAndroid Build Coastguard Worker }
75*fd1fabb7SAndroid Build Coastguard Worker
76*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
77*fd1fabb7SAndroid Build Coastguard Worker
SpoolAdobeData(dng_stream & stream,const dng_metadata * metadata,const dng_jpeg_preview * preview,const dng_memory_block * imageResources)78*fd1fabb7SAndroid Build Coastguard Worker static void SpoolAdobeData (dng_stream &stream,
79*fd1fabb7SAndroid Build Coastguard Worker const dng_metadata *metadata,
80*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *preview,
81*fd1fabb7SAndroid Build Coastguard Worker const dng_memory_block *imageResources)
82*fd1fabb7SAndroid Build Coastguard Worker {
83*fd1fabb7SAndroid Build Coastguard Worker
84*fd1fabb7SAndroid Build Coastguard Worker TempBigEndian tempEndian (stream);
85*fd1fabb7SAndroid Build Coastguard Worker
86*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
87*fd1fabb7SAndroid Build Coastguard Worker
88*fd1fabb7SAndroid Build Coastguard Worker if (metadata && metadata->GetXMP ())
89*fd1fabb7SAndroid Build Coastguard Worker {
90*fd1fabb7SAndroid Build Coastguard Worker
91*fd1fabb7SAndroid Build Coastguard Worker bool marked = false;
92*fd1fabb7SAndroid Build Coastguard Worker
93*fd1fabb7SAndroid Build Coastguard Worker if (metadata->GetXMP ()->GetBoolean (XMP_NS_XAP_RIGHTS,
94*fd1fabb7SAndroid Build Coastguard Worker "Marked",
95*fd1fabb7SAndroid Build Coastguard Worker marked))
96*fd1fabb7SAndroid Build Coastguard Worker {
97*fd1fabb7SAndroid Build Coastguard Worker
98*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (DNG_CHAR4 ('8','B','I','M'));
99*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (1034);
100*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (0);
101*fd1fabb7SAndroid Build Coastguard Worker
102*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (1);
103*fd1fabb7SAndroid Build Coastguard Worker
104*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (marked ? 1 : 0);
105*fd1fabb7SAndroid Build Coastguard Worker
106*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
107*fd1fabb7SAndroid Build Coastguard Worker
108*fd1fabb7SAndroid Build Coastguard Worker }
109*fd1fabb7SAndroid Build Coastguard Worker
110*fd1fabb7SAndroid Build Coastguard Worker dng_string webStatement;
111*fd1fabb7SAndroid Build Coastguard Worker
112*fd1fabb7SAndroid Build Coastguard Worker if (metadata->GetXMP ()->GetString (XMP_NS_XAP_RIGHTS,
113*fd1fabb7SAndroid Build Coastguard Worker "WebStatement",
114*fd1fabb7SAndroid Build Coastguard Worker webStatement))
115*fd1fabb7SAndroid Build Coastguard Worker {
116*fd1fabb7SAndroid Build Coastguard Worker
117*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data buffer;
118*fd1fabb7SAndroid Build Coastguard Worker
119*fd1fabb7SAndroid Build Coastguard Worker uint32 size = webStatement.Get_SystemEncoding (buffer);
120*fd1fabb7SAndroid Build Coastguard Worker
121*fd1fabb7SAndroid Build Coastguard Worker if (size > 0)
122*fd1fabb7SAndroid Build Coastguard Worker {
123*fd1fabb7SAndroid Build Coastguard Worker
124*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (DNG_CHAR4 ('8','B','I','M'));
125*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (1035);
126*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (0);
127*fd1fabb7SAndroid Build Coastguard Worker
128*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (size);
129*fd1fabb7SAndroid Build Coastguard Worker
130*fd1fabb7SAndroid Build Coastguard Worker stream.Put (buffer.Buffer (), size);
131*fd1fabb7SAndroid Build Coastguard Worker
132*fd1fabb7SAndroid Build Coastguard Worker if (size & 1)
133*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
134*fd1fabb7SAndroid Build Coastguard Worker
135*fd1fabb7SAndroid Build Coastguard Worker }
136*fd1fabb7SAndroid Build Coastguard Worker
137*fd1fabb7SAndroid Build Coastguard Worker }
138*fd1fabb7SAndroid Build Coastguard Worker
139*fd1fabb7SAndroid Build Coastguard Worker }
140*fd1fabb7SAndroid Build Coastguard Worker
141*fd1fabb7SAndroid Build Coastguard Worker #endif
142*fd1fabb7SAndroid Build Coastguard Worker
143*fd1fabb7SAndroid Build Coastguard Worker if (preview)
144*fd1fabb7SAndroid Build Coastguard Worker {
145*fd1fabb7SAndroid Build Coastguard Worker
146*fd1fabb7SAndroid Build Coastguard Worker preview->SpoolAdobeThumbnail (stream);
147*fd1fabb7SAndroid Build Coastguard Worker
148*fd1fabb7SAndroid Build Coastguard Worker }
149*fd1fabb7SAndroid Build Coastguard Worker
150*fd1fabb7SAndroid Build Coastguard Worker if (metadata && metadata->IPTCLength ())
151*fd1fabb7SAndroid Build Coastguard Worker {
152*fd1fabb7SAndroid Build Coastguard Worker
153*fd1fabb7SAndroid Build Coastguard Worker dng_fingerprint iptcDigest = metadata->IPTCDigest ();
154*fd1fabb7SAndroid Build Coastguard Worker
155*fd1fabb7SAndroid Build Coastguard Worker if (iptcDigest.IsValid ())
156*fd1fabb7SAndroid Build Coastguard Worker {
157*fd1fabb7SAndroid Build Coastguard Worker
158*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (DNG_CHAR4 ('8','B','I','M'));
159*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (1061);
160*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (0);
161*fd1fabb7SAndroid Build Coastguard Worker
162*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (16);
163*fd1fabb7SAndroid Build Coastguard Worker
164*fd1fabb7SAndroid Build Coastguard Worker stream.Put (iptcDigest.data, 16);
165*fd1fabb7SAndroid Build Coastguard Worker
166*fd1fabb7SAndroid Build Coastguard Worker }
167*fd1fabb7SAndroid Build Coastguard Worker
168*fd1fabb7SAndroid Build Coastguard Worker }
169*fd1fabb7SAndroid Build Coastguard Worker
170*fd1fabb7SAndroid Build Coastguard Worker if (imageResources)
171*fd1fabb7SAndroid Build Coastguard Worker {
172*fd1fabb7SAndroid Build Coastguard Worker
173*fd1fabb7SAndroid Build Coastguard Worker uint32 size = imageResources->LogicalSize ();
174*fd1fabb7SAndroid Build Coastguard Worker
175*fd1fabb7SAndroid Build Coastguard Worker stream.Put (imageResources->Buffer (), size);
176*fd1fabb7SAndroid Build Coastguard Worker
177*fd1fabb7SAndroid Build Coastguard Worker if (size & 1)
178*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
179*fd1fabb7SAndroid Build Coastguard Worker
180*fd1fabb7SAndroid Build Coastguard Worker }
181*fd1fabb7SAndroid Build Coastguard Worker
182*fd1fabb7SAndroid Build Coastguard Worker }
183*fd1fabb7SAndroid Build Coastguard Worker
184*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
185*fd1fabb7SAndroid Build Coastguard Worker
BuildAdobeData(dng_host & host,const dng_metadata * metadata,const dng_jpeg_preview * preview,const dng_memory_block * imageResources)186*fd1fabb7SAndroid Build Coastguard Worker static dng_memory_block * BuildAdobeData (dng_host &host,
187*fd1fabb7SAndroid Build Coastguard Worker const dng_metadata *metadata,
188*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *preview,
189*fd1fabb7SAndroid Build Coastguard Worker const dng_memory_block *imageResources)
190*fd1fabb7SAndroid Build Coastguard Worker {
191*fd1fabb7SAndroid Build Coastguard Worker
192*fd1fabb7SAndroid Build Coastguard Worker dng_memory_stream stream (host.Allocator ());
193*fd1fabb7SAndroid Build Coastguard Worker
194*fd1fabb7SAndroid Build Coastguard Worker SpoolAdobeData (stream,
195*fd1fabb7SAndroid Build Coastguard Worker metadata,
196*fd1fabb7SAndroid Build Coastguard Worker preview,
197*fd1fabb7SAndroid Build Coastguard Worker imageResources);
198*fd1fabb7SAndroid Build Coastguard Worker
199*fd1fabb7SAndroid Build Coastguard Worker return stream.AsMemoryBlock (host.Allocator ());
200*fd1fabb7SAndroid Build Coastguard Worker
201*fd1fabb7SAndroid Build Coastguard Worker }
202*fd1fabb7SAndroid Build Coastguard Worker
203*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
204*fd1fabb7SAndroid Build Coastguard Worker
tag_string(uint16 code,const dng_string & s,bool forceASCII)205*fd1fabb7SAndroid Build Coastguard Worker tag_string::tag_string (uint16 code,
206*fd1fabb7SAndroid Build Coastguard Worker const dng_string &s,
207*fd1fabb7SAndroid Build Coastguard Worker bool forceASCII)
208*fd1fabb7SAndroid Build Coastguard Worker
209*fd1fabb7SAndroid Build Coastguard Worker : tiff_tag (code, ttAscii, 0)
210*fd1fabb7SAndroid Build Coastguard Worker
211*fd1fabb7SAndroid Build Coastguard Worker , fString (s)
212*fd1fabb7SAndroid Build Coastguard Worker
213*fd1fabb7SAndroid Build Coastguard Worker {
214*fd1fabb7SAndroid Build Coastguard Worker
215*fd1fabb7SAndroid Build Coastguard Worker if (forceASCII)
216*fd1fabb7SAndroid Build Coastguard Worker {
217*fd1fabb7SAndroid Build Coastguard Worker
218*fd1fabb7SAndroid Build Coastguard Worker // Metadata working group recommendation - go ahead
219*fd1fabb7SAndroid Build Coastguard Worker // write UTF-8 into ASCII tag strings, rather than
220*fd1fabb7SAndroid Build Coastguard Worker // actually force the strings to ASCII. There is a matching
221*fd1fabb7SAndroid Build Coastguard Worker // change on the reading side to assume UTF-8 if the string
222*fd1fabb7SAndroid Build Coastguard Worker // contains a valid UTF-8 string.
223*fd1fabb7SAndroid Build Coastguard Worker //
224*fd1fabb7SAndroid Build Coastguard Worker // fString.ForceASCII ();
225*fd1fabb7SAndroid Build Coastguard Worker
226*fd1fabb7SAndroid Build Coastguard Worker }
227*fd1fabb7SAndroid Build Coastguard Worker
228*fd1fabb7SAndroid Build Coastguard Worker else if (!fString.IsASCII ())
229*fd1fabb7SAndroid Build Coastguard Worker {
230*fd1fabb7SAndroid Build Coastguard Worker
231*fd1fabb7SAndroid Build Coastguard Worker fType = ttByte;
232*fd1fabb7SAndroid Build Coastguard Worker
233*fd1fabb7SAndroid Build Coastguard Worker }
234*fd1fabb7SAndroid Build Coastguard Worker
235*fd1fabb7SAndroid Build Coastguard Worker fCount = fString.Length () + 1;
236*fd1fabb7SAndroid Build Coastguard Worker
237*fd1fabb7SAndroid Build Coastguard Worker }
238*fd1fabb7SAndroid Build Coastguard Worker
239*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
240*fd1fabb7SAndroid Build Coastguard Worker
Put(dng_stream & stream) const241*fd1fabb7SAndroid Build Coastguard Worker void tag_string::Put (dng_stream &stream) const
242*fd1fabb7SAndroid Build Coastguard Worker {
243*fd1fabb7SAndroid Build Coastguard Worker
244*fd1fabb7SAndroid Build Coastguard Worker stream.Put (fString.Get (), Size ());
245*fd1fabb7SAndroid Build Coastguard Worker
246*fd1fabb7SAndroid Build Coastguard Worker }
247*fd1fabb7SAndroid Build Coastguard Worker
248*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
249*fd1fabb7SAndroid Build Coastguard Worker
tag_encoded_text(uint16 code,const dng_string & text)250*fd1fabb7SAndroid Build Coastguard Worker tag_encoded_text::tag_encoded_text (uint16 code,
251*fd1fabb7SAndroid Build Coastguard Worker const dng_string &text)
252*fd1fabb7SAndroid Build Coastguard Worker
253*fd1fabb7SAndroid Build Coastguard Worker : tiff_tag (code, ttUndefined, 0)
254*fd1fabb7SAndroid Build Coastguard Worker
255*fd1fabb7SAndroid Build Coastguard Worker , fText (text)
256*fd1fabb7SAndroid Build Coastguard Worker
257*fd1fabb7SAndroid Build Coastguard Worker , fUTF16 ()
258*fd1fabb7SAndroid Build Coastguard Worker
259*fd1fabb7SAndroid Build Coastguard Worker {
260*fd1fabb7SAndroid Build Coastguard Worker
261*fd1fabb7SAndroid Build Coastguard Worker if (fText.IsASCII ())
262*fd1fabb7SAndroid Build Coastguard Worker {
263*fd1fabb7SAndroid Build Coastguard Worker
264*fd1fabb7SAndroid Build Coastguard Worker fCount = 8 + fText.Length ();
265*fd1fabb7SAndroid Build Coastguard Worker
266*fd1fabb7SAndroid Build Coastguard Worker }
267*fd1fabb7SAndroid Build Coastguard Worker
268*fd1fabb7SAndroid Build Coastguard Worker else
269*fd1fabb7SAndroid Build Coastguard Worker {
270*fd1fabb7SAndroid Build Coastguard Worker
271*fd1fabb7SAndroid Build Coastguard Worker fCount = 8 + fText.Get_UTF16 (fUTF16) * 2;
272*fd1fabb7SAndroid Build Coastguard Worker
273*fd1fabb7SAndroid Build Coastguard Worker }
274*fd1fabb7SAndroid Build Coastguard Worker
275*fd1fabb7SAndroid Build Coastguard Worker }
276*fd1fabb7SAndroid Build Coastguard Worker
277*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
278*fd1fabb7SAndroid Build Coastguard Worker
Put(dng_stream & stream) const279*fd1fabb7SAndroid Build Coastguard Worker void tag_encoded_text::Put (dng_stream &stream) const
280*fd1fabb7SAndroid Build Coastguard Worker {
281*fd1fabb7SAndroid Build Coastguard Worker
282*fd1fabb7SAndroid Build Coastguard Worker if (fUTF16.Buffer ())
283*fd1fabb7SAndroid Build Coastguard Worker {
284*fd1fabb7SAndroid Build Coastguard Worker
285*fd1fabb7SAndroid Build Coastguard Worker stream.Put ("UNICODE\000", 8);
286*fd1fabb7SAndroid Build Coastguard Worker
287*fd1fabb7SAndroid Build Coastguard Worker uint32 chars = (fCount - 8) >> 1;
288*fd1fabb7SAndroid Build Coastguard Worker
289*fd1fabb7SAndroid Build Coastguard Worker const uint16 *buf = fUTF16.Buffer_uint16 ();
290*fd1fabb7SAndroid Build Coastguard Worker
291*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < chars; j++)
292*fd1fabb7SAndroid Build Coastguard Worker {
293*fd1fabb7SAndroid Build Coastguard Worker
294*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (buf [j]);
295*fd1fabb7SAndroid Build Coastguard Worker
296*fd1fabb7SAndroid Build Coastguard Worker }
297*fd1fabb7SAndroid Build Coastguard Worker
298*fd1fabb7SAndroid Build Coastguard Worker }
299*fd1fabb7SAndroid Build Coastguard Worker
300*fd1fabb7SAndroid Build Coastguard Worker else
301*fd1fabb7SAndroid Build Coastguard Worker {
302*fd1fabb7SAndroid Build Coastguard Worker
303*fd1fabb7SAndroid Build Coastguard Worker stream.Put ("ASCII\000\000\000", 8);
304*fd1fabb7SAndroid Build Coastguard Worker
305*fd1fabb7SAndroid Build Coastguard Worker stream.Put (fText.Get (), fCount - 8);
306*fd1fabb7SAndroid Build Coastguard Worker
307*fd1fabb7SAndroid Build Coastguard Worker }
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
Put(dng_stream & stream) const313*fd1fabb7SAndroid Build Coastguard Worker void tag_data_ptr::Put (dng_stream &stream) const
314*fd1fabb7SAndroid Build Coastguard Worker {
315*fd1fabb7SAndroid Build Coastguard Worker
316*fd1fabb7SAndroid Build Coastguard Worker // If we are swapping bytes, we need to swap with the right size
317*fd1fabb7SAndroid Build Coastguard Worker // entries.
318*fd1fabb7SAndroid Build Coastguard Worker
319*fd1fabb7SAndroid Build Coastguard Worker if (stream.SwapBytes ())
320*fd1fabb7SAndroid Build Coastguard Worker {
321*fd1fabb7SAndroid Build Coastguard Worker
322*fd1fabb7SAndroid Build Coastguard Worker switch (Type ())
323*fd1fabb7SAndroid Build Coastguard Worker {
324*fd1fabb7SAndroid Build Coastguard Worker
325*fd1fabb7SAndroid Build Coastguard Worker // Two byte entries.
326*fd1fabb7SAndroid Build Coastguard Worker
327*fd1fabb7SAndroid Build Coastguard Worker case ttShort:
328*fd1fabb7SAndroid Build Coastguard Worker case ttSShort:
329*fd1fabb7SAndroid Build Coastguard Worker case ttUnicode:
330*fd1fabb7SAndroid Build Coastguard Worker {
331*fd1fabb7SAndroid Build Coastguard Worker
332*fd1fabb7SAndroid Build Coastguard Worker const uint16 *p = (const uint16 *) fData;
333*fd1fabb7SAndroid Build Coastguard Worker
334*fd1fabb7SAndroid Build Coastguard Worker uint32 entries = (Size () >> 1);
335*fd1fabb7SAndroid Build Coastguard Worker
336*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < entries; j++)
337*fd1fabb7SAndroid Build Coastguard Worker {
338*fd1fabb7SAndroid Build Coastguard Worker
339*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (p [j]);
340*fd1fabb7SAndroid Build Coastguard Worker
341*fd1fabb7SAndroid Build Coastguard Worker }
342*fd1fabb7SAndroid Build Coastguard Worker
343*fd1fabb7SAndroid Build Coastguard Worker return;
344*fd1fabb7SAndroid Build Coastguard Worker
345*fd1fabb7SAndroid Build Coastguard Worker }
346*fd1fabb7SAndroid Build Coastguard Worker
347*fd1fabb7SAndroid Build Coastguard Worker // Four byte entries.
348*fd1fabb7SAndroid Build Coastguard Worker
349*fd1fabb7SAndroid Build Coastguard Worker case ttLong:
350*fd1fabb7SAndroid Build Coastguard Worker case ttSLong:
351*fd1fabb7SAndroid Build Coastguard Worker case ttRational:
352*fd1fabb7SAndroid Build Coastguard Worker case ttSRational:
353*fd1fabb7SAndroid Build Coastguard Worker case ttIFD:
354*fd1fabb7SAndroid Build Coastguard Worker case ttFloat:
355*fd1fabb7SAndroid Build Coastguard Worker case ttComplex:
356*fd1fabb7SAndroid Build Coastguard Worker {
357*fd1fabb7SAndroid Build Coastguard Worker
358*fd1fabb7SAndroid Build Coastguard Worker const uint32 *p = (const uint32 *) fData;
359*fd1fabb7SAndroid Build Coastguard Worker
360*fd1fabb7SAndroid Build Coastguard Worker uint32 entries = (Size () >> 2);
361*fd1fabb7SAndroid Build Coastguard Worker
362*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < entries; j++)
363*fd1fabb7SAndroid Build Coastguard Worker {
364*fd1fabb7SAndroid Build Coastguard Worker
365*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (p [j]);
366*fd1fabb7SAndroid Build Coastguard Worker
367*fd1fabb7SAndroid Build Coastguard Worker }
368*fd1fabb7SAndroid Build Coastguard Worker
369*fd1fabb7SAndroid Build Coastguard Worker return;
370*fd1fabb7SAndroid Build Coastguard Worker
371*fd1fabb7SAndroid Build Coastguard Worker }
372*fd1fabb7SAndroid Build Coastguard Worker
373*fd1fabb7SAndroid Build Coastguard Worker // Eight byte entries.
374*fd1fabb7SAndroid Build Coastguard Worker
375*fd1fabb7SAndroid Build Coastguard Worker case ttDouble:
376*fd1fabb7SAndroid Build Coastguard Worker {
377*fd1fabb7SAndroid Build Coastguard Worker
378*fd1fabb7SAndroid Build Coastguard Worker const real64 *p = (const real64 *) fData;
379*fd1fabb7SAndroid Build Coastguard Worker
380*fd1fabb7SAndroid Build Coastguard Worker uint32 entries = (Size () >> 3);
381*fd1fabb7SAndroid Build Coastguard Worker
382*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < entries; j++)
383*fd1fabb7SAndroid Build Coastguard Worker {
384*fd1fabb7SAndroid Build Coastguard Worker
385*fd1fabb7SAndroid Build Coastguard Worker stream.Put_real64 (p [j]);
386*fd1fabb7SAndroid Build Coastguard Worker
387*fd1fabb7SAndroid Build Coastguard Worker }
388*fd1fabb7SAndroid Build Coastguard Worker
389*fd1fabb7SAndroid Build Coastguard Worker return;
390*fd1fabb7SAndroid Build Coastguard Worker
391*fd1fabb7SAndroid Build Coastguard Worker }
392*fd1fabb7SAndroid Build Coastguard Worker
393*fd1fabb7SAndroid Build Coastguard Worker // Entries don't need to be byte swapped. Fall through
394*fd1fabb7SAndroid Build Coastguard Worker // to non-byte swapped case.
395*fd1fabb7SAndroid Build Coastguard Worker
396*fd1fabb7SAndroid Build Coastguard Worker default:
397*fd1fabb7SAndroid Build Coastguard Worker {
398*fd1fabb7SAndroid Build Coastguard Worker
399*fd1fabb7SAndroid Build Coastguard Worker break;
400*fd1fabb7SAndroid Build Coastguard Worker
401*fd1fabb7SAndroid Build Coastguard Worker }
402*fd1fabb7SAndroid Build Coastguard Worker
403*fd1fabb7SAndroid Build Coastguard Worker }
404*fd1fabb7SAndroid Build Coastguard Worker
405*fd1fabb7SAndroid Build Coastguard Worker }
406*fd1fabb7SAndroid Build Coastguard Worker
407*fd1fabb7SAndroid Build Coastguard Worker // Non-byte swapped case.
408*fd1fabb7SAndroid Build Coastguard Worker
409*fd1fabb7SAndroid Build Coastguard Worker stream.Put (fData, Size ());
410*fd1fabb7SAndroid Build Coastguard Worker
411*fd1fabb7SAndroid Build Coastguard Worker }
412*fd1fabb7SAndroid Build Coastguard Worker
413*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
414*fd1fabb7SAndroid Build Coastguard Worker
tag_matrix(uint16 code,const dng_matrix & m)415*fd1fabb7SAndroid Build Coastguard Worker tag_matrix::tag_matrix (uint16 code,
416*fd1fabb7SAndroid Build Coastguard Worker const dng_matrix &m)
417*fd1fabb7SAndroid Build Coastguard Worker
418*fd1fabb7SAndroid Build Coastguard Worker : tag_srational_ptr (code, fEntry, m.Rows () * m.Cols ())
419*fd1fabb7SAndroid Build Coastguard Worker
420*fd1fabb7SAndroid Build Coastguard Worker {
421*fd1fabb7SAndroid Build Coastguard Worker
422*fd1fabb7SAndroid Build Coastguard Worker uint32 index = 0;
423*fd1fabb7SAndroid Build Coastguard Worker
424*fd1fabb7SAndroid Build Coastguard Worker for (uint32 r = 0; r < m.Rows (); r++)
425*fd1fabb7SAndroid Build Coastguard Worker for (uint32 c = 0; c < m.Cols (); c++)
426*fd1fabb7SAndroid Build Coastguard Worker {
427*fd1fabb7SAndroid Build Coastguard Worker
428*fd1fabb7SAndroid Build Coastguard Worker fEntry [index].Set_real64 (m [r] [c], 10000);
429*fd1fabb7SAndroid Build Coastguard Worker
430*fd1fabb7SAndroid Build Coastguard Worker index++;
431*fd1fabb7SAndroid Build Coastguard Worker
432*fd1fabb7SAndroid Build Coastguard Worker }
433*fd1fabb7SAndroid Build Coastguard Worker
434*fd1fabb7SAndroid Build Coastguard Worker }
435*fd1fabb7SAndroid Build Coastguard Worker
436*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
437*fd1fabb7SAndroid Build Coastguard Worker
tag_icc_profile(const void * profileData,uint32 profileSize)438*fd1fabb7SAndroid Build Coastguard Worker tag_icc_profile::tag_icc_profile (const void *profileData,
439*fd1fabb7SAndroid Build Coastguard Worker uint32 profileSize)
440*fd1fabb7SAndroid Build Coastguard Worker
441*fd1fabb7SAndroid Build Coastguard Worker : tag_data_ptr (tcICCProfile,
442*fd1fabb7SAndroid Build Coastguard Worker ttUndefined,
443*fd1fabb7SAndroid Build Coastguard Worker 0,
444*fd1fabb7SAndroid Build Coastguard Worker NULL)
445*fd1fabb7SAndroid Build Coastguard Worker
446*fd1fabb7SAndroid Build Coastguard Worker {
447*fd1fabb7SAndroid Build Coastguard Worker
448*fd1fabb7SAndroid Build Coastguard Worker if (profileData && profileSize)
449*fd1fabb7SAndroid Build Coastguard Worker {
450*fd1fabb7SAndroid Build Coastguard Worker
451*fd1fabb7SAndroid Build Coastguard Worker SetCount (profileSize);
452*fd1fabb7SAndroid Build Coastguard Worker SetData (profileData);
453*fd1fabb7SAndroid Build Coastguard Worker
454*fd1fabb7SAndroid Build Coastguard Worker }
455*fd1fabb7SAndroid Build Coastguard Worker
456*fd1fabb7SAndroid Build Coastguard Worker }
457*fd1fabb7SAndroid Build Coastguard Worker
458*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
459*fd1fabb7SAndroid Build Coastguard Worker
Put(dng_stream & stream) const460*fd1fabb7SAndroid Build Coastguard Worker void tag_cfa_pattern::Put (dng_stream &stream) const
461*fd1fabb7SAndroid Build Coastguard Worker {
462*fd1fabb7SAndroid Build Coastguard Worker
463*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 ((uint16) fCols);
464*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 ((uint16) fRows);
465*fd1fabb7SAndroid Build Coastguard Worker
466*fd1fabb7SAndroid Build Coastguard Worker for (uint32 col = 0; col < fCols; col++)
467*fd1fabb7SAndroid Build Coastguard Worker for (uint32 row = 0; row < fRows; row++)
468*fd1fabb7SAndroid Build Coastguard Worker {
469*fd1fabb7SAndroid Build Coastguard Worker
470*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (fPattern [row * kMaxCFAPattern + col]);
471*fd1fabb7SAndroid Build Coastguard Worker
472*fd1fabb7SAndroid Build Coastguard Worker }
473*fd1fabb7SAndroid Build Coastguard Worker
474*fd1fabb7SAndroid Build Coastguard Worker }
475*fd1fabb7SAndroid Build Coastguard Worker
476*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
477*fd1fabb7SAndroid Build Coastguard Worker
tag_exif_date_time(uint16 code,const dng_date_time & dt)478*fd1fabb7SAndroid Build Coastguard Worker tag_exif_date_time::tag_exif_date_time (uint16 code,
479*fd1fabb7SAndroid Build Coastguard Worker const dng_date_time &dt)
480*fd1fabb7SAndroid Build Coastguard Worker
481*fd1fabb7SAndroid Build Coastguard Worker : tag_data_ptr (code, ttAscii, 20, fData)
482*fd1fabb7SAndroid Build Coastguard Worker
483*fd1fabb7SAndroid Build Coastguard Worker {
484*fd1fabb7SAndroid Build Coastguard Worker
485*fd1fabb7SAndroid Build Coastguard Worker if (dt.IsValid ())
486*fd1fabb7SAndroid Build Coastguard Worker {
487*fd1fabb7SAndroid Build Coastguard Worker
488*fd1fabb7SAndroid Build Coastguard Worker sprintf (fData,
489*fd1fabb7SAndroid Build Coastguard Worker "%04d:%02d:%02d %02d:%02d:%02d",
490*fd1fabb7SAndroid Build Coastguard Worker (int) dt.fYear,
491*fd1fabb7SAndroid Build Coastguard Worker (int) dt.fMonth,
492*fd1fabb7SAndroid Build Coastguard Worker (int) dt.fDay,
493*fd1fabb7SAndroid Build Coastguard Worker (int) dt.fHour,
494*fd1fabb7SAndroid Build Coastguard Worker (int) dt.fMinute,
495*fd1fabb7SAndroid Build Coastguard Worker (int) dt.fSecond);
496*fd1fabb7SAndroid Build Coastguard Worker
497*fd1fabb7SAndroid Build Coastguard Worker }
498*fd1fabb7SAndroid Build Coastguard Worker
499*fd1fabb7SAndroid Build Coastguard Worker }
500*fd1fabb7SAndroid Build Coastguard Worker
501*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
502*fd1fabb7SAndroid Build Coastguard Worker
tag_iptc(const void * data,uint32 length)503*fd1fabb7SAndroid Build Coastguard Worker tag_iptc::tag_iptc (const void *data,
504*fd1fabb7SAndroid Build Coastguard Worker uint32 length)
505*fd1fabb7SAndroid Build Coastguard Worker
506*fd1fabb7SAndroid Build Coastguard Worker : tiff_tag (tcIPTC_NAA, ttLong, (length + 3) >> 2)
507*fd1fabb7SAndroid Build Coastguard Worker
508*fd1fabb7SAndroid Build Coastguard Worker , fData (data )
509*fd1fabb7SAndroid Build Coastguard Worker , fLength (length)
510*fd1fabb7SAndroid Build Coastguard Worker
511*fd1fabb7SAndroid Build Coastguard Worker {
512*fd1fabb7SAndroid Build Coastguard Worker
513*fd1fabb7SAndroid Build Coastguard Worker }
514*fd1fabb7SAndroid Build Coastguard Worker
515*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
516*fd1fabb7SAndroid Build Coastguard Worker
Put(dng_stream & stream) const517*fd1fabb7SAndroid Build Coastguard Worker void tag_iptc::Put (dng_stream &stream) const
518*fd1fabb7SAndroid Build Coastguard Worker {
519*fd1fabb7SAndroid Build Coastguard Worker
520*fd1fabb7SAndroid Build Coastguard Worker // Note: For historical compatiblity reasons, the standard TIFF data
521*fd1fabb7SAndroid Build Coastguard Worker // type for IPTC data is ttLong, but without byte swapping. This really
522*fd1fabb7SAndroid Build Coastguard Worker // should be ttUndefined, but doing the right thing would break some
523*fd1fabb7SAndroid Build Coastguard Worker // existing readers.
524*fd1fabb7SAndroid Build Coastguard Worker
525*fd1fabb7SAndroid Build Coastguard Worker stream.Put (fData, fLength);
526*fd1fabb7SAndroid Build Coastguard Worker
527*fd1fabb7SAndroid Build Coastguard Worker // Pad with zeros to get to long word boundary.
528*fd1fabb7SAndroid Build Coastguard Worker
529*fd1fabb7SAndroid Build Coastguard Worker uint32 extra = fCount * 4 - fLength;
530*fd1fabb7SAndroid Build Coastguard Worker
531*fd1fabb7SAndroid Build Coastguard Worker while (extra--)
532*fd1fabb7SAndroid Build Coastguard Worker {
533*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
534*fd1fabb7SAndroid Build Coastguard Worker }
535*fd1fabb7SAndroid Build Coastguard Worker
536*fd1fabb7SAndroid Build Coastguard Worker }
537*fd1fabb7SAndroid Build Coastguard Worker
538*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
539*fd1fabb7SAndroid Build Coastguard Worker
tag_xmp(const dng_xmp * xmp)540*fd1fabb7SAndroid Build Coastguard Worker tag_xmp::tag_xmp (const dng_xmp *xmp)
541*fd1fabb7SAndroid Build Coastguard Worker
542*fd1fabb7SAndroid Build Coastguard Worker : tag_uint8_ptr (tcXMP, NULL, 0)
543*fd1fabb7SAndroid Build Coastguard Worker
544*fd1fabb7SAndroid Build Coastguard Worker , fBuffer ()
545*fd1fabb7SAndroid Build Coastguard Worker
546*fd1fabb7SAndroid Build Coastguard Worker {
547*fd1fabb7SAndroid Build Coastguard Worker
548*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
549*fd1fabb7SAndroid Build Coastguard Worker
550*fd1fabb7SAndroid Build Coastguard Worker if (xmp)
551*fd1fabb7SAndroid Build Coastguard Worker {
552*fd1fabb7SAndroid Build Coastguard Worker
553*fd1fabb7SAndroid Build Coastguard Worker fBuffer.Reset (xmp->Serialize (true));
554*fd1fabb7SAndroid Build Coastguard Worker
555*fd1fabb7SAndroid Build Coastguard Worker if (fBuffer.Get ())
556*fd1fabb7SAndroid Build Coastguard Worker {
557*fd1fabb7SAndroid Build Coastguard Worker
558*fd1fabb7SAndroid Build Coastguard Worker SetData (fBuffer->Buffer_uint8 ());
559*fd1fabb7SAndroid Build Coastguard Worker
560*fd1fabb7SAndroid Build Coastguard Worker SetCount (fBuffer->LogicalSize ());
561*fd1fabb7SAndroid Build Coastguard Worker
562*fd1fabb7SAndroid Build Coastguard Worker }
563*fd1fabb7SAndroid Build Coastguard Worker
564*fd1fabb7SAndroid Build Coastguard Worker }
565*fd1fabb7SAndroid Build Coastguard Worker
566*fd1fabb7SAndroid Build Coastguard Worker #endif
567*fd1fabb7SAndroid Build Coastguard Worker
568*fd1fabb7SAndroid Build Coastguard Worker }
569*fd1fabb7SAndroid Build Coastguard Worker
570*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
571*fd1fabb7SAndroid Build Coastguard Worker
Add(const tiff_tag * tag)572*fd1fabb7SAndroid Build Coastguard Worker void dng_tiff_directory::Add (const tiff_tag *tag)
573*fd1fabb7SAndroid Build Coastguard Worker {
574*fd1fabb7SAndroid Build Coastguard Worker
575*fd1fabb7SAndroid Build Coastguard Worker if (fEntries >= kMaxEntries)
576*fd1fabb7SAndroid Build Coastguard Worker {
577*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
578*fd1fabb7SAndroid Build Coastguard Worker }
579*fd1fabb7SAndroid Build Coastguard Worker
580*fd1fabb7SAndroid Build Coastguard Worker // Tags must be sorted in increasing order of tag code.
581*fd1fabb7SAndroid Build Coastguard Worker
582*fd1fabb7SAndroid Build Coastguard Worker uint32 index = fEntries;
583*fd1fabb7SAndroid Build Coastguard Worker
584*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < fEntries; j++)
585*fd1fabb7SAndroid Build Coastguard Worker {
586*fd1fabb7SAndroid Build Coastguard Worker
587*fd1fabb7SAndroid Build Coastguard Worker if (tag->Code () < fTag [j]->Code ())
588*fd1fabb7SAndroid Build Coastguard Worker {
589*fd1fabb7SAndroid Build Coastguard Worker index = j;
590*fd1fabb7SAndroid Build Coastguard Worker break;
591*fd1fabb7SAndroid Build Coastguard Worker }
592*fd1fabb7SAndroid Build Coastguard Worker
593*fd1fabb7SAndroid Build Coastguard Worker }
594*fd1fabb7SAndroid Build Coastguard Worker
595*fd1fabb7SAndroid Build Coastguard Worker for (uint32 k = fEntries; k > index; k--)
596*fd1fabb7SAndroid Build Coastguard Worker {
597*fd1fabb7SAndroid Build Coastguard Worker
598*fd1fabb7SAndroid Build Coastguard Worker fTag [k] = fTag [k - 1];
599*fd1fabb7SAndroid Build Coastguard Worker
600*fd1fabb7SAndroid Build Coastguard Worker }
601*fd1fabb7SAndroid Build Coastguard Worker
602*fd1fabb7SAndroid Build Coastguard Worker fTag [index] = tag;
603*fd1fabb7SAndroid Build Coastguard Worker
604*fd1fabb7SAndroid Build Coastguard Worker fEntries++;
605*fd1fabb7SAndroid Build Coastguard Worker
606*fd1fabb7SAndroid Build Coastguard Worker }
607*fd1fabb7SAndroid Build Coastguard Worker
608*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
609*fd1fabb7SAndroid Build Coastguard Worker
Size() const610*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_tiff_directory::Size () const
611*fd1fabb7SAndroid Build Coastguard Worker {
612*fd1fabb7SAndroid Build Coastguard Worker
613*fd1fabb7SAndroid Build Coastguard Worker if (!fEntries) return 0;
614*fd1fabb7SAndroid Build Coastguard Worker
615*fd1fabb7SAndroid Build Coastguard Worker uint32 size = fEntries * 12 + 6;
616*fd1fabb7SAndroid Build Coastguard Worker
617*fd1fabb7SAndroid Build Coastguard Worker for (uint32 index = 0; index < fEntries; index++)
618*fd1fabb7SAndroid Build Coastguard Worker {
619*fd1fabb7SAndroid Build Coastguard Worker
620*fd1fabb7SAndroid Build Coastguard Worker uint32 tagSize = fTag [index]->Size ();
621*fd1fabb7SAndroid Build Coastguard Worker
622*fd1fabb7SAndroid Build Coastguard Worker if (tagSize > 4)
623*fd1fabb7SAndroid Build Coastguard Worker {
624*fd1fabb7SAndroid Build Coastguard Worker
625*fd1fabb7SAndroid Build Coastguard Worker size += (tagSize + 1) & ~1;
626*fd1fabb7SAndroid Build Coastguard Worker
627*fd1fabb7SAndroid Build Coastguard Worker }
628*fd1fabb7SAndroid Build Coastguard Worker
629*fd1fabb7SAndroid Build Coastguard Worker }
630*fd1fabb7SAndroid Build Coastguard Worker
631*fd1fabb7SAndroid Build Coastguard Worker return size;
632*fd1fabb7SAndroid Build Coastguard Worker
633*fd1fabb7SAndroid Build Coastguard Worker }
634*fd1fabb7SAndroid Build Coastguard Worker
635*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
636*fd1fabb7SAndroid Build Coastguard Worker
Put(dng_stream & stream,OffsetsBase offsetsBase,uint32 explicitBase) const637*fd1fabb7SAndroid Build Coastguard Worker void dng_tiff_directory::Put (dng_stream &stream,
638*fd1fabb7SAndroid Build Coastguard Worker OffsetsBase offsetsBase,
639*fd1fabb7SAndroid Build Coastguard Worker uint32 explicitBase) const
640*fd1fabb7SAndroid Build Coastguard Worker {
641*fd1fabb7SAndroid Build Coastguard Worker
642*fd1fabb7SAndroid Build Coastguard Worker if (!fEntries) return;
643*fd1fabb7SAndroid Build Coastguard Worker
644*fd1fabb7SAndroid Build Coastguard Worker uint32 index;
645*fd1fabb7SAndroid Build Coastguard Worker
646*fd1fabb7SAndroid Build Coastguard Worker uint32 bigData = fEntries * 12 + 6;
647*fd1fabb7SAndroid Build Coastguard Worker
648*fd1fabb7SAndroid Build Coastguard Worker if (offsetsBase == offsetsRelativeToStream)
649*fd1fabb7SAndroid Build Coastguard Worker bigData += (uint32) stream.Position ();
650*fd1fabb7SAndroid Build Coastguard Worker
651*fd1fabb7SAndroid Build Coastguard Worker else if (offsetsBase == offsetsRelativeToExplicitBase)
652*fd1fabb7SAndroid Build Coastguard Worker bigData += explicitBase;
653*fd1fabb7SAndroid Build Coastguard Worker
654*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 ((uint16) fEntries);
655*fd1fabb7SAndroid Build Coastguard Worker
656*fd1fabb7SAndroid Build Coastguard Worker for (index = 0; index < fEntries; index++)
657*fd1fabb7SAndroid Build Coastguard Worker {
658*fd1fabb7SAndroid Build Coastguard Worker
659*fd1fabb7SAndroid Build Coastguard Worker const tiff_tag &tag = *fTag [index];
660*fd1fabb7SAndroid Build Coastguard Worker
661*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (tag.Code ());
662*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (tag.Type ());
663*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (tag.Count ());
664*fd1fabb7SAndroid Build Coastguard Worker
665*fd1fabb7SAndroid Build Coastguard Worker uint32 size = tag.Size ();
666*fd1fabb7SAndroid Build Coastguard Worker
667*fd1fabb7SAndroid Build Coastguard Worker if (size <= 4)
668*fd1fabb7SAndroid Build Coastguard Worker {
669*fd1fabb7SAndroid Build Coastguard Worker
670*fd1fabb7SAndroid Build Coastguard Worker tag.Put (stream);
671*fd1fabb7SAndroid Build Coastguard Worker
672*fd1fabb7SAndroid Build Coastguard Worker while (size < 4)
673*fd1fabb7SAndroid Build Coastguard Worker {
674*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
675*fd1fabb7SAndroid Build Coastguard Worker size++;
676*fd1fabb7SAndroid Build Coastguard Worker }
677*fd1fabb7SAndroid Build Coastguard Worker
678*fd1fabb7SAndroid Build Coastguard Worker }
679*fd1fabb7SAndroid Build Coastguard Worker
680*fd1fabb7SAndroid Build Coastguard Worker else
681*fd1fabb7SAndroid Build Coastguard Worker {
682*fd1fabb7SAndroid Build Coastguard Worker
683*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (bigData);
684*fd1fabb7SAndroid Build Coastguard Worker
685*fd1fabb7SAndroid Build Coastguard Worker bigData += (size + 1) & ~1;
686*fd1fabb7SAndroid Build Coastguard Worker
687*fd1fabb7SAndroid Build Coastguard Worker }
688*fd1fabb7SAndroid Build Coastguard Worker
689*fd1fabb7SAndroid Build Coastguard Worker }
690*fd1fabb7SAndroid Build Coastguard Worker
691*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (fChained); // Next IFD offset
692*fd1fabb7SAndroid Build Coastguard Worker
693*fd1fabb7SAndroid Build Coastguard Worker for (index = 0; index < fEntries; index++)
694*fd1fabb7SAndroid Build Coastguard Worker {
695*fd1fabb7SAndroid Build Coastguard Worker
696*fd1fabb7SAndroid Build Coastguard Worker const tiff_tag &tag = *fTag [index];
697*fd1fabb7SAndroid Build Coastguard Worker
698*fd1fabb7SAndroid Build Coastguard Worker uint32 size = tag.Size ();
699*fd1fabb7SAndroid Build Coastguard Worker
700*fd1fabb7SAndroid Build Coastguard Worker if (size > 4)
701*fd1fabb7SAndroid Build Coastguard Worker {
702*fd1fabb7SAndroid Build Coastguard Worker
703*fd1fabb7SAndroid Build Coastguard Worker tag.Put (stream);
704*fd1fabb7SAndroid Build Coastguard Worker
705*fd1fabb7SAndroid Build Coastguard Worker if (size & 1)
706*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
707*fd1fabb7SAndroid Build Coastguard Worker
708*fd1fabb7SAndroid Build Coastguard Worker }
709*fd1fabb7SAndroid Build Coastguard Worker
710*fd1fabb7SAndroid Build Coastguard Worker }
711*fd1fabb7SAndroid Build Coastguard Worker
712*fd1fabb7SAndroid Build Coastguard Worker }
713*fd1fabb7SAndroid Build Coastguard Worker
714*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
715*fd1fabb7SAndroid Build Coastguard Worker
dng_basic_tag_set(dng_tiff_directory & directory,const dng_ifd & info)716*fd1fabb7SAndroid Build Coastguard Worker dng_basic_tag_set::dng_basic_tag_set (dng_tiff_directory &directory,
717*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &info)
718*fd1fabb7SAndroid Build Coastguard Worker
719*fd1fabb7SAndroid Build Coastguard Worker : fNewSubFileType (tcNewSubFileType, info.fNewSubFileType)
720*fd1fabb7SAndroid Build Coastguard Worker
721*fd1fabb7SAndroid Build Coastguard Worker , fImageWidth (tcImageWidth , info.fImageWidth )
722*fd1fabb7SAndroid Build Coastguard Worker , fImageLength (tcImageLength, info.fImageLength)
723*fd1fabb7SAndroid Build Coastguard Worker
724*fd1fabb7SAndroid Build Coastguard Worker , fPhotoInterpretation (tcPhotometricInterpretation,
725*fd1fabb7SAndroid Build Coastguard Worker (uint16) info.fPhotometricInterpretation)
726*fd1fabb7SAndroid Build Coastguard Worker
727*fd1fabb7SAndroid Build Coastguard Worker , fFillOrder (tcFillOrder, 1)
728*fd1fabb7SAndroid Build Coastguard Worker
729*fd1fabb7SAndroid Build Coastguard Worker , fSamplesPerPixel (tcSamplesPerPixel, (uint16) info.fSamplesPerPixel)
730*fd1fabb7SAndroid Build Coastguard Worker
731*fd1fabb7SAndroid Build Coastguard Worker , fBitsPerSample (tcBitsPerSample,
732*fd1fabb7SAndroid Build Coastguard Worker fBitsPerSampleData,
733*fd1fabb7SAndroid Build Coastguard Worker info.fSamplesPerPixel)
734*fd1fabb7SAndroid Build Coastguard Worker
735*fd1fabb7SAndroid Build Coastguard Worker , fStrips (info.fUsesStrips)
736*fd1fabb7SAndroid Build Coastguard Worker
737*fd1fabb7SAndroid Build Coastguard Worker , fTileWidth (tcTileWidth, info.fTileWidth)
738*fd1fabb7SAndroid Build Coastguard Worker
739*fd1fabb7SAndroid Build Coastguard Worker , fTileLength (fStrips ? tcRowsPerStrip : tcTileLength,
740*fd1fabb7SAndroid Build Coastguard Worker info.fTileLength)
741*fd1fabb7SAndroid Build Coastguard Worker
742*fd1fabb7SAndroid Build Coastguard Worker , fTileInfoBuffer (info.TilesPerImage (), 8)
743*fd1fabb7SAndroid Build Coastguard Worker
744*fd1fabb7SAndroid Build Coastguard Worker , fTileOffsetData (fTileInfoBuffer.Buffer_uint32 ())
745*fd1fabb7SAndroid Build Coastguard Worker
746*fd1fabb7SAndroid Build Coastguard Worker , fTileOffsets (fStrips ? tcStripOffsets : tcTileOffsets,
747*fd1fabb7SAndroid Build Coastguard Worker fTileOffsetData,
748*fd1fabb7SAndroid Build Coastguard Worker info.TilesPerImage ())
749*fd1fabb7SAndroid Build Coastguard Worker
750*fd1fabb7SAndroid Build Coastguard Worker , fTileByteCountData (fTileOffsetData + info.TilesPerImage ())
751*fd1fabb7SAndroid Build Coastguard Worker
752*fd1fabb7SAndroid Build Coastguard Worker , fTileByteCounts (fStrips ? tcStripByteCounts : tcTileByteCounts,
753*fd1fabb7SAndroid Build Coastguard Worker fTileByteCountData,
754*fd1fabb7SAndroid Build Coastguard Worker info.TilesPerImage ())
755*fd1fabb7SAndroid Build Coastguard Worker
756*fd1fabb7SAndroid Build Coastguard Worker , fPlanarConfiguration (tcPlanarConfiguration, pcInterleaved)
757*fd1fabb7SAndroid Build Coastguard Worker
758*fd1fabb7SAndroid Build Coastguard Worker , fCompression (tcCompression, (uint16) info.fCompression)
759*fd1fabb7SAndroid Build Coastguard Worker , fPredictor (tcPredictor , (uint16) info.fPredictor )
760*fd1fabb7SAndroid Build Coastguard Worker
761*fd1fabb7SAndroid Build Coastguard Worker , fExtraSamples (tcExtraSamples,
762*fd1fabb7SAndroid Build Coastguard Worker fExtraSamplesData,
763*fd1fabb7SAndroid Build Coastguard Worker info.fExtraSamplesCount)
764*fd1fabb7SAndroid Build Coastguard Worker
765*fd1fabb7SAndroid Build Coastguard Worker , fSampleFormat (tcSampleFormat,
766*fd1fabb7SAndroid Build Coastguard Worker fSampleFormatData,
767*fd1fabb7SAndroid Build Coastguard Worker info.fSamplesPerPixel)
768*fd1fabb7SAndroid Build Coastguard Worker
769*fd1fabb7SAndroid Build Coastguard Worker , fRowInterleaveFactor (tcRowInterleaveFactor,
770*fd1fabb7SAndroid Build Coastguard Worker (uint16) info.fRowInterleaveFactor)
771*fd1fabb7SAndroid Build Coastguard Worker
772*fd1fabb7SAndroid Build Coastguard Worker , fSubTileBlockSize (tcSubTileBlockSize,
773*fd1fabb7SAndroid Build Coastguard Worker fSubTileBlockSizeData,
774*fd1fabb7SAndroid Build Coastguard Worker 2)
775*fd1fabb7SAndroid Build Coastguard Worker
776*fd1fabb7SAndroid Build Coastguard Worker {
777*fd1fabb7SAndroid Build Coastguard Worker
778*fd1fabb7SAndroid Build Coastguard Worker uint32 j;
779*fd1fabb7SAndroid Build Coastguard Worker
780*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < info.fSamplesPerPixel; j++)
781*fd1fabb7SAndroid Build Coastguard Worker {
782*fd1fabb7SAndroid Build Coastguard Worker
783*fd1fabb7SAndroid Build Coastguard Worker fBitsPerSampleData [j] = (uint16) info.fBitsPerSample [0];
784*fd1fabb7SAndroid Build Coastguard Worker
785*fd1fabb7SAndroid Build Coastguard Worker }
786*fd1fabb7SAndroid Build Coastguard Worker
787*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fNewSubFileType);
788*fd1fabb7SAndroid Build Coastguard Worker
789*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fImageWidth);
790*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fImageLength);
791*fd1fabb7SAndroid Build Coastguard Worker
792*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fPhotoInterpretation);
793*fd1fabb7SAndroid Build Coastguard Worker
794*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fSamplesPerPixel);
795*fd1fabb7SAndroid Build Coastguard Worker
796*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBitsPerSample);
797*fd1fabb7SAndroid Build Coastguard Worker
798*fd1fabb7SAndroid Build Coastguard Worker if (info.fBitsPerSample [0] != 8 &&
799*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] != 16 &&
800*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] != 32)
801*fd1fabb7SAndroid Build Coastguard Worker {
802*fd1fabb7SAndroid Build Coastguard Worker
803*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fFillOrder);
804*fd1fabb7SAndroid Build Coastguard Worker
805*fd1fabb7SAndroid Build Coastguard Worker }
806*fd1fabb7SAndroid Build Coastguard Worker
807*fd1fabb7SAndroid Build Coastguard Worker if (!fStrips)
808*fd1fabb7SAndroid Build Coastguard Worker {
809*fd1fabb7SAndroid Build Coastguard Worker
810*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fTileWidth);
811*fd1fabb7SAndroid Build Coastguard Worker
812*fd1fabb7SAndroid Build Coastguard Worker }
813*fd1fabb7SAndroid Build Coastguard Worker
814*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fTileLength);
815*fd1fabb7SAndroid Build Coastguard Worker
816*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fTileOffsets);
817*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fTileByteCounts);
818*fd1fabb7SAndroid Build Coastguard Worker
819*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fPlanarConfiguration);
820*fd1fabb7SAndroid Build Coastguard Worker
821*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCompression);
822*fd1fabb7SAndroid Build Coastguard Worker
823*fd1fabb7SAndroid Build Coastguard Worker if (info.fPredictor != cpNullPredictor)
824*fd1fabb7SAndroid Build Coastguard Worker {
825*fd1fabb7SAndroid Build Coastguard Worker
826*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fPredictor);
827*fd1fabb7SAndroid Build Coastguard Worker
828*fd1fabb7SAndroid Build Coastguard Worker }
829*fd1fabb7SAndroid Build Coastguard Worker
830*fd1fabb7SAndroid Build Coastguard Worker if (info.fExtraSamplesCount != 0)
831*fd1fabb7SAndroid Build Coastguard Worker {
832*fd1fabb7SAndroid Build Coastguard Worker
833*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < info.fExtraSamplesCount; j++)
834*fd1fabb7SAndroid Build Coastguard Worker {
835*fd1fabb7SAndroid Build Coastguard Worker fExtraSamplesData [j] = (uint16) info.fExtraSamples [j];
836*fd1fabb7SAndroid Build Coastguard Worker }
837*fd1fabb7SAndroid Build Coastguard Worker
838*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fExtraSamples);
839*fd1fabb7SAndroid Build Coastguard Worker
840*fd1fabb7SAndroid Build Coastguard Worker }
841*fd1fabb7SAndroid Build Coastguard Worker
842*fd1fabb7SAndroid Build Coastguard Worker if (info.fSampleFormat [0] != sfUnsignedInteger)
843*fd1fabb7SAndroid Build Coastguard Worker {
844*fd1fabb7SAndroid Build Coastguard Worker
845*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < info.fSamplesPerPixel; j++)
846*fd1fabb7SAndroid Build Coastguard Worker {
847*fd1fabb7SAndroid Build Coastguard Worker fSampleFormatData [j] = (uint16) info.fSampleFormat [j];
848*fd1fabb7SAndroid Build Coastguard Worker }
849*fd1fabb7SAndroid Build Coastguard Worker
850*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fSampleFormat);
851*fd1fabb7SAndroid Build Coastguard Worker
852*fd1fabb7SAndroid Build Coastguard Worker }
853*fd1fabb7SAndroid Build Coastguard Worker
854*fd1fabb7SAndroid Build Coastguard Worker if (info.fRowInterleaveFactor != 1)
855*fd1fabb7SAndroid Build Coastguard Worker {
856*fd1fabb7SAndroid Build Coastguard Worker
857*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fRowInterleaveFactor);
858*fd1fabb7SAndroid Build Coastguard Worker
859*fd1fabb7SAndroid Build Coastguard Worker }
860*fd1fabb7SAndroid Build Coastguard Worker
861*fd1fabb7SAndroid Build Coastguard Worker if (info.fSubTileBlockRows != 1 ||
862*fd1fabb7SAndroid Build Coastguard Worker info.fSubTileBlockCols != 1)
863*fd1fabb7SAndroid Build Coastguard Worker {
864*fd1fabb7SAndroid Build Coastguard Worker
865*fd1fabb7SAndroid Build Coastguard Worker fSubTileBlockSizeData [0] = (uint16) info.fSubTileBlockRows;
866*fd1fabb7SAndroid Build Coastguard Worker fSubTileBlockSizeData [1] = (uint16) info.fSubTileBlockCols;
867*fd1fabb7SAndroid Build Coastguard Worker
868*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fSubTileBlockSize);
869*fd1fabb7SAndroid Build Coastguard Worker
870*fd1fabb7SAndroid Build Coastguard Worker }
871*fd1fabb7SAndroid Build Coastguard Worker
872*fd1fabb7SAndroid Build Coastguard Worker }
873*fd1fabb7SAndroid Build Coastguard Worker
874*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
875*fd1fabb7SAndroid Build Coastguard Worker
exif_tag_set(dng_tiff_directory & directory,const dng_exif & exif,bool makerNoteSafe,const void * makerNoteData,uint32 makerNoteLength,bool insideDNG)876*fd1fabb7SAndroid Build Coastguard Worker exif_tag_set::exif_tag_set (dng_tiff_directory &directory,
877*fd1fabb7SAndroid Build Coastguard Worker const dng_exif &exif,
878*fd1fabb7SAndroid Build Coastguard Worker bool makerNoteSafe,
879*fd1fabb7SAndroid Build Coastguard Worker const void *makerNoteData,
880*fd1fabb7SAndroid Build Coastguard Worker uint32 makerNoteLength,
881*fd1fabb7SAndroid Build Coastguard Worker bool insideDNG)
882*fd1fabb7SAndroid Build Coastguard Worker
883*fd1fabb7SAndroid Build Coastguard Worker : fExifIFD ()
884*fd1fabb7SAndroid Build Coastguard Worker , fGPSIFD ()
885*fd1fabb7SAndroid Build Coastguard Worker
886*fd1fabb7SAndroid Build Coastguard Worker , fExifLink (tcExifIFD, 0)
887*fd1fabb7SAndroid Build Coastguard Worker , fGPSLink (tcGPSInfo, 0)
888*fd1fabb7SAndroid Build Coastguard Worker
889*fd1fabb7SAndroid Build Coastguard Worker , fAddedExifLink (false)
890*fd1fabb7SAndroid Build Coastguard Worker , fAddedGPSLink (false)
891*fd1fabb7SAndroid Build Coastguard Worker
892*fd1fabb7SAndroid Build Coastguard Worker , fExifVersion (tcExifVersion, ttUndefined, 4, fExifVersionData)
893*fd1fabb7SAndroid Build Coastguard Worker
894*fd1fabb7SAndroid Build Coastguard Worker , fExposureTime (tcExposureTime , exif.fExposureTime )
895*fd1fabb7SAndroid Build Coastguard Worker , fShutterSpeedValue (tcShutterSpeedValue, exif.fShutterSpeedValue)
896*fd1fabb7SAndroid Build Coastguard Worker
897*fd1fabb7SAndroid Build Coastguard Worker , fFNumber (tcFNumber , exif.fFNumber )
898*fd1fabb7SAndroid Build Coastguard Worker , fApertureValue (tcApertureValue, exif.fApertureValue)
899*fd1fabb7SAndroid Build Coastguard Worker
900*fd1fabb7SAndroid Build Coastguard Worker , fBrightnessValue (tcBrightnessValue, exif.fBrightnessValue)
901*fd1fabb7SAndroid Build Coastguard Worker
902*fd1fabb7SAndroid Build Coastguard Worker , fExposureBiasValue (tcExposureBiasValue, exif.fExposureBiasValue)
903*fd1fabb7SAndroid Build Coastguard Worker
904*fd1fabb7SAndroid Build Coastguard Worker , fMaxApertureValue (tcMaxApertureValue , exif.fMaxApertureValue)
905*fd1fabb7SAndroid Build Coastguard Worker
906*fd1fabb7SAndroid Build Coastguard Worker , fSubjectDistance (tcSubjectDistance, exif.fSubjectDistance)
907*fd1fabb7SAndroid Build Coastguard Worker
908*fd1fabb7SAndroid Build Coastguard Worker , fFocalLength (tcFocalLength, exif.fFocalLength)
909*fd1fabb7SAndroid Build Coastguard Worker
910*fd1fabb7SAndroid Build Coastguard Worker // Special case: the EXIF 2.2 standard represents ISO speed ratings with 2 bytes,
911*fd1fabb7SAndroid Build Coastguard Worker // which cannot hold ISO speed ratings above 65535 (e.g., 102400). In these
912*fd1fabb7SAndroid Build Coastguard Worker // cases, we write the maximum representable ISO speed rating value in the EXIF
913*fd1fabb7SAndroid Build Coastguard Worker // tag, i.e., 65535.
914*fd1fabb7SAndroid Build Coastguard Worker
915*fd1fabb7SAndroid Build Coastguard Worker , fISOSpeedRatings (tcISOSpeedRatings,
916*fd1fabb7SAndroid Build Coastguard Worker (uint16) Min_uint32 (65535,
917*fd1fabb7SAndroid Build Coastguard Worker exif.fISOSpeedRatings [0]))
918*fd1fabb7SAndroid Build Coastguard Worker
919*fd1fabb7SAndroid Build Coastguard Worker , fSensitivityType (tcSensitivityType, (uint16) exif.fSensitivityType)
920*fd1fabb7SAndroid Build Coastguard Worker
921*fd1fabb7SAndroid Build Coastguard Worker , fStandardOutputSensitivity (tcStandardOutputSensitivity, exif.fStandardOutputSensitivity)
922*fd1fabb7SAndroid Build Coastguard Worker
923*fd1fabb7SAndroid Build Coastguard Worker , fRecommendedExposureIndex (tcRecommendedExposureIndex, exif.fRecommendedExposureIndex)
924*fd1fabb7SAndroid Build Coastguard Worker
925*fd1fabb7SAndroid Build Coastguard Worker , fISOSpeed (tcISOSpeed, exif.fISOSpeed)
926*fd1fabb7SAndroid Build Coastguard Worker
927*fd1fabb7SAndroid Build Coastguard Worker , fISOSpeedLatitudeyyy (tcISOSpeedLatitudeyyy, exif.fISOSpeedLatitudeyyy)
928*fd1fabb7SAndroid Build Coastguard Worker
929*fd1fabb7SAndroid Build Coastguard Worker , fISOSpeedLatitudezzz (tcISOSpeedLatitudezzz, exif.fISOSpeedLatitudezzz)
930*fd1fabb7SAndroid Build Coastguard Worker
931*fd1fabb7SAndroid Build Coastguard Worker , fFlash (tcFlash, (uint16) exif.fFlash)
932*fd1fabb7SAndroid Build Coastguard Worker
933*fd1fabb7SAndroid Build Coastguard Worker , fExposureProgram (tcExposureProgram, (uint16) exif.fExposureProgram)
934*fd1fabb7SAndroid Build Coastguard Worker
935*fd1fabb7SAndroid Build Coastguard Worker , fMeteringMode (tcMeteringMode, (uint16) exif.fMeteringMode)
936*fd1fabb7SAndroid Build Coastguard Worker
937*fd1fabb7SAndroid Build Coastguard Worker , fLightSource (tcLightSource, (uint16) exif.fLightSource)
938*fd1fabb7SAndroid Build Coastguard Worker
939*fd1fabb7SAndroid Build Coastguard Worker , fSensingMethod (tcSensingMethodExif, (uint16) exif.fSensingMethod)
940*fd1fabb7SAndroid Build Coastguard Worker
941*fd1fabb7SAndroid Build Coastguard Worker , fFocalLength35mm (tcFocalLengthIn35mmFilm, (uint16) exif.fFocalLengthIn35mmFilm)
942*fd1fabb7SAndroid Build Coastguard Worker
943*fd1fabb7SAndroid Build Coastguard Worker , fFileSourceData ((uint8) exif.fFileSource)
944*fd1fabb7SAndroid Build Coastguard Worker , fFileSource (tcFileSource, ttUndefined, 1, &fFileSourceData)
945*fd1fabb7SAndroid Build Coastguard Worker
946*fd1fabb7SAndroid Build Coastguard Worker , fSceneTypeData ((uint8) exif.fSceneType)
947*fd1fabb7SAndroid Build Coastguard Worker , fSceneType (tcSceneType, ttUndefined, 1, &fSceneTypeData)
948*fd1fabb7SAndroid Build Coastguard Worker
949*fd1fabb7SAndroid Build Coastguard Worker , fCFAPattern (tcCFAPatternExif,
950*fd1fabb7SAndroid Build Coastguard Worker exif.fCFARepeatPatternRows,
951*fd1fabb7SAndroid Build Coastguard Worker exif.fCFARepeatPatternCols,
952*fd1fabb7SAndroid Build Coastguard Worker &exif.fCFAPattern [0] [0])
953*fd1fabb7SAndroid Build Coastguard Worker
954*fd1fabb7SAndroid Build Coastguard Worker , fCustomRendered (tcCustomRendered , (uint16) exif.fCustomRendered )
955*fd1fabb7SAndroid Build Coastguard Worker , fExposureMode (tcExposureMode , (uint16) exif.fExposureMode )
956*fd1fabb7SAndroid Build Coastguard Worker , fWhiteBalance (tcWhiteBalance , (uint16) exif.fWhiteBalance )
957*fd1fabb7SAndroid Build Coastguard Worker , fSceneCaptureType (tcSceneCaptureType , (uint16) exif.fSceneCaptureType )
958*fd1fabb7SAndroid Build Coastguard Worker , fGainControl (tcGainControl , (uint16) exif.fGainControl )
959*fd1fabb7SAndroid Build Coastguard Worker , fContrast (tcContrast , (uint16) exif.fContrast )
960*fd1fabb7SAndroid Build Coastguard Worker , fSaturation (tcSaturation , (uint16) exif.fSaturation )
961*fd1fabb7SAndroid Build Coastguard Worker , fSharpness (tcSharpness , (uint16) exif.fSharpness )
962*fd1fabb7SAndroid Build Coastguard Worker , fSubjectDistanceRange (tcSubjectDistanceRange, (uint16) exif.fSubjectDistanceRange)
963*fd1fabb7SAndroid Build Coastguard Worker
964*fd1fabb7SAndroid Build Coastguard Worker , fDigitalZoomRatio (tcDigitalZoomRatio, exif.fDigitalZoomRatio)
965*fd1fabb7SAndroid Build Coastguard Worker
966*fd1fabb7SAndroid Build Coastguard Worker , fExposureIndex (tcExposureIndexExif, exif.fExposureIndex)
967*fd1fabb7SAndroid Build Coastguard Worker
968*fd1fabb7SAndroid Build Coastguard Worker , fImageNumber (tcImageNumber, exif.fImageNumber)
969*fd1fabb7SAndroid Build Coastguard Worker
970*fd1fabb7SAndroid Build Coastguard Worker , fSelfTimerMode (tcSelfTimerMode, (uint16) exif.fSelfTimerMode)
971*fd1fabb7SAndroid Build Coastguard Worker
972*fd1fabb7SAndroid Build Coastguard Worker , fBatteryLevelA (tcBatteryLevel, exif.fBatteryLevelA)
973*fd1fabb7SAndroid Build Coastguard Worker , fBatteryLevelR (tcBatteryLevel, exif.fBatteryLevelR)
974*fd1fabb7SAndroid Build Coastguard Worker
975*fd1fabb7SAndroid Build Coastguard Worker , fFocalPlaneXResolution (tcFocalPlaneXResolutionExif, exif.fFocalPlaneXResolution)
976*fd1fabb7SAndroid Build Coastguard Worker , fFocalPlaneYResolution (tcFocalPlaneYResolutionExif, exif.fFocalPlaneYResolution)
977*fd1fabb7SAndroid Build Coastguard Worker
978*fd1fabb7SAndroid Build Coastguard Worker , fFocalPlaneResolutionUnit (tcFocalPlaneResolutionUnitExif, (uint16) exif.fFocalPlaneResolutionUnit)
979*fd1fabb7SAndroid Build Coastguard Worker
980*fd1fabb7SAndroid Build Coastguard Worker , fSubjectArea (tcSubjectArea, fSubjectAreaData, exif.fSubjectAreaCount)
981*fd1fabb7SAndroid Build Coastguard Worker
982*fd1fabb7SAndroid Build Coastguard Worker , fLensInfo (tcLensInfo, fLensInfoData, 4)
983*fd1fabb7SAndroid Build Coastguard Worker
984*fd1fabb7SAndroid Build Coastguard Worker , fDateTime (tcDateTime , exif.fDateTime .DateTime ())
985*fd1fabb7SAndroid Build Coastguard Worker , fDateTimeOriginal (tcDateTimeOriginal , exif.fDateTimeOriginal .DateTime ())
986*fd1fabb7SAndroid Build Coastguard Worker , fDateTimeDigitized (tcDateTimeDigitized, exif.fDateTimeDigitized.DateTime ())
987*fd1fabb7SAndroid Build Coastguard Worker
988*fd1fabb7SAndroid Build Coastguard Worker , fSubsecTime (tcSubsecTime, exif.fDateTime .Subseconds ())
989*fd1fabb7SAndroid Build Coastguard Worker , fSubsecTimeOriginal (tcSubsecTimeOriginal, exif.fDateTimeOriginal .Subseconds ())
990*fd1fabb7SAndroid Build Coastguard Worker , fSubsecTimeDigitized (tcSubsecTimeDigitized, exif.fDateTimeDigitized.Subseconds ())
991*fd1fabb7SAndroid Build Coastguard Worker
992*fd1fabb7SAndroid Build Coastguard Worker , fMake (tcMake, exif.fMake)
993*fd1fabb7SAndroid Build Coastguard Worker
994*fd1fabb7SAndroid Build Coastguard Worker , fModel (tcModel, exif.fModel)
995*fd1fabb7SAndroid Build Coastguard Worker
996*fd1fabb7SAndroid Build Coastguard Worker , fArtist (tcArtist, exif.fArtist)
997*fd1fabb7SAndroid Build Coastguard Worker
998*fd1fabb7SAndroid Build Coastguard Worker , fSoftware (tcSoftware, exif.fSoftware)
999*fd1fabb7SAndroid Build Coastguard Worker
1000*fd1fabb7SAndroid Build Coastguard Worker , fCopyright (tcCopyright, exif.fCopyright)
1001*fd1fabb7SAndroid Build Coastguard Worker
1002*fd1fabb7SAndroid Build Coastguard Worker , fMakerNoteSafety (tcMakerNoteSafety, makerNoteSafe ? 1 : 0)
1003*fd1fabb7SAndroid Build Coastguard Worker
1004*fd1fabb7SAndroid Build Coastguard Worker , fMakerNote (tcMakerNote, ttUndefined, makerNoteLength, makerNoteData)
1005*fd1fabb7SAndroid Build Coastguard Worker
1006*fd1fabb7SAndroid Build Coastguard Worker , fImageDescription (tcImageDescription, exif.fImageDescription)
1007*fd1fabb7SAndroid Build Coastguard Worker
1008*fd1fabb7SAndroid Build Coastguard Worker , fSerialNumber (tcCameraSerialNumber, exif.fCameraSerialNumber)
1009*fd1fabb7SAndroid Build Coastguard Worker
1010*fd1fabb7SAndroid Build Coastguard Worker , fUserComment (tcUserComment, exif.fUserComment)
1011*fd1fabb7SAndroid Build Coastguard Worker
1012*fd1fabb7SAndroid Build Coastguard Worker , fImageUniqueID (tcImageUniqueID, ttAscii, 33, fImageUniqueIDData)
1013*fd1fabb7SAndroid Build Coastguard Worker
1014*fd1fabb7SAndroid Build Coastguard Worker // EXIF 2.3 tags.
1015*fd1fabb7SAndroid Build Coastguard Worker
1016*fd1fabb7SAndroid Build Coastguard Worker , fCameraOwnerName (tcCameraOwnerNameExif, exif.fOwnerName )
1017*fd1fabb7SAndroid Build Coastguard Worker , fBodySerialNumber (tcCameraSerialNumberExif, exif.fCameraSerialNumber)
1018*fd1fabb7SAndroid Build Coastguard Worker , fLensSpecification (tcLensSpecificationExif, fLensInfoData, 4 )
1019*fd1fabb7SAndroid Build Coastguard Worker , fLensMake (tcLensMakeExif, exif.fLensMake )
1020*fd1fabb7SAndroid Build Coastguard Worker , fLensModel (tcLensModelExif, exif.fLensName )
1021*fd1fabb7SAndroid Build Coastguard Worker , fLensSerialNumber (tcLensSerialNumberExif, exif.fLensSerialNumber )
1022*fd1fabb7SAndroid Build Coastguard Worker
1023*fd1fabb7SAndroid Build Coastguard Worker , fGPSVersionID (tcGPSVersionID, fGPSVersionData, 4)
1024*fd1fabb7SAndroid Build Coastguard Worker
1025*fd1fabb7SAndroid Build Coastguard Worker , fGPSLatitudeRef (tcGPSLatitudeRef, exif.fGPSLatitudeRef)
1026*fd1fabb7SAndroid Build Coastguard Worker , fGPSLatitude (tcGPSLatitude, exif.fGPSLatitude, 3)
1027*fd1fabb7SAndroid Build Coastguard Worker
1028*fd1fabb7SAndroid Build Coastguard Worker , fGPSLongitudeRef (tcGPSLongitudeRef, exif.fGPSLongitudeRef)
1029*fd1fabb7SAndroid Build Coastguard Worker , fGPSLongitude (tcGPSLongitude, exif.fGPSLongitude, 3)
1030*fd1fabb7SAndroid Build Coastguard Worker
1031*fd1fabb7SAndroid Build Coastguard Worker , fGPSAltitudeRef (tcGPSAltitudeRef, (uint8) exif.fGPSAltitudeRef)
1032*fd1fabb7SAndroid Build Coastguard Worker , fGPSAltitude (tcGPSAltitude, exif.fGPSAltitude )
1033*fd1fabb7SAndroid Build Coastguard Worker
1034*fd1fabb7SAndroid Build Coastguard Worker , fGPSTimeStamp (tcGPSTimeStamp, exif.fGPSTimeStamp, 3)
1035*fd1fabb7SAndroid Build Coastguard Worker
1036*fd1fabb7SAndroid Build Coastguard Worker , fGPSSatellites (tcGPSSatellites , exif.fGPSSatellites )
1037*fd1fabb7SAndroid Build Coastguard Worker , fGPSStatus (tcGPSStatus , exif.fGPSStatus )
1038*fd1fabb7SAndroid Build Coastguard Worker , fGPSMeasureMode (tcGPSMeasureMode, exif.fGPSMeasureMode)
1039*fd1fabb7SAndroid Build Coastguard Worker
1040*fd1fabb7SAndroid Build Coastguard Worker , fGPSDOP (tcGPSDOP, exif.fGPSDOP)
1041*fd1fabb7SAndroid Build Coastguard Worker
1042*fd1fabb7SAndroid Build Coastguard Worker , fGPSSpeedRef (tcGPSSpeedRef, exif.fGPSSpeedRef)
1043*fd1fabb7SAndroid Build Coastguard Worker , fGPSSpeed (tcGPSSpeed , exif.fGPSSpeed )
1044*fd1fabb7SAndroid Build Coastguard Worker
1045*fd1fabb7SAndroid Build Coastguard Worker , fGPSTrackRef (tcGPSTrackRef, exif.fGPSTrackRef)
1046*fd1fabb7SAndroid Build Coastguard Worker , fGPSTrack (tcGPSTrack , exif.fGPSTrack )
1047*fd1fabb7SAndroid Build Coastguard Worker
1048*fd1fabb7SAndroid Build Coastguard Worker , fGPSImgDirectionRef (tcGPSImgDirectionRef, exif.fGPSImgDirectionRef)
1049*fd1fabb7SAndroid Build Coastguard Worker , fGPSImgDirection (tcGPSImgDirection , exif.fGPSImgDirection )
1050*fd1fabb7SAndroid Build Coastguard Worker
1051*fd1fabb7SAndroid Build Coastguard Worker , fGPSMapDatum (tcGPSMapDatum, exif.fGPSMapDatum)
1052*fd1fabb7SAndroid Build Coastguard Worker
1053*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestLatitudeRef (tcGPSDestLatitudeRef, exif.fGPSDestLatitudeRef)
1054*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestLatitude (tcGPSDestLatitude, exif.fGPSDestLatitude, 3)
1055*fd1fabb7SAndroid Build Coastguard Worker
1056*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestLongitudeRef (tcGPSDestLongitudeRef, exif.fGPSDestLongitudeRef)
1057*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestLongitude (tcGPSDestLongitude, exif.fGPSDestLongitude, 3)
1058*fd1fabb7SAndroid Build Coastguard Worker
1059*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestBearingRef (tcGPSDestBearingRef, exif.fGPSDestBearingRef)
1060*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestBearing (tcGPSDestBearing , exif.fGPSDestBearing )
1061*fd1fabb7SAndroid Build Coastguard Worker
1062*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestDistanceRef (tcGPSDestDistanceRef, exif.fGPSDestDistanceRef)
1063*fd1fabb7SAndroid Build Coastguard Worker , fGPSDestDistance (tcGPSDestDistance , exif.fGPSDestDistance )
1064*fd1fabb7SAndroid Build Coastguard Worker
1065*fd1fabb7SAndroid Build Coastguard Worker , fGPSProcessingMethod (tcGPSProcessingMethod, exif.fGPSProcessingMethod)
1066*fd1fabb7SAndroid Build Coastguard Worker , fGPSAreaInformation (tcGPSAreaInformation , exif.fGPSAreaInformation )
1067*fd1fabb7SAndroid Build Coastguard Worker
1068*fd1fabb7SAndroid Build Coastguard Worker , fGPSDateStamp (tcGPSDateStamp, exif.fGPSDateStamp)
1069*fd1fabb7SAndroid Build Coastguard Worker
1070*fd1fabb7SAndroid Build Coastguard Worker , fGPSDifferential (tcGPSDifferential, (uint16) exif.fGPSDifferential)
1071*fd1fabb7SAndroid Build Coastguard Worker
1072*fd1fabb7SAndroid Build Coastguard Worker , fGPSHPositioningError (tcGPSHPositioningError, exif.fGPSHPositioningError)
1073*fd1fabb7SAndroid Build Coastguard Worker
1074*fd1fabb7SAndroid Build Coastguard Worker {
1075*fd1fabb7SAndroid Build Coastguard Worker
1076*fd1fabb7SAndroid Build Coastguard Worker if (exif.fExifVersion)
1077*fd1fabb7SAndroid Build Coastguard Worker {
1078*fd1fabb7SAndroid Build Coastguard Worker
1079*fd1fabb7SAndroid Build Coastguard Worker fExifVersionData [0] = (uint8) (exif.fExifVersion >> 24);
1080*fd1fabb7SAndroid Build Coastguard Worker fExifVersionData [1] = (uint8) (exif.fExifVersion >> 16);
1081*fd1fabb7SAndroid Build Coastguard Worker fExifVersionData [2] = (uint8) (exif.fExifVersion >> 8);
1082*fd1fabb7SAndroid Build Coastguard Worker fExifVersionData [3] = (uint8) (exif.fExifVersion );
1083*fd1fabb7SAndroid Build Coastguard Worker
1084*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fExifVersion);
1085*fd1fabb7SAndroid Build Coastguard Worker
1086*fd1fabb7SAndroid Build Coastguard Worker }
1087*fd1fabb7SAndroid Build Coastguard Worker
1088*fd1fabb7SAndroid Build Coastguard Worker if (exif.fExposureTime.IsValid ())
1089*fd1fabb7SAndroid Build Coastguard Worker {
1090*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fExposureTime);
1091*fd1fabb7SAndroid Build Coastguard Worker }
1092*fd1fabb7SAndroid Build Coastguard Worker
1093*fd1fabb7SAndroid Build Coastguard Worker if (exif.fShutterSpeedValue.IsValid ())
1094*fd1fabb7SAndroid Build Coastguard Worker {
1095*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fShutterSpeedValue);
1096*fd1fabb7SAndroid Build Coastguard Worker }
1097*fd1fabb7SAndroid Build Coastguard Worker
1098*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFNumber.IsValid ())
1099*fd1fabb7SAndroid Build Coastguard Worker {
1100*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFNumber);
1101*fd1fabb7SAndroid Build Coastguard Worker }
1102*fd1fabb7SAndroid Build Coastguard Worker
1103*fd1fabb7SAndroid Build Coastguard Worker if (exif.fApertureValue.IsValid ())
1104*fd1fabb7SAndroid Build Coastguard Worker {
1105*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fApertureValue);
1106*fd1fabb7SAndroid Build Coastguard Worker }
1107*fd1fabb7SAndroid Build Coastguard Worker
1108*fd1fabb7SAndroid Build Coastguard Worker if (exif.fBrightnessValue.IsValid ())
1109*fd1fabb7SAndroid Build Coastguard Worker {
1110*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fBrightnessValue);
1111*fd1fabb7SAndroid Build Coastguard Worker }
1112*fd1fabb7SAndroid Build Coastguard Worker
1113*fd1fabb7SAndroid Build Coastguard Worker if (exif.fExposureBiasValue.IsValid ())
1114*fd1fabb7SAndroid Build Coastguard Worker {
1115*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fExposureBiasValue);
1116*fd1fabb7SAndroid Build Coastguard Worker }
1117*fd1fabb7SAndroid Build Coastguard Worker
1118*fd1fabb7SAndroid Build Coastguard Worker if (exif.fMaxApertureValue.IsValid ())
1119*fd1fabb7SAndroid Build Coastguard Worker {
1120*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fMaxApertureValue);
1121*fd1fabb7SAndroid Build Coastguard Worker }
1122*fd1fabb7SAndroid Build Coastguard Worker
1123*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSubjectDistance.IsValid ())
1124*fd1fabb7SAndroid Build Coastguard Worker {
1125*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSubjectDistance);
1126*fd1fabb7SAndroid Build Coastguard Worker }
1127*fd1fabb7SAndroid Build Coastguard Worker
1128*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFocalLength.IsValid ())
1129*fd1fabb7SAndroid Build Coastguard Worker {
1130*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFocalLength);
1131*fd1fabb7SAndroid Build Coastguard Worker }
1132*fd1fabb7SAndroid Build Coastguard Worker
1133*fd1fabb7SAndroid Build Coastguard Worker if (exif.fISOSpeedRatings [0] != 0)
1134*fd1fabb7SAndroid Build Coastguard Worker {
1135*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fISOSpeedRatings);
1136*fd1fabb7SAndroid Build Coastguard Worker }
1137*fd1fabb7SAndroid Build Coastguard Worker
1138*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFlash <= 0x0FFFF)
1139*fd1fabb7SAndroid Build Coastguard Worker {
1140*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFlash);
1141*fd1fabb7SAndroid Build Coastguard Worker }
1142*fd1fabb7SAndroid Build Coastguard Worker
1143*fd1fabb7SAndroid Build Coastguard Worker if (exif.fExposureProgram <= 0x0FFFF)
1144*fd1fabb7SAndroid Build Coastguard Worker {
1145*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fExposureProgram);
1146*fd1fabb7SAndroid Build Coastguard Worker }
1147*fd1fabb7SAndroid Build Coastguard Worker
1148*fd1fabb7SAndroid Build Coastguard Worker if (exif.fMeteringMode <= 0x0FFFF)
1149*fd1fabb7SAndroid Build Coastguard Worker {
1150*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fMeteringMode);
1151*fd1fabb7SAndroid Build Coastguard Worker }
1152*fd1fabb7SAndroid Build Coastguard Worker
1153*fd1fabb7SAndroid Build Coastguard Worker if (exif.fLightSource <= 0x0FFFF)
1154*fd1fabb7SAndroid Build Coastguard Worker {
1155*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fLightSource);
1156*fd1fabb7SAndroid Build Coastguard Worker }
1157*fd1fabb7SAndroid Build Coastguard Worker
1158*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSensingMethod <= 0x0FFFF)
1159*fd1fabb7SAndroid Build Coastguard Worker {
1160*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSensingMethod);
1161*fd1fabb7SAndroid Build Coastguard Worker }
1162*fd1fabb7SAndroid Build Coastguard Worker
1163*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFocalLengthIn35mmFilm != 0)
1164*fd1fabb7SAndroid Build Coastguard Worker {
1165*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFocalLength35mm);
1166*fd1fabb7SAndroid Build Coastguard Worker }
1167*fd1fabb7SAndroid Build Coastguard Worker
1168*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFileSource <= 0x0FF)
1169*fd1fabb7SAndroid Build Coastguard Worker {
1170*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFileSource);
1171*fd1fabb7SAndroid Build Coastguard Worker }
1172*fd1fabb7SAndroid Build Coastguard Worker
1173*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSceneType <= 0x0FF)
1174*fd1fabb7SAndroid Build Coastguard Worker {
1175*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSceneType);
1176*fd1fabb7SAndroid Build Coastguard Worker }
1177*fd1fabb7SAndroid Build Coastguard Worker
1178*fd1fabb7SAndroid Build Coastguard Worker if (exif.fCFARepeatPatternRows &&
1179*fd1fabb7SAndroid Build Coastguard Worker exif.fCFARepeatPatternCols)
1180*fd1fabb7SAndroid Build Coastguard Worker {
1181*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fCFAPattern);
1182*fd1fabb7SAndroid Build Coastguard Worker }
1183*fd1fabb7SAndroid Build Coastguard Worker
1184*fd1fabb7SAndroid Build Coastguard Worker if (exif.fCustomRendered <= 0x0FFFF)
1185*fd1fabb7SAndroid Build Coastguard Worker {
1186*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fCustomRendered);
1187*fd1fabb7SAndroid Build Coastguard Worker }
1188*fd1fabb7SAndroid Build Coastguard Worker
1189*fd1fabb7SAndroid Build Coastguard Worker if (exif.fExposureMode <= 0x0FFFF)
1190*fd1fabb7SAndroid Build Coastguard Worker {
1191*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fExposureMode);
1192*fd1fabb7SAndroid Build Coastguard Worker }
1193*fd1fabb7SAndroid Build Coastguard Worker
1194*fd1fabb7SAndroid Build Coastguard Worker if (exif.fWhiteBalance <= 0x0FFFF)
1195*fd1fabb7SAndroid Build Coastguard Worker {
1196*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fWhiteBalance);
1197*fd1fabb7SAndroid Build Coastguard Worker }
1198*fd1fabb7SAndroid Build Coastguard Worker
1199*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSceneCaptureType <= 0x0FFFF)
1200*fd1fabb7SAndroid Build Coastguard Worker {
1201*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSceneCaptureType);
1202*fd1fabb7SAndroid Build Coastguard Worker }
1203*fd1fabb7SAndroid Build Coastguard Worker
1204*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGainControl <= 0x0FFFF)
1205*fd1fabb7SAndroid Build Coastguard Worker {
1206*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fGainControl);
1207*fd1fabb7SAndroid Build Coastguard Worker }
1208*fd1fabb7SAndroid Build Coastguard Worker
1209*fd1fabb7SAndroid Build Coastguard Worker if (exif.fContrast <= 0x0FFFF)
1210*fd1fabb7SAndroid Build Coastguard Worker {
1211*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fContrast);
1212*fd1fabb7SAndroid Build Coastguard Worker }
1213*fd1fabb7SAndroid Build Coastguard Worker
1214*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSaturation <= 0x0FFFF)
1215*fd1fabb7SAndroid Build Coastguard Worker {
1216*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSaturation);
1217*fd1fabb7SAndroid Build Coastguard Worker }
1218*fd1fabb7SAndroid Build Coastguard Worker
1219*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSharpness <= 0x0FFFF)
1220*fd1fabb7SAndroid Build Coastguard Worker {
1221*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSharpness);
1222*fd1fabb7SAndroid Build Coastguard Worker }
1223*fd1fabb7SAndroid Build Coastguard Worker
1224*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSubjectDistanceRange <= 0x0FFFF)
1225*fd1fabb7SAndroid Build Coastguard Worker {
1226*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSubjectDistanceRange);
1227*fd1fabb7SAndroid Build Coastguard Worker }
1228*fd1fabb7SAndroid Build Coastguard Worker
1229*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDigitalZoomRatio.IsValid ())
1230*fd1fabb7SAndroid Build Coastguard Worker {
1231*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fDigitalZoomRatio);
1232*fd1fabb7SAndroid Build Coastguard Worker }
1233*fd1fabb7SAndroid Build Coastguard Worker
1234*fd1fabb7SAndroid Build Coastguard Worker if (exif.fExposureIndex.IsValid ())
1235*fd1fabb7SAndroid Build Coastguard Worker {
1236*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fExposureIndex);
1237*fd1fabb7SAndroid Build Coastguard Worker }
1238*fd1fabb7SAndroid Build Coastguard Worker
1239*fd1fabb7SAndroid Build Coastguard Worker if (insideDNG) // TIFF-EP only tags
1240*fd1fabb7SAndroid Build Coastguard Worker {
1241*fd1fabb7SAndroid Build Coastguard Worker
1242*fd1fabb7SAndroid Build Coastguard Worker if (exif.fImageNumber != 0xFFFFFFFF)
1243*fd1fabb7SAndroid Build Coastguard Worker {
1244*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fImageNumber);
1245*fd1fabb7SAndroid Build Coastguard Worker }
1246*fd1fabb7SAndroid Build Coastguard Worker
1247*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSelfTimerMode <= 0x0FFFF)
1248*fd1fabb7SAndroid Build Coastguard Worker {
1249*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fSelfTimerMode);
1250*fd1fabb7SAndroid Build Coastguard Worker }
1251*fd1fabb7SAndroid Build Coastguard Worker
1252*fd1fabb7SAndroid Build Coastguard Worker if (exif.fBatteryLevelA.NotEmpty ())
1253*fd1fabb7SAndroid Build Coastguard Worker {
1254*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBatteryLevelA);
1255*fd1fabb7SAndroid Build Coastguard Worker }
1256*fd1fabb7SAndroid Build Coastguard Worker
1257*fd1fabb7SAndroid Build Coastguard Worker else if (exif.fBatteryLevelR.IsValid ())
1258*fd1fabb7SAndroid Build Coastguard Worker {
1259*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBatteryLevelR);
1260*fd1fabb7SAndroid Build Coastguard Worker }
1261*fd1fabb7SAndroid Build Coastguard Worker
1262*fd1fabb7SAndroid Build Coastguard Worker }
1263*fd1fabb7SAndroid Build Coastguard Worker
1264*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFocalPlaneXResolution.IsValid ())
1265*fd1fabb7SAndroid Build Coastguard Worker {
1266*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFocalPlaneXResolution);
1267*fd1fabb7SAndroid Build Coastguard Worker }
1268*fd1fabb7SAndroid Build Coastguard Worker
1269*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFocalPlaneYResolution.IsValid ())
1270*fd1fabb7SAndroid Build Coastguard Worker {
1271*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFocalPlaneYResolution);
1272*fd1fabb7SAndroid Build Coastguard Worker }
1273*fd1fabb7SAndroid Build Coastguard Worker
1274*fd1fabb7SAndroid Build Coastguard Worker if (exif.fFocalPlaneResolutionUnit <= 0x0FFFF)
1275*fd1fabb7SAndroid Build Coastguard Worker {
1276*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fFocalPlaneResolutionUnit);
1277*fd1fabb7SAndroid Build Coastguard Worker }
1278*fd1fabb7SAndroid Build Coastguard Worker
1279*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSubjectAreaCount)
1280*fd1fabb7SAndroid Build Coastguard Worker {
1281*fd1fabb7SAndroid Build Coastguard Worker
1282*fd1fabb7SAndroid Build Coastguard Worker fSubjectAreaData [0] = (uint16) exif.fSubjectArea [0];
1283*fd1fabb7SAndroid Build Coastguard Worker fSubjectAreaData [1] = (uint16) exif.fSubjectArea [1];
1284*fd1fabb7SAndroid Build Coastguard Worker fSubjectAreaData [2] = (uint16) exif.fSubjectArea [2];
1285*fd1fabb7SAndroid Build Coastguard Worker fSubjectAreaData [3] = (uint16) exif.fSubjectArea [3];
1286*fd1fabb7SAndroid Build Coastguard Worker
1287*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSubjectArea);
1288*fd1fabb7SAndroid Build Coastguard Worker
1289*fd1fabb7SAndroid Build Coastguard Worker }
1290*fd1fabb7SAndroid Build Coastguard Worker
1291*fd1fabb7SAndroid Build Coastguard Worker if (exif.fLensInfo [0].IsValid () &&
1292*fd1fabb7SAndroid Build Coastguard Worker exif.fLensInfo [1].IsValid ())
1293*fd1fabb7SAndroid Build Coastguard Worker {
1294*fd1fabb7SAndroid Build Coastguard Worker
1295*fd1fabb7SAndroid Build Coastguard Worker fLensInfoData [0] = exif.fLensInfo [0];
1296*fd1fabb7SAndroid Build Coastguard Worker fLensInfoData [1] = exif.fLensInfo [1];
1297*fd1fabb7SAndroid Build Coastguard Worker fLensInfoData [2] = exif.fLensInfo [2];
1298*fd1fabb7SAndroid Build Coastguard Worker fLensInfoData [3] = exif.fLensInfo [3];
1299*fd1fabb7SAndroid Build Coastguard Worker
1300*fd1fabb7SAndroid Build Coastguard Worker if (insideDNG)
1301*fd1fabb7SAndroid Build Coastguard Worker {
1302*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fLensInfo);
1303*fd1fabb7SAndroid Build Coastguard Worker }
1304*fd1fabb7SAndroid Build Coastguard Worker
1305*fd1fabb7SAndroid Build Coastguard Worker }
1306*fd1fabb7SAndroid Build Coastguard Worker
1307*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDateTime.IsValid ())
1308*fd1fabb7SAndroid Build Coastguard Worker {
1309*fd1fabb7SAndroid Build Coastguard Worker
1310*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fDateTime);
1311*fd1fabb7SAndroid Build Coastguard Worker
1312*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDateTime.Subseconds ().NotEmpty ())
1313*fd1fabb7SAndroid Build Coastguard Worker {
1314*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSubsecTime);
1315*fd1fabb7SAndroid Build Coastguard Worker }
1316*fd1fabb7SAndroid Build Coastguard Worker
1317*fd1fabb7SAndroid Build Coastguard Worker }
1318*fd1fabb7SAndroid Build Coastguard Worker
1319*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDateTimeOriginal.IsValid ())
1320*fd1fabb7SAndroid Build Coastguard Worker {
1321*fd1fabb7SAndroid Build Coastguard Worker
1322*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fDateTimeOriginal);
1323*fd1fabb7SAndroid Build Coastguard Worker
1324*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDateTimeOriginal.Subseconds ().NotEmpty ())
1325*fd1fabb7SAndroid Build Coastguard Worker {
1326*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSubsecTimeOriginal);
1327*fd1fabb7SAndroid Build Coastguard Worker }
1328*fd1fabb7SAndroid Build Coastguard Worker
1329*fd1fabb7SAndroid Build Coastguard Worker }
1330*fd1fabb7SAndroid Build Coastguard Worker
1331*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDateTimeDigitized.IsValid ())
1332*fd1fabb7SAndroid Build Coastguard Worker {
1333*fd1fabb7SAndroid Build Coastguard Worker
1334*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fDateTimeDigitized);
1335*fd1fabb7SAndroid Build Coastguard Worker
1336*fd1fabb7SAndroid Build Coastguard Worker if (exif.fDateTimeDigitized.Subseconds ().NotEmpty ())
1337*fd1fabb7SAndroid Build Coastguard Worker {
1338*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSubsecTimeDigitized);
1339*fd1fabb7SAndroid Build Coastguard Worker }
1340*fd1fabb7SAndroid Build Coastguard Worker
1341*fd1fabb7SAndroid Build Coastguard Worker }
1342*fd1fabb7SAndroid Build Coastguard Worker
1343*fd1fabb7SAndroid Build Coastguard Worker if (exif.fMake.NotEmpty ())
1344*fd1fabb7SAndroid Build Coastguard Worker {
1345*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fMake);
1346*fd1fabb7SAndroid Build Coastguard Worker }
1347*fd1fabb7SAndroid Build Coastguard Worker
1348*fd1fabb7SAndroid Build Coastguard Worker if (exif.fModel.NotEmpty ())
1349*fd1fabb7SAndroid Build Coastguard Worker {
1350*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fModel);
1351*fd1fabb7SAndroid Build Coastguard Worker }
1352*fd1fabb7SAndroid Build Coastguard Worker
1353*fd1fabb7SAndroid Build Coastguard Worker if (exif.fArtist.NotEmpty ())
1354*fd1fabb7SAndroid Build Coastguard Worker {
1355*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fArtist);
1356*fd1fabb7SAndroid Build Coastguard Worker }
1357*fd1fabb7SAndroid Build Coastguard Worker
1358*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSoftware.NotEmpty ())
1359*fd1fabb7SAndroid Build Coastguard Worker {
1360*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fSoftware);
1361*fd1fabb7SAndroid Build Coastguard Worker }
1362*fd1fabb7SAndroid Build Coastguard Worker
1363*fd1fabb7SAndroid Build Coastguard Worker if (exif.fCopyright.NotEmpty ())
1364*fd1fabb7SAndroid Build Coastguard Worker {
1365*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCopyright);
1366*fd1fabb7SAndroid Build Coastguard Worker }
1367*fd1fabb7SAndroid Build Coastguard Worker
1368*fd1fabb7SAndroid Build Coastguard Worker if (exif.fImageDescription.NotEmpty ())
1369*fd1fabb7SAndroid Build Coastguard Worker {
1370*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fImageDescription);
1371*fd1fabb7SAndroid Build Coastguard Worker }
1372*fd1fabb7SAndroid Build Coastguard Worker
1373*fd1fabb7SAndroid Build Coastguard Worker if (exif.fCameraSerialNumber.NotEmpty () && insideDNG)
1374*fd1fabb7SAndroid Build Coastguard Worker {
1375*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fSerialNumber);
1376*fd1fabb7SAndroid Build Coastguard Worker }
1377*fd1fabb7SAndroid Build Coastguard Worker
1378*fd1fabb7SAndroid Build Coastguard Worker if (makerNoteSafe && makerNoteData)
1379*fd1fabb7SAndroid Build Coastguard Worker {
1380*fd1fabb7SAndroid Build Coastguard Worker
1381*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fMakerNoteSafety);
1382*fd1fabb7SAndroid Build Coastguard Worker
1383*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fMakerNote);
1384*fd1fabb7SAndroid Build Coastguard Worker
1385*fd1fabb7SAndroid Build Coastguard Worker }
1386*fd1fabb7SAndroid Build Coastguard Worker
1387*fd1fabb7SAndroid Build Coastguard Worker if (exif.fUserComment.NotEmpty ())
1388*fd1fabb7SAndroid Build Coastguard Worker {
1389*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fUserComment);
1390*fd1fabb7SAndroid Build Coastguard Worker }
1391*fd1fabb7SAndroid Build Coastguard Worker
1392*fd1fabb7SAndroid Build Coastguard Worker if (exif.fImageUniqueID.IsValid ())
1393*fd1fabb7SAndroid Build Coastguard Worker {
1394*fd1fabb7SAndroid Build Coastguard Worker
1395*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < 16; j++)
1396*fd1fabb7SAndroid Build Coastguard Worker {
1397*fd1fabb7SAndroid Build Coastguard Worker
1398*fd1fabb7SAndroid Build Coastguard Worker sprintf (fImageUniqueIDData + j * 2,
1399*fd1fabb7SAndroid Build Coastguard Worker "%02X",
1400*fd1fabb7SAndroid Build Coastguard Worker (unsigned) exif.fImageUniqueID.data [j]);
1401*fd1fabb7SAndroid Build Coastguard Worker
1402*fd1fabb7SAndroid Build Coastguard Worker }
1403*fd1fabb7SAndroid Build Coastguard Worker
1404*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fImageUniqueID);
1405*fd1fabb7SAndroid Build Coastguard Worker
1406*fd1fabb7SAndroid Build Coastguard Worker }
1407*fd1fabb7SAndroid Build Coastguard Worker
1408*fd1fabb7SAndroid Build Coastguard Worker if (exif.AtLeastVersion0230 ())
1409*fd1fabb7SAndroid Build Coastguard Worker {
1410*fd1fabb7SAndroid Build Coastguard Worker
1411*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSensitivityType != 0)
1412*fd1fabb7SAndroid Build Coastguard Worker {
1413*fd1fabb7SAndroid Build Coastguard Worker
1414*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fSensitivityType);
1415*fd1fabb7SAndroid Build Coastguard Worker
1416*fd1fabb7SAndroid Build Coastguard Worker }
1417*fd1fabb7SAndroid Build Coastguard Worker
1418*fd1fabb7SAndroid Build Coastguard Worker // Sensitivity tags. Do not write these extra tags unless the SensitivityType
1419*fd1fabb7SAndroid Build Coastguard Worker // and PhotographicSensitivity (i.e., ISOSpeedRatings) values are valid.
1420*fd1fabb7SAndroid Build Coastguard Worker
1421*fd1fabb7SAndroid Build Coastguard Worker if (exif.fSensitivityType != 0 &&
1422*fd1fabb7SAndroid Build Coastguard Worker exif.fISOSpeedRatings [0] != 0)
1423*fd1fabb7SAndroid Build Coastguard Worker {
1424*fd1fabb7SAndroid Build Coastguard Worker
1425*fd1fabb7SAndroid Build Coastguard Worker // Standard Output Sensitivity (SOS).
1426*fd1fabb7SAndroid Build Coastguard Worker
1427*fd1fabb7SAndroid Build Coastguard Worker if (exif.fStandardOutputSensitivity != 0)
1428*fd1fabb7SAndroid Build Coastguard Worker {
1429*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fStandardOutputSensitivity);
1430*fd1fabb7SAndroid Build Coastguard Worker }
1431*fd1fabb7SAndroid Build Coastguard Worker
1432*fd1fabb7SAndroid Build Coastguard Worker // Recommended Exposure Index (REI).
1433*fd1fabb7SAndroid Build Coastguard Worker
1434*fd1fabb7SAndroid Build Coastguard Worker if (exif.fRecommendedExposureIndex != 0)
1435*fd1fabb7SAndroid Build Coastguard Worker {
1436*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fRecommendedExposureIndex);
1437*fd1fabb7SAndroid Build Coastguard Worker }
1438*fd1fabb7SAndroid Build Coastguard Worker
1439*fd1fabb7SAndroid Build Coastguard Worker // ISO Speed.
1440*fd1fabb7SAndroid Build Coastguard Worker
1441*fd1fabb7SAndroid Build Coastguard Worker if (exif.fISOSpeed != 0)
1442*fd1fabb7SAndroid Build Coastguard Worker {
1443*fd1fabb7SAndroid Build Coastguard Worker
1444*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fISOSpeed);
1445*fd1fabb7SAndroid Build Coastguard Worker
1446*fd1fabb7SAndroid Build Coastguard Worker if (exif.fISOSpeedLatitudeyyy != 0 &&
1447*fd1fabb7SAndroid Build Coastguard Worker exif.fISOSpeedLatitudezzz != 0)
1448*fd1fabb7SAndroid Build Coastguard Worker {
1449*fd1fabb7SAndroid Build Coastguard Worker
1450*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fISOSpeedLatitudeyyy);
1451*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fISOSpeedLatitudezzz);
1452*fd1fabb7SAndroid Build Coastguard Worker
1453*fd1fabb7SAndroid Build Coastguard Worker }
1454*fd1fabb7SAndroid Build Coastguard Worker
1455*fd1fabb7SAndroid Build Coastguard Worker }
1456*fd1fabb7SAndroid Build Coastguard Worker
1457*fd1fabb7SAndroid Build Coastguard Worker }
1458*fd1fabb7SAndroid Build Coastguard Worker
1459*fd1fabb7SAndroid Build Coastguard Worker if (exif.fOwnerName.NotEmpty ())
1460*fd1fabb7SAndroid Build Coastguard Worker {
1461*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fCameraOwnerName);
1462*fd1fabb7SAndroid Build Coastguard Worker }
1463*fd1fabb7SAndroid Build Coastguard Worker
1464*fd1fabb7SAndroid Build Coastguard Worker if (exif.fCameraSerialNumber.NotEmpty ())
1465*fd1fabb7SAndroid Build Coastguard Worker {
1466*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fBodySerialNumber);
1467*fd1fabb7SAndroid Build Coastguard Worker }
1468*fd1fabb7SAndroid Build Coastguard Worker
1469*fd1fabb7SAndroid Build Coastguard Worker if (exif.fLensInfo [0].IsValid () &&
1470*fd1fabb7SAndroid Build Coastguard Worker exif.fLensInfo [1].IsValid ())
1471*fd1fabb7SAndroid Build Coastguard Worker {
1472*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fLensSpecification);
1473*fd1fabb7SAndroid Build Coastguard Worker }
1474*fd1fabb7SAndroid Build Coastguard Worker
1475*fd1fabb7SAndroid Build Coastguard Worker if (exif.fLensMake.NotEmpty ())
1476*fd1fabb7SAndroid Build Coastguard Worker {
1477*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fLensMake);
1478*fd1fabb7SAndroid Build Coastguard Worker }
1479*fd1fabb7SAndroid Build Coastguard Worker
1480*fd1fabb7SAndroid Build Coastguard Worker if (exif.fLensName.NotEmpty ())
1481*fd1fabb7SAndroid Build Coastguard Worker {
1482*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fLensModel);
1483*fd1fabb7SAndroid Build Coastguard Worker }
1484*fd1fabb7SAndroid Build Coastguard Worker
1485*fd1fabb7SAndroid Build Coastguard Worker if (exif.fLensSerialNumber.NotEmpty ())
1486*fd1fabb7SAndroid Build Coastguard Worker {
1487*fd1fabb7SAndroid Build Coastguard Worker fExifIFD.Add (&fLensSerialNumber);
1488*fd1fabb7SAndroid Build Coastguard Worker }
1489*fd1fabb7SAndroid Build Coastguard Worker
1490*fd1fabb7SAndroid Build Coastguard Worker }
1491*fd1fabb7SAndroid Build Coastguard Worker
1492*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSVersionID)
1493*fd1fabb7SAndroid Build Coastguard Worker {
1494*fd1fabb7SAndroid Build Coastguard Worker
1495*fd1fabb7SAndroid Build Coastguard Worker fGPSVersionData [0] = (uint8) (exif.fGPSVersionID >> 24);
1496*fd1fabb7SAndroid Build Coastguard Worker fGPSVersionData [1] = (uint8) (exif.fGPSVersionID >> 16);
1497*fd1fabb7SAndroid Build Coastguard Worker fGPSVersionData [2] = (uint8) (exif.fGPSVersionID >> 8);
1498*fd1fabb7SAndroid Build Coastguard Worker fGPSVersionData [3] = (uint8) (exif.fGPSVersionID );
1499*fd1fabb7SAndroid Build Coastguard Worker
1500*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSVersionID);
1501*fd1fabb7SAndroid Build Coastguard Worker
1502*fd1fabb7SAndroid Build Coastguard Worker }
1503*fd1fabb7SAndroid Build Coastguard Worker
1504*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSLatitudeRef.NotEmpty () &&
1505*fd1fabb7SAndroid Build Coastguard Worker exif.fGPSLatitude [0].IsValid ())
1506*fd1fabb7SAndroid Build Coastguard Worker {
1507*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSLatitudeRef);
1508*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSLatitude );
1509*fd1fabb7SAndroid Build Coastguard Worker }
1510*fd1fabb7SAndroid Build Coastguard Worker
1511*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSLongitudeRef.NotEmpty () &&
1512*fd1fabb7SAndroid Build Coastguard Worker exif.fGPSLongitude [0].IsValid ())
1513*fd1fabb7SAndroid Build Coastguard Worker {
1514*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSLongitudeRef);
1515*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSLongitude );
1516*fd1fabb7SAndroid Build Coastguard Worker }
1517*fd1fabb7SAndroid Build Coastguard Worker
1518*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSAltitudeRef <= 0x0FF)
1519*fd1fabb7SAndroid Build Coastguard Worker {
1520*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSAltitudeRef);
1521*fd1fabb7SAndroid Build Coastguard Worker }
1522*fd1fabb7SAndroid Build Coastguard Worker
1523*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSAltitude.IsValid ())
1524*fd1fabb7SAndroid Build Coastguard Worker {
1525*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSAltitude);
1526*fd1fabb7SAndroid Build Coastguard Worker }
1527*fd1fabb7SAndroid Build Coastguard Worker
1528*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSTimeStamp [0].IsValid ())
1529*fd1fabb7SAndroid Build Coastguard Worker {
1530*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSTimeStamp);
1531*fd1fabb7SAndroid Build Coastguard Worker }
1532*fd1fabb7SAndroid Build Coastguard Worker
1533*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSSatellites.NotEmpty ())
1534*fd1fabb7SAndroid Build Coastguard Worker {
1535*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSSatellites);
1536*fd1fabb7SAndroid Build Coastguard Worker }
1537*fd1fabb7SAndroid Build Coastguard Worker
1538*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSStatus.NotEmpty ())
1539*fd1fabb7SAndroid Build Coastguard Worker {
1540*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSStatus);
1541*fd1fabb7SAndroid Build Coastguard Worker }
1542*fd1fabb7SAndroid Build Coastguard Worker
1543*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSMeasureMode.NotEmpty ())
1544*fd1fabb7SAndroid Build Coastguard Worker {
1545*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSMeasureMode);
1546*fd1fabb7SAndroid Build Coastguard Worker }
1547*fd1fabb7SAndroid Build Coastguard Worker
1548*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDOP.IsValid ())
1549*fd1fabb7SAndroid Build Coastguard Worker {
1550*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDOP);
1551*fd1fabb7SAndroid Build Coastguard Worker }
1552*fd1fabb7SAndroid Build Coastguard Worker
1553*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSSpeedRef.NotEmpty ())
1554*fd1fabb7SAndroid Build Coastguard Worker {
1555*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSSpeedRef);
1556*fd1fabb7SAndroid Build Coastguard Worker }
1557*fd1fabb7SAndroid Build Coastguard Worker
1558*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSSpeed.IsValid ())
1559*fd1fabb7SAndroid Build Coastguard Worker {
1560*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSSpeed);
1561*fd1fabb7SAndroid Build Coastguard Worker }
1562*fd1fabb7SAndroid Build Coastguard Worker
1563*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSTrackRef.NotEmpty ())
1564*fd1fabb7SAndroid Build Coastguard Worker {
1565*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSTrackRef);
1566*fd1fabb7SAndroid Build Coastguard Worker }
1567*fd1fabb7SAndroid Build Coastguard Worker
1568*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSTrack.IsValid ())
1569*fd1fabb7SAndroid Build Coastguard Worker {
1570*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSTrack);
1571*fd1fabb7SAndroid Build Coastguard Worker }
1572*fd1fabb7SAndroid Build Coastguard Worker
1573*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSImgDirectionRef.NotEmpty ())
1574*fd1fabb7SAndroid Build Coastguard Worker {
1575*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSImgDirectionRef);
1576*fd1fabb7SAndroid Build Coastguard Worker }
1577*fd1fabb7SAndroid Build Coastguard Worker
1578*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSImgDirection.IsValid ())
1579*fd1fabb7SAndroid Build Coastguard Worker {
1580*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSImgDirection);
1581*fd1fabb7SAndroid Build Coastguard Worker }
1582*fd1fabb7SAndroid Build Coastguard Worker
1583*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSMapDatum.NotEmpty ())
1584*fd1fabb7SAndroid Build Coastguard Worker {
1585*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSMapDatum);
1586*fd1fabb7SAndroid Build Coastguard Worker }
1587*fd1fabb7SAndroid Build Coastguard Worker
1588*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDestLatitudeRef.NotEmpty () &&
1589*fd1fabb7SAndroid Build Coastguard Worker exif.fGPSDestLatitude [0].IsValid ())
1590*fd1fabb7SAndroid Build Coastguard Worker {
1591*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestLatitudeRef);
1592*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestLatitude );
1593*fd1fabb7SAndroid Build Coastguard Worker }
1594*fd1fabb7SAndroid Build Coastguard Worker
1595*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDestLongitudeRef.NotEmpty () &&
1596*fd1fabb7SAndroid Build Coastguard Worker exif.fGPSDestLongitude [0].IsValid ())
1597*fd1fabb7SAndroid Build Coastguard Worker {
1598*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestLongitudeRef);
1599*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestLongitude );
1600*fd1fabb7SAndroid Build Coastguard Worker }
1601*fd1fabb7SAndroid Build Coastguard Worker
1602*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDestBearingRef.NotEmpty ())
1603*fd1fabb7SAndroid Build Coastguard Worker {
1604*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestBearingRef);
1605*fd1fabb7SAndroid Build Coastguard Worker }
1606*fd1fabb7SAndroid Build Coastguard Worker
1607*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDestBearing.IsValid ())
1608*fd1fabb7SAndroid Build Coastguard Worker {
1609*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestBearing);
1610*fd1fabb7SAndroid Build Coastguard Worker }
1611*fd1fabb7SAndroid Build Coastguard Worker
1612*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDestDistanceRef.NotEmpty ())
1613*fd1fabb7SAndroid Build Coastguard Worker {
1614*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestDistanceRef);
1615*fd1fabb7SAndroid Build Coastguard Worker }
1616*fd1fabb7SAndroid Build Coastguard Worker
1617*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDestDistance.IsValid ())
1618*fd1fabb7SAndroid Build Coastguard Worker {
1619*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDestDistance);
1620*fd1fabb7SAndroid Build Coastguard Worker }
1621*fd1fabb7SAndroid Build Coastguard Worker
1622*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSProcessingMethod.NotEmpty ())
1623*fd1fabb7SAndroid Build Coastguard Worker {
1624*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSProcessingMethod);
1625*fd1fabb7SAndroid Build Coastguard Worker }
1626*fd1fabb7SAndroid Build Coastguard Worker
1627*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSAreaInformation.NotEmpty ())
1628*fd1fabb7SAndroid Build Coastguard Worker {
1629*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSAreaInformation);
1630*fd1fabb7SAndroid Build Coastguard Worker }
1631*fd1fabb7SAndroid Build Coastguard Worker
1632*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDateStamp.NotEmpty ())
1633*fd1fabb7SAndroid Build Coastguard Worker {
1634*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDateStamp);
1635*fd1fabb7SAndroid Build Coastguard Worker }
1636*fd1fabb7SAndroid Build Coastguard Worker
1637*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSDifferential <= 0x0FFFF)
1638*fd1fabb7SAndroid Build Coastguard Worker {
1639*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSDifferential);
1640*fd1fabb7SAndroid Build Coastguard Worker }
1641*fd1fabb7SAndroid Build Coastguard Worker
1642*fd1fabb7SAndroid Build Coastguard Worker if (exif.AtLeastVersion0230 ())
1643*fd1fabb7SAndroid Build Coastguard Worker {
1644*fd1fabb7SAndroid Build Coastguard Worker
1645*fd1fabb7SAndroid Build Coastguard Worker if (exif.fGPSHPositioningError.IsValid ())
1646*fd1fabb7SAndroid Build Coastguard Worker {
1647*fd1fabb7SAndroid Build Coastguard Worker fGPSIFD.Add (&fGPSHPositioningError);
1648*fd1fabb7SAndroid Build Coastguard Worker }
1649*fd1fabb7SAndroid Build Coastguard Worker
1650*fd1fabb7SAndroid Build Coastguard Worker }
1651*fd1fabb7SAndroid Build Coastguard Worker
1652*fd1fabb7SAndroid Build Coastguard Worker AddLinks (directory);
1653*fd1fabb7SAndroid Build Coastguard Worker
1654*fd1fabb7SAndroid Build Coastguard Worker }
1655*fd1fabb7SAndroid Build Coastguard Worker
1656*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
1657*fd1fabb7SAndroid Build Coastguard Worker
AddLinks(dng_tiff_directory & directory)1658*fd1fabb7SAndroid Build Coastguard Worker void exif_tag_set::AddLinks (dng_tiff_directory &directory)
1659*fd1fabb7SAndroid Build Coastguard Worker {
1660*fd1fabb7SAndroid Build Coastguard Worker
1661*fd1fabb7SAndroid Build Coastguard Worker if (fExifIFD.Size () != 0 && !fAddedExifLink)
1662*fd1fabb7SAndroid Build Coastguard Worker {
1663*fd1fabb7SAndroid Build Coastguard Worker
1664*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fExifLink);
1665*fd1fabb7SAndroid Build Coastguard Worker
1666*fd1fabb7SAndroid Build Coastguard Worker fAddedExifLink = true;
1667*fd1fabb7SAndroid Build Coastguard Worker
1668*fd1fabb7SAndroid Build Coastguard Worker }
1669*fd1fabb7SAndroid Build Coastguard Worker
1670*fd1fabb7SAndroid Build Coastguard Worker if (fGPSIFD.Size () != 0 && !fAddedGPSLink)
1671*fd1fabb7SAndroid Build Coastguard Worker {
1672*fd1fabb7SAndroid Build Coastguard Worker
1673*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fGPSLink);
1674*fd1fabb7SAndroid Build Coastguard Worker
1675*fd1fabb7SAndroid Build Coastguard Worker fAddedGPSLink = true;
1676*fd1fabb7SAndroid Build Coastguard Worker
1677*fd1fabb7SAndroid Build Coastguard Worker }
1678*fd1fabb7SAndroid Build Coastguard Worker
1679*fd1fabb7SAndroid Build Coastguard Worker }
1680*fd1fabb7SAndroid Build Coastguard Worker
1681*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
1682*fd1fabb7SAndroid Build Coastguard Worker
1683*fd1fabb7SAndroid Build Coastguard Worker class range_tag_set
1684*fd1fabb7SAndroid Build Coastguard Worker {
1685*fd1fabb7SAndroid Build Coastguard Worker
1686*fd1fabb7SAndroid Build Coastguard Worker private:
1687*fd1fabb7SAndroid Build Coastguard Worker
1688*fd1fabb7SAndroid Build Coastguard Worker uint32 fActiveAreaData [4];
1689*fd1fabb7SAndroid Build Coastguard Worker
1690*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr fActiveArea;
1691*fd1fabb7SAndroid Build Coastguard Worker
1692*fd1fabb7SAndroid Build Coastguard Worker uint32 fMaskedAreaData [kMaxMaskedAreas * 4];
1693*fd1fabb7SAndroid Build Coastguard Worker
1694*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr fMaskedAreas;
1695*fd1fabb7SAndroid Build Coastguard Worker
1696*fd1fabb7SAndroid Build Coastguard Worker tag_uint16_ptr fLinearizationTable;
1697*fd1fabb7SAndroid Build Coastguard Worker
1698*fd1fabb7SAndroid Build Coastguard Worker uint16 fBlackLevelRepeatDimData [2];
1699*fd1fabb7SAndroid Build Coastguard Worker
1700*fd1fabb7SAndroid Build Coastguard Worker tag_uint16_ptr fBlackLevelRepeatDim;
1701*fd1fabb7SAndroid Build Coastguard Worker
1702*fd1fabb7SAndroid Build Coastguard Worker dng_urational fBlackLevelData [kMaxBlackPattern *
1703*fd1fabb7SAndroid Build Coastguard Worker kMaxBlackPattern *
1704*fd1fabb7SAndroid Build Coastguard Worker kMaxSamplesPerPixel];
1705*fd1fabb7SAndroid Build Coastguard Worker
1706*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr fBlackLevel;
1707*fd1fabb7SAndroid Build Coastguard Worker
1708*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data fBlackLevelDeltaHData;
1709*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data fBlackLevelDeltaVData;
1710*fd1fabb7SAndroid Build Coastguard Worker
1711*fd1fabb7SAndroid Build Coastguard Worker tag_srational_ptr fBlackLevelDeltaH;
1712*fd1fabb7SAndroid Build Coastguard Worker tag_srational_ptr fBlackLevelDeltaV;
1713*fd1fabb7SAndroid Build Coastguard Worker
1714*fd1fabb7SAndroid Build Coastguard Worker uint16 fWhiteLevelData16 [kMaxSamplesPerPixel];
1715*fd1fabb7SAndroid Build Coastguard Worker uint32 fWhiteLevelData32 [kMaxSamplesPerPixel];
1716*fd1fabb7SAndroid Build Coastguard Worker
1717*fd1fabb7SAndroid Build Coastguard Worker tag_uint16_ptr fWhiteLevel16;
1718*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr fWhiteLevel32;
1719*fd1fabb7SAndroid Build Coastguard Worker
1720*fd1fabb7SAndroid Build Coastguard Worker public:
1721*fd1fabb7SAndroid Build Coastguard Worker
1722*fd1fabb7SAndroid Build Coastguard Worker range_tag_set (dng_tiff_directory &directory,
1723*fd1fabb7SAndroid Build Coastguard Worker const dng_negative &negative);
1724*fd1fabb7SAndroid Build Coastguard Worker
1725*fd1fabb7SAndroid Build Coastguard Worker };
1726*fd1fabb7SAndroid Build Coastguard Worker
1727*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
1728*fd1fabb7SAndroid Build Coastguard Worker
range_tag_set(dng_tiff_directory & directory,const dng_negative & negative)1729*fd1fabb7SAndroid Build Coastguard Worker range_tag_set::range_tag_set (dng_tiff_directory &directory,
1730*fd1fabb7SAndroid Build Coastguard Worker const dng_negative &negative)
1731*fd1fabb7SAndroid Build Coastguard Worker
1732*fd1fabb7SAndroid Build Coastguard Worker : fActiveArea (tcActiveArea,
1733*fd1fabb7SAndroid Build Coastguard Worker fActiveAreaData,
1734*fd1fabb7SAndroid Build Coastguard Worker 4)
1735*fd1fabb7SAndroid Build Coastguard Worker
1736*fd1fabb7SAndroid Build Coastguard Worker , fMaskedAreas (tcMaskedAreas,
1737*fd1fabb7SAndroid Build Coastguard Worker fMaskedAreaData,
1738*fd1fabb7SAndroid Build Coastguard Worker 0)
1739*fd1fabb7SAndroid Build Coastguard Worker
1740*fd1fabb7SAndroid Build Coastguard Worker , fLinearizationTable (tcLinearizationTable,
1741*fd1fabb7SAndroid Build Coastguard Worker NULL,
1742*fd1fabb7SAndroid Build Coastguard Worker 0)
1743*fd1fabb7SAndroid Build Coastguard Worker
1744*fd1fabb7SAndroid Build Coastguard Worker , fBlackLevelRepeatDim (tcBlackLevelRepeatDim,
1745*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelRepeatDimData,
1746*fd1fabb7SAndroid Build Coastguard Worker 2)
1747*fd1fabb7SAndroid Build Coastguard Worker
1748*fd1fabb7SAndroid Build Coastguard Worker , fBlackLevel (tcBlackLevel,
1749*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelData)
1750*fd1fabb7SAndroid Build Coastguard Worker
1751*fd1fabb7SAndroid Build Coastguard Worker , fBlackLevelDeltaHData ()
1752*fd1fabb7SAndroid Build Coastguard Worker , fBlackLevelDeltaVData ()
1753*fd1fabb7SAndroid Build Coastguard Worker
1754*fd1fabb7SAndroid Build Coastguard Worker , fBlackLevelDeltaH (tcBlackLevelDeltaH)
1755*fd1fabb7SAndroid Build Coastguard Worker , fBlackLevelDeltaV (tcBlackLevelDeltaV)
1756*fd1fabb7SAndroid Build Coastguard Worker
1757*fd1fabb7SAndroid Build Coastguard Worker , fWhiteLevel16 (tcWhiteLevel,
1758*fd1fabb7SAndroid Build Coastguard Worker fWhiteLevelData16)
1759*fd1fabb7SAndroid Build Coastguard Worker
1760*fd1fabb7SAndroid Build Coastguard Worker , fWhiteLevel32 (tcWhiteLevel,
1761*fd1fabb7SAndroid Build Coastguard Worker fWhiteLevelData32)
1762*fd1fabb7SAndroid Build Coastguard Worker
1763*fd1fabb7SAndroid Build Coastguard Worker {
1764*fd1fabb7SAndroid Build Coastguard Worker
1765*fd1fabb7SAndroid Build Coastguard Worker const dng_image &rawImage (negative.RawImage ());
1766*fd1fabb7SAndroid Build Coastguard Worker
1767*fd1fabb7SAndroid Build Coastguard Worker const dng_linearization_info *rangeInfo = negative.GetLinearizationInfo ();
1768*fd1fabb7SAndroid Build Coastguard Worker
1769*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo)
1770*fd1fabb7SAndroid Build Coastguard Worker {
1771*fd1fabb7SAndroid Build Coastguard Worker
1772*fd1fabb7SAndroid Build Coastguard Worker // ActiveArea:
1773*fd1fabb7SAndroid Build Coastguard Worker
1774*fd1fabb7SAndroid Build Coastguard Worker {
1775*fd1fabb7SAndroid Build Coastguard Worker
1776*fd1fabb7SAndroid Build Coastguard Worker const dng_rect &r = rangeInfo->fActiveArea;
1777*fd1fabb7SAndroid Build Coastguard Worker
1778*fd1fabb7SAndroid Build Coastguard Worker if (r.NotEmpty ())
1779*fd1fabb7SAndroid Build Coastguard Worker {
1780*fd1fabb7SAndroid Build Coastguard Worker
1781*fd1fabb7SAndroid Build Coastguard Worker fActiveAreaData [0] = r.t;
1782*fd1fabb7SAndroid Build Coastguard Worker fActiveAreaData [1] = r.l;
1783*fd1fabb7SAndroid Build Coastguard Worker fActiveAreaData [2] = r.b;
1784*fd1fabb7SAndroid Build Coastguard Worker fActiveAreaData [3] = r.r;
1785*fd1fabb7SAndroid Build Coastguard Worker
1786*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fActiveArea);
1787*fd1fabb7SAndroid Build Coastguard Worker
1788*fd1fabb7SAndroid Build Coastguard Worker }
1789*fd1fabb7SAndroid Build Coastguard Worker
1790*fd1fabb7SAndroid Build Coastguard Worker }
1791*fd1fabb7SAndroid Build Coastguard Worker
1792*fd1fabb7SAndroid Build Coastguard Worker // MaskedAreas:
1793*fd1fabb7SAndroid Build Coastguard Worker
1794*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo->fMaskedAreaCount)
1795*fd1fabb7SAndroid Build Coastguard Worker {
1796*fd1fabb7SAndroid Build Coastguard Worker
1797*fd1fabb7SAndroid Build Coastguard Worker fMaskedAreas.SetCount (rangeInfo->fMaskedAreaCount * 4);
1798*fd1fabb7SAndroid Build Coastguard Worker
1799*fd1fabb7SAndroid Build Coastguard Worker for (uint32 index = 0; index < rangeInfo->fMaskedAreaCount; index++)
1800*fd1fabb7SAndroid Build Coastguard Worker {
1801*fd1fabb7SAndroid Build Coastguard Worker
1802*fd1fabb7SAndroid Build Coastguard Worker const dng_rect &r = rangeInfo->fMaskedArea [index];
1803*fd1fabb7SAndroid Build Coastguard Worker
1804*fd1fabb7SAndroid Build Coastguard Worker fMaskedAreaData [index * 4 + 0] = r.t;
1805*fd1fabb7SAndroid Build Coastguard Worker fMaskedAreaData [index * 4 + 1] = r.l;
1806*fd1fabb7SAndroid Build Coastguard Worker fMaskedAreaData [index * 4 + 2] = r.b;
1807*fd1fabb7SAndroid Build Coastguard Worker fMaskedAreaData [index * 4 + 3] = r.r;
1808*fd1fabb7SAndroid Build Coastguard Worker
1809*fd1fabb7SAndroid Build Coastguard Worker }
1810*fd1fabb7SAndroid Build Coastguard Worker
1811*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fMaskedAreas);
1812*fd1fabb7SAndroid Build Coastguard Worker
1813*fd1fabb7SAndroid Build Coastguard Worker }
1814*fd1fabb7SAndroid Build Coastguard Worker
1815*fd1fabb7SAndroid Build Coastguard Worker // LinearizationTable:
1816*fd1fabb7SAndroid Build Coastguard Worker
1817*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo->fLinearizationTable.Get ())
1818*fd1fabb7SAndroid Build Coastguard Worker {
1819*fd1fabb7SAndroid Build Coastguard Worker
1820*fd1fabb7SAndroid Build Coastguard Worker fLinearizationTable.SetData (rangeInfo->fLinearizationTable->Buffer_uint16 () );
1821*fd1fabb7SAndroid Build Coastguard Worker fLinearizationTable.SetCount (rangeInfo->fLinearizationTable->LogicalSize () >> 1);
1822*fd1fabb7SAndroid Build Coastguard Worker
1823*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fLinearizationTable);
1824*fd1fabb7SAndroid Build Coastguard Worker
1825*fd1fabb7SAndroid Build Coastguard Worker }
1826*fd1fabb7SAndroid Build Coastguard Worker
1827*fd1fabb7SAndroid Build Coastguard Worker // BlackLevelRepeatDim:
1828*fd1fabb7SAndroid Build Coastguard Worker
1829*fd1fabb7SAndroid Build Coastguard Worker {
1830*fd1fabb7SAndroid Build Coastguard Worker
1831*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelRepeatDimData [0] = (uint16) rangeInfo->fBlackLevelRepeatRows;
1832*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelRepeatDimData [1] = (uint16) rangeInfo->fBlackLevelRepeatCols;
1833*fd1fabb7SAndroid Build Coastguard Worker
1834*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBlackLevelRepeatDim);
1835*fd1fabb7SAndroid Build Coastguard Worker
1836*fd1fabb7SAndroid Build Coastguard Worker }
1837*fd1fabb7SAndroid Build Coastguard Worker
1838*fd1fabb7SAndroid Build Coastguard Worker // BlackLevel:
1839*fd1fabb7SAndroid Build Coastguard Worker
1840*fd1fabb7SAndroid Build Coastguard Worker {
1841*fd1fabb7SAndroid Build Coastguard Worker
1842*fd1fabb7SAndroid Build Coastguard Worker uint32 index = 0;
1843*fd1fabb7SAndroid Build Coastguard Worker
1844*fd1fabb7SAndroid Build Coastguard Worker for (uint16 v = 0; v < rangeInfo->fBlackLevelRepeatRows; v++)
1845*fd1fabb7SAndroid Build Coastguard Worker {
1846*fd1fabb7SAndroid Build Coastguard Worker
1847*fd1fabb7SAndroid Build Coastguard Worker for (uint32 h = 0; h < rangeInfo->fBlackLevelRepeatCols; h++)
1848*fd1fabb7SAndroid Build Coastguard Worker {
1849*fd1fabb7SAndroid Build Coastguard Worker
1850*fd1fabb7SAndroid Build Coastguard Worker for (uint32 c = 0; c < rawImage.Planes (); c++)
1851*fd1fabb7SAndroid Build Coastguard Worker {
1852*fd1fabb7SAndroid Build Coastguard Worker
1853*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelData [index++] = rangeInfo->BlackLevel (v, h, c);
1854*fd1fabb7SAndroid Build Coastguard Worker
1855*fd1fabb7SAndroid Build Coastguard Worker }
1856*fd1fabb7SAndroid Build Coastguard Worker
1857*fd1fabb7SAndroid Build Coastguard Worker }
1858*fd1fabb7SAndroid Build Coastguard Worker
1859*fd1fabb7SAndroid Build Coastguard Worker }
1860*fd1fabb7SAndroid Build Coastguard Worker
1861*fd1fabb7SAndroid Build Coastguard Worker fBlackLevel.SetCount (rangeInfo->fBlackLevelRepeatRows *
1862*fd1fabb7SAndroid Build Coastguard Worker rangeInfo->fBlackLevelRepeatCols * rawImage.Planes ());
1863*fd1fabb7SAndroid Build Coastguard Worker
1864*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBlackLevel);
1865*fd1fabb7SAndroid Build Coastguard Worker
1866*fd1fabb7SAndroid Build Coastguard Worker }
1867*fd1fabb7SAndroid Build Coastguard Worker
1868*fd1fabb7SAndroid Build Coastguard Worker // BlackLevelDeltaH:
1869*fd1fabb7SAndroid Build Coastguard Worker
1870*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo->ColumnBlackCount ())
1871*fd1fabb7SAndroid Build Coastguard Worker {
1872*fd1fabb7SAndroid Build Coastguard Worker
1873*fd1fabb7SAndroid Build Coastguard Worker uint32 count = rangeInfo->ColumnBlackCount ();
1874*fd1fabb7SAndroid Build Coastguard Worker
1875*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelDeltaHData.Allocate (count, sizeof (dng_srational));
1876*fd1fabb7SAndroid Build Coastguard Worker
1877*fd1fabb7SAndroid Build Coastguard Worker dng_srational *blacks = (dng_srational *) fBlackLevelDeltaHData.Buffer ();
1878*fd1fabb7SAndroid Build Coastguard Worker
1879*fd1fabb7SAndroid Build Coastguard Worker for (uint32 col = 0; col < count; col++)
1880*fd1fabb7SAndroid Build Coastguard Worker {
1881*fd1fabb7SAndroid Build Coastguard Worker
1882*fd1fabb7SAndroid Build Coastguard Worker blacks [col] = rangeInfo->ColumnBlack (col);
1883*fd1fabb7SAndroid Build Coastguard Worker
1884*fd1fabb7SAndroid Build Coastguard Worker }
1885*fd1fabb7SAndroid Build Coastguard Worker
1886*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelDeltaH.SetData (blacks);
1887*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelDeltaH.SetCount (count );
1888*fd1fabb7SAndroid Build Coastguard Worker
1889*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBlackLevelDeltaH);
1890*fd1fabb7SAndroid Build Coastguard Worker
1891*fd1fabb7SAndroid Build Coastguard Worker }
1892*fd1fabb7SAndroid Build Coastguard Worker
1893*fd1fabb7SAndroid Build Coastguard Worker // BlackLevelDeltaV:
1894*fd1fabb7SAndroid Build Coastguard Worker
1895*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo->RowBlackCount ())
1896*fd1fabb7SAndroid Build Coastguard Worker {
1897*fd1fabb7SAndroid Build Coastguard Worker
1898*fd1fabb7SAndroid Build Coastguard Worker uint32 count = rangeInfo->RowBlackCount ();
1899*fd1fabb7SAndroid Build Coastguard Worker
1900*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelDeltaVData.Allocate (count, sizeof (dng_srational));
1901*fd1fabb7SAndroid Build Coastguard Worker
1902*fd1fabb7SAndroid Build Coastguard Worker dng_srational *blacks = (dng_srational *) fBlackLevelDeltaVData.Buffer ();
1903*fd1fabb7SAndroid Build Coastguard Worker
1904*fd1fabb7SAndroid Build Coastguard Worker for (uint32 row = 0; row < count; row++)
1905*fd1fabb7SAndroid Build Coastguard Worker {
1906*fd1fabb7SAndroid Build Coastguard Worker
1907*fd1fabb7SAndroid Build Coastguard Worker blacks [row] = rangeInfo->RowBlack (row);
1908*fd1fabb7SAndroid Build Coastguard Worker
1909*fd1fabb7SAndroid Build Coastguard Worker }
1910*fd1fabb7SAndroid Build Coastguard Worker
1911*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelDeltaV.SetData (blacks);
1912*fd1fabb7SAndroid Build Coastguard Worker fBlackLevelDeltaV.SetCount (count );
1913*fd1fabb7SAndroid Build Coastguard Worker
1914*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBlackLevelDeltaV);
1915*fd1fabb7SAndroid Build Coastguard Worker
1916*fd1fabb7SAndroid Build Coastguard Worker }
1917*fd1fabb7SAndroid Build Coastguard Worker
1918*fd1fabb7SAndroid Build Coastguard Worker }
1919*fd1fabb7SAndroid Build Coastguard Worker
1920*fd1fabb7SAndroid Build Coastguard Worker // WhiteLevel:
1921*fd1fabb7SAndroid Build Coastguard Worker
1922*fd1fabb7SAndroid Build Coastguard Worker // Only use the 32-bit data type if we must use it since there
1923*fd1fabb7SAndroid Build Coastguard Worker // are some lazy (non-Adobe) DNG readers out there.
1924*fd1fabb7SAndroid Build Coastguard Worker
1925*fd1fabb7SAndroid Build Coastguard Worker bool needs32 = false;
1926*fd1fabb7SAndroid Build Coastguard Worker
1927*fd1fabb7SAndroid Build Coastguard Worker fWhiteLevel16.SetCount (rawImage.Planes ());
1928*fd1fabb7SAndroid Build Coastguard Worker fWhiteLevel32.SetCount (rawImage.Planes ());
1929*fd1fabb7SAndroid Build Coastguard Worker
1930*fd1fabb7SAndroid Build Coastguard Worker for (uint32 c = 0; c < fWhiteLevel16.Count (); c++)
1931*fd1fabb7SAndroid Build Coastguard Worker {
1932*fd1fabb7SAndroid Build Coastguard Worker
1933*fd1fabb7SAndroid Build Coastguard Worker fWhiteLevelData32 [c] = negative.WhiteLevel (c);
1934*fd1fabb7SAndroid Build Coastguard Worker
1935*fd1fabb7SAndroid Build Coastguard Worker if (fWhiteLevelData32 [c] > 0x0FFFF)
1936*fd1fabb7SAndroid Build Coastguard Worker {
1937*fd1fabb7SAndroid Build Coastguard Worker needs32 = true;
1938*fd1fabb7SAndroid Build Coastguard Worker }
1939*fd1fabb7SAndroid Build Coastguard Worker
1940*fd1fabb7SAndroid Build Coastguard Worker fWhiteLevelData16 [c] = (uint16) fWhiteLevelData32 [c];
1941*fd1fabb7SAndroid Build Coastguard Worker
1942*fd1fabb7SAndroid Build Coastguard Worker }
1943*fd1fabb7SAndroid Build Coastguard Worker
1944*fd1fabb7SAndroid Build Coastguard Worker if (needs32)
1945*fd1fabb7SAndroid Build Coastguard Worker {
1946*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fWhiteLevel32);
1947*fd1fabb7SAndroid Build Coastguard Worker }
1948*fd1fabb7SAndroid Build Coastguard Worker
1949*fd1fabb7SAndroid Build Coastguard Worker else
1950*fd1fabb7SAndroid Build Coastguard Worker {
1951*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fWhiteLevel16);
1952*fd1fabb7SAndroid Build Coastguard Worker }
1953*fd1fabb7SAndroid Build Coastguard Worker
1954*fd1fabb7SAndroid Build Coastguard Worker }
1955*fd1fabb7SAndroid Build Coastguard Worker
1956*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
1957*fd1fabb7SAndroid Build Coastguard Worker
1958*fd1fabb7SAndroid Build Coastguard Worker class mosaic_tag_set
1959*fd1fabb7SAndroid Build Coastguard Worker {
1960*fd1fabb7SAndroid Build Coastguard Worker
1961*fd1fabb7SAndroid Build Coastguard Worker private:
1962*fd1fabb7SAndroid Build Coastguard Worker
1963*fd1fabb7SAndroid Build Coastguard Worker uint16 fCFARepeatPatternDimData [2];
1964*fd1fabb7SAndroid Build Coastguard Worker
1965*fd1fabb7SAndroid Build Coastguard Worker tag_uint16_ptr fCFARepeatPatternDim;
1966*fd1fabb7SAndroid Build Coastguard Worker
1967*fd1fabb7SAndroid Build Coastguard Worker uint8 fCFAPatternData [kMaxCFAPattern *
1968*fd1fabb7SAndroid Build Coastguard Worker kMaxCFAPattern];
1969*fd1fabb7SAndroid Build Coastguard Worker
1970*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr fCFAPattern;
1971*fd1fabb7SAndroid Build Coastguard Worker
1972*fd1fabb7SAndroid Build Coastguard Worker uint8 fCFAPlaneColorData [kMaxColorPlanes];
1973*fd1fabb7SAndroid Build Coastguard Worker
1974*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr fCFAPlaneColor;
1975*fd1fabb7SAndroid Build Coastguard Worker
1976*fd1fabb7SAndroid Build Coastguard Worker tag_uint16 fCFALayout;
1977*fd1fabb7SAndroid Build Coastguard Worker
1978*fd1fabb7SAndroid Build Coastguard Worker tag_uint32 fGreenSplit;
1979*fd1fabb7SAndroid Build Coastguard Worker
1980*fd1fabb7SAndroid Build Coastguard Worker public:
1981*fd1fabb7SAndroid Build Coastguard Worker
1982*fd1fabb7SAndroid Build Coastguard Worker mosaic_tag_set (dng_tiff_directory &directory,
1983*fd1fabb7SAndroid Build Coastguard Worker const dng_mosaic_info &info);
1984*fd1fabb7SAndroid Build Coastguard Worker
1985*fd1fabb7SAndroid Build Coastguard Worker };
1986*fd1fabb7SAndroid Build Coastguard Worker
1987*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
1988*fd1fabb7SAndroid Build Coastguard Worker
mosaic_tag_set(dng_tiff_directory & directory,const dng_mosaic_info & info)1989*fd1fabb7SAndroid Build Coastguard Worker mosaic_tag_set::mosaic_tag_set (dng_tiff_directory &directory,
1990*fd1fabb7SAndroid Build Coastguard Worker const dng_mosaic_info &info)
1991*fd1fabb7SAndroid Build Coastguard Worker
1992*fd1fabb7SAndroid Build Coastguard Worker : fCFARepeatPatternDim (tcCFARepeatPatternDim,
1993*fd1fabb7SAndroid Build Coastguard Worker fCFARepeatPatternDimData,
1994*fd1fabb7SAndroid Build Coastguard Worker 2)
1995*fd1fabb7SAndroid Build Coastguard Worker
1996*fd1fabb7SAndroid Build Coastguard Worker , fCFAPattern (tcCFAPattern,
1997*fd1fabb7SAndroid Build Coastguard Worker fCFAPatternData)
1998*fd1fabb7SAndroid Build Coastguard Worker
1999*fd1fabb7SAndroid Build Coastguard Worker , fCFAPlaneColor (tcCFAPlaneColor,
2000*fd1fabb7SAndroid Build Coastguard Worker fCFAPlaneColorData)
2001*fd1fabb7SAndroid Build Coastguard Worker
2002*fd1fabb7SAndroid Build Coastguard Worker , fCFALayout (tcCFALayout,
2003*fd1fabb7SAndroid Build Coastguard Worker (uint16) info.fCFALayout)
2004*fd1fabb7SAndroid Build Coastguard Worker
2005*fd1fabb7SAndroid Build Coastguard Worker , fGreenSplit (tcBayerGreenSplit,
2006*fd1fabb7SAndroid Build Coastguard Worker info.fBayerGreenSplit)
2007*fd1fabb7SAndroid Build Coastguard Worker
2008*fd1fabb7SAndroid Build Coastguard Worker {
2009*fd1fabb7SAndroid Build Coastguard Worker
2010*fd1fabb7SAndroid Build Coastguard Worker if (info.IsColorFilterArray ())
2011*fd1fabb7SAndroid Build Coastguard Worker {
2012*fd1fabb7SAndroid Build Coastguard Worker
2013*fd1fabb7SAndroid Build Coastguard Worker // CFARepeatPatternDim:
2014*fd1fabb7SAndroid Build Coastguard Worker
2015*fd1fabb7SAndroid Build Coastguard Worker fCFARepeatPatternDimData [0] = (uint16) info.fCFAPatternSize.v;
2016*fd1fabb7SAndroid Build Coastguard Worker fCFARepeatPatternDimData [1] = (uint16) info.fCFAPatternSize.h;
2017*fd1fabb7SAndroid Build Coastguard Worker
2018*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCFARepeatPatternDim);
2019*fd1fabb7SAndroid Build Coastguard Worker
2020*fd1fabb7SAndroid Build Coastguard Worker // CFAPattern:
2021*fd1fabb7SAndroid Build Coastguard Worker
2022*fd1fabb7SAndroid Build Coastguard Worker fCFAPattern.SetCount (info.fCFAPatternSize.v *
2023*fd1fabb7SAndroid Build Coastguard Worker info.fCFAPatternSize.h);
2024*fd1fabb7SAndroid Build Coastguard Worker
2025*fd1fabb7SAndroid Build Coastguard Worker for (int32 r = 0; r < info.fCFAPatternSize.v; r++)
2026*fd1fabb7SAndroid Build Coastguard Worker {
2027*fd1fabb7SAndroid Build Coastguard Worker
2028*fd1fabb7SAndroid Build Coastguard Worker for (int32 c = 0; c < info.fCFAPatternSize.h; c++)
2029*fd1fabb7SAndroid Build Coastguard Worker {
2030*fd1fabb7SAndroid Build Coastguard Worker
2031*fd1fabb7SAndroid Build Coastguard Worker fCFAPatternData [r * info.fCFAPatternSize.h + c] = info.fCFAPattern [r] [c];
2032*fd1fabb7SAndroid Build Coastguard Worker
2033*fd1fabb7SAndroid Build Coastguard Worker }
2034*fd1fabb7SAndroid Build Coastguard Worker
2035*fd1fabb7SAndroid Build Coastguard Worker }
2036*fd1fabb7SAndroid Build Coastguard Worker
2037*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCFAPattern);
2038*fd1fabb7SAndroid Build Coastguard Worker
2039*fd1fabb7SAndroid Build Coastguard Worker // CFAPlaneColor:
2040*fd1fabb7SAndroid Build Coastguard Worker
2041*fd1fabb7SAndroid Build Coastguard Worker fCFAPlaneColor.SetCount (info.fColorPlanes);
2042*fd1fabb7SAndroid Build Coastguard Worker
2043*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < info.fColorPlanes; j++)
2044*fd1fabb7SAndroid Build Coastguard Worker {
2045*fd1fabb7SAndroid Build Coastguard Worker
2046*fd1fabb7SAndroid Build Coastguard Worker fCFAPlaneColorData [j] = info.fCFAPlaneColor [j];
2047*fd1fabb7SAndroid Build Coastguard Worker
2048*fd1fabb7SAndroid Build Coastguard Worker }
2049*fd1fabb7SAndroid Build Coastguard Worker
2050*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCFAPlaneColor);
2051*fd1fabb7SAndroid Build Coastguard Worker
2052*fd1fabb7SAndroid Build Coastguard Worker // CFALayout:
2053*fd1fabb7SAndroid Build Coastguard Worker
2054*fd1fabb7SAndroid Build Coastguard Worker fCFALayout.Set ((uint16) info.fCFALayout);
2055*fd1fabb7SAndroid Build Coastguard Worker
2056*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCFALayout);
2057*fd1fabb7SAndroid Build Coastguard Worker
2058*fd1fabb7SAndroid Build Coastguard Worker // BayerGreenSplit: (only include if the pattern is a Bayer pattern)
2059*fd1fabb7SAndroid Build Coastguard Worker
2060*fd1fabb7SAndroid Build Coastguard Worker if (info.fCFAPatternSize == dng_point (2, 2) &&
2061*fd1fabb7SAndroid Build Coastguard Worker info.fColorPlanes == 3)
2062*fd1fabb7SAndroid Build Coastguard Worker {
2063*fd1fabb7SAndroid Build Coastguard Worker
2064*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fGreenSplit);
2065*fd1fabb7SAndroid Build Coastguard Worker
2066*fd1fabb7SAndroid Build Coastguard Worker }
2067*fd1fabb7SAndroid Build Coastguard Worker
2068*fd1fabb7SAndroid Build Coastguard Worker }
2069*fd1fabb7SAndroid Build Coastguard Worker
2070*fd1fabb7SAndroid Build Coastguard Worker }
2071*fd1fabb7SAndroid Build Coastguard Worker
2072*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2073*fd1fabb7SAndroid Build Coastguard Worker
2074*fd1fabb7SAndroid Build Coastguard Worker class color_tag_set
2075*fd1fabb7SAndroid Build Coastguard Worker {
2076*fd1fabb7SAndroid Build Coastguard Worker
2077*fd1fabb7SAndroid Build Coastguard Worker private:
2078*fd1fabb7SAndroid Build Coastguard Worker
2079*fd1fabb7SAndroid Build Coastguard Worker uint32 fColorChannels;
2080*fd1fabb7SAndroid Build Coastguard Worker
2081*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fCameraCalibration1;
2082*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fCameraCalibration2;
2083*fd1fabb7SAndroid Build Coastguard Worker
2084*fd1fabb7SAndroid Build Coastguard Worker tag_string fCameraCalibrationSignature;
2085*fd1fabb7SAndroid Build Coastguard Worker
2086*fd1fabb7SAndroid Build Coastguard Worker tag_string fAsShotProfileName;
2087*fd1fabb7SAndroid Build Coastguard Worker
2088*fd1fabb7SAndroid Build Coastguard Worker dng_urational fAnalogBalanceData [4];
2089*fd1fabb7SAndroid Build Coastguard Worker
2090*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr fAnalogBalance;
2091*fd1fabb7SAndroid Build Coastguard Worker
2092*fd1fabb7SAndroid Build Coastguard Worker dng_urational fAsShotNeutralData [4];
2093*fd1fabb7SAndroid Build Coastguard Worker
2094*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr fAsShotNeutral;
2095*fd1fabb7SAndroid Build Coastguard Worker
2096*fd1fabb7SAndroid Build Coastguard Worker dng_urational fAsShotWhiteXYData [2];
2097*fd1fabb7SAndroid Build Coastguard Worker
2098*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr fAsShotWhiteXY;
2099*fd1fabb7SAndroid Build Coastguard Worker
2100*fd1fabb7SAndroid Build Coastguard Worker tag_urational fLinearResponseLimit;
2101*fd1fabb7SAndroid Build Coastguard Worker
2102*fd1fabb7SAndroid Build Coastguard Worker public:
2103*fd1fabb7SAndroid Build Coastguard Worker
2104*fd1fabb7SAndroid Build Coastguard Worker color_tag_set (dng_tiff_directory &directory,
2105*fd1fabb7SAndroid Build Coastguard Worker const dng_negative &negative);
2106*fd1fabb7SAndroid Build Coastguard Worker
2107*fd1fabb7SAndroid Build Coastguard Worker };
2108*fd1fabb7SAndroid Build Coastguard Worker
2109*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2110*fd1fabb7SAndroid Build Coastguard Worker
color_tag_set(dng_tiff_directory & directory,const dng_negative & negative)2111*fd1fabb7SAndroid Build Coastguard Worker color_tag_set::color_tag_set (dng_tiff_directory &directory,
2112*fd1fabb7SAndroid Build Coastguard Worker const dng_negative &negative)
2113*fd1fabb7SAndroid Build Coastguard Worker
2114*fd1fabb7SAndroid Build Coastguard Worker : fColorChannels (negative.ColorChannels ())
2115*fd1fabb7SAndroid Build Coastguard Worker
2116*fd1fabb7SAndroid Build Coastguard Worker , fCameraCalibration1 (tcCameraCalibration1,
2117*fd1fabb7SAndroid Build Coastguard Worker negative.CameraCalibration1 ())
2118*fd1fabb7SAndroid Build Coastguard Worker
2119*fd1fabb7SAndroid Build Coastguard Worker , fCameraCalibration2 (tcCameraCalibration2,
2120*fd1fabb7SAndroid Build Coastguard Worker negative.CameraCalibration2 ())
2121*fd1fabb7SAndroid Build Coastguard Worker
2122*fd1fabb7SAndroid Build Coastguard Worker , fCameraCalibrationSignature (tcCameraCalibrationSignature,
2123*fd1fabb7SAndroid Build Coastguard Worker negative.CameraCalibrationSignature ())
2124*fd1fabb7SAndroid Build Coastguard Worker
2125*fd1fabb7SAndroid Build Coastguard Worker , fAsShotProfileName (tcAsShotProfileName,
2126*fd1fabb7SAndroid Build Coastguard Worker negative.AsShotProfileName ())
2127*fd1fabb7SAndroid Build Coastguard Worker
2128*fd1fabb7SAndroid Build Coastguard Worker , fAnalogBalance (tcAnalogBalance,
2129*fd1fabb7SAndroid Build Coastguard Worker fAnalogBalanceData,
2130*fd1fabb7SAndroid Build Coastguard Worker fColorChannels)
2131*fd1fabb7SAndroid Build Coastguard Worker
2132*fd1fabb7SAndroid Build Coastguard Worker , fAsShotNeutral (tcAsShotNeutral,
2133*fd1fabb7SAndroid Build Coastguard Worker fAsShotNeutralData,
2134*fd1fabb7SAndroid Build Coastguard Worker fColorChannels)
2135*fd1fabb7SAndroid Build Coastguard Worker
2136*fd1fabb7SAndroid Build Coastguard Worker , fAsShotWhiteXY (tcAsShotWhiteXY,
2137*fd1fabb7SAndroid Build Coastguard Worker fAsShotWhiteXYData,
2138*fd1fabb7SAndroid Build Coastguard Worker 2)
2139*fd1fabb7SAndroid Build Coastguard Worker
2140*fd1fabb7SAndroid Build Coastguard Worker , fLinearResponseLimit (tcLinearResponseLimit,
2141*fd1fabb7SAndroid Build Coastguard Worker negative.LinearResponseLimitR ())
2142*fd1fabb7SAndroid Build Coastguard Worker
2143*fd1fabb7SAndroid Build Coastguard Worker {
2144*fd1fabb7SAndroid Build Coastguard Worker
2145*fd1fabb7SAndroid Build Coastguard Worker if (fColorChannels > 1)
2146*fd1fabb7SAndroid Build Coastguard Worker {
2147*fd1fabb7SAndroid Build Coastguard Worker
2148*fd1fabb7SAndroid Build Coastguard Worker uint32 channels2 = fColorChannels * fColorChannels;
2149*fd1fabb7SAndroid Build Coastguard Worker
2150*fd1fabb7SAndroid Build Coastguard Worker if (fCameraCalibration1.Count () == channels2)
2151*fd1fabb7SAndroid Build Coastguard Worker {
2152*fd1fabb7SAndroid Build Coastguard Worker
2153*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCameraCalibration1);
2154*fd1fabb7SAndroid Build Coastguard Worker
2155*fd1fabb7SAndroid Build Coastguard Worker }
2156*fd1fabb7SAndroid Build Coastguard Worker
2157*fd1fabb7SAndroid Build Coastguard Worker if (fCameraCalibration2.Count () == channels2)
2158*fd1fabb7SAndroid Build Coastguard Worker {
2159*fd1fabb7SAndroid Build Coastguard Worker
2160*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCameraCalibration2);
2161*fd1fabb7SAndroid Build Coastguard Worker
2162*fd1fabb7SAndroid Build Coastguard Worker }
2163*fd1fabb7SAndroid Build Coastguard Worker
2164*fd1fabb7SAndroid Build Coastguard Worker if (fCameraCalibration1.Count () == channels2 ||
2165*fd1fabb7SAndroid Build Coastguard Worker fCameraCalibration2.Count () == channels2)
2166*fd1fabb7SAndroid Build Coastguard Worker {
2167*fd1fabb7SAndroid Build Coastguard Worker
2168*fd1fabb7SAndroid Build Coastguard Worker if (negative.CameraCalibrationSignature ().NotEmpty ())
2169*fd1fabb7SAndroid Build Coastguard Worker {
2170*fd1fabb7SAndroid Build Coastguard Worker
2171*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCameraCalibrationSignature);
2172*fd1fabb7SAndroid Build Coastguard Worker
2173*fd1fabb7SAndroid Build Coastguard Worker }
2174*fd1fabb7SAndroid Build Coastguard Worker
2175*fd1fabb7SAndroid Build Coastguard Worker }
2176*fd1fabb7SAndroid Build Coastguard Worker
2177*fd1fabb7SAndroid Build Coastguard Worker if (negative.AsShotProfileName ().NotEmpty ())
2178*fd1fabb7SAndroid Build Coastguard Worker {
2179*fd1fabb7SAndroid Build Coastguard Worker
2180*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fAsShotProfileName);
2181*fd1fabb7SAndroid Build Coastguard Worker
2182*fd1fabb7SAndroid Build Coastguard Worker }
2183*fd1fabb7SAndroid Build Coastguard Worker
2184*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < fColorChannels; j++)
2185*fd1fabb7SAndroid Build Coastguard Worker {
2186*fd1fabb7SAndroid Build Coastguard Worker
2187*fd1fabb7SAndroid Build Coastguard Worker fAnalogBalanceData [j] = negative.AnalogBalanceR (j);
2188*fd1fabb7SAndroid Build Coastguard Worker
2189*fd1fabb7SAndroid Build Coastguard Worker }
2190*fd1fabb7SAndroid Build Coastguard Worker
2191*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fAnalogBalance);
2192*fd1fabb7SAndroid Build Coastguard Worker
2193*fd1fabb7SAndroid Build Coastguard Worker if (negative.HasCameraNeutral ())
2194*fd1fabb7SAndroid Build Coastguard Worker {
2195*fd1fabb7SAndroid Build Coastguard Worker
2196*fd1fabb7SAndroid Build Coastguard Worker for (uint32 k = 0; k < fColorChannels; k++)
2197*fd1fabb7SAndroid Build Coastguard Worker {
2198*fd1fabb7SAndroid Build Coastguard Worker
2199*fd1fabb7SAndroid Build Coastguard Worker fAsShotNeutralData [k] = negative.CameraNeutralR (k);
2200*fd1fabb7SAndroid Build Coastguard Worker
2201*fd1fabb7SAndroid Build Coastguard Worker }
2202*fd1fabb7SAndroid Build Coastguard Worker
2203*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fAsShotNeutral);
2204*fd1fabb7SAndroid Build Coastguard Worker
2205*fd1fabb7SAndroid Build Coastguard Worker }
2206*fd1fabb7SAndroid Build Coastguard Worker
2207*fd1fabb7SAndroid Build Coastguard Worker else if (negative.HasCameraWhiteXY ())
2208*fd1fabb7SAndroid Build Coastguard Worker {
2209*fd1fabb7SAndroid Build Coastguard Worker
2210*fd1fabb7SAndroid Build Coastguard Worker negative.GetCameraWhiteXY (fAsShotWhiteXYData [0],
2211*fd1fabb7SAndroid Build Coastguard Worker fAsShotWhiteXYData [1]);
2212*fd1fabb7SAndroid Build Coastguard Worker
2213*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fAsShotWhiteXY);
2214*fd1fabb7SAndroid Build Coastguard Worker
2215*fd1fabb7SAndroid Build Coastguard Worker }
2216*fd1fabb7SAndroid Build Coastguard Worker
2217*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fLinearResponseLimit);
2218*fd1fabb7SAndroid Build Coastguard Worker
2219*fd1fabb7SAndroid Build Coastguard Worker }
2220*fd1fabb7SAndroid Build Coastguard Worker
2221*fd1fabb7SAndroid Build Coastguard Worker }
2222*fd1fabb7SAndroid Build Coastguard Worker
2223*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2224*fd1fabb7SAndroid Build Coastguard Worker
2225*fd1fabb7SAndroid Build Coastguard Worker class profile_tag_set
2226*fd1fabb7SAndroid Build Coastguard Worker {
2227*fd1fabb7SAndroid Build Coastguard Worker
2228*fd1fabb7SAndroid Build Coastguard Worker private:
2229*fd1fabb7SAndroid Build Coastguard Worker
2230*fd1fabb7SAndroid Build Coastguard Worker tag_uint16 fCalibrationIlluminant1;
2231*fd1fabb7SAndroid Build Coastguard Worker tag_uint16 fCalibrationIlluminant2;
2232*fd1fabb7SAndroid Build Coastguard Worker
2233*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fColorMatrix1;
2234*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fColorMatrix2;
2235*fd1fabb7SAndroid Build Coastguard Worker
2236*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fForwardMatrix1;
2237*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fForwardMatrix2;
2238*fd1fabb7SAndroid Build Coastguard Worker
2239*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fReductionMatrix1;
2240*fd1fabb7SAndroid Build Coastguard Worker tag_matrix fReductionMatrix2;
2241*fd1fabb7SAndroid Build Coastguard Worker
2242*fd1fabb7SAndroid Build Coastguard Worker tag_string fProfileName;
2243*fd1fabb7SAndroid Build Coastguard Worker
2244*fd1fabb7SAndroid Build Coastguard Worker tag_string fProfileCalibrationSignature;
2245*fd1fabb7SAndroid Build Coastguard Worker
2246*fd1fabb7SAndroid Build Coastguard Worker tag_uint32 fEmbedPolicyTag;
2247*fd1fabb7SAndroid Build Coastguard Worker
2248*fd1fabb7SAndroid Build Coastguard Worker tag_string fCopyrightTag;
2249*fd1fabb7SAndroid Build Coastguard Worker
2250*fd1fabb7SAndroid Build Coastguard Worker uint32 fHueSatMapDimData [3];
2251*fd1fabb7SAndroid Build Coastguard Worker
2252*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr fHueSatMapDims;
2253*fd1fabb7SAndroid Build Coastguard Worker
2254*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr fHueSatData1;
2255*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr fHueSatData2;
2256*fd1fabb7SAndroid Build Coastguard Worker
2257*fd1fabb7SAndroid Build Coastguard Worker tag_uint32 fHueSatMapEncodingTag;
2258*fd1fabb7SAndroid Build Coastguard Worker
2259*fd1fabb7SAndroid Build Coastguard Worker uint32 fLookTableDimData [3];
2260*fd1fabb7SAndroid Build Coastguard Worker
2261*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr fLookTableDims;
2262*fd1fabb7SAndroid Build Coastguard Worker
2263*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr fLookTableData;
2264*fd1fabb7SAndroid Build Coastguard Worker
2265*fd1fabb7SAndroid Build Coastguard Worker tag_uint32 fLookTableEncodingTag;
2266*fd1fabb7SAndroid Build Coastguard Worker
2267*fd1fabb7SAndroid Build Coastguard Worker tag_srational fBaselineExposureOffsetTag;
2268*fd1fabb7SAndroid Build Coastguard Worker
2269*fd1fabb7SAndroid Build Coastguard Worker tag_uint32 fDefaultBlackRenderTag;
2270*fd1fabb7SAndroid Build Coastguard Worker
2271*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data fToneCurveBuffer;
2272*fd1fabb7SAndroid Build Coastguard Worker
2273*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr fToneCurveTag;
2274*fd1fabb7SAndroid Build Coastguard Worker
2275*fd1fabb7SAndroid Build Coastguard Worker public:
2276*fd1fabb7SAndroid Build Coastguard Worker
2277*fd1fabb7SAndroid Build Coastguard Worker profile_tag_set (dng_tiff_directory &directory,
2278*fd1fabb7SAndroid Build Coastguard Worker const dng_camera_profile &profile);
2279*fd1fabb7SAndroid Build Coastguard Worker
2280*fd1fabb7SAndroid Build Coastguard Worker };
2281*fd1fabb7SAndroid Build Coastguard Worker
2282*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2283*fd1fabb7SAndroid Build Coastguard Worker
profile_tag_set(dng_tiff_directory & directory,const dng_camera_profile & profile)2284*fd1fabb7SAndroid Build Coastguard Worker profile_tag_set::profile_tag_set (dng_tiff_directory &directory,
2285*fd1fabb7SAndroid Build Coastguard Worker const dng_camera_profile &profile)
2286*fd1fabb7SAndroid Build Coastguard Worker
2287*fd1fabb7SAndroid Build Coastguard Worker : fCalibrationIlluminant1 (tcCalibrationIlluminant1,
2288*fd1fabb7SAndroid Build Coastguard Worker (uint16) profile.CalibrationIlluminant1 ())
2289*fd1fabb7SAndroid Build Coastguard Worker
2290*fd1fabb7SAndroid Build Coastguard Worker , fCalibrationIlluminant2 (tcCalibrationIlluminant2,
2291*fd1fabb7SAndroid Build Coastguard Worker (uint16) profile.CalibrationIlluminant2 ())
2292*fd1fabb7SAndroid Build Coastguard Worker
2293*fd1fabb7SAndroid Build Coastguard Worker , fColorMatrix1 (tcColorMatrix1,
2294*fd1fabb7SAndroid Build Coastguard Worker profile.ColorMatrix1 ())
2295*fd1fabb7SAndroid Build Coastguard Worker
2296*fd1fabb7SAndroid Build Coastguard Worker , fColorMatrix2 (tcColorMatrix2,
2297*fd1fabb7SAndroid Build Coastguard Worker profile.ColorMatrix2 ())
2298*fd1fabb7SAndroid Build Coastguard Worker
2299*fd1fabb7SAndroid Build Coastguard Worker , fForwardMatrix1 (tcForwardMatrix1,
2300*fd1fabb7SAndroid Build Coastguard Worker profile.ForwardMatrix1 ())
2301*fd1fabb7SAndroid Build Coastguard Worker
2302*fd1fabb7SAndroid Build Coastguard Worker , fForwardMatrix2 (tcForwardMatrix2,
2303*fd1fabb7SAndroid Build Coastguard Worker profile.ForwardMatrix2 ())
2304*fd1fabb7SAndroid Build Coastguard Worker
2305*fd1fabb7SAndroid Build Coastguard Worker , fReductionMatrix1 (tcReductionMatrix1,
2306*fd1fabb7SAndroid Build Coastguard Worker profile.ReductionMatrix1 ())
2307*fd1fabb7SAndroid Build Coastguard Worker
2308*fd1fabb7SAndroid Build Coastguard Worker , fReductionMatrix2 (tcReductionMatrix2,
2309*fd1fabb7SAndroid Build Coastguard Worker profile.ReductionMatrix2 ())
2310*fd1fabb7SAndroid Build Coastguard Worker
2311*fd1fabb7SAndroid Build Coastguard Worker , fProfileName (tcProfileName,
2312*fd1fabb7SAndroid Build Coastguard Worker profile.Name (),
2313*fd1fabb7SAndroid Build Coastguard Worker false)
2314*fd1fabb7SAndroid Build Coastguard Worker
2315*fd1fabb7SAndroid Build Coastguard Worker , fProfileCalibrationSignature (tcProfileCalibrationSignature,
2316*fd1fabb7SAndroid Build Coastguard Worker profile.ProfileCalibrationSignature (),
2317*fd1fabb7SAndroid Build Coastguard Worker false)
2318*fd1fabb7SAndroid Build Coastguard Worker
2319*fd1fabb7SAndroid Build Coastguard Worker , fEmbedPolicyTag (tcProfileEmbedPolicy,
2320*fd1fabb7SAndroid Build Coastguard Worker profile.EmbedPolicy ())
2321*fd1fabb7SAndroid Build Coastguard Worker
2322*fd1fabb7SAndroid Build Coastguard Worker , fCopyrightTag (tcProfileCopyright,
2323*fd1fabb7SAndroid Build Coastguard Worker profile.Copyright (),
2324*fd1fabb7SAndroid Build Coastguard Worker false)
2325*fd1fabb7SAndroid Build Coastguard Worker
2326*fd1fabb7SAndroid Build Coastguard Worker , fHueSatMapDims (tcProfileHueSatMapDims,
2327*fd1fabb7SAndroid Build Coastguard Worker fHueSatMapDimData,
2328*fd1fabb7SAndroid Build Coastguard Worker 3)
2329*fd1fabb7SAndroid Build Coastguard Worker
2330*fd1fabb7SAndroid Build Coastguard Worker , fHueSatData1 (tcProfileHueSatMapData1,
2331*fd1fabb7SAndroid Build Coastguard Worker ttFloat,
2332*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatDeltas1 ().DeltasCount () * 3,
2333*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatDeltas1 ().GetConstDeltas ())
2334*fd1fabb7SAndroid Build Coastguard Worker
2335*fd1fabb7SAndroid Build Coastguard Worker , fHueSatData2 (tcProfileHueSatMapData2,
2336*fd1fabb7SAndroid Build Coastguard Worker ttFloat,
2337*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatDeltas2 ().DeltasCount () * 3,
2338*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatDeltas2 ().GetConstDeltas ())
2339*fd1fabb7SAndroid Build Coastguard Worker
2340*fd1fabb7SAndroid Build Coastguard Worker , fHueSatMapEncodingTag (tcProfileHueSatMapEncoding,
2341*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatMapEncoding ())
2342*fd1fabb7SAndroid Build Coastguard Worker
2343*fd1fabb7SAndroid Build Coastguard Worker , fLookTableDims (tcProfileLookTableDims,
2344*fd1fabb7SAndroid Build Coastguard Worker fLookTableDimData,
2345*fd1fabb7SAndroid Build Coastguard Worker 3)
2346*fd1fabb7SAndroid Build Coastguard Worker
2347*fd1fabb7SAndroid Build Coastguard Worker , fLookTableData (tcProfileLookTableData,
2348*fd1fabb7SAndroid Build Coastguard Worker ttFloat,
2349*fd1fabb7SAndroid Build Coastguard Worker profile.LookTable ().DeltasCount () * 3,
2350*fd1fabb7SAndroid Build Coastguard Worker profile.LookTable ().GetConstDeltas ())
2351*fd1fabb7SAndroid Build Coastguard Worker
2352*fd1fabb7SAndroid Build Coastguard Worker , fLookTableEncodingTag (tcProfileLookTableEncoding,
2353*fd1fabb7SAndroid Build Coastguard Worker profile.LookTableEncoding ())
2354*fd1fabb7SAndroid Build Coastguard Worker
2355*fd1fabb7SAndroid Build Coastguard Worker , fBaselineExposureOffsetTag (tcBaselineExposureOffset,
2356*fd1fabb7SAndroid Build Coastguard Worker profile.BaselineExposureOffset ())
2357*fd1fabb7SAndroid Build Coastguard Worker
2358*fd1fabb7SAndroid Build Coastguard Worker , fDefaultBlackRenderTag (tcDefaultBlackRender,
2359*fd1fabb7SAndroid Build Coastguard Worker profile.DefaultBlackRender ())
2360*fd1fabb7SAndroid Build Coastguard Worker
2361*fd1fabb7SAndroid Build Coastguard Worker , fToneCurveBuffer ()
2362*fd1fabb7SAndroid Build Coastguard Worker
2363*fd1fabb7SAndroid Build Coastguard Worker , fToneCurveTag (tcProfileToneCurve,
2364*fd1fabb7SAndroid Build Coastguard Worker ttFloat,
2365*fd1fabb7SAndroid Build Coastguard Worker 0,
2366*fd1fabb7SAndroid Build Coastguard Worker NULL)
2367*fd1fabb7SAndroid Build Coastguard Worker
2368*fd1fabb7SAndroid Build Coastguard Worker {
2369*fd1fabb7SAndroid Build Coastguard Worker
2370*fd1fabb7SAndroid Build Coastguard Worker if (profile.HasColorMatrix1 ())
2371*fd1fabb7SAndroid Build Coastguard Worker {
2372*fd1fabb7SAndroid Build Coastguard Worker
2373*fd1fabb7SAndroid Build Coastguard Worker uint32 colorChannels = profile.ColorMatrix1 ().Rows ();
2374*fd1fabb7SAndroid Build Coastguard Worker
2375*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCalibrationIlluminant1);
2376*fd1fabb7SAndroid Build Coastguard Worker
2377*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fColorMatrix1);
2378*fd1fabb7SAndroid Build Coastguard Worker
2379*fd1fabb7SAndroid Build Coastguard Worker if (fForwardMatrix1.Count () == colorChannels * 3)
2380*fd1fabb7SAndroid Build Coastguard Worker {
2381*fd1fabb7SAndroid Build Coastguard Worker
2382*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fForwardMatrix1);
2383*fd1fabb7SAndroid Build Coastguard Worker
2384*fd1fabb7SAndroid Build Coastguard Worker }
2385*fd1fabb7SAndroid Build Coastguard Worker
2386*fd1fabb7SAndroid Build Coastguard Worker if (colorChannels > 3 && fReductionMatrix1.Count () == colorChannels * 3)
2387*fd1fabb7SAndroid Build Coastguard Worker {
2388*fd1fabb7SAndroid Build Coastguard Worker
2389*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fReductionMatrix1);
2390*fd1fabb7SAndroid Build Coastguard Worker
2391*fd1fabb7SAndroid Build Coastguard Worker }
2392*fd1fabb7SAndroid Build Coastguard Worker
2393*fd1fabb7SAndroid Build Coastguard Worker if (profile.HasColorMatrix2 ())
2394*fd1fabb7SAndroid Build Coastguard Worker {
2395*fd1fabb7SAndroid Build Coastguard Worker
2396*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCalibrationIlluminant2);
2397*fd1fabb7SAndroid Build Coastguard Worker
2398*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fColorMatrix2);
2399*fd1fabb7SAndroid Build Coastguard Worker
2400*fd1fabb7SAndroid Build Coastguard Worker if (fForwardMatrix2.Count () == colorChannels * 3)
2401*fd1fabb7SAndroid Build Coastguard Worker {
2402*fd1fabb7SAndroid Build Coastguard Worker
2403*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fForwardMatrix2);
2404*fd1fabb7SAndroid Build Coastguard Worker
2405*fd1fabb7SAndroid Build Coastguard Worker }
2406*fd1fabb7SAndroid Build Coastguard Worker
2407*fd1fabb7SAndroid Build Coastguard Worker if (colorChannels > 3 && fReductionMatrix2.Count () == colorChannels * 3)
2408*fd1fabb7SAndroid Build Coastguard Worker {
2409*fd1fabb7SAndroid Build Coastguard Worker
2410*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fReductionMatrix2);
2411*fd1fabb7SAndroid Build Coastguard Worker
2412*fd1fabb7SAndroid Build Coastguard Worker }
2413*fd1fabb7SAndroid Build Coastguard Worker
2414*fd1fabb7SAndroid Build Coastguard Worker }
2415*fd1fabb7SAndroid Build Coastguard Worker
2416*fd1fabb7SAndroid Build Coastguard Worker if (profile.Name ().NotEmpty ())
2417*fd1fabb7SAndroid Build Coastguard Worker {
2418*fd1fabb7SAndroid Build Coastguard Worker
2419*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fProfileName);
2420*fd1fabb7SAndroid Build Coastguard Worker
2421*fd1fabb7SAndroid Build Coastguard Worker }
2422*fd1fabb7SAndroid Build Coastguard Worker
2423*fd1fabb7SAndroid Build Coastguard Worker if (profile.ProfileCalibrationSignature ().NotEmpty ())
2424*fd1fabb7SAndroid Build Coastguard Worker {
2425*fd1fabb7SAndroid Build Coastguard Worker
2426*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fProfileCalibrationSignature);
2427*fd1fabb7SAndroid Build Coastguard Worker
2428*fd1fabb7SAndroid Build Coastguard Worker }
2429*fd1fabb7SAndroid Build Coastguard Worker
2430*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fEmbedPolicyTag);
2431*fd1fabb7SAndroid Build Coastguard Worker
2432*fd1fabb7SAndroid Build Coastguard Worker if (profile.Copyright ().NotEmpty ())
2433*fd1fabb7SAndroid Build Coastguard Worker {
2434*fd1fabb7SAndroid Build Coastguard Worker
2435*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fCopyrightTag);
2436*fd1fabb7SAndroid Build Coastguard Worker
2437*fd1fabb7SAndroid Build Coastguard Worker }
2438*fd1fabb7SAndroid Build Coastguard Worker
2439*fd1fabb7SAndroid Build Coastguard Worker bool haveHueSat1 = profile.HueSatDeltas1 ().IsValid ();
2440*fd1fabb7SAndroid Build Coastguard Worker
2441*fd1fabb7SAndroid Build Coastguard Worker bool haveHueSat2 = profile.HueSatDeltas2 ().IsValid () &&
2442*fd1fabb7SAndroid Build Coastguard Worker profile.HasColorMatrix2 ();
2443*fd1fabb7SAndroid Build Coastguard Worker
2444*fd1fabb7SAndroid Build Coastguard Worker if (haveHueSat1 || haveHueSat2)
2445*fd1fabb7SAndroid Build Coastguard Worker {
2446*fd1fabb7SAndroid Build Coastguard Worker
2447*fd1fabb7SAndroid Build Coastguard Worker uint32 hueDivs = 0;
2448*fd1fabb7SAndroid Build Coastguard Worker uint32 satDivs = 0;
2449*fd1fabb7SAndroid Build Coastguard Worker uint32 valDivs = 0;
2450*fd1fabb7SAndroid Build Coastguard Worker
2451*fd1fabb7SAndroid Build Coastguard Worker if (haveHueSat1)
2452*fd1fabb7SAndroid Build Coastguard Worker {
2453*fd1fabb7SAndroid Build Coastguard Worker
2454*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatDeltas1 ().GetDivisions (hueDivs,
2455*fd1fabb7SAndroid Build Coastguard Worker satDivs,
2456*fd1fabb7SAndroid Build Coastguard Worker valDivs);
2457*fd1fabb7SAndroid Build Coastguard Worker
2458*fd1fabb7SAndroid Build Coastguard Worker }
2459*fd1fabb7SAndroid Build Coastguard Worker
2460*fd1fabb7SAndroid Build Coastguard Worker else
2461*fd1fabb7SAndroid Build Coastguard Worker {
2462*fd1fabb7SAndroid Build Coastguard Worker
2463*fd1fabb7SAndroid Build Coastguard Worker profile.HueSatDeltas2 ().GetDivisions (hueDivs,
2464*fd1fabb7SAndroid Build Coastguard Worker satDivs,
2465*fd1fabb7SAndroid Build Coastguard Worker valDivs);
2466*fd1fabb7SAndroid Build Coastguard Worker
2467*fd1fabb7SAndroid Build Coastguard Worker }
2468*fd1fabb7SAndroid Build Coastguard Worker
2469*fd1fabb7SAndroid Build Coastguard Worker fHueSatMapDimData [0] = hueDivs;
2470*fd1fabb7SAndroid Build Coastguard Worker fHueSatMapDimData [1] = satDivs;
2471*fd1fabb7SAndroid Build Coastguard Worker fHueSatMapDimData [2] = valDivs;
2472*fd1fabb7SAndroid Build Coastguard Worker
2473*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fHueSatMapDims);
2474*fd1fabb7SAndroid Build Coastguard Worker
2475*fd1fabb7SAndroid Build Coastguard Worker // Don't bother including the ProfileHueSatMapEncoding tag unless it's
2476*fd1fabb7SAndroid Build Coastguard Worker // non-linear.
2477*fd1fabb7SAndroid Build Coastguard Worker
2478*fd1fabb7SAndroid Build Coastguard Worker if (profile.HueSatMapEncoding () != encoding_Linear)
2479*fd1fabb7SAndroid Build Coastguard Worker {
2480*fd1fabb7SAndroid Build Coastguard Worker
2481*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fHueSatMapEncodingTag);
2482*fd1fabb7SAndroid Build Coastguard Worker
2483*fd1fabb7SAndroid Build Coastguard Worker }
2484*fd1fabb7SAndroid Build Coastguard Worker
2485*fd1fabb7SAndroid Build Coastguard Worker }
2486*fd1fabb7SAndroid Build Coastguard Worker
2487*fd1fabb7SAndroid Build Coastguard Worker if (haveHueSat1)
2488*fd1fabb7SAndroid Build Coastguard Worker {
2489*fd1fabb7SAndroid Build Coastguard Worker
2490*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fHueSatData1);
2491*fd1fabb7SAndroid Build Coastguard Worker
2492*fd1fabb7SAndroid Build Coastguard Worker }
2493*fd1fabb7SAndroid Build Coastguard Worker
2494*fd1fabb7SAndroid Build Coastguard Worker if (haveHueSat2)
2495*fd1fabb7SAndroid Build Coastguard Worker {
2496*fd1fabb7SAndroid Build Coastguard Worker
2497*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fHueSatData2);
2498*fd1fabb7SAndroid Build Coastguard Worker
2499*fd1fabb7SAndroid Build Coastguard Worker }
2500*fd1fabb7SAndroid Build Coastguard Worker
2501*fd1fabb7SAndroid Build Coastguard Worker if (profile.HasLookTable ())
2502*fd1fabb7SAndroid Build Coastguard Worker {
2503*fd1fabb7SAndroid Build Coastguard Worker
2504*fd1fabb7SAndroid Build Coastguard Worker uint32 hueDivs = 0;
2505*fd1fabb7SAndroid Build Coastguard Worker uint32 satDivs = 0;
2506*fd1fabb7SAndroid Build Coastguard Worker uint32 valDivs = 0;
2507*fd1fabb7SAndroid Build Coastguard Worker
2508*fd1fabb7SAndroid Build Coastguard Worker profile.LookTable ().GetDivisions (hueDivs,
2509*fd1fabb7SAndroid Build Coastguard Worker satDivs,
2510*fd1fabb7SAndroid Build Coastguard Worker valDivs);
2511*fd1fabb7SAndroid Build Coastguard Worker
2512*fd1fabb7SAndroid Build Coastguard Worker fLookTableDimData [0] = hueDivs;
2513*fd1fabb7SAndroid Build Coastguard Worker fLookTableDimData [1] = satDivs;
2514*fd1fabb7SAndroid Build Coastguard Worker fLookTableDimData [2] = valDivs;
2515*fd1fabb7SAndroid Build Coastguard Worker
2516*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fLookTableDims);
2517*fd1fabb7SAndroid Build Coastguard Worker
2518*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fLookTableData);
2519*fd1fabb7SAndroid Build Coastguard Worker
2520*fd1fabb7SAndroid Build Coastguard Worker // Don't bother including the ProfileLookTableEncoding tag unless it's
2521*fd1fabb7SAndroid Build Coastguard Worker // non-linear.
2522*fd1fabb7SAndroid Build Coastguard Worker
2523*fd1fabb7SAndroid Build Coastguard Worker if (profile.LookTableEncoding () != encoding_Linear)
2524*fd1fabb7SAndroid Build Coastguard Worker {
2525*fd1fabb7SAndroid Build Coastguard Worker
2526*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fLookTableEncodingTag);
2527*fd1fabb7SAndroid Build Coastguard Worker
2528*fd1fabb7SAndroid Build Coastguard Worker }
2529*fd1fabb7SAndroid Build Coastguard Worker
2530*fd1fabb7SAndroid Build Coastguard Worker }
2531*fd1fabb7SAndroid Build Coastguard Worker
2532*fd1fabb7SAndroid Build Coastguard Worker // Don't bother including the BaselineExposureOffset tag unless it's both
2533*fd1fabb7SAndroid Build Coastguard Worker // valid and non-zero.
2534*fd1fabb7SAndroid Build Coastguard Worker
2535*fd1fabb7SAndroid Build Coastguard Worker if (profile.BaselineExposureOffset ().IsValid ())
2536*fd1fabb7SAndroid Build Coastguard Worker {
2537*fd1fabb7SAndroid Build Coastguard Worker
2538*fd1fabb7SAndroid Build Coastguard Worker if (profile.BaselineExposureOffset ().As_real64 () != 0.0)
2539*fd1fabb7SAndroid Build Coastguard Worker {
2540*fd1fabb7SAndroid Build Coastguard Worker
2541*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fBaselineExposureOffsetTag);
2542*fd1fabb7SAndroid Build Coastguard Worker
2543*fd1fabb7SAndroid Build Coastguard Worker }
2544*fd1fabb7SAndroid Build Coastguard Worker
2545*fd1fabb7SAndroid Build Coastguard Worker }
2546*fd1fabb7SAndroid Build Coastguard Worker
2547*fd1fabb7SAndroid Build Coastguard Worker if (profile.DefaultBlackRender () != defaultBlackRender_Auto)
2548*fd1fabb7SAndroid Build Coastguard Worker {
2549*fd1fabb7SAndroid Build Coastguard Worker
2550*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fDefaultBlackRenderTag);
2551*fd1fabb7SAndroid Build Coastguard Worker
2552*fd1fabb7SAndroid Build Coastguard Worker }
2553*fd1fabb7SAndroid Build Coastguard Worker
2554*fd1fabb7SAndroid Build Coastguard Worker if (profile.ToneCurve ().IsValid ())
2555*fd1fabb7SAndroid Build Coastguard Worker {
2556*fd1fabb7SAndroid Build Coastguard Worker
2557*fd1fabb7SAndroid Build Coastguard Worker // Tone curve stored as pairs of 32-bit coordinates. Probably could do with
2558*fd1fabb7SAndroid Build Coastguard Worker // 16-bits here, but should be small number of points so...
2559*fd1fabb7SAndroid Build Coastguard Worker
2560*fd1fabb7SAndroid Build Coastguard Worker uint32 toneCurvePoints = (uint32) (profile.ToneCurve ().fCoord.size ());
2561*fd1fabb7SAndroid Build Coastguard Worker
2562*fd1fabb7SAndroid Build Coastguard Worker fToneCurveBuffer.Allocate (SafeUint32Mult(toneCurvePoints, 2),
2563*fd1fabb7SAndroid Build Coastguard Worker sizeof (real32));
2564*fd1fabb7SAndroid Build Coastguard Worker
2565*fd1fabb7SAndroid Build Coastguard Worker real32 *points = fToneCurveBuffer.Buffer_real32 ();
2566*fd1fabb7SAndroid Build Coastguard Worker
2567*fd1fabb7SAndroid Build Coastguard Worker fToneCurveTag.SetCount (toneCurvePoints * 2);
2568*fd1fabb7SAndroid Build Coastguard Worker fToneCurveTag.SetData (points);
2569*fd1fabb7SAndroid Build Coastguard Worker
2570*fd1fabb7SAndroid Build Coastguard Worker for (uint32 i = 0; i < toneCurvePoints; i++)
2571*fd1fabb7SAndroid Build Coastguard Worker {
2572*fd1fabb7SAndroid Build Coastguard Worker
2573*fd1fabb7SAndroid Build Coastguard Worker // Transpose coordinates so they are in a more expected
2574*fd1fabb7SAndroid Build Coastguard Worker // order (domain -> range).
2575*fd1fabb7SAndroid Build Coastguard Worker
2576*fd1fabb7SAndroid Build Coastguard Worker points [i * 2 ] = (real32) profile.ToneCurve ().fCoord [i].h;
2577*fd1fabb7SAndroid Build Coastguard Worker points [i * 2 + 1] = (real32) profile.ToneCurve ().fCoord [i].v;
2578*fd1fabb7SAndroid Build Coastguard Worker
2579*fd1fabb7SAndroid Build Coastguard Worker }
2580*fd1fabb7SAndroid Build Coastguard Worker
2581*fd1fabb7SAndroid Build Coastguard Worker directory.Add (&fToneCurveTag);
2582*fd1fabb7SAndroid Build Coastguard Worker
2583*fd1fabb7SAndroid Build Coastguard Worker }
2584*fd1fabb7SAndroid Build Coastguard Worker
2585*fd1fabb7SAndroid Build Coastguard Worker }
2586*fd1fabb7SAndroid Build Coastguard Worker
2587*fd1fabb7SAndroid Build Coastguard Worker }
2588*fd1fabb7SAndroid Build Coastguard Worker
2589*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2590*fd1fabb7SAndroid Build Coastguard Worker
tiff_dng_extended_color_profile(const dng_camera_profile & profile)2591*fd1fabb7SAndroid Build Coastguard Worker tiff_dng_extended_color_profile::tiff_dng_extended_color_profile
2592*fd1fabb7SAndroid Build Coastguard Worker (const dng_camera_profile &profile)
2593*fd1fabb7SAndroid Build Coastguard Worker
2594*fd1fabb7SAndroid Build Coastguard Worker : fProfile (profile)
2595*fd1fabb7SAndroid Build Coastguard Worker
2596*fd1fabb7SAndroid Build Coastguard Worker {
2597*fd1fabb7SAndroid Build Coastguard Worker
2598*fd1fabb7SAndroid Build Coastguard Worker }
2599*fd1fabb7SAndroid Build Coastguard Worker
2600*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2601*fd1fabb7SAndroid Build Coastguard Worker
Put(dng_stream & stream,bool includeModelRestriction)2602*fd1fabb7SAndroid Build Coastguard Worker void tiff_dng_extended_color_profile::Put (dng_stream &stream,
2603*fd1fabb7SAndroid Build Coastguard Worker bool includeModelRestriction)
2604*fd1fabb7SAndroid Build Coastguard Worker {
2605*fd1fabb7SAndroid Build Coastguard Worker
2606*fd1fabb7SAndroid Build Coastguard Worker // Profile header.
2607*fd1fabb7SAndroid Build Coastguard Worker
2608*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (stream.BigEndian () ? byteOrderMM : byteOrderII);
2609*fd1fabb7SAndroid Build Coastguard Worker
2610*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (magicExtendedProfile);
2611*fd1fabb7SAndroid Build Coastguard Worker
2612*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (8);
2613*fd1fabb7SAndroid Build Coastguard Worker
2614*fd1fabb7SAndroid Build Coastguard Worker // Profile tags.
2615*fd1fabb7SAndroid Build Coastguard Worker
2616*fd1fabb7SAndroid Build Coastguard Worker profile_tag_set tagSet (*this, fProfile);
2617*fd1fabb7SAndroid Build Coastguard Worker
2618*fd1fabb7SAndroid Build Coastguard Worker // Camera this profile is for.
2619*fd1fabb7SAndroid Build Coastguard Worker
2620*fd1fabb7SAndroid Build Coastguard Worker tag_string cameraModelTag (tcUniqueCameraModel,
2621*fd1fabb7SAndroid Build Coastguard Worker fProfile.UniqueCameraModelRestriction ());
2622*fd1fabb7SAndroid Build Coastguard Worker
2623*fd1fabb7SAndroid Build Coastguard Worker if (includeModelRestriction)
2624*fd1fabb7SAndroid Build Coastguard Worker {
2625*fd1fabb7SAndroid Build Coastguard Worker
2626*fd1fabb7SAndroid Build Coastguard Worker if (fProfile.UniqueCameraModelRestriction ().NotEmpty ())
2627*fd1fabb7SAndroid Build Coastguard Worker {
2628*fd1fabb7SAndroid Build Coastguard Worker
2629*fd1fabb7SAndroid Build Coastguard Worker Add (&cameraModelTag);
2630*fd1fabb7SAndroid Build Coastguard Worker
2631*fd1fabb7SAndroid Build Coastguard Worker }
2632*fd1fabb7SAndroid Build Coastguard Worker
2633*fd1fabb7SAndroid Build Coastguard Worker }
2634*fd1fabb7SAndroid Build Coastguard Worker
2635*fd1fabb7SAndroid Build Coastguard Worker // Write it all out.
2636*fd1fabb7SAndroid Build Coastguard Worker
2637*fd1fabb7SAndroid Build Coastguard Worker dng_tiff_directory::Put (stream, offsetsRelativeToExplicitBase, 8);
2638*fd1fabb7SAndroid Build Coastguard Worker
2639*fd1fabb7SAndroid Build Coastguard Worker }
2640*fd1fabb7SAndroid Build Coastguard Worker
2641*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2642*fd1fabb7SAndroid Build Coastguard Worker
tag_dng_noise_profile(const dng_noise_profile & profile)2643*fd1fabb7SAndroid Build Coastguard Worker tag_dng_noise_profile::tag_dng_noise_profile (const dng_noise_profile &profile)
2644*fd1fabb7SAndroid Build Coastguard Worker
2645*fd1fabb7SAndroid Build Coastguard Worker : tag_data_ptr (tcNoiseProfile,
2646*fd1fabb7SAndroid Build Coastguard Worker ttDouble,
2647*fd1fabb7SAndroid Build Coastguard Worker 2 * profile.NumFunctions (),
2648*fd1fabb7SAndroid Build Coastguard Worker fValues)
2649*fd1fabb7SAndroid Build Coastguard Worker
2650*fd1fabb7SAndroid Build Coastguard Worker {
2651*fd1fabb7SAndroid Build Coastguard Worker
2652*fd1fabb7SAndroid Build Coastguard Worker DNG_REQUIRE (profile.NumFunctions () <= kMaxColorPlanes,
2653*fd1fabb7SAndroid Build Coastguard Worker "Too many noise functions in tag_dng_noise_profile.");
2654*fd1fabb7SAndroid Build Coastguard Worker
2655*fd1fabb7SAndroid Build Coastguard Worker for (uint32 i = 0; i < profile.NumFunctions (); i++)
2656*fd1fabb7SAndroid Build Coastguard Worker {
2657*fd1fabb7SAndroid Build Coastguard Worker
2658*fd1fabb7SAndroid Build Coastguard Worker fValues [(2 * i) ] = profile.NoiseFunction (i).Scale ();
2659*fd1fabb7SAndroid Build Coastguard Worker fValues [(2 * i) + 1] = profile.NoiseFunction (i).Offset ();
2660*fd1fabb7SAndroid Build Coastguard Worker
2661*fd1fabb7SAndroid Build Coastguard Worker }
2662*fd1fabb7SAndroid Build Coastguard Worker
2663*fd1fabb7SAndroid Build Coastguard Worker }
2664*fd1fabb7SAndroid Build Coastguard Worker
2665*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2666*fd1fabb7SAndroid Build Coastguard Worker
dng_image_writer()2667*fd1fabb7SAndroid Build Coastguard Worker dng_image_writer::dng_image_writer ()
2668*fd1fabb7SAndroid Build Coastguard Worker {
2669*fd1fabb7SAndroid Build Coastguard Worker
2670*fd1fabb7SAndroid Build Coastguard Worker }
2671*fd1fabb7SAndroid Build Coastguard Worker
2672*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2673*fd1fabb7SAndroid Build Coastguard Worker
~dng_image_writer()2674*fd1fabb7SAndroid Build Coastguard Worker dng_image_writer::~dng_image_writer ()
2675*fd1fabb7SAndroid Build Coastguard Worker {
2676*fd1fabb7SAndroid Build Coastguard Worker
2677*fd1fabb7SAndroid Build Coastguard Worker }
2678*fd1fabb7SAndroid Build Coastguard Worker
2679*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2680*fd1fabb7SAndroid Build Coastguard Worker
CompressedBufferSize(const dng_ifd & ifd,uint32 uncompressedSize)2681*fd1fabb7SAndroid Build Coastguard Worker uint32 dng_image_writer::CompressedBufferSize (const dng_ifd &ifd,
2682*fd1fabb7SAndroid Build Coastguard Worker uint32 uncompressedSize)
2683*fd1fabb7SAndroid Build Coastguard Worker {
2684*fd1fabb7SAndroid Build Coastguard Worker
2685*fd1fabb7SAndroid Build Coastguard Worker switch (ifd.fCompression)
2686*fd1fabb7SAndroid Build Coastguard Worker {
2687*fd1fabb7SAndroid Build Coastguard Worker
2688*fd1fabb7SAndroid Build Coastguard Worker case ccLZW:
2689*fd1fabb7SAndroid Build Coastguard Worker {
2690*fd1fabb7SAndroid Build Coastguard Worker
2691*fd1fabb7SAndroid Build Coastguard Worker // Add lots of slop for LZW to expand data.
2692*fd1fabb7SAndroid Build Coastguard Worker
2693*fd1fabb7SAndroid Build Coastguard Worker return SafeUint32Add (SafeUint32Mult (uncompressedSize, 2), 1024);
2694*fd1fabb7SAndroid Build Coastguard Worker
2695*fd1fabb7SAndroid Build Coastguard Worker }
2696*fd1fabb7SAndroid Build Coastguard Worker
2697*fd1fabb7SAndroid Build Coastguard Worker case ccDeflate:
2698*fd1fabb7SAndroid Build Coastguard Worker {
2699*fd1fabb7SAndroid Build Coastguard Worker
2700*fd1fabb7SAndroid Build Coastguard Worker // ZLib says maximum is source size + 0.1% + 12 bytes.
2701*fd1fabb7SAndroid Build Coastguard Worker
2702*fd1fabb7SAndroid Build Coastguard Worker return SafeUint32Add (SafeUint32Add (uncompressedSize,
2703*fd1fabb7SAndroid Build Coastguard Worker uncompressedSize >> 8), 64);
2704*fd1fabb7SAndroid Build Coastguard Worker
2705*fd1fabb7SAndroid Build Coastguard Worker }
2706*fd1fabb7SAndroid Build Coastguard Worker
2707*fd1fabb7SAndroid Build Coastguard Worker case ccJPEG:
2708*fd1fabb7SAndroid Build Coastguard Worker {
2709*fd1fabb7SAndroid Build Coastguard Worker
2710*fd1fabb7SAndroid Build Coastguard Worker // If we are saving lossless JPEG from an 8-bit image, reserve
2711*fd1fabb7SAndroid Build Coastguard Worker // space to pad the data out to 16-bits.
2712*fd1fabb7SAndroid Build Coastguard Worker
2713*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fBitsPerSample [0] <= 8)
2714*fd1fabb7SAndroid Build Coastguard Worker {
2715*fd1fabb7SAndroid Build Coastguard Worker
2716*fd1fabb7SAndroid Build Coastguard Worker return SafeUint32Mult (uncompressedSize, 2);
2717*fd1fabb7SAndroid Build Coastguard Worker
2718*fd1fabb7SAndroid Build Coastguard Worker }
2719*fd1fabb7SAndroid Build Coastguard Worker
2720*fd1fabb7SAndroid Build Coastguard Worker break;
2721*fd1fabb7SAndroid Build Coastguard Worker
2722*fd1fabb7SAndroid Build Coastguard Worker }
2723*fd1fabb7SAndroid Build Coastguard Worker
2724*fd1fabb7SAndroid Build Coastguard Worker default:
2725*fd1fabb7SAndroid Build Coastguard Worker break;
2726*fd1fabb7SAndroid Build Coastguard Worker
2727*fd1fabb7SAndroid Build Coastguard Worker }
2728*fd1fabb7SAndroid Build Coastguard Worker
2729*fd1fabb7SAndroid Build Coastguard Worker return 0;
2730*fd1fabb7SAndroid Build Coastguard Worker
2731*fd1fabb7SAndroid Build Coastguard Worker }
2732*fd1fabb7SAndroid Build Coastguard Worker
2733*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2734*fd1fabb7SAndroid Build Coastguard Worker
EncodeDelta8(uint8 * dPtr,uint32 rows,uint32 cols,uint32 channels)2735*fd1fabb7SAndroid Build Coastguard Worker static void EncodeDelta8 (uint8 *dPtr,
2736*fd1fabb7SAndroid Build Coastguard Worker uint32 rows,
2737*fd1fabb7SAndroid Build Coastguard Worker uint32 cols,
2738*fd1fabb7SAndroid Build Coastguard Worker uint32 channels)
2739*fd1fabb7SAndroid Build Coastguard Worker {
2740*fd1fabb7SAndroid Build Coastguard Worker
2741*fd1fabb7SAndroid Build Coastguard Worker const uint32 dRowStep = cols * channels;
2742*fd1fabb7SAndroid Build Coastguard Worker
2743*fd1fabb7SAndroid Build Coastguard Worker for (uint32 row = 0; row < rows; row++)
2744*fd1fabb7SAndroid Build Coastguard Worker {
2745*fd1fabb7SAndroid Build Coastguard Worker
2746*fd1fabb7SAndroid Build Coastguard Worker for (uint32 col = cols - 1; col > 0; col--)
2747*fd1fabb7SAndroid Build Coastguard Worker {
2748*fd1fabb7SAndroid Build Coastguard Worker
2749*fd1fabb7SAndroid Build Coastguard Worker for (uint32 channel = 0; channel < channels; channel++)
2750*fd1fabb7SAndroid Build Coastguard Worker {
2751*fd1fabb7SAndroid Build Coastguard Worker
2752*fd1fabb7SAndroid Build Coastguard Worker dPtr [col * channels + channel] -= dPtr [(col - 1) * channels + channel];
2753*fd1fabb7SAndroid Build Coastguard Worker
2754*fd1fabb7SAndroid Build Coastguard Worker }
2755*fd1fabb7SAndroid Build Coastguard Worker
2756*fd1fabb7SAndroid Build Coastguard Worker }
2757*fd1fabb7SAndroid Build Coastguard Worker
2758*fd1fabb7SAndroid Build Coastguard Worker dPtr += dRowStep;
2759*fd1fabb7SAndroid Build Coastguard Worker
2760*fd1fabb7SAndroid Build Coastguard Worker }
2761*fd1fabb7SAndroid Build Coastguard Worker
2762*fd1fabb7SAndroid Build Coastguard Worker }
2763*fd1fabb7SAndroid Build Coastguard Worker
2764*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2765*fd1fabb7SAndroid Build Coastguard Worker
EncodeDelta16(uint16 * dPtr,uint32 rows,uint32 cols,uint32 channels)2766*fd1fabb7SAndroid Build Coastguard Worker static void EncodeDelta16 (uint16 *dPtr,
2767*fd1fabb7SAndroid Build Coastguard Worker uint32 rows,
2768*fd1fabb7SAndroid Build Coastguard Worker uint32 cols,
2769*fd1fabb7SAndroid Build Coastguard Worker uint32 channels)
2770*fd1fabb7SAndroid Build Coastguard Worker {
2771*fd1fabb7SAndroid Build Coastguard Worker
2772*fd1fabb7SAndroid Build Coastguard Worker const uint32 dRowStep = cols * channels;
2773*fd1fabb7SAndroid Build Coastguard Worker
2774*fd1fabb7SAndroid Build Coastguard Worker for (uint32 row = 0; row < rows; row++)
2775*fd1fabb7SAndroid Build Coastguard Worker {
2776*fd1fabb7SAndroid Build Coastguard Worker
2777*fd1fabb7SAndroid Build Coastguard Worker for (uint32 col = cols - 1; col > 0; col--)
2778*fd1fabb7SAndroid Build Coastguard Worker {
2779*fd1fabb7SAndroid Build Coastguard Worker
2780*fd1fabb7SAndroid Build Coastguard Worker for (uint32 channel = 0; channel < channels; channel++)
2781*fd1fabb7SAndroid Build Coastguard Worker {
2782*fd1fabb7SAndroid Build Coastguard Worker
2783*fd1fabb7SAndroid Build Coastguard Worker dPtr [col * channels + channel] -= dPtr [(col - 1) * channels + channel];
2784*fd1fabb7SAndroid Build Coastguard Worker
2785*fd1fabb7SAndroid Build Coastguard Worker }
2786*fd1fabb7SAndroid Build Coastguard Worker
2787*fd1fabb7SAndroid Build Coastguard Worker }
2788*fd1fabb7SAndroid Build Coastguard Worker
2789*fd1fabb7SAndroid Build Coastguard Worker dPtr += dRowStep;
2790*fd1fabb7SAndroid Build Coastguard Worker
2791*fd1fabb7SAndroid Build Coastguard Worker }
2792*fd1fabb7SAndroid Build Coastguard Worker
2793*fd1fabb7SAndroid Build Coastguard Worker }
2794*fd1fabb7SAndroid Build Coastguard Worker
2795*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
2796*fd1fabb7SAndroid Build Coastguard Worker
EncodeDelta32(uint32 * dPtr,uint32 rows,uint32 cols,uint32 channels)2797*fd1fabb7SAndroid Build Coastguard Worker static void EncodeDelta32 (uint32 *dPtr,
2798*fd1fabb7SAndroid Build Coastguard Worker uint32 rows,
2799*fd1fabb7SAndroid Build Coastguard Worker uint32 cols,
2800*fd1fabb7SAndroid Build Coastguard Worker uint32 channels)
2801*fd1fabb7SAndroid Build Coastguard Worker {
2802*fd1fabb7SAndroid Build Coastguard Worker
2803*fd1fabb7SAndroid Build Coastguard Worker const uint32 dRowStep = cols * channels;
2804*fd1fabb7SAndroid Build Coastguard Worker
2805*fd1fabb7SAndroid Build Coastguard Worker for (uint32 row = 0; row < rows; row++)
2806*fd1fabb7SAndroid Build Coastguard Worker {
2807*fd1fabb7SAndroid Build Coastguard Worker
2808*fd1fabb7SAndroid Build Coastguard Worker for (uint32 col = cols - 1; col > 0; col--)
2809*fd1fabb7SAndroid Build Coastguard Worker {
2810*fd1fabb7SAndroid Build Coastguard Worker
2811*fd1fabb7SAndroid Build Coastguard Worker for (uint32 channel = 0; channel < channels; channel++)
2812*fd1fabb7SAndroid Build Coastguard Worker {
2813*fd1fabb7SAndroid Build Coastguard Worker
2814*fd1fabb7SAndroid Build Coastguard Worker dPtr [col * channels + channel] -= dPtr [(col - 1) * channels + channel];
2815*fd1fabb7SAndroid Build Coastguard Worker
2816*fd1fabb7SAndroid Build Coastguard Worker }
2817*fd1fabb7SAndroid Build Coastguard Worker
2818*fd1fabb7SAndroid Build Coastguard Worker }
2819*fd1fabb7SAndroid Build Coastguard Worker
2820*fd1fabb7SAndroid Build Coastguard Worker dPtr += dRowStep;
2821*fd1fabb7SAndroid Build Coastguard Worker
2822*fd1fabb7SAndroid Build Coastguard Worker }
2823*fd1fabb7SAndroid Build Coastguard Worker
2824*fd1fabb7SAndroid Build Coastguard Worker }
2825*fd1fabb7SAndroid Build Coastguard Worker
2826*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2827*fd1fabb7SAndroid Build Coastguard Worker
EncodeDeltaBytes(uint8 * bytePtr,int32 cols,int32 channels)2828*fd1fabb7SAndroid Build Coastguard Worker inline void EncodeDeltaBytes (uint8 *bytePtr, int32 cols, int32 channels)
2829*fd1fabb7SAndroid Build Coastguard Worker {
2830*fd1fabb7SAndroid Build Coastguard Worker
2831*fd1fabb7SAndroid Build Coastguard Worker if (channels == 1)
2832*fd1fabb7SAndroid Build Coastguard Worker {
2833*fd1fabb7SAndroid Build Coastguard Worker
2834*fd1fabb7SAndroid Build Coastguard Worker bytePtr += (cols - 1);
2835*fd1fabb7SAndroid Build Coastguard Worker
2836*fd1fabb7SAndroid Build Coastguard Worker uint8 this0 = bytePtr [0];
2837*fd1fabb7SAndroid Build Coastguard Worker
2838*fd1fabb7SAndroid Build Coastguard Worker for (int32 col = 1; col < cols; col++)
2839*fd1fabb7SAndroid Build Coastguard Worker {
2840*fd1fabb7SAndroid Build Coastguard Worker
2841*fd1fabb7SAndroid Build Coastguard Worker uint8 prev0 = bytePtr [-1];
2842*fd1fabb7SAndroid Build Coastguard Worker
2843*fd1fabb7SAndroid Build Coastguard Worker this0 -= prev0;
2844*fd1fabb7SAndroid Build Coastguard Worker
2845*fd1fabb7SAndroid Build Coastguard Worker bytePtr [0] = this0;
2846*fd1fabb7SAndroid Build Coastguard Worker
2847*fd1fabb7SAndroid Build Coastguard Worker this0 = prev0;
2848*fd1fabb7SAndroid Build Coastguard Worker
2849*fd1fabb7SAndroid Build Coastguard Worker bytePtr -= 1;
2850*fd1fabb7SAndroid Build Coastguard Worker
2851*fd1fabb7SAndroid Build Coastguard Worker }
2852*fd1fabb7SAndroid Build Coastguard Worker
2853*fd1fabb7SAndroid Build Coastguard Worker }
2854*fd1fabb7SAndroid Build Coastguard Worker
2855*fd1fabb7SAndroid Build Coastguard Worker else if (channels == 3)
2856*fd1fabb7SAndroid Build Coastguard Worker {
2857*fd1fabb7SAndroid Build Coastguard Worker
2858*fd1fabb7SAndroid Build Coastguard Worker bytePtr += (cols - 1) * 3;
2859*fd1fabb7SAndroid Build Coastguard Worker
2860*fd1fabb7SAndroid Build Coastguard Worker uint8 this0 = bytePtr [0];
2861*fd1fabb7SAndroid Build Coastguard Worker uint8 this1 = bytePtr [1];
2862*fd1fabb7SAndroid Build Coastguard Worker uint8 this2 = bytePtr [2];
2863*fd1fabb7SAndroid Build Coastguard Worker
2864*fd1fabb7SAndroid Build Coastguard Worker for (int32 col = 1; col < cols; col++)
2865*fd1fabb7SAndroid Build Coastguard Worker {
2866*fd1fabb7SAndroid Build Coastguard Worker
2867*fd1fabb7SAndroid Build Coastguard Worker uint8 prev0 = bytePtr [-3];
2868*fd1fabb7SAndroid Build Coastguard Worker uint8 prev1 = bytePtr [-2];
2869*fd1fabb7SAndroid Build Coastguard Worker uint8 prev2 = bytePtr [-1];
2870*fd1fabb7SAndroid Build Coastguard Worker
2871*fd1fabb7SAndroid Build Coastguard Worker this0 -= prev0;
2872*fd1fabb7SAndroid Build Coastguard Worker this1 -= prev1;
2873*fd1fabb7SAndroid Build Coastguard Worker this2 -= prev2;
2874*fd1fabb7SAndroid Build Coastguard Worker
2875*fd1fabb7SAndroid Build Coastguard Worker bytePtr [0] = this0;
2876*fd1fabb7SAndroid Build Coastguard Worker bytePtr [1] = this1;
2877*fd1fabb7SAndroid Build Coastguard Worker bytePtr [2] = this2;
2878*fd1fabb7SAndroid Build Coastguard Worker
2879*fd1fabb7SAndroid Build Coastguard Worker this0 = prev0;
2880*fd1fabb7SAndroid Build Coastguard Worker this1 = prev1;
2881*fd1fabb7SAndroid Build Coastguard Worker this2 = prev2;
2882*fd1fabb7SAndroid Build Coastguard Worker
2883*fd1fabb7SAndroid Build Coastguard Worker bytePtr -= 3;
2884*fd1fabb7SAndroid Build Coastguard Worker
2885*fd1fabb7SAndroid Build Coastguard Worker }
2886*fd1fabb7SAndroid Build Coastguard Worker
2887*fd1fabb7SAndroid Build Coastguard Worker }
2888*fd1fabb7SAndroid Build Coastguard Worker
2889*fd1fabb7SAndroid Build Coastguard Worker else
2890*fd1fabb7SAndroid Build Coastguard Worker {
2891*fd1fabb7SAndroid Build Coastguard Worker
2892*fd1fabb7SAndroid Build Coastguard Worker uint32 rowBytes = cols * channels;
2893*fd1fabb7SAndroid Build Coastguard Worker
2894*fd1fabb7SAndroid Build Coastguard Worker bytePtr += rowBytes - 1;
2895*fd1fabb7SAndroid Build Coastguard Worker
2896*fd1fabb7SAndroid Build Coastguard Worker for (uint32 col = channels; col < rowBytes; col++)
2897*fd1fabb7SAndroid Build Coastguard Worker {
2898*fd1fabb7SAndroid Build Coastguard Worker
2899*fd1fabb7SAndroid Build Coastguard Worker bytePtr [0] -= bytePtr [-channels];
2900*fd1fabb7SAndroid Build Coastguard Worker
2901*fd1fabb7SAndroid Build Coastguard Worker bytePtr--;
2902*fd1fabb7SAndroid Build Coastguard Worker
2903*fd1fabb7SAndroid Build Coastguard Worker }
2904*fd1fabb7SAndroid Build Coastguard Worker
2905*fd1fabb7SAndroid Build Coastguard Worker }
2906*fd1fabb7SAndroid Build Coastguard Worker
2907*fd1fabb7SAndroid Build Coastguard Worker }
2908*fd1fabb7SAndroid Build Coastguard Worker
2909*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
2910*fd1fabb7SAndroid Build Coastguard Worker
EncodeFPDelta(uint8 * buffer,uint8 * temp,int32 cols,int32 channels,int32 bytesPerSample)2911*fd1fabb7SAndroid Build Coastguard Worker static void EncodeFPDelta (uint8 *buffer,
2912*fd1fabb7SAndroid Build Coastguard Worker uint8 *temp,
2913*fd1fabb7SAndroid Build Coastguard Worker int32 cols,
2914*fd1fabb7SAndroid Build Coastguard Worker int32 channels,
2915*fd1fabb7SAndroid Build Coastguard Worker int32 bytesPerSample)
2916*fd1fabb7SAndroid Build Coastguard Worker {
2917*fd1fabb7SAndroid Build Coastguard Worker
2918*fd1fabb7SAndroid Build Coastguard Worker int32 rowIncrement = cols * channels;
2919*fd1fabb7SAndroid Build Coastguard Worker
2920*fd1fabb7SAndroid Build Coastguard Worker if (bytesPerSample == 2)
2921*fd1fabb7SAndroid Build Coastguard Worker {
2922*fd1fabb7SAndroid Build Coastguard Worker
2923*fd1fabb7SAndroid Build Coastguard Worker const uint8 *src = buffer;
2924*fd1fabb7SAndroid Build Coastguard Worker
2925*fd1fabb7SAndroid Build Coastguard Worker #if qDNGBigEndian
2926*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst0 = temp;
2927*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst1 = temp + rowIncrement;
2928*fd1fabb7SAndroid Build Coastguard Worker #else
2929*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst1 = temp;
2930*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst0 = temp + rowIncrement;
2931*fd1fabb7SAndroid Build Coastguard Worker #endif
2932*fd1fabb7SAndroid Build Coastguard Worker
2933*fd1fabb7SAndroid Build Coastguard Worker for (int32 col = 0; col < rowIncrement; ++col)
2934*fd1fabb7SAndroid Build Coastguard Worker {
2935*fd1fabb7SAndroid Build Coastguard Worker
2936*fd1fabb7SAndroid Build Coastguard Worker dst0 [col] = src [0];
2937*fd1fabb7SAndroid Build Coastguard Worker dst1 [col] = src [1];
2938*fd1fabb7SAndroid Build Coastguard Worker
2939*fd1fabb7SAndroid Build Coastguard Worker src += 2;
2940*fd1fabb7SAndroid Build Coastguard Worker
2941*fd1fabb7SAndroid Build Coastguard Worker }
2942*fd1fabb7SAndroid Build Coastguard Worker
2943*fd1fabb7SAndroid Build Coastguard Worker }
2944*fd1fabb7SAndroid Build Coastguard Worker
2945*fd1fabb7SAndroid Build Coastguard Worker else if (bytesPerSample == 3)
2946*fd1fabb7SAndroid Build Coastguard Worker {
2947*fd1fabb7SAndroid Build Coastguard Worker
2948*fd1fabb7SAndroid Build Coastguard Worker const uint8 *src = buffer;
2949*fd1fabb7SAndroid Build Coastguard Worker
2950*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst0 = temp;
2951*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst1 = temp + rowIncrement;
2952*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst2 = temp + rowIncrement * 2;
2953*fd1fabb7SAndroid Build Coastguard Worker
2954*fd1fabb7SAndroid Build Coastguard Worker for (int32 col = 0; col < rowIncrement; ++col)
2955*fd1fabb7SAndroid Build Coastguard Worker {
2956*fd1fabb7SAndroid Build Coastguard Worker
2957*fd1fabb7SAndroid Build Coastguard Worker dst0 [col] = src [0];
2958*fd1fabb7SAndroid Build Coastguard Worker dst1 [col] = src [1];
2959*fd1fabb7SAndroid Build Coastguard Worker dst2 [col] = src [2];
2960*fd1fabb7SAndroid Build Coastguard Worker
2961*fd1fabb7SAndroid Build Coastguard Worker src += 3;
2962*fd1fabb7SAndroid Build Coastguard Worker
2963*fd1fabb7SAndroid Build Coastguard Worker }
2964*fd1fabb7SAndroid Build Coastguard Worker
2965*fd1fabb7SAndroid Build Coastguard Worker }
2966*fd1fabb7SAndroid Build Coastguard Worker
2967*fd1fabb7SAndroid Build Coastguard Worker else
2968*fd1fabb7SAndroid Build Coastguard Worker {
2969*fd1fabb7SAndroid Build Coastguard Worker
2970*fd1fabb7SAndroid Build Coastguard Worker const uint8 *src = buffer;
2971*fd1fabb7SAndroid Build Coastguard Worker
2972*fd1fabb7SAndroid Build Coastguard Worker #if qDNGBigEndian
2973*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst0 = temp;
2974*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst1 = temp + rowIncrement;
2975*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst2 = temp + rowIncrement * 2;
2976*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst3 = temp + rowIncrement * 3;
2977*fd1fabb7SAndroid Build Coastguard Worker #else
2978*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst3 = temp;
2979*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst2 = temp + rowIncrement;
2980*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst1 = temp + rowIncrement * 2;
2981*fd1fabb7SAndroid Build Coastguard Worker uint8 *dst0 = temp + rowIncrement * 3;
2982*fd1fabb7SAndroid Build Coastguard Worker #endif
2983*fd1fabb7SAndroid Build Coastguard Worker
2984*fd1fabb7SAndroid Build Coastguard Worker for (int32 col = 0; col < rowIncrement; ++col)
2985*fd1fabb7SAndroid Build Coastguard Worker {
2986*fd1fabb7SAndroid Build Coastguard Worker
2987*fd1fabb7SAndroid Build Coastguard Worker dst0 [col] = src [0];
2988*fd1fabb7SAndroid Build Coastguard Worker dst1 [col] = src [1];
2989*fd1fabb7SAndroid Build Coastguard Worker dst2 [col] = src [2];
2990*fd1fabb7SAndroid Build Coastguard Worker dst3 [col] = src [3];
2991*fd1fabb7SAndroid Build Coastguard Worker
2992*fd1fabb7SAndroid Build Coastguard Worker src += 4;
2993*fd1fabb7SAndroid Build Coastguard Worker
2994*fd1fabb7SAndroid Build Coastguard Worker }
2995*fd1fabb7SAndroid Build Coastguard Worker
2996*fd1fabb7SAndroid Build Coastguard Worker }
2997*fd1fabb7SAndroid Build Coastguard Worker
2998*fd1fabb7SAndroid Build Coastguard Worker EncodeDeltaBytes (temp, cols*bytesPerSample, channels);
2999*fd1fabb7SAndroid Build Coastguard Worker
3000*fd1fabb7SAndroid Build Coastguard Worker memcpy (buffer, temp, cols*bytesPerSample*channels);
3001*fd1fabb7SAndroid Build Coastguard Worker
3002*fd1fabb7SAndroid Build Coastguard Worker }
3003*fd1fabb7SAndroid Build Coastguard Worker
3004*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3005*fd1fabb7SAndroid Build Coastguard Worker
EncodePredictor(dng_host & host,const dng_ifd & ifd,dng_pixel_buffer & buffer,AutoPtr<dng_memory_block> & tempBuffer)3006*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::EncodePredictor (dng_host &host,
3007*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &ifd,
3008*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer &buffer,
3009*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &tempBuffer)
3010*fd1fabb7SAndroid Build Coastguard Worker {
3011*fd1fabb7SAndroid Build Coastguard Worker
3012*fd1fabb7SAndroid Build Coastguard Worker switch (ifd.fPredictor)
3013*fd1fabb7SAndroid Build Coastguard Worker {
3014*fd1fabb7SAndroid Build Coastguard Worker
3015*fd1fabb7SAndroid Build Coastguard Worker case cpHorizontalDifference:
3016*fd1fabb7SAndroid Build Coastguard Worker case cpHorizontalDifferenceX2:
3017*fd1fabb7SAndroid Build Coastguard Worker case cpHorizontalDifferenceX4:
3018*fd1fabb7SAndroid Build Coastguard Worker {
3019*fd1fabb7SAndroid Build Coastguard Worker
3020*fd1fabb7SAndroid Build Coastguard Worker int32 xFactor = 1;
3021*fd1fabb7SAndroid Build Coastguard Worker
3022*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fPredictor == cpHorizontalDifferenceX2)
3023*fd1fabb7SAndroid Build Coastguard Worker {
3024*fd1fabb7SAndroid Build Coastguard Worker xFactor = 2;
3025*fd1fabb7SAndroid Build Coastguard Worker }
3026*fd1fabb7SAndroid Build Coastguard Worker
3027*fd1fabb7SAndroid Build Coastguard Worker else if (ifd.fPredictor == cpHorizontalDifferenceX4)
3028*fd1fabb7SAndroid Build Coastguard Worker {
3029*fd1fabb7SAndroid Build Coastguard Worker xFactor = 4;
3030*fd1fabb7SAndroid Build Coastguard Worker }
3031*fd1fabb7SAndroid Build Coastguard Worker
3032*fd1fabb7SAndroid Build Coastguard Worker switch (buffer.fPixelType)
3033*fd1fabb7SAndroid Build Coastguard Worker {
3034*fd1fabb7SAndroid Build Coastguard Worker
3035*fd1fabb7SAndroid Build Coastguard Worker case ttByte:
3036*fd1fabb7SAndroid Build Coastguard Worker {
3037*fd1fabb7SAndroid Build Coastguard Worker
3038*fd1fabb7SAndroid Build Coastguard Worker EncodeDelta8 ((uint8 *) buffer.fData,
3039*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.H (),
3040*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.W () / xFactor,
3041*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlanes * xFactor);
3042*fd1fabb7SAndroid Build Coastguard Worker
3043*fd1fabb7SAndroid Build Coastguard Worker return;
3044*fd1fabb7SAndroid Build Coastguard Worker
3045*fd1fabb7SAndroid Build Coastguard Worker }
3046*fd1fabb7SAndroid Build Coastguard Worker
3047*fd1fabb7SAndroid Build Coastguard Worker case ttShort:
3048*fd1fabb7SAndroid Build Coastguard Worker {
3049*fd1fabb7SAndroid Build Coastguard Worker
3050*fd1fabb7SAndroid Build Coastguard Worker EncodeDelta16 ((uint16 *) buffer.fData,
3051*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.H (),
3052*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.W () / xFactor,
3053*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlanes * xFactor);
3054*fd1fabb7SAndroid Build Coastguard Worker
3055*fd1fabb7SAndroid Build Coastguard Worker return;
3056*fd1fabb7SAndroid Build Coastguard Worker
3057*fd1fabb7SAndroid Build Coastguard Worker }
3058*fd1fabb7SAndroid Build Coastguard Worker
3059*fd1fabb7SAndroid Build Coastguard Worker case ttLong:
3060*fd1fabb7SAndroid Build Coastguard Worker {
3061*fd1fabb7SAndroid Build Coastguard Worker
3062*fd1fabb7SAndroid Build Coastguard Worker EncodeDelta32 ((uint32 *) buffer.fData,
3063*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.H (),
3064*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.W () / xFactor,
3065*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlanes * xFactor);
3066*fd1fabb7SAndroid Build Coastguard Worker
3067*fd1fabb7SAndroid Build Coastguard Worker return;
3068*fd1fabb7SAndroid Build Coastguard Worker
3069*fd1fabb7SAndroid Build Coastguard Worker }
3070*fd1fabb7SAndroid Build Coastguard Worker
3071*fd1fabb7SAndroid Build Coastguard Worker default:
3072*fd1fabb7SAndroid Build Coastguard Worker break;
3073*fd1fabb7SAndroid Build Coastguard Worker
3074*fd1fabb7SAndroid Build Coastguard Worker }
3075*fd1fabb7SAndroid Build Coastguard Worker
3076*fd1fabb7SAndroid Build Coastguard Worker break;
3077*fd1fabb7SAndroid Build Coastguard Worker
3078*fd1fabb7SAndroid Build Coastguard Worker }
3079*fd1fabb7SAndroid Build Coastguard Worker
3080*fd1fabb7SAndroid Build Coastguard Worker case cpFloatingPoint:
3081*fd1fabb7SAndroid Build Coastguard Worker case cpFloatingPointX2:
3082*fd1fabb7SAndroid Build Coastguard Worker case cpFloatingPointX4:
3083*fd1fabb7SAndroid Build Coastguard Worker {
3084*fd1fabb7SAndroid Build Coastguard Worker
3085*fd1fabb7SAndroid Build Coastguard Worker int32 xFactor = 1;
3086*fd1fabb7SAndroid Build Coastguard Worker
3087*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fPredictor == cpFloatingPointX2)
3088*fd1fabb7SAndroid Build Coastguard Worker {
3089*fd1fabb7SAndroid Build Coastguard Worker xFactor = 2;
3090*fd1fabb7SAndroid Build Coastguard Worker }
3091*fd1fabb7SAndroid Build Coastguard Worker
3092*fd1fabb7SAndroid Build Coastguard Worker else if (ifd.fPredictor == cpFloatingPointX4)
3093*fd1fabb7SAndroid Build Coastguard Worker {
3094*fd1fabb7SAndroid Build Coastguard Worker xFactor = 4;
3095*fd1fabb7SAndroid Build Coastguard Worker }
3096*fd1fabb7SAndroid Build Coastguard Worker
3097*fd1fabb7SAndroid Build Coastguard Worker if (buffer.fRowStep < 0)
3098*fd1fabb7SAndroid Build Coastguard Worker {
3099*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("Row step may not be negative");
3100*fd1fabb7SAndroid Build Coastguard Worker }
3101*fd1fabb7SAndroid Build Coastguard Worker uint32 tempBufferSize = SafeUint32Mult (
3102*fd1fabb7SAndroid Build Coastguard Worker static_cast<uint32>(buffer.fRowStep),
3103*fd1fabb7SAndroid Build Coastguard Worker buffer.fPixelSize);
3104*fd1fabb7SAndroid Build Coastguard Worker
3105*fd1fabb7SAndroid Build Coastguard Worker if (!tempBuffer.Get () || tempBuffer->LogicalSize () < tempBufferSize)
3106*fd1fabb7SAndroid Build Coastguard Worker {
3107*fd1fabb7SAndroid Build Coastguard Worker
3108*fd1fabb7SAndroid Build Coastguard Worker tempBuffer.Reset (host.Allocate (tempBufferSize));
3109*fd1fabb7SAndroid Build Coastguard Worker
3110*fd1fabb7SAndroid Build Coastguard Worker }
3111*fd1fabb7SAndroid Build Coastguard Worker
3112*fd1fabb7SAndroid Build Coastguard Worker for (int32 row = buffer.fArea.t; row < buffer.fArea.b; row++)
3113*fd1fabb7SAndroid Build Coastguard Worker {
3114*fd1fabb7SAndroid Build Coastguard Worker
3115*fd1fabb7SAndroid Build Coastguard Worker EncodeFPDelta ((uint8 *) buffer.DirtyPixel (row, buffer.fArea.l, buffer.fPlane),
3116*fd1fabb7SAndroid Build Coastguard Worker tempBuffer->Buffer_uint8 (),
3117*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.W () / xFactor,
3118*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlanes * xFactor,
3119*fd1fabb7SAndroid Build Coastguard Worker buffer.fPixelSize);
3120*fd1fabb7SAndroid Build Coastguard Worker
3121*fd1fabb7SAndroid Build Coastguard Worker }
3122*fd1fabb7SAndroid Build Coastguard Worker
3123*fd1fabb7SAndroid Build Coastguard Worker return;
3124*fd1fabb7SAndroid Build Coastguard Worker
3125*fd1fabb7SAndroid Build Coastguard Worker }
3126*fd1fabb7SAndroid Build Coastguard Worker
3127*fd1fabb7SAndroid Build Coastguard Worker default:
3128*fd1fabb7SAndroid Build Coastguard Worker break;
3129*fd1fabb7SAndroid Build Coastguard Worker
3130*fd1fabb7SAndroid Build Coastguard Worker }
3131*fd1fabb7SAndroid Build Coastguard Worker
3132*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fPredictor != cpNullPredictor)
3133*fd1fabb7SAndroid Build Coastguard Worker {
3134*fd1fabb7SAndroid Build Coastguard Worker
3135*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
3136*fd1fabb7SAndroid Build Coastguard Worker
3137*fd1fabb7SAndroid Build Coastguard Worker }
3138*fd1fabb7SAndroid Build Coastguard Worker
3139*fd1fabb7SAndroid Build Coastguard Worker }
3140*fd1fabb7SAndroid Build Coastguard Worker
3141*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3142*fd1fabb7SAndroid Build Coastguard Worker
ByteSwapBuffer(dng_host &,dng_pixel_buffer & buffer)3143*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::ByteSwapBuffer (dng_host & /* host */,
3144*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer &buffer)
3145*fd1fabb7SAndroid Build Coastguard Worker {
3146*fd1fabb7SAndroid Build Coastguard Worker
3147*fd1fabb7SAndroid Build Coastguard Worker uint32 pixels = buffer.fRowStep * buffer.fArea.H ();
3148*fd1fabb7SAndroid Build Coastguard Worker
3149*fd1fabb7SAndroid Build Coastguard Worker switch (buffer.fPixelSize)
3150*fd1fabb7SAndroid Build Coastguard Worker {
3151*fd1fabb7SAndroid Build Coastguard Worker
3152*fd1fabb7SAndroid Build Coastguard Worker case 2:
3153*fd1fabb7SAndroid Build Coastguard Worker {
3154*fd1fabb7SAndroid Build Coastguard Worker
3155*fd1fabb7SAndroid Build Coastguard Worker DoSwapBytes16 ((uint16 *) buffer.fData,
3156*fd1fabb7SAndroid Build Coastguard Worker pixels);
3157*fd1fabb7SAndroid Build Coastguard Worker
3158*fd1fabb7SAndroid Build Coastguard Worker break;
3159*fd1fabb7SAndroid Build Coastguard Worker
3160*fd1fabb7SAndroid Build Coastguard Worker }
3161*fd1fabb7SAndroid Build Coastguard Worker
3162*fd1fabb7SAndroid Build Coastguard Worker case 4:
3163*fd1fabb7SAndroid Build Coastguard Worker {
3164*fd1fabb7SAndroid Build Coastguard Worker
3165*fd1fabb7SAndroid Build Coastguard Worker DoSwapBytes32 ((uint32 *) buffer.fData,
3166*fd1fabb7SAndroid Build Coastguard Worker pixels);
3167*fd1fabb7SAndroid Build Coastguard Worker
3168*fd1fabb7SAndroid Build Coastguard Worker break;
3169*fd1fabb7SAndroid Build Coastguard Worker
3170*fd1fabb7SAndroid Build Coastguard Worker }
3171*fd1fabb7SAndroid Build Coastguard Worker
3172*fd1fabb7SAndroid Build Coastguard Worker default:
3173*fd1fabb7SAndroid Build Coastguard Worker break;
3174*fd1fabb7SAndroid Build Coastguard Worker
3175*fd1fabb7SAndroid Build Coastguard Worker }
3176*fd1fabb7SAndroid Build Coastguard Worker
3177*fd1fabb7SAndroid Build Coastguard Worker }
3178*fd1fabb7SAndroid Build Coastguard Worker
3179*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3180*fd1fabb7SAndroid Build Coastguard Worker
ReorderSubTileBlocks(const dng_ifd & ifd,dng_pixel_buffer & buffer,AutoPtr<dng_memory_block> & uncompressedBuffer,AutoPtr<dng_memory_block> & subTileBlockBuffer)3181*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::ReorderSubTileBlocks (const dng_ifd &ifd,
3182*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer &buffer,
3183*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &uncompressedBuffer,
3184*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &subTileBlockBuffer)
3185*fd1fabb7SAndroid Build Coastguard Worker {
3186*fd1fabb7SAndroid Build Coastguard Worker
3187*fd1fabb7SAndroid Build Coastguard Worker uint32 blockRows = ifd.fSubTileBlockRows;
3188*fd1fabb7SAndroid Build Coastguard Worker uint32 blockCols = ifd.fSubTileBlockCols;
3189*fd1fabb7SAndroid Build Coastguard Worker
3190*fd1fabb7SAndroid Build Coastguard Worker uint32 rowBlocks = buffer.fArea.H () / blockRows;
3191*fd1fabb7SAndroid Build Coastguard Worker uint32 colBlocks = buffer.fArea.W () / blockCols;
3192*fd1fabb7SAndroid Build Coastguard Worker
3193*fd1fabb7SAndroid Build Coastguard Worker int32 rowStep = buffer.fRowStep * buffer.fPixelSize;
3194*fd1fabb7SAndroid Build Coastguard Worker int32 colStep = buffer.fColStep * buffer.fPixelSize;
3195*fd1fabb7SAndroid Build Coastguard Worker
3196*fd1fabb7SAndroid Build Coastguard Worker int32 rowBlockStep = rowStep * blockRows;
3197*fd1fabb7SAndroid Build Coastguard Worker int32 colBlockStep = colStep * blockCols;
3198*fd1fabb7SAndroid Build Coastguard Worker
3199*fd1fabb7SAndroid Build Coastguard Worker uint32 blockColBytes = blockCols * buffer.fPlanes * buffer.fPixelSize;
3200*fd1fabb7SAndroid Build Coastguard Worker
3201*fd1fabb7SAndroid Build Coastguard Worker const uint8 *s0 = uncompressedBuffer->Buffer_uint8 ();
3202*fd1fabb7SAndroid Build Coastguard Worker uint8 *d0 = subTileBlockBuffer->Buffer_uint8 ();
3203*fd1fabb7SAndroid Build Coastguard Worker
3204*fd1fabb7SAndroid Build Coastguard Worker for (uint32 rowBlock = 0; rowBlock < rowBlocks; rowBlock++)
3205*fd1fabb7SAndroid Build Coastguard Worker {
3206*fd1fabb7SAndroid Build Coastguard Worker
3207*fd1fabb7SAndroid Build Coastguard Worker const uint8 *s1 = s0;
3208*fd1fabb7SAndroid Build Coastguard Worker
3209*fd1fabb7SAndroid Build Coastguard Worker for (uint32 colBlock = 0; colBlock < colBlocks; colBlock++)
3210*fd1fabb7SAndroid Build Coastguard Worker {
3211*fd1fabb7SAndroid Build Coastguard Worker
3212*fd1fabb7SAndroid Build Coastguard Worker const uint8 *s2 = s1;
3213*fd1fabb7SAndroid Build Coastguard Worker
3214*fd1fabb7SAndroid Build Coastguard Worker for (uint32 blockRow = 0; blockRow < blockRows; blockRow++)
3215*fd1fabb7SAndroid Build Coastguard Worker {
3216*fd1fabb7SAndroid Build Coastguard Worker
3217*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < blockColBytes; j++)
3218*fd1fabb7SAndroid Build Coastguard Worker {
3219*fd1fabb7SAndroid Build Coastguard Worker
3220*fd1fabb7SAndroid Build Coastguard Worker d0 [j] = s2 [j];
3221*fd1fabb7SAndroid Build Coastguard Worker
3222*fd1fabb7SAndroid Build Coastguard Worker }
3223*fd1fabb7SAndroid Build Coastguard Worker
3224*fd1fabb7SAndroid Build Coastguard Worker d0 += blockColBytes;
3225*fd1fabb7SAndroid Build Coastguard Worker
3226*fd1fabb7SAndroid Build Coastguard Worker s2 += rowStep;
3227*fd1fabb7SAndroid Build Coastguard Worker
3228*fd1fabb7SAndroid Build Coastguard Worker }
3229*fd1fabb7SAndroid Build Coastguard Worker
3230*fd1fabb7SAndroid Build Coastguard Worker s1 += colBlockStep;
3231*fd1fabb7SAndroid Build Coastguard Worker
3232*fd1fabb7SAndroid Build Coastguard Worker }
3233*fd1fabb7SAndroid Build Coastguard Worker
3234*fd1fabb7SAndroid Build Coastguard Worker s0 += rowBlockStep;
3235*fd1fabb7SAndroid Build Coastguard Worker
3236*fd1fabb7SAndroid Build Coastguard Worker }
3237*fd1fabb7SAndroid Build Coastguard Worker
3238*fd1fabb7SAndroid Build Coastguard Worker // Copy back reordered pixels.
3239*fd1fabb7SAndroid Build Coastguard Worker
3240*fd1fabb7SAndroid Build Coastguard Worker DoCopyBytes (subTileBlockBuffer->Buffer (),
3241*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer->Buffer (),
3242*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer->LogicalSize ());
3243*fd1fabb7SAndroid Build Coastguard Worker
3244*fd1fabb7SAndroid Build Coastguard Worker }
3245*fd1fabb7SAndroid Build Coastguard Worker
3246*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
3247*fd1fabb7SAndroid Build Coastguard Worker
3248*fd1fabb7SAndroid Build Coastguard Worker class dng_lzw_compressor
3249*fd1fabb7SAndroid Build Coastguard Worker {
3250*fd1fabb7SAndroid Build Coastguard Worker
3251*fd1fabb7SAndroid Build Coastguard Worker private:
3252*fd1fabb7SAndroid Build Coastguard Worker
3253*fd1fabb7SAndroid Build Coastguard Worker enum
3254*fd1fabb7SAndroid Build Coastguard Worker {
3255*fd1fabb7SAndroid Build Coastguard Worker kResetCode = 256,
3256*fd1fabb7SAndroid Build Coastguard Worker kEndCode = 257,
3257*fd1fabb7SAndroid Build Coastguard Worker kTableSize = 4096
3258*fd1fabb7SAndroid Build Coastguard Worker };
3259*fd1fabb7SAndroid Build Coastguard Worker
3260*fd1fabb7SAndroid Build Coastguard Worker // Compressor nodes have two son pointers. The low order bit of
3261*fd1fabb7SAndroid Build Coastguard Worker // the next code determines which pointer is used. This cuts the
3262*fd1fabb7SAndroid Build Coastguard Worker // number of nodes searched for the next code by two on average.
3263*fd1fabb7SAndroid Build Coastguard Worker
3264*fd1fabb7SAndroid Build Coastguard Worker struct LZWCompressorNode
3265*fd1fabb7SAndroid Build Coastguard Worker {
3266*fd1fabb7SAndroid Build Coastguard Worker int16 final;
3267*fd1fabb7SAndroid Build Coastguard Worker int16 son0;
3268*fd1fabb7SAndroid Build Coastguard Worker int16 son1;
3269*fd1fabb7SAndroid Build Coastguard Worker int16 brother;
3270*fd1fabb7SAndroid Build Coastguard Worker };
3271*fd1fabb7SAndroid Build Coastguard Worker
3272*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data fBuffer;
3273*fd1fabb7SAndroid Build Coastguard Worker
3274*fd1fabb7SAndroid Build Coastguard Worker LZWCompressorNode *fTable;
3275*fd1fabb7SAndroid Build Coastguard Worker
3276*fd1fabb7SAndroid Build Coastguard Worker uint8 *fDstPtr;
3277*fd1fabb7SAndroid Build Coastguard Worker
3278*fd1fabb7SAndroid Build Coastguard Worker int32 fDstCount;
3279*fd1fabb7SAndroid Build Coastguard Worker
3280*fd1fabb7SAndroid Build Coastguard Worker int32 fBitOffset;
3281*fd1fabb7SAndroid Build Coastguard Worker
3282*fd1fabb7SAndroid Build Coastguard Worker int32 fNextCode;
3283*fd1fabb7SAndroid Build Coastguard Worker
3284*fd1fabb7SAndroid Build Coastguard Worker int32 fCodeSize;
3285*fd1fabb7SAndroid Build Coastguard Worker
3286*fd1fabb7SAndroid Build Coastguard Worker public:
3287*fd1fabb7SAndroid Build Coastguard Worker
3288*fd1fabb7SAndroid Build Coastguard Worker dng_lzw_compressor ();
3289*fd1fabb7SAndroid Build Coastguard Worker
3290*fd1fabb7SAndroid Build Coastguard Worker void Compress (const uint8 *sPtr,
3291*fd1fabb7SAndroid Build Coastguard Worker uint8 *dPtr,
3292*fd1fabb7SAndroid Build Coastguard Worker uint32 sCount,
3293*fd1fabb7SAndroid Build Coastguard Worker uint32 &dCount);
3294*fd1fabb7SAndroid Build Coastguard Worker
3295*fd1fabb7SAndroid Build Coastguard Worker private:
3296*fd1fabb7SAndroid Build Coastguard Worker
3297*fd1fabb7SAndroid Build Coastguard Worker void InitTable ();
3298*fd1fabb7SAndroid Build Coastguard Worker
SearchTable(int32 w,int32 k) const3299*fd1fabb7SAndroid Build Coastguard Worker int32 SearchTable (int32 w, int32 k) const
3300*fd1fabb7SAndroid Build Coastguard Worker {
3301*fd1fabb7SAndroid Build Coastguard Worker
3302*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT ((w >= 0) && (w <= kTableSize),
3303*fd1fabb7SAndroid Build Coastguard Worker "Bad w value in dng_lzw_compressor::SearchTable");
3304*fd1fabb7SAndroid Build Coastguard Worker
3305*fd1fabb7SAndroid Build Coastguard Worker int32 son0 = fTable [w] . son0;
3306*fd1fabb7SAndroid Build Coastguard Worker int32 son1 = fTable [w] . son1;
3307*fd1fabb7SAndroid Build Coastguard Worker
3308*fd1fabb7SAndroid Build Coastguard Worker // Branchless version of:
3309*fd1fabb7SAndroid Build Coastguard Worker // int32 code = (k & 1) ? son1 : son0;
3310*fd1fabb7SAndroid Build Coastguard Worker
3311*fd1fabb7SAndroid Build Coastguard Worker int32 code = son0 + ((-((int32) (k & 1))) & (son1 - son0));
3312*fd1fabb7SAndroid Build Coastguard Worker
3313*fd1fabb7SAndroid Build Coastguard Worker while (code > 0 && fTable [code].final != k)
3314*fd1fabb7SAndroid Build Coastguard Worker {
3315*fd1fabb7SAndroid Build Coastguard Worker code = fTable [code].brother;
3316*fd1fabb7SAndroid Build Coastguard Worker }
3317*fd1fabb7SAndroid Build Coastguard Worker
3318*fd1fabb7SAndroid Build Coastguard Worker return code;
3319*fd1fabb7SAndroid Build Coastguard Worker
3320*fd1fabb7SAndroid Build Coastguard Worker }
3321*fd1fabb7SAndroid Build Coastguard Worker
3322*fd1fabb7SAndroid Build Coastguard Worker void AddTable (int32 w, int32 k);
3323*fd1fabb7SAndroid Build Coastguard Worker
3324*fd1fabb7SAndroid Build Coastguard Worker void PutCodeWord (int32 code);
3325*fd1fabb7SAndroid Build Coastguard Worker
3326*fd1fabb7SAndroid Build Coastguard Worker // Hidden copy constructor and assignment operator.
3327*fd1fabb7SAndroid Build Coastguard Worker
3328*fd1fabb7SAndroid Build Coastguard Worker dng_lzw_compressor (const dng_lzw_compressor &compressor);
3329*fd1fabb7SAndroid Build Coastguard Worker
3330*fd1fabb7SAndroid Build Coastguard Worker dng_lzw_compressor & operator= (const dng_lzw_compressor &compressor);
3331*fd1fabb7SAndroid Build Coastguard Worker
3332*fd1fabb7SAndroid Build Coastguard Worker };
3333*fd1fabb7SAndroid Build Coastguard Worker
3334*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
3335*fd1fabb7SAndroid Build Coastguard Worker
dng_lzw_compressor()3336*fd1fabb7SAndroid Build Coastguard Worker dng_lzw_compressor::dng_lzw_compressor ()
3337*fd1fabb7SAndroid Build Coastguard Worker
3338*fd1fabb7SAndroid Build Coastguard Worker : fBuffer ()
3339*fd1fabb7SAndroid Build Coastguard Worker , fTable (NULL)
3340*fd1fabb7SAndroid Build Coastguard Worker , fDstPtr (NULL)
3341*fd1fabb7SAndroid Build Coastguard Worker , fDstCount (0)
3342*fd1fabb7SAndroid Build Coastguard Worker , fBitOffset (0)
3343*fd1fabb7SAndroid Build Coastguard Worker , fNextCode (0)
3344*fd1fabb7SAndroid Build Coastguard Worker , fCodeSize (0)
3345*fd1fabb7SAndroid Build Coastguard Worker
3346*fd1fabb7SAndroid Build Coastguard Worker {
3347*fd1fabb7SAndroid Build Coastguard Worker
3348*fd1fabb7SAndroid Build Coastguard Worker fBuffer.Allocate (kTableSize, sizeof (LZWCompressorNode));
3349*fd1fabb7SAndroid Build Coastguard Worker
3350*fd1fabb7SAndroid Build Coastguard Worker fTable = (LZWCompressorNode *) fBuffer.Buffer ();
3351*fd1fabb7SAndroid Build Coastguard Worker
3352*fd1fabb7SAndroid Build Coastguard Worker }
3353*fd1fabb7SAndroid Build Coastguard Worker
3354*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
3355*fd1fabb7SAndroid Build Coastguard Worker
InitTable()3356*fd1fabb7SAndroid Build Coastguard Worker void dng_lzw_compressor::InitTable ()
3357*fd1fabb7SAndroid Build Coastguard Worker {
3358*fd1fabb7SAndroid Build Coastguard Worker
3359*fd1fabb7SAndroid Build Coastguard Worker fCodeSize = 9;
3360*fd1fabb7SAndroid Build Coastguard Worker
3361*fd1fabb7SAndroid Build Coastguard Worker fNextCode = 258;
3362*fd1fabb7SAndroid Build Coastguard Worker
3363*fd1fabb7SAndroid Build Coastguard Worker LZWCompressorNode *node = &fTable [0];
3364*fd1fabb7SAndroid Build Coastguard Worker
3365*fd1fabb7SAndroid Build Coastguard Worker for (int32 code = 0; code < 256; ++code)
3366*fd1fabb7SAndroid Build Coastguard Worker {
3367*fd1fabb7SAndroid Build Coastguard Worker
3368*fd1fabb7SAndroid Build Coastguard Worker node->final = (int16) code;
3369*fd1fabb7SAndroid Build Coastguard Worker node->son0 = -1;
3370*fd1fabb7SAndroid Build Coastguard Worker node->son1 = -1;
3371*fd1fabb7SAndroid Build Coastguard Worker node->brother = -1;
3372*fd1fabb7SAndroid Build Coastguard Worker
3373*fd1fabb7SAndroid Build Coastguard Worker node++;
3374*fd1fabb7SAndroid Build Coastguard Worker
3375*fd1fabb7SAndroid Build Coastguard Worker }
3376*fd1fabb7SAndroid Build Coastguard Worker
3377*fd1fabb7SAndroid Build Coastguard Worker }
3378*fd1fabb7SAndroid Build Coastguard Worker
3379*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
3380*fd1fabb7SAndroid Build Coastguard Worker
AddTable(int32 w,int32 k)3381*fd1fabb7SAndroid Build Coastguard Worker void dng_lzw_compressor::AddTable (int32 w, int32 k)
3382*fd1fabb7SAndroid Build Coastguard Worker {
3383*fd1fabb7SAndroid Build Coastguard Worker
3384*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT ((w >= 0) && (w <= kTableSize),
3385*fd1fabb7SAndroid Build Coastguard Worker "Bad w value in dng_lzw_compressor::AddTable");
3386*fd1fabb7SAndroid Build Coastguard Worker
3387*fd1fabb7SAndroid Build Coastguard Worker LZWCompressorNode *node = &fTable [w];
3388*fd1fabb7SAndroid Build Coastguard Worker
3389*fd1fabb7SAndroid Build Coastguard Worker int32 nextCode = fNextCode;
3390*fd1fabb7SAndroid Build Coastguard Worker
3391*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT ((nextCode >= 0) && (nextCode <= kTableSize),
3392*fd1fabb7SAndroid Build Coastguard Worker "Bad fNextCode value in dng_lzw_compressor::AddTable");
3393*fd1fabb7SAndroid Build Coastguard Worker
3394*fd1fabb7SAndroid Build Coastguard Worker LZWCompressorNode *node2 = &fTable [nextCode];
3395*fd1fabb7SAndroid Build Coastguard Worker
3396*fd1fabb7SAndroid Build Coastguard Worker fNextCode++;
3397*fd1fabb7SAndroid Build Coastguard Worker
3398*fd1fabb7SAndroid Build Coastguard Worker int32 oldSon;
3399*fd1fabb7SAndroid Build Coastguard Worker
3400*fd1fabb7SAndroid Build Coastguard Worker if( k&1 )
3401*fd1fabb7SAndroid Build Coastguard Worker {
3402*fd1fabb7SAndroid Build Coastguard Worker oldSon = node->son1;
3403*fd1fabb7SAndroid Build Coastguard Worker node->son1 = (int16) nextCode;
3404*fd1fabb7SAndroid Build Coastguard Worker }
3405*fd1fabb7SAndroid Build Coastguard Worker else
3406*fd1fabb7SAndroid Build Coastguard Worker {
3407*fd1fabb7SAndroid Build Coastguard Worker oldSon = node->son0;
3408*fd1fabb7SAndroid Build Coastguard Worker node->son0 = (int16) nextCode;
3409*fd1fabb7SAndroid Build Coastguard Worker }
3410*fd1fabb7SAndroid Build Coastguard Worker
3411*fd1fabb7SAndroid Build Coastguard Worker node2->final = (int16) k;
3412*fd1fabb7SAndroid Build Coastguard Worker node2->son0 = -1;
3413*fd1fabb7SAndroid Build Coastguard Worker node2->son1 = -1;
3414*fd1fabb7SAndroid Build Coastguard Worker node2->brother = (int16) oldSon;
3415*fd1fabb7SAndroid Build Coastguard Worker
3416*fd1fabb7SAndroid Build Coastguard Worker if (nextCode == (1 << fCodeSize) - 1)
3417*fd1fabb7SAndroid Build Coastguard Worker {
3418*fd1fabb7SAndroid Build Coastguard Worker if (fCodeSize != 12)
3419*fd1fabb7SAndroid Build Coastguard Worker fCodeSize++;
3420*fd1fabb7SAndroid Build Coastguard Worker }
3421*fd1fabb7SAndroid Build Coastguard Worker
3422*fd1fabb7SAndroid Build Coastguard Worker }
3423*fd1fabb7SAndroid Build Coastguard Worker
3424*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
3425*fd1fabb7SAndroid Build Coastguard Worker
PutCodeWord(int32 code)3426*fd1fabb7SAndroid Build Coastguard Worker void dng_lzw_compressor::PutCodeWord (int32 code)
3427*fd1fabb7SAndroid Build Coastguard Worker {
3428*fd1fabb7SAndroid Build Coastguard Worker
3429*fd1fabb7SAndroid Build Coastguard Worker int32 bit = (int32) (fBitOffset & 7);
3430*fd1fabb7SAndroid Build Coastguard Worker
3431*fd1fabb7SAndroid Build Coastguard Worker int32 offset1 = fBitOffset >> 3;
3432*fd1fabb7SAndroid Build Coastguard Worker int32 offset2 = (fBitOffset + fCodeSize - 1) >> 3;
3433*fd1fabb7SAndroid Build Coastguard Worker
3434*fd1fabb7SAndroid Build Coastguard Worker int32 shift1 = (fCodeSize + bit) - 8;
3435*fd1fabb7SAndroid Build Coastguard Worker int32 shift2 = (fCodeSize + bit) - 16;
3436*fd1fabb7SAndroid Build Coastguard Worker
3437*fd1fabb7SAndroid Build Coastguard Worker uint8 byte1 = (uint8) (code >> shift1);
3438*fd1fabb7SAndroid Build Coastguard Worker
3439*fd1fabb7SAndroid Build Coastguard Worker uint8 *dstPtr1 = fDstPtr + offset1;
3440*fd1fabb7SAndroid Build Coastguard Worker uint8 *dstPtr3 = fDstPtr + offset2;
3441*fd1fabb7SAndroid Build Coastguard Worker
3442*fd1fabb7SAndroid Build Coastguard Worker if (offset1 + 1 == offset2)
3443*fd1fabb7SAndroid Build Coastguard Worker {
3444*fd1fabb7SAndroid Build Coastguard Worker
3445*fd1fabb7SAndroid Build Coastguard Worker uint8 byte2 = (uint8) (code << (-shift2));
3446*fd1fabb7SAndroid Build Coastguard Worker
3447*fd1fabb7SAndroid Build Coastguard Worker if (bit)
3448*fd1fabb7SAndroid Build Coastguard Worker *dstPtr1 |= byte1;
3449*fd1fabb7SAndroid Build Coastguard Worker else
3450*fd1fabb7SAndroid Build Coastguard Worker *dstPtr1 = byte1;
3451*fd1fabb7SAndroid Build Coastguard Worker
3452*fd1fabb7SAndroid Build Coastguard Worker *dstPtr3 = byte2;
3453*fd1fabb7SAndroid Build Coastguard Worker
3454*fd1fabb7SAndroid Build Coastguard Worker }
3455*fd1fabb7SAndroid Build Coastguard Worker
3456*fd1fabb7SAndroid Build Coastguard Worker else
3457*fd1fabb7SAndroid Build Coastguard Worker {
3458*fd1fabb7SAndroid Build Coastguard Worker
3459*fd1fabb7SAndroid Build Coastguard Worker int32 shift3 = (fCodeSize + bit) - 24;
3460*fd1fabb7SAndroid Build Coastguard Worker
3461*fd1fabb7SAndroid Build Coastguard Worker uint8 byte2 = (uint8) (code >> shift2);
3462*fd1fabb7SAndroid Build Coastguard Worker uint8 byte3 = (uint8) (code << (-shift3));
3463*fd1fabb7SAndroid Build Coastguard Worker
3464*fd1fabb7SAndroid Build Coastguard Worker uint8 *dstPtr2 = fDstPtr + (offset1 + 1);
3465*fd1fabb7SAndroid Build Coastguard Worker
3466*fd1fabb7SAndroid Build Coastguard Worker if (bit)
3467*fd1fabb7SAndroid Build Coastguard Worker *dstPtr1 |= byte1;
3468*fd1fabb7SAndroid Build Coastguard Worker else
3469*fd1fabb7SAndroid Build Coastguard Worker *dstPtr1 = byte1;
3470*fd1fabb7SAndroid Build Coastguard Worker
3471*fd1fabb7SAndroid Build Coastguard Worker *dstPtr2 = byte2;
3472*fd1fabb7SAndroid Build Coastguard Worker
3473*fd1fabb7SAndroid Build Coastguard Worker *dstPtr3 = byte3;
3474*fd1fabb7SAndroid Build Coastguard Worker
3475*fd1fabb7SAndroid Build Coastguard Worker }
3476*fd1fabb7SAndroid Build Coastguard Worker
3477*fd1fabb7SAndroid Build Coastguard Worker fBitOffset += fCodeSize;
3478*fd1fabb7SAndroid Build Coastguard Worker
3479*fd1fabb7SAndroid Build Coastguard Worker }
3480*fd1fabb7SAndroid Build Coastguard Worker
3481*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
3482*fd1fabb7SAndroid Build Coastguard Worker
Compress(const uint8 * sPtr,uint8 * dPtr,uint32 sCount,uint32 & dCount)3483*fd1fabb7SAndroid Build Coastguard Worker void dng_lzw_compressor::Compress (const uint8 *sPtr,
3484*fd1fabb7SAndroid Build Coastguard Worker uint8 *dPtr,
3485*fd1fabb7SAndroid Build Coastguard Worker uint32 sCount,
3486*fd1fabb7SAndroid Build Coastguard Worker uint32 &dCount)
3487*fd1fabb7SAndroid Build Coastguard Worker {
3488*fd1fabb7SAndroid Build Coastguard Worker
3489*fd1fabb7SAndroid Build Coastguard Worker fDstPtr = dPtr;
3490*fd1fabb7SAndroid Build Coastguard Worker
3491*fd1fabb7SAndroid Build Coastguard Worker fBitOffset = 0;
3492*fd1fabb7SAndroid Build Coastguard Worker
3493*fd1fabb7SAndroid Build Coastguard Worker InitTable ();
3494*fd1fabb7SAndroid Build Coastguard Worker
3495*fd1fabb7SAndroid Build Coastguard Worker PutCodeWord (kResetCode);
3496*fd1fabb7SAndroid Build Coastguard Worker
3497*fd1fabb7SAndroid Build Coastguard Worker int32 code = -1;
3498*fd1fabb7SAndroid Build Coastguard Worker
3499*fd1fabb7SAndroid Build Coastguard Worker int32 pixel;
3500*fd1fabb7SAndroid Build Coastguard Worker
3501*fd1fabb7SAndroid Build Coastguard Worker if (sCount > 0)
3502*fd1fabb7SAndroid Build Coastguard Worker {
3503*fd1fabb7SAndroid Build Coastguard Worker
3504*fd1fabb7SAndroid Build Coastguard Worker pixel = *sPtr;
3505*fd1fabb7SAndroid Build Coastguard Worker sPtr = sPtr + 1;
3506*fd1fabb7SAndroid Build Coastguard Worker code = pixel;
3507*fd1fabb7SAndroid Build Coastguard Worker
3508*fd1fabb7SAndroid Build Coastguard Worker sCount--;
3509*fd1fabb7SAndroid Build Coastguard Worker
3510*fd1fabb7SAndroid Build Coastguard Worker while (sCount--)
3511*fd1fabb7SAndroid Build Coastguard Worker {
3512*fd1fabb7SAndroid Build Coastguard Worker
3513*fd1fabb7SAndroid Build Coastguard Worker pixel = *sPtr;
3514*fd1fabb7SAndroid Build Coastguard Worker sPtr = sPtr + 1;
3515*fd1fabb7SAndroid Build Coastguard Worker
3516*fd1fabb7SAndroid Build Coastguard Worker int32 newCode = SearchTable (code, pixel);
3517*fd1fabb7SAndroid Build Coastguard Worker
3518*fd1fabb7SAndroid Build Coastguard Worker if (newCode == -1)
3519*fd1fabb7SAndroid Build Coastguard Worker {
3520*fd1fabb7SAndroid Build Coastguard Worker
3521*fd1fabb7SAndroid Build Coastguard Worker PutCodeWord (code);
3522*fd1fabb7SAndroid Build Coastguard Worker
3523*fd1fabb7SAndroid Build Coastguard Worker if (fNextCode < 4093)
3524*fd1fabb7SAndroid Build Coastguard Worker {
3525*fd1fabb7SAndroid Build Coastguard Worker AddTable (code, pixel);
3526*fd1fabb7SAndroid Build Coastguard Worker }
3527*fd1fabb7SAndroid Build Coastguard Worker else
3528*fd1fabb7SAndroid Build Coastguard Worker {
3529*fd1fabb7SAndroid Build Coastguard Worker PutCodeWord (kResetCode);
3530*fd1fabb7SAndroid Build Coastguard Worker InitTable ();
3531*fd1fabb7SAndroid Build Coastguard Worker }
3532*fd1fabb7SAndroid Build Coastguard Worker
3533*fd1fabb7SAndroid Build Coastguard Worker code = pixel;
3534*fd1fabb7SAndroid Build Coastguard Worker
3535*fd1fabb7SAndroid Build Coastguard Worker }
3536*fd1fabb7SAndroid Build Coastguard Worker
3537*fd1fabb7SAndroid Build Coastguard Worker else
3538*fd1fabb7SAndroid Build Coastguard Worker code = newCode;
3539*fd1fabb7SAndroid Build Coastguard Worker
3540*fd1fabb7SAndroid Build Coastguard Worker }
3541*fd1fabb7SAndroid Build Coastguard Worker
3542*fd1fabb7SAndroid Build Coastguard Worker }
3543*fd1fabb7SAndroid Build Coastguard Worker
3544*fd1fabb7SAndroid Build Coastguard Worker if (code != -1)
3545*fd1fabb7SAndroid Build Coastguard Worker {
3546*fd1fabb7SAndroid Build Coastguard Worker PutCodeWord (code);
3547*fd1fabb7SAndroid Build Coastguard Worker AddTable (code, 0);
3548*fd1fabb7SAndroid Build Coastguard Worker }
3549*fd1fabb7SAndroid Build Coastguard Worker
3550*fd1fabb7SAndroid Build Coastguard Worker PutCodeWord (kEndCode);
3551*fd1fabb7SAndroid Build Coastguard Worker
3552*fd1fabb7SAndroid Build Coastguard Worker dCount = (fBitOffset + 7) >> 3;
3553*fd1fabb7SAndroid Build Coastguard Worker
3554*fd1fabb7SAndroid Build Coastguard Worker }
3555*fd1fabb7SAndroid Build Coastguard Worker
3556*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3557*fd1fabb7SAndroid Build Coastguard Worker
3558*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseLibJPEG
3559*fd1fabb7SAndroid Build Coastguard Worker
3560*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3561*fd1fabb7SAndroid Build Coastguard Worker
dng_error_exit(j_common_ptr cinfo)3562*fd1fabb7SAndroid Build Coastguard Worker static void dng_error_exit (j_common_ptr cinfo)
3563*fd1fabb7SAndroid Build Coastguard Worker {
3564*fd1fabb7SAndroid Build Coastguard Worker
3565*fd1fabb7SAndroid Build Coastguard Worker // Output message.
3566*fd1fabb7SAndroid Build Coastguard Worker
3567*fd1fabb7SAndroid Build Coastguard Worker (*cinfo->err->output_message) (cinfo);
3568*fd1fabb7SAndroid Build Coastguard Worker
3569*fd1fabb7SAndroid Build Coastguard Worker // Convert to a dng_exception.
3570*fd1fabb7SAndroid Build Coastguard Worker
3571*fd1fabb7SAndroid Build Coastguard Worker switch (cinfo->err->msg_code)
3572*fd1fabb7SAndroid Build Coastguard Worker {
3573*fd1fabb7SAndroid Build Coastguard Worker
3574*fd1fabb7SAndroid Build Coastguard Worker case JERR_OUT_OF_MEMORY:
3575*fd1fabb7SAndroid Build Coastguard Worker {
3576*fd1fabb7SAndroid Build Coastguard Worker ThrowMemoryFull ();
3577*fd1fabb7SAndroid Build Coastguard Worker break;
3578*fd1fabb7SAndroid Build Coastguard Worker }
3579*fd1fabb7SAndroid Build Coastguard Worker
3580*fd1fabb7SAndroid Build Coastguard Worker default:
3581*fd1fabb7SAndroid Build Coastguard Worker {
3582*fd1fabb7SAndroid Build Coastguard Worker ThrowBadFormat ();
3583*fd1fabb7SAndroid Build Coastguard Worker }
3584*fd1fabb7SAndroid Build Coastguard Worker
3585*fd1fabb7SAndroid Build Coastguard Worker }
3586*fd1fabb7SAndroid Build Coastguard Worker
3587*fd1fabb7SAndroid Build Coastguard Worker }
3588*fd1fabb7SAndroid Build Coastguard Worker
3589*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3590*fd1fabb7SAndroid Build Coastguard Worker
dng_output_message(j_common_ptr cinfo)3591*fd1fabb7SAndroid Build Coastguard Worker static void dng_output_message (j_common_ptr cinfo)
3592*fd1fabb7SAndroid Build Coastguard Worker {
3593*fd1fabb7SAndroid Build Coastguard Worker
3594*fd1fabb7SAndroid Build Coastguard Worker // Format message to string.
3595*fd1fabb7SAndroid Build Coastguard Worker
3596*fd1fabb7SAndroid Build Coastguard Worker char buffer [JMSG_LENGTH_MAX];
3597*fd1fabb7SAndroid Build Coastguard Worker
3598*fd1fabb7SAndroid Build Coastguard Worker (*cinfo->err->format_message) (cinfo, buffer);
3599*fd1fabb7SAndroid Build Coastguard Worker
3600*fd1fabb7SAndroid Build Coastguard Worker // Report the libjpeg message as a warning.
3601*fd1fabb7SAndroid Build Coastguard Worker
3602*fd1fabb7SAndroid Build Coastguard Worker ReportWarning ("libjpeg", buffer);
3603*fd1fabb7SAndroid Build Coastguard Worker
3604*fd1fabb7SAndroid Build Coastguard Worker }
3605*fd1fabb7SAndroid Build Coastguard Worker
3606*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3607*fd1fabb7SAndroid Build Coastguard Worker
3608*fd1fabb7SAndroid Build Coastguard Worker struct dng_jpeg_stream_dest
3609*fd1fabb7SAndroid Build Coastguard Worker {
3610*fd1fabb7SAndroid Build Coastguard Worker
3611*fd1fabb7SAndroid Build Coastguard Worker struct jpeg_destination_mgr pub;
3612*fd1fabb7SAndroid Build Coastguard Worker
3613*fd1fabb7SAndroid Build Coastguard Worker dng_stream *fStream;
3614*fd1fabb7SAndroid Build Coastguard Worker
3615*fd1fabb7SAndroid Build Coastguard Worker uint8 fBuffer [4096];
3616*fd1fabb7SAndroid Build Coastguard Worker
3617*fd1fabb7SAndroid Build Coastguard Worker };
3618*fd1fabb7SAndroid Build Coastguard Worker
3619*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3620*fd1fabb7SAndroid Build Coastguard Worker
dng_init_destination(j_compress_ptr cinfo)3621*fd1fabb7SAndroid Build Coastguard Worker static void dng_init_destination (j_compress_ptr cinfo)
3622*fd1fabb7SAndroid Build Coastguard Worker {
3623*fd1fabb7SAndroid Build Coastguard Worker
3624*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_stream_dest *dest = (dng_jpeg_stream_dest *) cinfo->dest;
3625*fd1fabb7SAndroid Build Coastguard Worker
3626*fd1fabb7SAndroid Build Coastguard Worker dest->pub.next_output_byte = dest->fBuffer;
3627*fd1fabb7SAndroid Build Coastguard Worker dest->pub.free_in_buffer = sizeof (dest->fBuffer);
3628*fd1fabb7SAndroid Build Coastguard Worker
3629*fd1fabb7SAndroid Build Coastguard Worker }
3630*fd1fabb7SAndroid Build Coastguard Worker
3631*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3632*fd1fabb7SAndroid Build Coastguard Worker
dng_empty_output_buffer(j_compress_ptr cinfo)3633*fd1fabb7SAndroid Build Coastguard Worker static boolean dng_empty_output_buffer (j_compress_ptr cinfo)
3634*fd1fabb7SAndroid Build Coastguard Worker {
3635*fd1fabb7SAndroid Build Coastguard Worker
3636*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_stream_dest *dest = (dng_jpeg_stream_dest *) cinfo->dest;
3637*fd1fabb7SAndroid Build Coastguard Worker
3638*fd1fabb7SAndroid Build Coastguard Worker dest->fStream->Put (dest->fBuffer, sizeof (dest->fBuffer));
3639*fd1fabb7SAndroid Build Coastguard Worker
3640*fd1fabb7SAndroid Build Coastguard Worker dest->pub.next_output_byte = dest->fBuffer;
3641*fd1fabb7SAndroid Build Coastguard Worker dest->pub.free_in_buffer = sizeof (dest->fBuffer);
3642*fd1fabb7SAndroid Build Coastguard Worker
3643*fd1fabb7SAndroid Build Coastguard Worker return TRUE;
3644*fd1fabb7SAndroid Build Coastguard Worker
3645*fd1fabb7SAndroid Build Coastguard Worker }
3646*fd1fabb7SAndroid Build Coastguard Worker
3647*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3648*fd1fabb7SAndroid Build Coastguard Worker
dng_term_destination(j_compress_ptr cinfo)3649*fd1fabb7SAndroid Build Coastguard Worker static void dng_term_destination (j_compress_ptr cinfo)
3650*fd1fabb7SAndroid Build Coastguard Worker {
3651*fd1fabb7SAndroid Build Coastguard Worker
3652*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_stream_dest *dest = (dng_jpeg_stream_dest *) cinfo->dest;
3653*fd1fabb7SAndroid Build Coastguard Worker
3654*fd1fabb7SAndroid Build Coastguard Worker uint32 datacount = sizeof (dest->fBuffer) -
3655*fd1fabb7SAndroid Build Coastguard Worker (uint32) dest->pub.free_in_buffer;
3656*fd1fabb7SAndroid Build Coastguard Worker
3657*fd1fabb7SAndroid Build Coastguard Worker if (datacount)
3658*fd1fabb7SAndroid Build Coastguard Worker {
3659*fd1fabb7SAndroid Build Coastguard Worker dest->fStream->Put (dest->fBuffer, datacount);
3660*fd1fabb7SAndroid Build Coastguard Worker }
3661*fd1fabb7SAndroid Build Coastguard Worker
3662*fd1fabb7SAndroid Build Coastguard Worker }
3663*fd1fabb7SAndroid Build Coastguard Worker
3664*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3665*fd1fabb7SAndroid Build Coastguard Worker
jpeg_set_adobe_quality(struct jpeg_compress_struct * cinfo,int32 quality)3666*fd1fabb7SAndroid Build Coastguard Worker static void jpeg_set_adobe_quality (struct jpeg_compress_struct *cinfo,
3667*fd1fabb7SAndroid Build Coastguard Worker int32 quality)
3668*fd1fabb7SAndroid Build Coastguard Worker {
3669*fd1fabb7SAndroid Build Coastguard Worker
3670*fd1fabb7SAndroid Build Coastguard Worker // If out of range, map to default.
3671*fd1fabb7SAndroid Build Coastguard Worker
3672*fd1fabb7SAndroid Build Coastguard Worker if (quality < 0 || quality > 12)
3673*fd1fabb7SAndroid Build Coastguard Worker {
3674*fd1fabb7SAndroid Build Coastguard Worker quality = 10;
3675*fd1fabb7SAndroid Build Coastguard Worker }
3676*fd1fabb7SAndroid Build Coastguard Worker
3677*fd1fabb7SAndroid Build Coastguard Worker // Adobe turns off chroma downsampling at high quality levels.
3678*fd1fabb7SAndroid Build Coastguard Worker
3679*fd1fabb7SAndroid Build Coastguard Worker bool useChromaDownsampling = (quality <= 6);
3680*fd1fabb7SAndroid Build Coastguard Worker
3681*fd1fabb7SAndroid Build Coastguard Worker // Approximate mapping from Adobe quality levels to LibJPEG levels.
3682*fd1fabb7SAndroid Build Coastguard Worker
3683*fd1fabb7SAndroid Build Coastguard Worker const int kLibJPEGQuality [13] =
3684*fd1fabb7SAndroid Build Coastguard Worker {
3685*fd1fabb7SAndroid Build Coastguard Worker 5, 11, 23, 34, 46, 63, 76, 77, 86, 90, 94, 97, 99
3686*fd1fabb7SAndroid Build Coastguard Worker };
3687*fd1fabb7SAndroid Build Coastguard Worker
3688*fd1fabb7SAndroid Build Coastguard Worker quality = kLibJPEGQuality [quality];
3689*fd1fabb7SAndroid Build Coastguard Worker
3690*fd1fabb7SAndroid Build Coastguard Worker jpeg_set_quality (cinfo, quality, TRUE);
3691*fd1fabb7SAndroid Build Coastguard Worker
3692*fd1fabb7SAndroid Build Coastguard Worker // LibJPEG defaults to always using chroma downsampling. Turn if off
3693*fd1fabb7SAndroid Build Coastguard Worker // if we need it off to match Adobe.
3694*fd1fabb7SAndroid Build Coastguard Worker
3695*fd1fabb7SAndroid Build Coastguard Worker if (!useChromaDownsampling)
3696*fd1fabb7SAndroid Build Coastguard Worker {
3697*fd1fabb7SAndroid Build Coastguard Worker
3698*fd1fabb7SAndroid Build Coastguard Worker cinfo->comp_info [0].h_samp_factor = 1;
3699*fd1fabb7SAndroid Build Coastguard Worker cinfo->comp_info [0].h_samp_factor = 1;
3700*fd1fabb7SAndroid Build Coastguard Worker
3701*fd1fabb7SAndroid Build Coastguard Worker }
3702*fd1fabb7SAndroid Build Coastguard Worker
3703*fd1fabb7SAndroid Build Coastguard Worker }
3704*fd1fabb7SAndroid Build Coastguard Worker
3705*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3706*fd1fabb7SAndroid Build Coastguard Worker
3707*fd1fabb7SAndroid Build Coastguard Worker #endif
3708*fd1fabb7SAndroid Build Coastguard Worker
3709*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
3710*fd1fabb7SAndroid Build Coastguard Worker
WriteData(dng_host & host,const dng_ifd & ifd,dng_stream & stream,dng_pixel_buffer & buffer,AutoPtr<dng_memory_block> & compressedBuffer)3711*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteData (dng_host &host,
3712*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &ifd,
3713*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
3714*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer &buffer,
3715*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &compressedBuffer)
3716*fd1fabb7SAndroid Build Coastguard Worker {
3717*fd1fabb7SAndroid Build Coastguard Worker
3718*fd1fabb7SAndroid Build Coastguard Worker switch (ifd.fCompression)
3719*fd1fabb7SAndroid Build Coastguard Worker {
3720*fd1fabb7SAndroid Build Coastguard Worker
3721*fd1fabb7SAndroid Build Coastguard Worker case ccUncompressed:
3722*fd1fabb7SAndroid Build Coastguard Worker {
3723*fd1fabb7SAndroid Build Coastguard Worker
3724*fd1fabb7SAndroid Build Coastguard Worker // Special case support for when we save to 8-bits from
3725*fd1fabb7SAndroid Build Coastguard Worker // 16-bit data.
3726*fd1fabb7SAndroid Build Coastguard Worker
3727*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fBitsPerSample [0] == 8 && buffer.fPixelType == ttShort)
3728*fd1fabb7SAndroid Build Coastguard Worker {
3729*fd1fabb7SAndroid Build Coastguard Worker
3730*fd1fabb7SAndroid Build Coastguard Worker uint32 count = buffer.fRowStep *
3731*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.H ();
3732*fd1fabb7SAndroid Build Coastguard Worker
3733*fd1fabb7SAndroid Build Coastguard Worker const uint16 *sPtr = (const uint16 *) buffer.fData;
3734*fd1fabb7SAndroid Build Coastguard Worker
3735*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < count; j++)
3736*fd1fabb7SAndroid Build Coastguard Worker {
3737*fd1fabb7SAndroid Build Coastguard Worker
3738*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 ((uint8) sPtr [j]);
3739*fd1fabb7SAndroid Build Coastguard Worker
3740*fd1fabb7SAndroid Build Coastguard Worker }
3741*fd1fabb7SAndroid Build Coastguard Worker
3742*fd1fabb7SAndroid Build Coastguard Worker }
3743*fd1fabb7SAndroid Build Coastguard Worker
3744*fd1fabb7SAndroid Build Coastguard Worker else
3745*fd1fabb7SAndroid Build Coastguard Worker {
3746*fd1fabb7SAndroid Build Coastguard Worker
3747*fd1fabb7SAndroid Build Coastguard Worker // Swap bytes if required.
3748*fd1fabb7SAndroid Build Coastguard Worker
3749*fd1fabb7SAndroid Build Coastguard Worker if (stream.SwapBytes ())
3750*fd1fabb7SAndroid Build Coastguard Worker {
3751*fd1fabb7SAndroid Build Coastguard Worker
3752*fd1fabb7SAndroid Build Coastguard Worker ByteSwapBuffer (host, buffer);
3753*fd1fabb7SAndroid Build Coastguard Worker
3754*fd1fabb7SAndroid Build Coastguard Worker }
3755*fd1fabb7SAndroid Build Coastguard Worker
3756*fd1fabb7SAndroid Build Coastguard Worker // Write the bytes.
3757*fd1fabb7SAndroid Build Coastguard Worker
3758*fd1fabb7SAndroid Build Coastguard Worker stream.Put (buffer.fData, buffer.fRowStep *
3759*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.H () *
3760*fd1fabb7SAndroid Build Coastguard Worker buffer.fPixelSize);
3761*fd1fabb7SAndroid Build Coastguard Worker
3762*fd1fabb7SAndroid Build Coastguard Worker }
3763*fd1fabb7SAndroid Build Coastguard Worker
3764*fd1fabb7SAndroid Build Coastguard Worker break;
3765*fd1fabb7SAndroid Build Coastguard Worker
3766*fd1fabb7SAndroid Build Coastguard Worker }
3767*fd1fabb7SAndroid Build Coastguard Worker
3768*fd1fabb7SAndroid Build Coastguard Worker case ccLZW:
3769*fd1fabb7SAndroid Build Coastguard Worker case ccDeflate:
3770*fd1fabb7SAndroid Build Coastguard Worker {
3771*fd1fabb7SAndroid Build Coastguard Worker
3772*fd1fabb7SAndroid Build Coastguard Worker // Both these compression algorithms are byte based. The floating
3773*fd1fabb7SAndroid Build Coastguard Worker // point predictor already does byte ordering, so don't ever swap
3774*fd1fabb7SAndroid Build Coastguard Worker // when using it.
3775*fd1fabb7SAndroid Build Coastguard Worker
3776*fd1fabb7SAndroid Build Coastguard Worker if (stream.SwapBytes () && ifd.fPredictor != cpFloatingPoint)
3777*fd1fabb7SAndroid Build Coastguard Worker {
3778*fd1fabb7SAndroid Build Coastguard Worker
3779*fd1fabb7SAndroid Build Coastguard Worker ByteSwapBuffer (host,
3780*fd1fabb7SAndroid Build Coastguard Worker buffer);
3781*fd1fabb7SAndroid Build Coastguard Worker
3782*fd1fabb7SAndroid Build Coastguard Worker }
3783*fd1fabb7SAndroid Build Coastguard Worker
3784*fd1fabb7SAndroid Build Coastguard Worker // Run the compression algorithm.
3785*fd1fabb7SAndroid Build Coastguard Worker
3786*fd1fabb7SAndroid Build Coastguard Worker uint32 sBytes = buffer.fRowStep *
3787*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.H () *
3788*fd1fabb7SAndroid Build Coastguard Worker buffer.fPixelSize;
3789*fd1fabb7SAndroid Build Coastguard Worker
3790*fd1fabb7SAndroid Build Coastguard Worker uint8 *sBuffer = (uint8 *) buffer.fData;
3791*fd1fabb7SAndroid Build Coastguard Worker
3792*fd1fabb7SAndroid Build Coastguard Worker uint32 dBytes = 0;
3793*fd1fabb7SAndroid Build Coastguard Worker
3794*fd1fabb7SAndroid Build Coastguard Worker uint8 *dBuffer = compressedBuffer->Buffer_uint8 ();
3795*fd1fabb7SAndroid Build Coastguard Worker
3796*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fCompression == ccLZW)
3797*fd1fabb7SAndroid Build Coastguard Worker {
3798*fd1fabb7SAndroid Build Coastguard Worker
3799*fd1fabb7SAndroid Build Coastguard Worker dng_lzw_compressor lzwCompressor;
3800*fd1fabb7SAndroid Build Coastguard Worker
3801*fd1fabb7SAndroid Build Coastguard Worker lzwCompressor.Compress (sBuffer,
3802*fd1fabb7SAndroid Build Coastguard Worker dBuffer,
3803*fd1fabb7SAndroid Build Coastguard Worker sBytes,
3804*fd1fabb7SAndroid Build Coastguard Worker dBytes);
3805*fd1fabb7SAndroid Build Coastguard Worker
3806*fd1fabb7SAndroid Build Coastguard Worker }
3807*fd1fabb7SAndroid Build Coastguard Worker
3808*fd1fabb7SAndroid Build Coastguard Worker else
3809*fd1fabb7SAndroid Build Coastguard Worker {
3810*fd1fabb7SAndroid Build Coastguard Worker
3811*fd1fabb7SAndroid Build Coastguard Worker uLongf dCount = compressedBuffer->LogicalSize ();
3812*fd1fabb7SAndroid Build Coastguard Worker
3813*fd1fabb7SAndroid Build Coastguard Worker int32 level = Z_DEFAULT_COMPRESSION;
3814*fd1fabb7SAndroid Build Coastguard Worker
3815*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fCompressionQuality >= Z_BEST_SPEED &&
3816*fd1fabb7SAndroid Build Coastguard Worker ifd.fCompressionQuality <= Z_BEST_COMPRESSION)
3817*fd1fabb7SAndroid Build Coastguard Worker {
3818*fd1fabb7SAndroid Build Coastguard Worker
3819*fd1fabb7SAndroid Build Coastguard Worker level = ifd.fCompressionQuality;
3820*fd1fabb7SAndroid Build Coastguard Worker
3821*fd1fabb7SAndroid Build Coastguard Worker }
3822*fd1fabb7SAndroid Build Coastguard Worker
3823*fd1fabb7SAndroid Build Coastguard Worker int zResult = ::compress2 (dBuffer,
3824*fd1fabb7SAndroid Build Coastguard Worker &dCount,
3825*fd1fabb7SAndroid Build Coastguard Worker sBuffer,
3826*fd1fabb7SAndroid Build Coastguard Worker sBytes,
3827*fd1fabb7SAndroid Build Coastguard Worker level);
3828*fd1fabb7SAndroid Build Coastguard Worker
3829*fd1fabb7SAndroid Build Coastguard Worker if (zResult != Z_OK)
3830*fd1fabb7SAndroid Build Coastguard Worker {
3831*fd1fabb7SAndroid Build Coastguard Worker
3832*fd1fabb7SAndroid Build Coastguard Worker ThrowMemoryFull ();
3833*fd1fabb7SAndroid Build Coastguard Worker
3834*fd1fabb7SAndroid Build Coastguard Worker }
3835*fd1fabb7SAndroid Build Coastguard Worker
3836*fd1fabb7SAndroid Build Coastguard Worker dBytes = (uint32) dCount;
3837*fd1fabb7SAndroid Build Coastguard Worker
3838*fd1fabb7SAndroid Build Coastguard Worker }
3839*fd1fabb7SAndroid Build Coastguard Worker
3840*fd1fabb7SAndroid Build Coastguard Worker if (dBytes > compressedBuffer->LogicalSize ())
3841*fd1fabb7SAndroid Build Coastguard Worker {
3842*fd1fabb7SAndroid Build Coastguard Worker
3843*fd1fabb7SAndroid Build Coastguard Worker DNG_REPORT ("Compression output buffer overflow");
3844*fd1fabb7SAndroid Build Coastguard Worker
3845*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
3846*fd1fabb7SAndroid Build Coastguard Worker
3847*fd1fabb7SAndroid Build Coastguard Worker }
3848*fd1fabb7SAndroid Build Coastguard Worker
3849*fd1fabb7SAndroid Build Coastguard Worker stream.Put (dBuffer, dBytes);
3850*fd1fabb7SAndroid Build Coastguard Worker
3851*fd1fabb7SAndroid Build Coastguard Worker return;
3852*fd1fabb7SAndroid Build Coastguard Worker
3853*fd1fabb7SAndroid Build Coastguard Worker }
3854*fd1fabb7SAndroid Build Coastguard Worker
3855*fd1fabb7SAndroid Build Coastguard Worker case ccJPEG:
3856*fd1fabb7SAndroid Build Coastguard Worker {
3857*fd1fabb7SAndroid Build Coastguard Worker
3858*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer temp (buffer);
3859*fd1fabb7SAndroid Build Coastguard Worker
3860*fd1fabb7SAndroid Build Coastguard Worker if (buffer.fPixelType == ttByte)
3861*fd1fabb7SAndroid Build Coastguard Worker {
3862*fd1fabb7SAndroid Build Coastguard Worker
3863*fd1fabb7SAndroid Build Coastguard Worker // The lossless JPEG encoder needs 16-bit data, so if we are
3864*fd1fabb7SAndroid Build Coastguard Worker // are saving 8 bit data, we need to pad it out to 16-bits.
3865*fd1fabb7SAndroid Build Coastguard Worker
3866*fd1fabb7SAndroid Build Coastguard Worker temp.fData = compressedBuffer->Buffer ();
3867*fd1fabb7SAndroid Build Coastguard Worker
3868*fd1fabb7SAndroid Build Coastguard Worker temp.fPixelType = ttShort;
3869*fd1fabb7SAndroid Build Coastguard Worker temp.fPixelSize = 2;
3870*fd1fabb7SAndroid Build Coastguard Worker
3871*fd1fabb7SAndroid Build Coastguard Worker temp.CopyArea (buffer,
3872*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea,
3873*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlane,
3874*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlanes);
3875*fd1fabb7SAndroid Build Coastguard Worker
3876*fd1fabb7SAndroid Build Coastguard Worker }
3877*fd1fabb7SAndroid Build Coastguard Worker
3878*fd1fabb7SAndroid Build Coastguard Worker EncodeLosslessJPEG ((const uint16 *) temp.fData,
3879*fd1fabb7SAndroid Build Coastguard Worker temp.fArea.H (),
3880*fd1fabb7SAndroid Build Coastguard Worker temp.fArea.W (),
3881*fd1fabb7SAndroid Build Coastguard Worker temp.fPlanes,
3882*fd1fabb7SAndroid Build Coastguard Worker ifd.fBitsPerSample [0],
3883*fd1fabb7SAndroid Build Coastguard Worker temp.fRowStep,
3884*fd1fabb7SAndroid Build Coastguard Worker temp.fColStep,
3885*fd1fabb7SAndroid Build Coastguard Worker stream);
3886*fd1fabb7SAndroid Build Coastguard Worker
3887*fd1fabb7SAndroid Build Coastguard Worker break;
3888*fd1fabb7SAndroid Build Coastguard Worker
3889*fd1fabb7SAndroid Build Coastguard Worker }
3890*fd1fabb7SAndroid Build Coastguard Worker
3891*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseLibJPEG
3892*fd1fabb7SAndroid Build Coastguard Worker
3893*fd1fabb7SAndroid Build Coastguard Worker case ccLossyJPEG:
3894*fd1fabb7SAndroid Build Coastguard Worker {
3895*fd1fabb7SAndroid Build Coastguard Worker
3896*fd1fabb7SAndroid Build Coastguard Worker struct jpeg_compress_struct cinfo;
3897*fd1fabb7SAndroid Build Coastguard Worker
3898*fd1fabb7SAndroid Build Coastguard Worker // Setup the error manager.
3899*fd1fabb7SAndroid Build Coastguard Worker
3900*fd1fabb7SAndroid Build Coastguard Worker struct jpeg_error_mgr jerr;
3901*fd1fabb7SAndroid Build Coastguard Worker
3902*fd1fabb7SAndroid Build Coastguard Worker cinfo.err = jpeg_std_error (&jerr);
3903*fd1fabb7SAndroid Build Coastguard Worker
3904*fd1fabb7SAndroid Build Coastguard Worker jerr.error_exit = dng_error_exit;
3905*fd1fabb7SAndroid Build Coastguard Worker jerr.output_message = dng_output_message;
3906*fd1fabb7SAndroid Build Coastguard Worker
3907*fd1fabb7SAndroid Build Coastguard Worker try
3908*fd1fabb7SAndroid Build Coastguard Worker {
3909*fd1fabb7SAndroid Build Coastguard Worker
3910*fd1fabb7SAndroid Build Coastguard Worker // Create the compression context.
3911*fd1fabb7SAndroid Build Coastguard Worker
3912*fd1fabb7SAndroid Build Coastguard Worker jpeg_create_compress (&cinfo);
3913*fd1fabb7SAndroid Build Coastguard Worker
3914*fd1fabb7SAndroid Build Coastguard Worker // Setup the destination manager to write to stream.
3915*fd1fabb7SAndroid Build Coastguard Worker
3916*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_stream_dest dest;
3917*fd1fabb7SAndroid Build Coastguard Worker
3918*fd1fabb7SAndroid Build Coastguard Worker dest.fStream = &stream;
3919*fd1fabb7SAndroid Build Coastguard Worker
3920*fd1fabb7SAndroid Build Coastguard Worker dest.pub.init_destination = dng_init_destination;
3921*fd1fabb7SAndroid Build Coastguard Worker dest.pub.empty_output_buffer = dng_empty_output_buffer;
3922*fd1fabb7SAndroid Build Coastguard Worker dest.pub.term_destination = dng_term_destination;
3923*fd1fabb7SAndroid Build Coastguard Worker
3924*fd1fabb7SAndroid Build Coastguard Worker cinfo.dest = &dest.pub;
3925*fd1fabb7SAndroid Build Coastguard Worker
3926*fd1fabb7SAndroid Build Coastguard Worker // Setup basic image info.
3927*fd1fabb7SAndroid Build Coastguard Worker
3928*fd1fabb7SAndroid Build Coastguard Worker cinfo.image_width = buffer.fArea.W ();
3929*fd1fabb7SAndroid Build Coastguard Worker cinfo.image_height = buffer.fArea.H ();
3930*fd1fabb7SAndroid Build Coastguard Worker cinfo.input_components = buffer.fPlanes;
3931*fd1fabb7SAndroid Build Coastguard Worker
3932*fd1fabb7SAndroid Build Coastguard Worker switch (buffer.fPlanes)
3933*fd1fabb7SAndroid Build Coastguard Worker {
3934*fd1fabb7SAndroid Build Coastguard Worker
3935*fd1fabb7SAndroid Build Coastguard Worker case 1:
3936*fd1fabb7SAndroid Build Coastguard Worker cinfo.in_color_space = JCS_GRAYSCALE;
3937*fd1fabb7SAndroid Build Coastguard Worker break;
3938*fd1fabb7SAndroid Build Coastguard Worker
3939*fd1fabb7SAndroid Build Coastguard Worker case 3:
3940*fd1fabb7SAndroid Build Coastguard Worker cinfo.in_color_space = JCS_RGB;
3941*fd1fabb7SAndroid Build Coastguard Worker break;
3942*fd1fabb7SAndroid Build Coastguard Worker
3943*fd1fabb7SAndroid Build Coastguard Worker case 4:
3944*fd1fabb7SAndroid Build Coastguard Worker cinfo.in_color_space = JCS_CMYK;
3945*fd1fabb7SAndroid Build Coastguard Worker break;
3946*fd1fabb7SAndroid Build Coastguard Worker
3947*fd1fabb7SAndroid Build Coastguard Worker default:
3948*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
3949*fd1fabb7SAndroid Build Coastguard Worker
3950*fd1fabb7SAndroid Build Coastguard Worker }
3951*fd1fabb7SAndroid Build Coastguard Worker
3952*fd1fabb7SAndroid Build Coastguard Worker // Setup the compression parameters.
3953*fd1fabb7SAndroid Build Coastguard Worker
3954*fd1fabb7SAndroid Build Coastguard Worker jpeg_set_defaults (&cinfo);
3955*fd1fabb7SAndroid Build Coastguard Worker
3956*fd1fabb7SAndroid Build Coastguard Worker jpeg_set_adobe_quality (&cinfo, ifd.fCompressionQuality);
3957*fd1fabb7SAndroid Build Coastguard Worker
3958*fd1fabb7SAndroid Build Coastguard Worker // Write the JPEG header.
3959*fd1fabb7SAndroid Build Coastguard Worker
3960*fd1fabb7SAndroid Build Coastguard Worker jpeg_start_compress (&cinfo, TRUE);
3961*fd1fabb7SAndroid Build Coastguard Worker
3962*fd1fabb7SAndroid Build Coastguard Worker // Write the scanlines.
3963*fd1fabb7SAndroid Build Coastguard Worker
3964*fd1fabb7SAndroid Build Coastguard Worker for (int32 row = buffer.fArea.t; row < buffer.fArea.b; row++)
3965*fd1fabb7SAndroid Build Coastguard Worker {
3966*fd1fabb7SAndroid Build Coastguard Worker
3967*fd1fabb7SAndroid Build Coastguard Worker uint8 *sampArray [1];
3968*fd1fabb7SAndroid Build Coastguard Worker
3969*fd1fabb7SAndroid Build Coastguard Worker sampArray [0] = buffer.DirtyPixel_uint8 (row,
3970*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.l,
3971*fd1fabb7SAndroid Build Coastguard Worker 0);
3972*fd1fabb7SAndroid Build Coastguard Worker
3973*fd1fabb7SAndroid Build Coastguard Worker jpeg_write_scanlines (&cinfo, sampArray, 1);
3974*fd1fabb7SAndroid Build Coastguard Worker
3975*fd1fabb7SAndroid Build Coastguard Worker }
3976*fd1fabb7SAndroid Build Coastguard Worker
3977*fd1fabb7SAndroid Build Coastguard Worker // Cleanup.
3978*fd1fabb7SAndroid Build Coastguard Worker
3979*fd1fabb7SAndroid Build Coastguard Worker jpeg_finish_compress (&cinfo);
3980*fd1fabb7SAndroid Build Coastguard Worker
3981*fd1fabb7SAndroid Build Coastguard Worker jpeg_destroy_compress (&cinfo);
3982*fd1fabb7SAndroid Build Coastguard Worker
3983*fd1fabb7SAndroid Build Coastguard Worker }
3984*fd1fabb7SAndroid Build Coastguard Worker
3985*fd1fabb7SAndroid Build Coastguard Worker catch (...)
3986*fd1fabb7SAndroid Build Coastguard Worker {
3987*fd1fabb7SAndroid Build Coastguard Worker
3988*fd1fabb7SAndroid Build Coastguard Worker jpeg_destroy_compress (&cinfo);
3989*fd1fabb7SAndroid Build Coastguard Worker
3990*fd1fabb7SAndroid Build Coastguard Worker throw;
3991*fd1fabb7SAndroid Build Coastguard Worker
3992*fd1fabb7SAndroid Build Coastguard Worker }
3993*fd1fabb7SAndroid Build Coastguard Worker
3994*fd1fabb7SAndroid Build Coastguard Worker return;
3995*fd1fabb7SAndroid Build Coastguard Worker
3996*fd1fabb7SAndroid Build Coastguard Worker }
3997*fd1fabb7SAndroid Build Coastguard Worker
3998*fd1fabb7SAndroid Build Coastguard Worker #endif
3999*fd1fabb7SAndroid Build Coastguard Worker
4000*fd1fabb7SAndroid Build Coastguard Worker default:
4001*fd1fabb7SAndroid Build Coastguard Worker {
4002*fd1fabb7SAndroid Build Coastguard Worker
4003*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
4004*fd1fabb7SAndroid Build Coastguard Worker
4005*fd1fabb7SAndroid Build Coastguard Worker }
4006*fd1fabb7SAndroid Build Coastguard Worker
4007*fd1fabb7SAndroid Build Coastguard Worker }
4008*fd1fabb7SAndroid Build Coastguard Worker
4009*fd1fabb7SAndroid Build Coastguard Worker }
4010*fd1fabb7SAndroid Build Coastguard Worker
4011*fd1fabb7SAndroid Build Coastguard Worker /******************************************************************************/
4012*fd1fabb7SAndroid Build Coastguard Worker
EncodeJPEGPreview(dng_host & host,const dng_image & image,dng_jpeg_preview & preview,int32 quality)4013*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::EncodeJPEGPreview (dng_host &host,
4014*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
4015*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_preview &preview,
4016*fd1fabb7SAndroid Build Coastguard Worker int32 quality)
4017*fd1fabb7SAndroid Build Coastguard Worker {
4018*fd1fabb7SAndroid Build Coastguard Worker
4019*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseLibJPEG
4020*fd1fabb7SAndroid Build Coastguard Worker
4021*fd1fabb7SAndroid Build Coastguard Worker dng_memory_stream stream (host.Allocator ());
4022*fd1fabb7SAndroid Build Coastguard Worker
4023*fd1fabb7SAndroid Build Coastguard Worker struct jpeg_compress_struct cinfo;
4024*fd1fabb7SAndroid Build Coastguard Worker
4025*fd1fabb7SAndroid Build Coastguard Worker // Setup the error manager.
4026*fd1fabb7SAndroid Build Coastguard Worker
4027*fd1fabb7SAndroid Build Coastguard Worker struct jpeg_error_mgr jerr;
4028*fd1fabb7SAndroid Build Coastguard Worker
4029*fd1fabb7SAndroid Build Coastguard Worker cinfo.err = jpeg_std_error (&jerr);
4030*fd1fabb7SAndroid Build Coastguard Worker
4031*fd1fabb7SAndroid Build Coastguard Worker jerr.error_exit = dng_error_exit;
4032*fd1fabb7SAndroid Build Coastguard Worker jerr.output_message = dng_output_message;
4033*fd1fabb7SAndroid Build Coastguard Worker
4034*fd1fabb7SAndroid Build Coastguard Worker try
4035*fd1fabb7SAndroid Build Coastguard Worker {
4036*fd1fabb7SAndroid Build Coastguard Worker
4037*fd1fabb7SAndroid Build Coastguard Worker // Create the compression context.
4038*fd1fabb7SAndroid Build Coastguard Worker
4039*fd1fabb7SAndroid Build Coastguard Worker jpeg_create_compress (&cinfo);
4040*fd1fabb7SAndroid Build Coastguard Worker
4041*fd1fabb7SAndroid Build Coastguard Worker // Setup the destination manager to write to stream.
4042*fd1fabb7SAndroid Build Coastguard Worker
4043*fd1fabb7SAndroid Build Coastguard Worker dng_jpeg_stream_dest dest;
4044*fd1fabb7SAndroid Build Coastguard Worker
4045*fd1fabb7SAndroid Build Coastguard Worker dest.fStream = &stream;
4046*fd1fabb7SAndroid Build Coastguard Worker
4047*fd1fabb7SAndroid Build Coastguard Worker dest.pub.init_destination = dng_init_destination;
4048*fd1fabb7SAndroid Build Coastguard Worker dest.pub.empty_output_buffer = dng_empty_output_buffer;
4049*fd1fabb7SAndroid Build Coastguard Worker dest.pub.term_destination = dng_term_destination;
4050*fd1fabb7SAndroid Build Coastguard Worker
4051*fd1fabb7SAndroid Build Coastguard Worker cinfo.dest = &dest.pub;
4052*fd1fabb7SAndroid Build Coastguard Worker
4053*fd1fabb7SAndroid Build Coastguard Worker // Setup basic image info.
4054*fd1fabb7SAndroid Build Coastguard Worker
4055*fd1fabb7SAndroid Build Coastguard Worker cinfo.image_width = image.Bounds ().W ();
4056*fd1fabb7SAndroid Build Coastguard Worker cinfo.image_height = image.Bounds ().H ();
4057*fd1fabb7SAndroid Build Coastguard Worker cinfo.input_components = image.Planes ();
4058*fd1fabb7SAndroid Build Coastguard Worker
4059*fd1fabb7SAndroid Build Coastguard Worker switch (image.Planes ())
4060*fd1fabb7SAndroid Build Coastguard Worker {
4061*fd1fabb7SAndroid Build Coastguard Worker
4062*fd1fabb7SAndroid Build Coastguard Worker case 1:
4063*fd1fabb7SAndroid Build Coastguard Worker cinfo.in_color_space = JCS_GRAYSCALE;
4064*fd1fabb7SAndroid Build Coastguard Worker break;
4065*fd1fabb7SAndroid Build Coastguard Worker
4066*fd1fabb7SAndroid Build Coastguard Worker case 3:
4067*fd1fabb7SAndroid Build Coastguard Worker cinfo.in_color_space = JCS_RGB;
4068*fd1fabb7SAndroid Build Coastguard Worker break;
4069*fd1fabb7SAndroid Build Coastguard Worker
4070*fd1fabb7SAndroid Build Coastguard Worker default:
4071*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
4072*fd1fabb7SAndroid Build Coastguard Worker
4073*fd1fabb7SAndroid Build Coastguard Worker }
4074*fd1fabb7SAndroid Build Coastguard Worker
4075*fd1fabb7SAndroid Build Coastguard Worker // Setup the compression parameters.
4076*fd1fabb7SAndroid Build Coastguard Worker
4077*fd1fabb7SAndroid Build Coastguard Worker jpeg_set_defaults (&cinfo);
4078*fd1fabb7SAndroid Build Coastguard Worker
4079*fd1fabb7SAndroid Build Coastguard Worker jpeg_set_adobe_quality (&cinfo, quality);
4080*fd1fabb7SAndroid Build Coastguard Worker
4081*fd1fabb7SAndroid Build Coastguard Worker // Find some preview information based on the compression settings.
4082*fd1fabb7SAndroid Build Coastguard Worker
4083*fd1fabb7SAndroid Build Coastguard Worker preview.fPreviewSize = image.Size ();
4084*fd1fabb7SAndroid Build Coastguard Worker
4085*fd1fabb7SAndroid Build Coastguard Worker if (image.Planes () == 1)
4086*fd1fabb7SAndroid Build Coastguard Worker {
4087*fd1fabb7SAndroid Build Coastguard Worker
4088*fd1fabb7SAndroid Build Coastguard Worker preview.fPhotometricInterpretation = piBlackIsZero;
4089*fd1fabb7SAndroid Build Coastguard Worker
4090*fd1fabb7SAndroid Build Coastguard Worker }
4091*fd1fabb7SAndroid Build Coastguard Worker
4092*fd1fabb7SAndroid Build Coastguard Worker else
4093*fd1fabb7SAndroid Build Coastguard Worker {
4094*fd1fabb7SAndroid Build Coastguard Worker
4095*fd1fabb7SAndroid Build Coastguard Worker preview.fPhotometricInterpretation = piYCbCr;
4096*fd1fabb7SAndroid Build Coastguard Worker
4097*fd1fabb7SAndroid Build Coastguard Worker preview.fYCbCrSubSampling.h = cinfo.comp_info [0].h_samp_factor;
4098*fd1fabb7SAndroid Build Coastguard Worker preview.fYCbCrSubSampling.v = cinfo.comp_info [0].v_samp_factor;
4099*fd1fabb7SAndroid Build Coastguard Worker
4100*fd1fabb7SAndroid Build Coastguard Worker }
4101*fd1fabb7SAndroid Build Coastguard Worker
4102*fd1fabb7SAndroid Build Coastguard Worker // Write the JPEG header.
4103*fd1fabb7SAndroid Build Coastguard Worker
4104*fd1fabb7SAndroid Build Coastguard Worker jpeg_start_compress (&cinfo, TRUE);
4105*fd1fabb7SAndroid Build Coastguard Worker
4106*fd1fabb7SAndroid Build Coastguard Worker // Write the scanlines.
4107*fd1fabb7SAndroid Build Coastguard Worker
4108*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer buffer (image.Bounds (), 0, image.Planes (), ttByte,
4109*fd1fabb7SAndroid Build Coastguard Worker pcInterleaved, NULL);
4110*fd1fabb7SAndroid Build Coastguard Worker
4111*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> bufferData (host.Allocate (buffer.fRowStep));
4112*fd1fabb7SAndroid Build Coastguard Worker
4113*fd1fabb7SAndroid Build Coastguard Worker buffer.fData = bufferData->Buffer ();
4114*fd1fabb7SAndroid Build Coastguard Worker
4115*fd1fabb7SAndroid Build Coastguard Worker for (uint32 row = 0; row < cinfo.image_height; row++)
4116*fd1fabb7SAndroid Build Coastguard Worker {
4117*fd1fabb7SAndroid Build Coastguard Worker
4118*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.t = row;
4119*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.b = row + 1;
4120*fd1fabb7SAndroid Build Coastguard Worker
4121*fd1fabb7SAndroid Build Coastguard Worker image.Get (buffer);
4122*fd1fabb7SAndroid Build Coastguard Worker
4123*fd1fabb7SAndroid Build Coastguard Worker uint8 *sampArray [1];
4124*fd1fabb7SAndroid Build Coastguard Worker
4125*fd1fabb7SAndroid Build Coastguard Worker sampArray [0] = buffer.DirtyPixel_uint8 (row,
4126*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.l,
4127*fd1fabb7SAndroid Build Coastguard Worker 0);
4128*fd1fabb7SAndroid Build Coastguard Worker
4129*fd1fabb7SAndroid Build Coastguard Worker jpeg_write_scanlines (&cinfo, sampArray, 1);
4130*fd1fabb7SAndroid Build Coastguard Worker
4131*fd1fabb7SAndroid Build Coastguard Worker }
4132*fd1fabb7SAndroid Build Coastguard Worker
4133*fd1fabb7SAndroid Build Coastguard Worker // Cleanup.
4134*fd1fabb7SAndroid Build Coastguard Worker
4135*fd1fabb7SAndroid Build Coastguard Worker jpeg_finish_compress (&cinfo);
4136*fd1fabb7SAndroid Build Coastguard Worker
4137*fd1fabb7SAndroid Build Coastguard Worker jpeg_destroy_compress (&cinfo);
4138*fd1fabb7SAndroid Build Coastguard Worker
4139*fd1fabb7SAndroid Build Coastguard Worker }
4140*fd1fabb7SAndroid Build Coastguard Worker
4141*fd1fabb7SAndroid Build Coastguard Worker catch (...)
4142*fd1fabb7SAndroid Build Coastguard Worker {
4143*fd1fabb7SAndroid Build Coastguard Worker
4144*fd1fabb7SAndroid Build Coastguard Worker jpeg_destroy_compress (&cinfo);
4145*fd1fabb7SAndroid Build Coastguard Worker
4146*fd1fabb7SAndroid Build Coastguard Worker throw;
4147*fd1fabb7SAndroid Build Coastguard Worker
4148*fd1fabb7SAndroid Build Coastguard Worker }
4149*fd1fabb7SAndroid Build Coastguard Worker
4150*fd1fabb7SAndroid Build Coastguard Worker preview.fCompressedData.Reset (stream.AsMemoryBlock (host.Allocator ()));
4151*fd1fabb7SAndroid Build Coastguard Worker
4152*fd1fabb7SAndroid Build Coastguard Worker #else
4153*fd1fabb7SAndroid Build Coastguard Worker
4154*fd1fabb7SAndroid Build Coastguard Worker (void) host;
4155*fd1fabb7SAndroid Build Coastguard Worker (void) image;
4156*fd1fabb7SAndroid Build Coastguard Worker (void) preview;
4157*fd1fabb7SAndroid Build Coastguard Worker (void) quality;
4158*fd1fabb7SAndroid Build Coastguard Worker
4159*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("No JPEG encoder");
4160*fd1fabb7SAndroid Build Coastguard Worker
4161*fd1fabb7SAndroid Build Coastguard Worker #endif
4162*fd1fabb7SAndroid Build Coastguard Worker
4163*fd1fabb7SAndroid Build Coastguard Worker }
4164*fd1fabb7SAndroid Build Coastguard Worker
4165*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4166*fd1fabb7SAndroid Build Coastguard Worker
WriteTile(dng_host & host,const dng_ifd & ifd,dng_stream & stream,const dng_image & image,const dng_rect & tileArea,uint32 fakeChannels,AutoPtr<dng_memory_block> & compressedBuffer,AutoPtr<dng_memory_block> & uncompressedBuffer,AutoPtr<dng_memory_block> & subTileBlockBuffer,AutoPtr<dng_memory_block> & tempBuffer)4167*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteTile (dng_host &host,
4168*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &ifd,
4169*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
4170*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
4171*fd1fabb7SAndroid Build Coastguard Worker const dng_rect &tileArea,
4172*fd1fabb7SAndroid Build Coastguard Worker uint32 fakeChannels,
4173*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &compressedBuffer,
4174*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &uncompressedBuffer,
4175*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &subTileBlockBuffer,
4176*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> &tempBuffer)
4177*fd1fabb7SAndroid Build Coastguard Worker {
4178*fd1fabb7SAndroid Build Coastguard Worker
4179*fd1fabb7SAndroid Build Coastguard Worker // Create pixel buffer to hold uncompressed tile.
4180*fd1fabb7SAndroid Build Coastguard Worker
4181*fd1fabb7SAndroid Build Coastguard Worker dng_pixel_buffer buffer (tileArea, 0, ifd.fSamplesPerPixel,
4182*fd1fabb7SAndroid Build Coastguard Worker image.PixelType(), pcInterleaved, uncompressedBuffer->Buffer());
4183*fd1fabb7SAndroid Build Coastguard Worker
4184*fd1fabb7SAndroid Build Coastguard Worker // Get the uncompressed data.
4185*fd1fabb7SAndroid Build Coastguard Worker
4186*fd1fabb7SAndroid Build Coastguard Worker image.Get (buffer, dng_image::edge_zero);
4187*fd1fabb7SAndroid Build Coastguard Worker
4188*fd1fabb7SAndroid Build Coastguard Worker // Deal with sub-tile blocks.
4189*fd1fabb7SAndroid Build Coastguard Worker
4190*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fSubTileBlockRows > 1)
4191*fd1fabb7SAndroid Build Coastguard Worker {
4192*fd1fabb7SAndroid Build Coastguard Worker
4193*fd1fabb7SAndroid Build Coastguard Worker ReorderSubTileBlocks (ifd,
4194*fd1fabb7SAndroid Build Coastguard Worker buffer,
4195*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer,
4196*fd1fabb7SAndroid Build Coastguard Worker subTileBlockBuffer);
4197*fd1fabb7SAndroid Build Coastguard Worker
4198*fd1fabb7SAndroid Build Coastguard Worker }
4199*fd1fabb7SAndroid Build Coastguard Worker
4200*fd1fabb7SAndroid Build Coastguard Worker // Floating point depth conversion.
4201*fd1fabb7SAndroid Build Coastguard Worker
4202*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fSampleFormat [0] == sfFloatingPoint)
4203*fd1fabb7SAndroid Build Coastguard Worker {
4204*fd1fabb7SAndroid Build Coastguard Worker
4205*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fBitsPerSample [0] == 16)
4206*fd1fabb7SAndroid Build Coastguard Worker {
4207*fd1fabb7SAndroid Build Coastguard Worker
4208*fd1fabb7SAndroid Build Coastguard Worker uint32 *srcPtr = (uint32 *) buffer.fData;
4209*fd1fabb7SAndroid Build Coastguard Worker uint16 *dstPtr = (uint16 *) buffer.fData;
4210*fd1fabb7SAndroid Build Coastguard Worker
4211*fd1fabb7SAndroid Build Coastguard Worker uint32 pixels = tileArea.W () * tileArea.H () * buffer.fPlanes;
4212*fd1fabb7SAndroid Build Coastguard Worker
4213*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < pixels; j++)
4214*fd1fabb7SAndroid Build Coastguard Worker {
4215*fd1fabb7SAndroid Build Coastguard Worker
4216*fd1fabb7SAndroid Build Coastguard Worker dstPtr [j] = DNG_FloatToHalf (srcPtr [j]);
4217*fd1fabb7SAndroid Build Coastguard Worker
4218*fd1fabb7SAndroid Build Coastguard Worker }
4219*fd1fabb7SAndroid Build Coastguard Worker
4220*fd1fabb7SAndroid Build Coastguard Worker buffer.fPixelSize = 2;
4221*fd1fabb7SAndroid Build Coastguard Worker
4222*fd1fabb7SAndroid Build Coastguard Worker }
4223*fd1fabb7SAndroid Build Coastguard Worker
4224*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fBitsPerSample [0] == 24)
4225*fd1fabb7SAndroid Build Coastguard Worker {
4226*fd1fabb7SAndroid Build Coastguard Worker
4227*fd1fabb7SAndroid Build Coastguard Worker uint32 *srcPtr = (uint32 *) buffer.fData;
4228*fd1fabb7SAndroid Build Coastguard Worker uint8 *dstPtr = (uint8 *) buffer.fData;
4229*fd1fabb7SAndroid Build Coastguard Worker
4230*fd1fabb7SAndroid Build Coastguard Worker uint32 pixels = tileArea.W () * tileArea.H () * buffer.fPlanes;
4231*fd1fabb7SAndroid Build Coastguard Worker
4232*fd1fabb7SAndroid Build Coastguard Worker if (stream.BigEndian () || ifd.fPredictor == cpFloatingPoint ||
4233*fd1fabb7SAndroid Build Coastguard Worker ifd.fPredictor == cpFloatingPointX2 ||
4234*fd1fabb7SAndroid Build Coastguard Worker ifd.fPredictor == cpFloatingPointX4)
4235*fd1fabb7SAndroid Build Coastguard Worker {
4236*fd1fabb7SAndroid Build Coastguard Worker
4237*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < pixels; j++)
4238*fd1fabb7SAndroid Build Coastguard Worker {
4239*fd1fabb7SAndroid Build Coastguard Worker
4240*fd1fabb7SAndroid Build Coastguard Worker DNG_FloatToFP24 (srcPtr [j], dstPtr);
4241*fd1fabb7SAndroid Build Coastguard Worker
4242*fd1fabb7SAndroid Build Coastguard Worker dstPtr += 3;
4243*fd1fabb7SAndroid Build Coastguard Worker
4244*fd1fabb7SAndroid Build Coastguard Worker }
4245*fd1fabb7SAndroid Build Coastguard Worker
4246*fd1fabb7SAndroid Build Coastguard Worker }
4247*fd1fabb7SAndroid Build Coastguard Worker
4248*fd1fabb7SAndroid Build Coastguard Worker else
4249*fd1fabb7SAndroid Build Coastguard Worker {
4250*fd1fabb7SAndroid Build Coastguard Worker
4251*fd1fabb7SAndroid Build Coastguard Worker for (uint32 j = 0; j < pixels; j++)
4252*fd1fabb7SAndroid Build Coastguard Worker {
4253*fd1fabb7SAndroid Build Coastguard Worker
4254*fd1fabb7SAndroid Build Coastguard Worker uint8 output [3];
4255*fd1fabb7SAndroid Build Coastguard Worker
4256*fd1fabb7SAndroid Build Coastguard Worker DNG_FloatToFP24 (srcPtr [j], output);
4257*fd1fabb7SAndroid Build Coastguard Worker
4258*fd1fabb7SAndroid Build Coastguard Worker dstPtr [0] = output [2];
4259*fd1fabb7SAndroid Build Coastguard Worker dstPtr [1] = output [1];
4260*fd1fabb7SAndroid Build Coastguard Worker dstPtr [2] = output [0];
4261*fd1fabb7SAndroid Build Coastguard Worker
4262*fd1fabb7SAndroid Build Coastguard Worker dstPtr += 3;
4263*fd1fabb7SAndroid Build Coastguard Worker
4264*fd1fabb7SAndroid Build Coastguard Worker }
4265*fd1fabb7SAndroid Build Coastguard Worker
4266*fd1fabb7SAndroid Build Coastguard Worker }
4267*fd1fabb7SAndroid Build Coastguard Worker
4268*fd1fabb7SAndroid Build Coastguard Worker buffer.fPixelSize = 3;
4269*fd1fabb7SAndroid Build Coastguard Worker
4270*fd1fabb7SAndroid Build Coastguard Worker }
4271*fd1fabb7SAndroid Build Coastguard Worker
4272*fd1fabb7SAndroid Build Coastguard Worker }
4273*fd1fabb7SAndroid Build Coastguard Worker
4274*fd1fabb7SAndroid Build Coastguard Worker // Run predictor.
4275*fd1fabb7SAndroid Build Coastguard Worker
4276*fd1fabb7SAndroid Build Coastguard Worker EncodePredictor (host,
4277*fd1fabb7SAndroid Build Coastguard Worker ifd,
4278*fd1fabb7SAndroid Build Coastguard Worker buffer,
4279*fd1fabb7SAndroid Build Coastguard Worker tempBuffer);
4280*fd1fabb7SAndroid Build Coastguard Worker
4281*fd1fabb7SAndroid Build Coastguard Worker // Adjust pixel buffer for fake channels.
4282*fd1fabb7SAndroid Build Coastguard Worker
4283*fd1fabb7SAndroid Build Coastguard Worker if (fakeChannels > 1)
4284*fd1fabb7SAndroid Build Coastguard Worker {
4285*fd1fabb7SAndroid Build Coastguard Worker
4286*fd1fabb7SAndroid Build Coastguard Worker buffer.fPlanes *= fakeChannels;
4287*fd1fabb7SAndroid Build Coastguard Worker buffer.fColStep *= fakeChannels;
4288*fd1fabb7SAndroid Build Coastguard Worker
4289*fd1fabb7SAndroid Build Coastguard Worker buffer.fArea.r = buffer.fArea.l + (buffer.fArea.W () / fakeChannels);
4290*fd1fabb7SAndroid Build Coastguard Worker
4291*fd1fabb7SAndroid Build Coastguard Worker }
4292*fd1fabb7SAndroid Build Coastguard Worker
4293*fd1fabb7SAndroid Build Coastguard Worker // Compress (if required) and write out the data.
4294*fd1fabb7SAndroid Build Coastguard Worker
4295*fd1fabb7SAndroid Build Coastguard Worker WriteData (host,
4296*fd1fabb7SAndroid Build Coastguard Worker ifd,
4297*fd1fabb7SAndroid Build Coastguard Worker stream,
4298*fd1fabb7SAndroid Build Coastguard Worker buffer,
4299*fd1fabb7SAndroid Build Coastguard Worker compressedBuffer);
4300*fd1fabb7SAndroid Build Coastguard Worker
4301*fd1fabb7SAndroid Build Coastguard Worker }
4302*fd1fabb7SAndroid Build Coastguard Worker
4303*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4304*fd1fabb7SAndroid Build Coastguard Worker
4305*fd1fabb7SAndroid Build Coastguard Worker class dng_write_tiles_task : public dng_area_task
4306*fd1fabb7SAndroid Build Coastguard Worker {
4307*fd1fabb7SAndroid Build Coastguard Worker
4308*fd1fabb7SAndroid Build Coastguard Worker private:
4309*fd1fabb7SAndroid Build Coastguard Worker
4310*fd1fabb7SAndroid Build Coastguard Worker dng_image_writer &fImageWriter;
4311*fd1fabb7SAndroid Build Coastguard Worker
4312*fd1fabb7SAndroid Build Coastguard Worker dng_host &fHost;
4313*fd1fabb7SAndroid Build Coastguard Worker
4314*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &fIFD;
4315*fd1fabb7SAndroid Build Coastguard Worker
4316*fd1fabb7SAndroid Build Coastguard Worker dng_basic_tag_set &fBasic;
4317*fd1fabb7SAndroid Build Coastguard Worker
4318*fd1fabb7SAndroid Build Coastguard Worker dng_stream &fStream;
4319*fd1fabb7SAndroid Build Coastguard Worker
4320*fd1fabb7SAndroid Build Coastguard Worker const dng_image &fImage;
4321*fd1fabb7SAndroid Build Coastguard Worker
4322*fd1fabb7SAndroid Build Coastguard Worker uint32 fFakeChannels;
4323*fd1fabb7SAndroid Build Coastguard Worker
4324*fd1fabb7SAndroid Build Coastguard Worker uint32 fTilesDown;
4325*fd1fabb7SAndroid Build Coastguard Worker
4326*fd1fabb7SAndroid Build Coastguard Worker uint32 fTilesAcross;
4327*fd1fabb7SAndroid Build Coastguard Worker
4328*fd1fabb7SAndroid Build Coastguard Worker uint32 fCompressedSize;
4329*fd1fabb7SAndroid Build Coastguard Worker
4330*fd1fabb7SAndroid Build Coastguard Worker uint32 fUncompressedSize;
4331*fd1fabb7SAndroid Build Coastguard Worker
4332*fd1fabb7SAndroid Build Coastguard Worker dng_mutex fMutex1;
4333*fd1fabb7SAndroid Build Coastguard Worker
4334*fd1fabb7SAndroid Build Coastguard Worker uint32 fNextTileIndex;
4335*fd1fabb7SAndroid Build Coastguard Worker
4336*fd1fabb7SAndroid Build Coastguard Worker dng_mutex fMutex2;
4337*fd1fabb7SAndroid Build Coastguard Worker
4338*fd1fabb7SAndroid Build Coastguard Worker dng_condition fCondition;
4339*fd1fabb7SAndroid Build Coastguard Worker
4340*fd1fabb7SAndroid Build Coastguard Worker bool fTaskFailed;
4341*fd1fabb7SAndroid Build Coastguard Worker
4342*fd1fabb7SAndroid Build Coastguard Worker uint32 fWriteTileIndex;
4343*fd1fabb7SAndroid Build Coastguard Worker
4344*fd1fabb7SAndroid Build Coastguard Worker public:
4345*fd1fabb7SAndroid Build Coastguard Worker
dng_write_tiles_task(dng_image_writer & imageWriter,dng_host & host,const dng_ifd & ifd,dng_basic_tag_set & basic,dng_stream & stream,const dng_image & image,uint32 fakeChannels,uint32 tilesDown,uint32 tilesAcross,uint32 compressedSize,uint32 uncompressedSize)4346*fd1fabb7SAndroid Build Coastguard Worker dng_write_tiles_task (dng_image_writer &imageWriter,
4347*fd1fabb7SAndroid Build Coastguard Worker dng_host &host,
4348*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &ifd,
4349*fd1fabb7SAndroid Build Coastguard Worker dng_basic_tag_set &basic,
4350*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
4351*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
4352*fd1fabb7SAndroid Build Coastguard Worker uint32 fakeChannels,
4353*fd1fabb7SAndroid Build Coastguard Worker uint32 tilesDown,
4354*fd1fabb7SAndroid Build Coastguard Worker uint32 tilesAcross,
4355*fd1fabb7SAndroid Build Coastguard Worker uint32 compressedSize,
4356*fd1fabb7SAndroid Build Coastguard Worker uint32 uncompressedSize)
4357*fd1fabb7SAndroid Build Coastguard Worker
4358*fd1fabb7SAndroid Build Coastguard Worker : fImageWriter (imageWriter)
4359*fd1fabb7SAndroid Build Coastguard Worker , fHost (host)
4360*fd1fabb7SAndroid Build Coastguard Worker , fIFD (ifd)
4361*fd1fabb7SAndroid Build Coastguard Worker , fBasic (basic)
4362*fd1fabb7SAndroid Build Coastguard Worker , fStream (stream)
4363*fd1fabb7SAndroid Build Coastguard Worker , fImage (image)
4364*fd1fabb7SAndroid Build Coastguard Worker , fFakeChannels (fakeChannels)
4365*fd1fabb7SAndroid Build Coastguard Worker , fTilesDown (tilesDown)
4366*fd1fabb7SAndroid Build Coastguard Worker , fTilesAcross (tilesAcross)
4367*fd1fabb7SAndroid Build Coastguard Worker , fCompressedSize (compressedSize)
4368*fd1fabb7SAndroid Build Coastguard Worker , fUncompressedSize (uncompressedSize)
4369*fd1fabb7SAndroid Build Coastguard Worker , fMutex1 ("dng_write_tiles_task_1")
4370*fd1fabb7SAndroid Build Coastguard Worker , fNextTileIndex (0)
4371*fd1fabb7SAndroid Build Coastguard Worker , fMutex2 ("dng_write_tiles_task_2")
4372*fd1fabb7SAndroid Build Coastguard Worker , fCondition ()
4373*fd1fabb7SAndroid Build Coastguard Worker , fTaskFailed (false)
4374*fd1fabb7SAndroid Build Coastguard Worker , fWriteTileIndex (0)
4375*fd1fabb7SAndroid Build Coastguard Worker
4376*fd1fabb7SAndroid Build Coastguard Worker {
4377*fd1fabb7SAndroid Build Coastguard Worker
4378*fd1fabb7SAndroid Build Coastguard Worker fMinTaskArea = 16 * 16;
4379*fd1fabb7SAndroid Build Coastguard Worker fUnitCell = dng_point (16, 16);
4380*fd1fabb7SAndroid Build Coastguard Worker fMaxTileSize = dng_point (16, 16);
4381*fd1fabb7SAndroid Build Coastguard Worker
4382*fd1fabb7SAndroid Build Coastguard Worker }
4383*fd1fabb7SAndroid Build Coastguard Worker
Process(uint32,const dng_rect &,dng_abort_sniffer * sniffer)4384*fd1fabb7SAndroid Build Coastguard Worker void Process (uint32 /* threadIndex */,
4385*fd1fabb7SAndroid Build Coastguard Worker const dng_rect & /* tile */,
4386*fd1fabb7SAndroid Build Coastguard Worker dng_abort_sniffer *sniffer)
4387*fd1fabb7SAndroid Build Coastguard Worker {
4388*fd1fabb7SAndroid Build Coastguard Worker
4389*fd1fabb7SAndroid Build Coastguard Worker try
4390*fd1fabb7SAndroid Build Coastguard Worker {
4391*fd1fabb7SAndroid Build Coastguard Worker
4392*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> compressedBuffer;
4393*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> uncompressedBuffer;
4394*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> subTileBlockBuffer;
4395*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> tempBuffer;
4396*fd1fabb7SAndroid Build Coastguard Worker
4397*fd1fabb7SAndroid Build Coastguard Worker if (fCompressedSize)
4398*fd1fabb7SAndroid Build Coastguard Worker {
4399*fd1fabb7SAndroid Build Coastguard Worker compressedBuffer.Reset (fHost.Allocate (fCompressedSize));
4400*fd1fabb7SAndroid Build Coastguard Worker }
4401*fd1fabb7SAndroid Build Coastguard Worker
4402*fd1fabb7SAndroid Build Coastguard Worker if (fUncompressedSize)
4403*fd1fabb7SAndroid Build Coastguard Worker {
4404*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer.Reset (fHost.Allocate (fUncompressedSize));
4405*fd1fabb7SAndroid Build Coastguard Worker }
4406*fd1fabb7SAndroid Build Coastguard Worker
4407*fd1fabb7SAndroid Build Coastguard Worker if (fIFD.fSubTileBlockRows > 1 && fUncompressedSize)
4408*fd1fabb7SAndroid Build Coastguard Worker {
4409*fd1fabb7SAndroid Build Coastguard Worker subTileBlockBuffer.Reset (fHost.Allocate (fUncompressedSize));
4410*fd1fabb7SAndroid Build Coastguard Worker }
4411*fd1fabb7SAndroid Build Coastguard Worker
4412*fd1fabb7SAndroid Build Coastguard Worker while (true)
4413*fd1fabb7SAndroid Build Coastguard Worker {
4414*fd1fabb7SAndroid Build Coastguard Worker
4415*fd1fabb7SAndroid Build Coastguard Worker // Find tile index to compress.
4416*fd1fabb7SAndroid Build Coastguard Worker
4417*fd1fabb7SAndroid Build Coastguard Worker uint32 tileIndex;
4418*fd1fabb7SAndroid Build Coastguard Worker
4419*fd1fabb7SAndroid Build Coastguard Worker {
4420*fd1fabb7SAndroid Build Coastguard Worker
4421*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex lock (&fMutex1);
4422*fd1fabb7SAndroid Build Coastguard Worker
4423*fd1fabb7SAndroid Build Coastguard Worker if (fNextTileIndex == fTilesDown * fTilesAcross)
4424*fd1fabb7SAndroid Build Coastguard Worker {
4425*fd1fabb7SAndroid Build Coastguard Worker return;
4426*fd1fabb7SAndroid Build Coastguard Worker }
4427*fd1fabb7SAndroid Build Coastguard Worker
4428*fd1fabb7SAndroid Build Coastguard Worker tileIndex = fNextTileIndex++;
4429*fd1fabb7SAndroid Build Coastguard Worker
4430*fd1fabb7SAndroid Build Coastguard Worker }
4431*fd1fabb7SAndroid Build Coastguard Worker
4432*fd1fabb7SAndroid Build Coastguard Worker dng_abort_sniffer::SniffForAbort (sniffer);
4433*fd1fabb7SAndroid Build Coastguard Worker
4434*fd1fabb7SAndroid Build Coastguard Worker // Compress tile.
4435*fd1fabb7SAndroid Build Coastguard Worker
4436*fd1fabb7SAndroid Build Coastguard Worker uint32 rowIndex = tileIndex / fTilesAcross;
4437*fd1fabb7SAndroid Build Coastguard Worker
4438*fd1fabb7SAndroid Build Coastguard Worker uint32 colIndex = tileIndex - rowIndex * fTilesAcross;
4439*fd1fabb7SAndroid Build Coastguard Worker
4440*fd1fabb7SAndroid Build Coastguard Worker dng_rect tileArea = fIFD.TileArea (rowIndex, colIndex);
4441*fd1fabb7SAndroid Build Coastguard Worker
4442*fd1fabb7SAndroid Build Coastguard Worker dng_memory_stream tileStream (fHost.Allocator ());
4443*fd1fabb7SAndroid Build Coastguard Worker
4444*fd1fabb7SAndroid Build Coastguard Worker tileStream.SetLittleEndian (fStream.LittleEndian ());
4445*fd1fabb7SAndroid Build Coastguard Worker
4446*fd1fabb7SAndroid Build Coastguard Worker dng_host host (&fHost.Allocator (),
4447*fd1fabb7SAndroid Build Coastguard Worker sniffer);
4448*fd1fabb7SAndroid Build Coastguard Worker
4449*fd1fabb7SAndroid Build Coastguard Worker fImageWriter.WriteTile (host,
4450*fd1fabb7SAndroid Build Coastguard Worker fIFD,
4451*fd1fabb7SAndroid Build Coastguard Worker tileStream,
4452*fd1fabb7SAndroid Build Coastguard Worker fImage,
4453*fd1fabb7SAndroid Build Coastguard Worker tileArea,
4454*fd1fabb7SAndroid Build Coastguard Worker fFakeChannels,
4455*fd1fabb7SAndroid Build Coastguard Worker compressedBuffer,
4456*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer,
4457*fd1fabb7SAndroid Build Coastguard Worker subTileBlockBuffer,
4458*fd1fabb7SAndroid Build Coastguard Worker tempBuffer);
4459*fd1fabb7SAndroid Build Coastguard Worker
4460*fd1fabb7SAndroid Build Coastguard Worker tileStream.Flush ();
4461*fd1fabb7SAndroid Build Coastguard Worker
4462*fd1fabb7SAndroid Build Coastguard Worker uint32 tileByteCount = (uint32) tileStream.Length ();
4463*fd1fabb7SAndroid Build Coastguard Worker
4464*fd1fabb7SAndroid Build Coastguard Worker tileStream.SetReadPosition (0);
4465*fd1fabb7SAndroid Build Coastguard Worker
4466*fd1fabb7SAndroid Build Coastguard Worker // Wait until it is our turn to write tile.
4467*fd1fabb7SAndroid Build Coastguard Worker
4468*fd1fabb7SAndroid Build Coastguard Worker {
4469*fd1fabb7SAndroid Build Coastguard Worker
4470*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex lock (&fMutex2);
4471*fd1fabb7SAndroid Build Coastguard Worker
4472*fd1fabb7SAndroid Build Coastguard Worker while (!fTaskFailed &&
4473*fd1fabb7SAndroid Build Coastguard Worker fWriteTileIndex != tileIndex)
4474*fd1fabb7SAndroid Build Coastguard Worker {
4475*fd1fabb7SAndroid Build Coastguard Worker
4476*fd1fabb7SAndroid Build Coastguard Worker fCondition.Wait (fMutex2);
4477*fd1fabb7SAndroid Build Coastguard Worker
4478*fd1fabb7SAndroid Build Coastguard Worker }
4479*fd1fabb7SAndroid Build Coastguard Worker
4480*fd1fabb7SAndroid Build Coastguard Worker // If the task failed in another thread, that thread already threw an exception.
4481*fd1fabb7SAndroid Build Coastguard Worker
4482*fd1fabb7SAndroid Build Coastguard Worker if (fTaskFailed)
4483*fd1fabb7SAndroid Build Coastguard Worker return;
4484*fd1fabb7SAndroid Build Coastguard Worker
4485*fd1fabb7SAndroid Build Coastguard Worker }
4486*fd1fabb7SAndroid Build Coastguard Worker
4487*fd1fabb7SAndroid Build Coastguard Worker dng_abort_sniffer::SniffForAbort (sniffer);
4488*fd1fabb7SAndroid Build Coastguard Worker
4489*fd1fabb7SAndroid Build Coastguard Worker // Remember this offset.
4490*fd1fabb7SAndroid Build Coastguard Worker
4491*fd1fabb7SAndroid Build Coastguard Worker uint32 tileOffset = (uint32) fStream.Position ();
4492*fd1fabb7SAndroid Build Coastguard Worker
4493*fd1fabb7SAndroid Build Coastguard Worker fBasic.SetTileOffset (tileIndex, tileOffset);
4494*fd1fabb7SAndroid Build Coastguard Worker
4495*fd1fabb7SAndroid Build Coastguard Worker // Copy tile stream for tile into main stream.
4496*fd1fabb7SAndroid Build Coastguard Worker
4497*fd1fabb7SAndroid Build Coastguard Worker tileStream.CopyToStream (fStream, tileByteCount);
4498*fd1fabb7SAndroid Build Coastguard Worker
4499*fd1fabb7SAndroid Build Coastguard Worker // Update tile count.
4500*fd1fabb7SAndroid Build Coastguard Worker
4501*fd1fabb7SAndroid Build Coastguard Worker fBasic.SetTileByteCount (tileIndex, tileByteCount);
4502*fd1fabb7SAndroid Build Coastguard Worker
4503*fd1fabb7SAndroid Build Coastguard Worker // Keep the tiles on even byte offsets.
4504*fd1fabb7SAndroid Build Coastguard Worker
4505*fd1fabb7SAndroid Build Coastguard Worker if (tileByteCount & 1)
4506*fd1fabb7SAndroid Build Coastguard Worker {
4507*fd1fabb7SAndroid Build Coastguard Worker fStream.Put_uint8 (0);
4508*fd1fabb7SAndroid Build Coastguard Worker }
4509*fd1fabb7SAndroid Build Coastguard Worker
4510*fd1fabb7SAndroid Build Coastguard Worker // Let other threads know it is safe to write to stream.
4511*fd1fabb7SAndroid Build Coastguard Worker
4512*fd1fabb7SAndroid Build Coastguard Worker {
4513*fd1fabb7SAndroid Build Coastguard Worker
4514*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex lock (&fMutex2);
4515*fd1fabb7SAndroid Build Coastguard Worker
4516*fd1fabb7SAndroid Build Coastguard Worker // If the task failed in another thread, that thread already threw an exception.
4517*fd1fabb7SAndroid Build Coastguard Worker
4518*fd1fabb7SAndroid Build Coastguard Worker if (fTaskFailed)
4519*fd1fabb7SAndroid Build Coastguard Worker return;
4520*fd1fabb7SAndroid Build Coastguard Worker
4521*fd1fabb7SAndroid Build Coastguard Worker fWriteTileIndex++;
4522*fd1fabb7SAndroid Build Coastguard Worker
4523*fd1fabb7SAndroid Build Coastguard Worker fCondition.Broadcast ();
4524*fd1fabb7SAndroid Build Coastguard Worker
4525*fd1fabb7SAndroid Build Coastguard Worker }
4526*fd1fabb7SAndroid Build Coastguard Worker
4527*fd1fabb7SAndroid Build Coastguard Worker }
4528*fd1fabb7SAndroid Build Coastguard Worker
4529*fd1fabb7SAndroid Build Coastguard Worker }
4530*fd1fabb7SAndroid Build Coastguard Worker
4531*fd1fabb7SAndroid Build Coastguard Worker catch (...)
4532*fd1fabb7SAndroid Build Coastguard Worker {
4533*fd1fabb7SAndroid Build Coastguard Worker
4534*fd1fabb7SAndroid Build Coastguard Worker // If first to fail, wake up any threads waiting on condition.
4535*fd1fabb7SAndroid Build Coastguard Worker
4536*fd1fabb7SAndroid Build Coastguard Worker bool needBroadcast = false;
4537*fd1fabb7SAndroid Build Coastguard Worker
4538*fd1fabb7SAndroid Build Coastguard Worker {
4539*fd1fabb7SAndroid Build Coastguard Worker
4540*fd1fabb7SAndroid Build Coastguard Worker dng_lock_mutex lock (&fMutex2);
4541*fd1fabb7SAndroid Build Coastguard Worker
4542*fd1fabb7SAndroid Build Coastguard Worker needBroadcast = !fTaskFailed;
4543*fd1fabb7SAndroid Build Coastguard Worker fTaskFailed = true;
4544*fd1fabb7SAndroid Build Coastguard Worker
4545*fd1fabb7SAndroid Build Coastguard Worker }
4546*fd1fabb7SAndroid Build Coastguard Worker
4547*fd1fabb7SAndroid Build Coastguard Worker if (needBroadcast)
4548*fd1fabb7SAndroid Build Coastguard Worker fCondition.Broadcast ();
4549*fd1fabb7SAndroid Build Coastguard Worker
4550*fd1fabb7SAndroid Build Coastguard Worker throw;
4551*fd1fabb7SAndroid Build Coastguard Worker
4552*fd1fabb7SAndroid Build Coastguard Worker }
4553*fd1fabb7SAndroid Build Coastguard Worker
4554*fd1fabb7SAndroid Build Coastguard Worker }
4555*fd1fabb7SAndroid Build Coastguard Worker
4556*fd1fabb7SAndroid Build Coastguard Worker private:
4557*fd1fabb7SAndroid Build Coastguard Worker
4558*fd1fabb7SAndroid Build Coastguard Worker // Hidden copy constructor and assignment operator.
4559*fd1fabb7SAndroid Build Coastguard Worker
4560*fd1fabb7SAndroid Build Coastguard Worker dng_write_tiles_task (const dng_write_tiles_task &);
4561*fd1fabb7SAndroid Build Coastguard Worker
4562*fd1fabb7SAndroid Build Coastguard Worker dng_write_tiles_task & operator= (const dng_write_tiles_task &);
4563*fd1fabb7SAndroid Build Coastguard Worker
4564*fd1fabb7SAndroid Build Coastguard Worker };
4565*fd1fabb7SAndroid Build Coastguard Worker
4566*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4567*fd1fabb7SAndroid Build Coastguard Worker
WriteImage(dng_host & host,const dng_ifd & ifd,dng_basic_tag_set & basic,dng_stream & stream,const dng_image & image,uint32 fakeChannels)4568*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteImage (dng_host &host,
4569*fd1fabb7SAndroid Build Coastguard Worker const dng_ifd &ifd,
4570*fd1fabb7SAndroid Build Coastguard Worker dng_basic_tag_set &basic,
4571*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
4572*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
4573*fd1fabb7SAndroid Build Coastguard Worker uint32 fakeChannels)
4574*fd1fabb7SAndroid Build Coastguard Worker {
4575*fd1fabb7SAndroid Build Coastguard Worker
4576*fd1fabb7SAndroid Build Coastguard Worker // Deal with row interleaved images.
4577*fd1fabb7SAndroid Build Coastguard Worker
4578*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fRowInterleaveFactor > 1 &&
4579*fd1fabb7SAndroid Build Coastguard Worker ifd.fRowInterleaveFactor < ifd.fImageLength)
4580*fd1fabb7SAndroid Build Coastguard Worker {
4581*fd1fabb7SAndroid Build Coastguard Worker
4582*fd1fabb7SAndroid Build Coastguard Worker dng_ifd tempIFD (ifd);
4583*fd1fabb7SAndroid Build Coastguard Worker
4584*fd1fabb7SAndroid Build Coastguard Worker tempIFD.fRowInterleaveFactor = 1;
4585*fd1fabb7SAndroid Build Coastguard Worker
4586*fd1fabb7SAndroid Build Coastguard Worker dng_row_interleaved_image tempImage (*((dng_image *) &image),
4587*fd1fabb7SAndroid Build Coastguard Worker ifd.fRowInterleaveFactor);
4588*fd1fabb7SAndroid Build Coastguard Worker
4589*fd1fabb7SAndroid Build Coastguard Worker WriteImage (host,
4590*fd1fabb7SAndroid Build Coastguard Worker tempIFD,
4591*fd1fabb7SAndroid Build Coastguard Worker basic,
4592*fd1fabb7SAndroid Build Coastguard Worker stream,
4593*fd1fabb7SAndroid Build Coastguard Worker tempImage,
4594*fd1fabb7SAndroid Build Coastguard Worker fakeChannels);
4595*fd1fabb7SAndroid Build Coastguard Worker
4596*fd1fabb7SAndroid Build Coastguard Worker return;
4597*fd1fabb7SAndroid Build Coastguard Worker
4598*fd1fabb7SAndroid Build Coastguard Worker }
4599*fd1fabb7SAndroid Build Coastguard Worker
4600*fd1fabb7SAndroid Build Coastguard Worker // Compute basic information.
4601*fd1fabb7SAndroid Build Coastguard Worker
4602*fd1fabb7SAndroid Build Coastguard Worker uint32 bytesPerSample = TagTypeSize (image.PixelType ());
4603*fd1fabb7SAndroid Build Coastguard Worker
4604*fd1fabb7SAndroid Build Coastguard Worker uint32 bytesPerPixel = SafeUint32Mult (ifd.fSamplesPerPixel,
4605*fd1fabb7SAndroid Build Coastguard Worker bytesPerSample);
4606*fd1fabb7SAndroid Build Coastguard Worker
4607*fd1fabb7SAndroid Build Coastguard Worker uint32 tileRowBytes = SafeUint32Mult (ifd.fTileWidth, bytesPerPixel);
4608*fd1fabb7SAndroid Build Coastguard Worker
4609*fd1fabb7SAndroid Build Coastguard Worker // If we can compute the number of bytes needed to store the
4610*fd1fabb7SAndroid Build Coastguard Worker // data, we can split the write for each tile into sub-tiles.
4611*fd1fabb7SAndroid Build Coastguard Worker
4612*fd1fabb7SAndroid Build Coastguard Worker uint32 subTileLength = ifd.fTileLength;
4613*fd1fabb7SAndroid Build Coastguard Worker
4614*fd1fabb7SAndroid Build Coastguard Worker if (ifd.TileByteCount (ifd.TileArea (0, 0)) != 0)
4615*fd1fabb7SAndroid Build Coastguard Worker {
4616*fd1fabb7SAndroid Build Coastguard Worker
4617*fd1fabb7SAndroid Build Coastguard Worker subTileLength = Pin_uint32 (ifd.fSubTileBlockRows,
4618*fd1fabb7SAndroid Build Coastguard Worker kImageBufferSize / tileRowBytes,
4619*fd1fabb7SAndroid Build Coastguard Worker ifd.fTileLength);
4620*fd1fabb7SAndroid Build Coastguard Worker
4621*fd1fabb7SAndroid Build Coastguard Worker // Don't split sub-tiles across subTileBlocks.
4622*fd1fabb7SAndroid Build Coastguard Worker
4623*fd1fabb7SAndroid Build Coastguard Worker subTileLength = subTileLength / ifd.fSubTileBlockRows
4624*fd1fabb7SAndroid Build Coastguard Worker * ifd.fSubTileBlockRows;
4625*fd1fabb7SAndroid Build Coastguard Worker
4626*fd1fabb7SAndroid Build Coastguard Worker }
4627*fd1fabb7SAndroid Build Coastguard Worker
4628*fd1fabb7SAndroid Build Coastguard Worker // Find size of uncompressed buffer.
4629*fd1fabb7SAndroid Build Coastguard Worker
4630*fd1fabb7SAndroid Build Coastguard Worker uint32 uncompressedSize = SafeUint32Mult(subTileLength, tileRowBytes);
4631*fd1fabb7SAndroid Build Coastguard Worker
4632*fd1fabb7SAndroid Build Coastguard Worker // Find size of compressed buffer, if required.
4633*fd1fabb7SAndroid Build Coastguard Worker
4634*fd1fabb7SAndroid Build Coastguard Worker uint32 compressedSize = CompressedBufferSize (ifd, uncompressedSize);
4635*fd1fabb7SAndroid Build Coastguard Worker
4636*fd1fabb7SAndroid Build Coastguard Worker // See if we can do this write using multiple threads.
4637*fd1fabb7SAndroid Build Coastguard Worker
4638*fd1fabb7SAndroid Build Coastguard Worker uint32 tilesAcross = ifd.TilesAcross ();
4639*fd1fabb7SAndroid Build Coastguard Worker uint32 tilesDown = ifd.TilesDown ();
4640*fd1fabb7SAndroid Build Coastguard Worker
4641*fd1fabb7SAndroid Build Coastguard Worker bool useMultipleThreads = (tilesDown * tilesAcross >= 2) &&
4642*fd1fabb7SAndroid Build Coastguard Worker (host.PerformAreaTaskThreads () > 1) &&
4643*fd1fabb7SAndroid Build Coastguard Worker (subTileLength == ifd.fTileLength) &&
4644*fd1fabb7SAndroid Build Coastguard Worker (ifd.fCompression != ccUncompressed);
4645*fd1fabb7SAndroid Build Coastguard Worker
4646*fd1fabb7SAndroid Build Coastguard Worker
4647*fd1fabb7SAndroid Build Coastguard Worker #if qImagecore
4648*fd1fabb7SAndroid Build Coastguard Worker useMultipleThreads = false;
4649*fd1fabb7SAndroid Build Coastguard Worker #endif
4650*fd1fabb7SAndroid Build Coastguard Worker
4651*fd1fabb7SAndroid Build Coastguard Worker if (useMultipleThreads)
4652*fd1fabb7SAndroid Build Coastguard Worker {
4653*fd1fabb7SAndroid Build Coastguard Worker
4654*fd1fabb7SAndroid Build Coastguard Worker uint32 threadCount = Min_uint32 (tilesDown * tilesAcross,
4655*fd1fabb7SAndroid Build Coastguard Worker host.PerformAreaTaskThreads ());
4656*fd1fabb7SAndroid Build Coastguard Worker
4657*fd1fabb7SAndroid Build Coastguard Worker dng_write_tiles_task task (*this,
4658*fd1fabb7SAndroid Build Coastguard Worker host,
4659*fd1fabb7SAndroid Build Coastguard Worker ifd,
4660*fd1fabb7SAndroid Build Coastguard Worker basic,
4661*fd1fabb7SAndroid Build Coastguard Worker stream,
4662*fd1fabb7SAndroid Build Coastguard Worker image,
4663*fd1fabb7SAndroid Build Coastguard Worker fakeChannels,
4664*fd1fabb7SAndroid Build Coastguard Worker tilesDown,
4665*fd1fabb7SAndroid Build Coastguard Worker tilesAcross,
4666*fd1fabb7SAndroid Build Coastguard Worker compressedSize,
4667*fd1fabb7SAndroid Build Coastguard Worker uncompressedSize);
4668*fd1fabb7SAndroid Build Coastguard Worker
4669*fd1fabb7SAndroid Build Coastguard Worker host.PerformAreaTask (task,
4670*fd1fabb7SAndroid Build Coastguard Worker dng_rect (0, 0, 16, 16 * threadCount));
4671*fd1fabb7SAndroid Build Coastguard Worker
4672*fd1fabb7SAndroid Build Coastguard Worker }
4673*fd1fabb7SAndroid Build Coastguard Worker
4674*fd1fabb7SAndroid Build Coastguard Worker else
4675*fd1fabb7SAndroid Build Coastguard Worker {
4676*fd1fabb7SAndroid Build Coastguard Worker
4677*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> compressedBuffer;
4678*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> uncompressedBuffer;
4679*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> subTileBlockBuffer;
4680*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> tempBuffer;
4681*fd1fabb7SAndroid Build Coastguard Worker
4682*fd1fabb7SAndroid Build Coastguard Worker if (compressedSize)
4683*fd1fabb7SAndroid Build Coastguard Worker {
4684*fd1fabb7SAndroid Build Coastguard Worker compressedBuffer.Reset (host.Allocate (compressedSize));
4685*fd1fabb7SAndroid Build Coastguard Worker }
4686*fd1fabb7SAndroid Build Coastguard Worker
4687*fd1fabb7SAndroid Build Coastguard Worker if (uncompressedSize)
4688*fd1fabb7SAndroid Build Coastguard Worker {
4689*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer.Reset (host.Allocate (uncompressedSize));
4690*fd1fabb7SAndroid Build Coastguard Worker }
4691*fd1fabb7SAndroid Build Coastguard Worker
4692*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fSubTileBlockRows > 1 && uncompressedSize)
4693*fd1fabb7SAndroid Build Coastguard Worker {
4694*fd1fabb7SAndroid Build Coastguard Worker subTileBlockBuffer.Reset (host.Allocate (uncompressedSize));
4695*fd1fabb7SAndroid Build Coastguard Worker }
4696*fd1fabb7SAndroid Build Coastguard Worker
4697*fd1fabb7SAndroid Build Coastguard Worker // Write out each tile.
4698*fd1fabb7SAndroid Build Coastguard Worker
4699*fd1fabb7SAndroid Build Coastguard Worker uint32 tileIndex = 0;
4700*fd1fabb7SAndroid Build Coastguard Worker
4701*fd1fabb7SAndroid Build Coastguard Worker for (uint32 rowIndex = 0; rowIndex < tilesDown; rowIndex++)
4702*fd1fabb7SAndroid Build Coastguard Worker {
4703*fd1fabb7SAndroid Build Coastguard Worker
4704*fd1fabb7SAndroid Build Coastguard Worker for (uint32 colIndex = 0; colIndex < tilesAcross; colIndex++)
4705*fd1fabb7SAndroid Build Coastguard Worker {
4706*fd1fabb7SAndroid Build Coastguard Worker
4707*fd1fabb7SAndroid Build Coastguard Worker // Remember this offset.
4708*fd1fabb7SAndroid Build Coastguard Worker
4709*fd1fabb7SAndroid Build Coastguard Worker uint32 tileOffset = (uint32) stream.Position ();
4710*fd1fabb7SAndroid Build Coastguard Worker
4711*fd1fabb7SAndroid Build Coastguard Worker basic.SetTileOffset (tileIndex, tileOffset);
4712*fd1fabb7SAndroid Build Coastguard Worker
4713*fd1fabb7SAndroid Build Coastguard Worker // Split tile into sub-tiles if possible.
4714*fd1fabb7SAndroid Build Coastguard Worker
4715*fd1fabb7SAndroid Build Coastguard Worker dng_rect tileArea = ifd.TileArea (rowIndex, colIndex);
4716*fd1fabb7SAndroid Build Coastguard Worker
4717*fd1fabb7SAndroid Build Coastguard Worker uint32 subTileCount = (tileArea.H () + subTileLength - 1) /
4718*fd1fabb7SAndroid Build Coastguard Worker subTileLength;
4719*fd1fabb7SAndroid Build Coastguard Worker
4720*fd1fabb7SAndroid Build Coastguard Worker for (uint32 subIndex = 0; subIndex < subTileCount; subIndex++)
4721*fd1fabb7SAndroid Build Coastguard Worker {
4722*fd1fabb7SAndroid Build Coastguard Worker
4723*fd1fabb7SAndroid Build Coastguard Worker host.SniffForAbort ();
4724*fd1fabb7SAndroid Build Coastguard Worker
4725*fd1fabb7SAndroid Build Coastguard Worker dng_rect subArea (tileArea);
4726*fd1fabb7SAndroid Build Coastguard Worker
4727*fd1fabb7SAndroid Build Coastguard Worker subArea.t = tileArea.t + subIndex * subTileLength;
4728*fd1fabb7SAndroid Build Coastguard Worker
4729*fd1fabb7SAndroid Build Coastguard Worker subArea.b = Min_int32 (subArea.t + subTileLength,
4730*fd1fabb7SAndroid Build Coastguard Worker tileArea.b);
4731*fd1fabb7SAndroid Build Coastguard Worker
4732*fd1fabb7SAndroid Build Coastguard Worker // Write the sub-tile.
4733*fd1fabb7SAndroid Build Coastguard Worker
4734*fd1fabb7SAndroid Build Coastguard Worker WriteTile (host,
4735*fd1fabb7SAndroid Build Coastguard Worker ifd,
4736*fd1fabb7SAndroid Build Coastguard Worker stream,
4737*fd1fabb7SAndroid Build Coastguard Worker image,
4738*fd1fabb7SAndroid Build Coastguard Worker subArea,
4739*fd1fabb7SAndroid Build Coastguard Worker fakeChannels,
4740*fd1fabb7SAndroid Build Coastguard Worker compressedBuffer,
4741*fd1fabb7SAndroid Build Coastguard Worker uncompressedBuffer,
4742*fd1fabb7SAndroid Build Coastguard Worker subTileBlockBuffer,
4743*fd1fabb7SAndroid Build Coastguard Worker tempBuffer);
4744*fd1fabb7SAndroid Build Coastguard Worker
4745*fd1fabb7SAndroid Build Coastguard Worker }
4746*fd1fabb7SAndroid Build Coastguard Worker
4747*fd1fabb7SAndroid Build Coastguard Worker // Update tile count.
4748*fd1fabb7SAndroid Build Coastguard Worker
4749*fd1fabb7SAndroid Build Coastguard Worker uint32 tileByteCount = (uint32) stream.Position () - tileOffset;
4750*fd1fabb7SAndroid Build Coastguard Worker
4751*fd1fabb7SAndroid Build Coastguard Worker basic.SetTileByteCount (tileIndex, tileByteCount);
4752*fd1fabb7SAndroid Build Coastguard Worker
4753*fd1fabb7SAndroid Build Coastguard Worker tileIndex++;
4754*fd1fabb7SAndroid Build Coastguard Worker
4755*fd1fabb7SAndroid Build Coastguard Worker // Keep the tiles on even byte offsets.
4756*fd1fabb7SAndroid Build Coastguard Worker
4757*fd1fabb7SAndroid Build Coastguard Worker if (tileByteCount & 1)
4758*fd1fabb7SAndroid Build Coastguard Worker {
4759*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
4760*fd1fabb7SAndroid Build Coastguard Worker }
4761*fd1fabb7SAndroid Build Coastguard Worker
4762*fd1fabb7SAndroid Build Coastguard Worker }
4763*fd1fabb7SAndroid Build Coastguard Worker
4764*fd1fabb7SAndroid Build Coastguard Worker }
4765*fd1fabb7SAndroid Build Coastguard Worker
4766*fd1fabb7SAndroid Build Coastguard Worker }
4767*fd1fabb7SAndroid Build Coastguard Worker
4768*fd1fabb7SAndroid Build Coastguard Worker }
4769*fd1fabb7SAndroid Build Coastguard Worker
4770*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4771*fd1fabb7SAndroid Build Coastguard Worker
4772*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
4773*fd1fabb7SAndroid Build Coastguard Worker
CopyString(const dng_xmp & oldXMP,dng_xmp & newXMP,const char * ns,const char * path,dng_string * exif=NULL)4774*fd1fabb7SAndroid Build Coastguard Worker static void CopyString (const dng_xmp &oldXMP,
4775*fd1fabb7SAndroid Build Coastguard Worker dng_xmp &newXMP,
4776*fd1fabb7SAndroid Build Coastguard Worker const char *ns,
4777*fd1fabb7SAndroid Build Coastguard Worker const char *path,
4778*fd1fabb7SAndroid Build Coastguard Worker dng_string *exif = NULL)
4779*fd1fabb7SAndroid Build Coastguard Worker {
4780*fd1fabb7SAndroid Build Coastguard Worker
4781*fd1fabb7SAndroid Build Coastguard Worker dng_string s;
4782*fd1fabb7SAndroid Build Coastguard Worker
4783*fd1fabb7SAndroid Build Coastguard Worker if (oldXMP.GetString (ns, path, s))
4784*fd1fabb7SAndroid Build Coastguard Worker {
4785*fd1fabb7SAndroid Build Coastguard Worker
4786*fd1fabb7SAndroid Build Coastguard Worker if (s.NotEmpty ())
4787*fd1fabb7SAndroid Build Coastguard Worker {
4788*fd1fabb7SAndroid Build Coastguard Worker
4789*fd1fabb7SAndroid Build Coastguard Worker newXMP.SetString (ns, path, s);
4790*fd1fabb7SAndroid Build Coastguard Worker
4791*fd1fabb7SAndroid Build Coastguard Worker if (exif)
4792*fd1fabb7SAndroid Build Coastguard Worker {
4793*fd1fabb7SAndroid Build Coastguard Worker
4794*fd1fabb7SAndroid Build Coastguard Worker *exif = s;
4795*fd1fabb7SAndroid Build Coastguard Worker
4796*fd1fabb7SAndroid Build Coastguard Worker }
4797*fd1fabb7SAndroid Build Coastguard Worker
4798*fd1fabb7SAndroid Build Coastguard Worker }
4799*fd1fabb7SAndroid Build Coastguard Worker
4800*fd1fabb7SAndroid Build Coastguard Worker }
4801*fd1fabb7SAndroid Build Coastguard Worker
4802*fd1fabb7SAndroid Build Coastguard Worker }
4803*fd1fabb7SAndroid Build Coastguard Worker
4804*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4805*fd1fabb7SAndroid Build Coastguard Worker
CopyStringList(const dng_xmp & oldXMP,dng_xmp & newXMP,const char * ns,const char * path,bool isBag)4806*fd1fabb7SAndroid Build Coastguard Worker static void CopyStringList (const dng_xmp &oldXMP,
4807*fd1fabb7SAndroid Build Coastguard Worker dng_xmp &newXMP,
4808*fd1fabb7SAndroid Build Coastguard Worker const char *ns,
4809*fd1fabb7SAndroid Build Coastguard Worker const char *path,
4810*fd1fabb7SAndroid Build Coastguard Worker bool isBag)
4811*fd1fabb7SAndroid Build Coastguard Worker {
4812*fd1fabb7SAndroid Build Coastguard Worker
4813*fd1fabb7SAndroid Build Coastguard Worker dng_string_list list;
4814*fd1fabb7SAndroid Build Coastguard Worker
4815*fd1fabb7SAndroid Build Coastguard Worker if (oldXMP.GetStringList (ns, path, list))
4816*fd1fabb7SAndroid Build Coastguard Worker {
4817*fd1fabb7SAndroid Build Coastguard Worker
4818*fd1fabb7SAndroid Build Coastguard Worker if (list.Count ())
4819*fd1fabb7SAndroid Build Coastguard Worker {
4820*fd1fabb7SAndroid Build Coastguard Worker
4821*fd1fabb7SAndroid Build Coastguard Worker newXMP.SetStringList (ns, path, list, isBag);
4822*fd1fabb7SAndroid Build Coastguard Worker
4823*fd1fabb7SAndroid Build Coastguard Worker }
4824*fd1fabb7SAndroid Build Coastguard Worker
4825*fd1fabb7SAndroid Build Coastguard Worker }
4826*fd1fabb7SAndroid Build Coastguard Worker
4827*fd1fabb7SAndroid Build Coastguard Worker }
4828*fd1fabb7SAndroid Build Coastguard Worker
4829*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4830*fd1fabb7SAndroid Build Coastguard Worker
CopyAltLangDefault(const dng_xmp & oldXMP,dng_xmp & newXMP,const char * ns,const char * path,dng_string * exif=NULL)4831*fd1fabb7SAndroid Build Coastguard Worker static void CopyAltLangDefault (const dng_xmp &oldXMP,
4832*fd1fabb7SAndroid Build Coastguard Worker dng_xmp &newXMP,
4833*fd1fabb7SAndroid Build Coastguard Worker const char *ns,
4834*fd1fabb7SAndroid Build Coastguard Worker const char *path,
4835*fd1fabb7SAndroid Build Coastguard Worker dng_string *exif = NULL)
4836*fd1fabb7SAndroid Build Coastguard Worker {
4837*fd1fabb7SAndroid Build Coastguard Worker
4838*fd1fabb7SAndroid Build Coastguard Worker dng_string s;
4839*fd1fabb7SAndroid Build Coastguard Worker
4840*fd1fabb7SAndroid Build Coastguard Worker if (oldXMP.GetAltLangDefault (ns, path, s))
4841*fd1fabb7SAndroid Build Coastguard Worker {
4842*fd1fabb7SAndroid Build Coastguard Worker
4843*fd1fabb7SAndroid Build Coastguard Worker if (s.NotEmpty ())
4844*fd1fabb7SAndroid Build Coastguard Worker {
4845*fd1fabb7SAndroid Build Coastguard Worker
4846*fd1fabb7SAndroid Build Coastguard Worker newXMP.SetAltLangDefault (ns, path, s);
4847*fd1fabb7SAndroid Build Coastguard Worker
4848*fd1fabb7SAndroid Build Coastguard Worker if (exif)
4849*fd1fabb7SAndroid Build Coastguard Worker {
4850*fd1fabb7SAndroid Build Coastguard Worker
4851*fd1fabb7SAndroid Build Coastguard Worker *exif = s;
4852*fd1fabb7SAndroid Build Coastguard Worker
4853*fd1fabb7SAndroid Build Coastguard Worker }
4854*fd1fabb7SAndroid Build Coastguard Worker
4855*fd1fabb7SAndroid Build Coastguard Worker }
4856*fd1fabb7SAndroid Build Coastguard Worker
4857*fd1fabb7SAndroid Build Coastguard Worker }
4858*fd1fabb7SAndroid Build Coastguard Worker
4859*fd1fabb7SAndroid Build Coastguard Worker }
4860*fd1fabb7SAndroid Build Coastguard Worker
4861*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4862*fd1fabb7SAndroid Build Coastguard Worker
CopyStructField(const dng_xmp & oldXMP,dng_xmp & newXMP,const char * ns,const char * path,const char * field)4863*fd1fabb7SAndroid Build Coastguard Worker static void CopyStructField (const dng_xmp &oldXMP,
4864*fd1fabb7SAndroid Build Coastguard Worker dng_xmp &newXMP,
4865*fd1fabb7SAndroid Build Coastguard Worker const char *ns,
4866*fd1fabb7SAndroid Build Coastguard Worker const char *path,
4867*fd1fabb7SAndroid Build Coastguard Worker const char *field)
4868*fd1fabb7SAndroid Build Coastguard Worker {
4869*fd1fabb7SAndroid Build Coastguard Worker
4870*fd1fabb7SAndroid Build Coastguard Worker dng_string s;
4871*fd1fabb7SAndroid Build Coastguard Worker
4872*fd1fabb7SAndroid Build Coastguard Worker if (oldXMP.GetStructField (ns, path, ns, field, s))
4873*fd1fabb7SAndroid Build Coastguard Worker {
4874*fd1fabb7SAndroid Build Coastguard Worker
4875*fd1fabb7SAndroid Build Coastguard Worker if (s.NotEmpty ())
4876*fd1fabb7SAndroid Build Coastguard Worker {
4877*fd1fabb7SAndroid Build Coastguard Worker
4878*fd1fabb7SAndroid Build Coastguard Worker newXMP.SetStructField (ns, path, ns, field, s);
4879*fd1fabb7SAndroid Build Coastguard Worker
4880*fd1fabb7SAndroid Build Coastguard Worker }
4881*fd1fabb7SAndroid Build Coastguard Worker
4882*fd1fabb7SAndroid Build Coastguard Worker }
4883*fd1fabb7SAndroid Build Coastguard Worker
4884*fd1fabb7SAndroid Build Coastguard Worker }
4885*fd1fabb7SAndroid Build Coastguard Worker
4886*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4887*fd1fabb7SAndroid Build Coastguard Worker
CopyBoolean(const dng_xmp & oldXMP,dng_xmp & newXMP,const char * ns,const char * path)4888*fd1fabb7SAndroid Build Coastguard Worker static void CopyBoolean (const dng_xmp &oldXMP,
4889*fd1fabb7SAndroid Build Coastguard Worker dng_xmp &newXMP,
4890*fd1fabb7SAndroid Build Coastguard Worker const char *ns,
4891*fd1fabb7SAndroid Build Coastguard Worker const char *path)
4892*fd1fabb7SAndroid Build Coastguard Worker {
4893*fd1fabb7SAndroid Build Coastguard Worker
4894*fd1fabb7SAndroid Build Coastguard Worker bool b;
4895*fd1fabb7SAndroid Build Coastguard Worker
4896*fd1fabb7SAndroid Build Coastguard Worker if (oldXMP.GetBoolean (ns, path, b))
4897*fd1fabb7SAndroid Build Coastguard Worker {
4898*fd1fabb7SAndroid Build Coastguard Worker
4899*fd1fabb7SAndroid Build Coastguard Worker newXMP.SetBoolean (ns, path, b);
4900*fd1fabb7SAndroid Build Coastguard Worker
4901*fd1fabb7SAndroid Build Coastguard Worker }
4902*fd1fabb7SAndroid Build Coastguard Worker
4903*fd1fabb7SAndroid Build Coastguard Worker }
4904*fd1fabb7SAndroid Build Coastguard Worker
4905*fd1fabb7SAndroid Build Coastguard Worker #endif
4906*fd1fabb7SAndroid Build Coastguard Worker
4907*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
4908*fd1fabb7SAndroid Build Coastguard Worker
CleanUpMetadata(dng_host & host,dng_metadata & metadata,dng_metadata_subset metadataSubset,const char * dstMIMI,const char * software)4909*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::CleanUpMetadata (dng_host &host,
4910*fd1fabb7SAndroid Build Coastguard Worker dng_metadata &metadata,
4911*fd1fabb7SAndroid Build Coastguard Worker dng_metadata_subset metadataSubset,
4912*fd1fabb7SAndroid Build Coastguard Worker const char *dstMIMI,
4913*fd1fabb7SAndroid Build Coastguard Worker const char *software)
4914*fd1fabb7SAndroid Build Coastguard Worker {
4915*fd1fabb7SAndroid Build Coastguard Worker
4916*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
4917*fd1fabb7SAndroid Build Coastguard Worker
4918*fd1fabb7SAndroid Build Coastguard Worker if (metadata.GetXMP () && metadata.GetExif ())
4919*fd1fabb7SAndroid Build Coastguard Worker {
4920*fd1fabb7SAndroid Build Coastguard Worker
4921*fd1fabb7SAndroid Build Coastguard Worker dng_xmp &newXMP (*metadata.GetXMP ());
4922*fd1fabb7SAndroid Build Coastguard Worker dng_exif &newEXIF (*metadata.GetExif ());
4923*fd1fabb7SAndroid Build Coastguard Worker
4924*fd1fabb7SAndroid Build Coastguard Worker // Update software tag.
4925*fd1fabb7SAndroid Build Coastguard Worker
4926*fd1fabb7SAndroid Build Coastguard Worker if (software)
4927*fd1fabb7SAndroid Build Coastguard Worker {
4928*fd1fabb7SAndroid Build Coastguard Worker
4929*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fSoftware.Set (software);
4930*fd1fabb7SAndroid Build Coastguard Worker
4931*fd1fabb7SAndroid Build Coastguard Worker newXMP.Set (XMP_NS_XAP,
4932*fd1fabb7SAndroid Build Coastguard Worker "CreatorTool",
4933*fd1fabb7SAndroid Build Coastguard Worker software);
4934*fd1fabb7SAndroid Build Coastguard Worker
4935*fd1fabb7SAndroid Build Coastguard Worker }
4936*fd1fabb7SAndroid Build Coastguard Worker
4937*fd1fabb7SAndroid Build Coastguard Worker #if qDNGXMPDocOps
4938*fd1fabb7SAndroid Build Coastguard Worker
4939*fd1fabb7SAndroid Build Coastguard Worker newXMP.DocOpsPrepareForSave (metadata.SourceMIMI ().Get (),
4940*fd1fabb7SAndroid Build Coastguard Worker dstMIMI);
4941*fd1fabb7SAndroid Build Coastguard Worker
4942*fd1fabb7SAndroid Build Coastguard Worker #else
4943*fd1fabb7SAndroid Build Coastguard Worker
4944*fd1fabb7SAndroid Build Coastguard Worker metadata.UpdateDateTimeToNow ();
4945*fd1fabb7SAndroid Build Coastguard Worker
4946*fd1fabb7SAndroid Build Coastguard Worker #endif
4947*fd1fabb7SAndroid Build Coastguard Worker
4948*fd1fabb7SAndroid Build Coastguard Worker // Update EXIF version to at least 2.3 so all the exif tags
4949*fd1fabb7SAndroid Build Coastguard Worker // can be written.
4950*fd1fabb7SAndroid Build Coastguard Worker
4951*fd1fabb7SAndroid Build Coastguard Worker if (newEXIF.fExifVersion < DNG_CHAR4 ('0','2','3','0'))
4952*fd1fabb7SAndroid Build Coastguard Worker {
4953*fd1fabb7SAndroid Build Coastguard Worker
4954*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fExifVersion = DNG_CHAR4 ('0','2','3','0');
4955*fd1fabb7SAndroid Build Coastguard Worker
4956*fd1fabb7SAndroid Build Coastguard Worker newXMP.Set (XMP_NS_EXIF, "ExifVersion", "0230");
4957*fd1fabb7SAndroid Build Coastguard Worker
4958*fd1fabb7SAndroid Build Coastguard Worker }
4959*fd1fabb7SAndroid Build Coastguard Worker
4960*fd1fabb7SAndroid Build Coastguard Worker // Resync EXIF, remove EXIF tags from XMP.
4961*fd1fabb7SAndroid Build Coastguard Worker
4962*fd1fabb7SAndroid Build Coastguard Worker newXMP.SyncExif (newEXIF,
4963*fd1fabb7SAndroid Build Coastguard Worker metadata.GetOriginalExif (),
4964*fd1fabb7SAndroid Build Coastguard Worker false,
4965*fd1fabb7SAndroid Build Coastguard Worker true);
4966*fd1fabb7SAndroid Build Coastguard Worker
4967*fd1fabb7SAndroid Build Coastguard Worker // Deal with ImageIngesterPro bug. This program is adding lots of
4968*fd1fabb7SAndroid Build Coastguard Worker // empty metadata strings into the XMP, which is screwing up Adobe CS4.
4969*fd1fabb7SAndroid Build Coastguard Worker // We are saving a new file, so this is a chance to clean up this mess.
4970*fd1fabb7SAndroid Build Coastguard Worker
4971*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveEmptyStringsAndArrays (XMP_NS_DC);
4972*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveEmptyStringsAndArrays (XMP_NS_XAP);
4973*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveEmptyStringsAndArrays (XMP_NS_PHOTOSHOP);
4974*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveEmptyStringsAndArrays (XMP_NS_IPTC);
4975*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveEmptyStringsAndArrays (XMP_NS_XAP_RIGHTS);
4976*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveEmptyStringsAndArrays ("http://ns.iview-multimedia.com/mediapro/1.0/");
4977*fd1fabb7SAndroid Build Coastguard Worker
4978*fd1fabb7SAndroid Build Coastguard Worker // Process metadata subset.
4979*fd1fabb7SAndroid Build Coastguard Worker
4980*fd1fabb7SAndroid Build Coastguard Worker if (metadataSubset == kMetadataSubset_CopyrightOnly ||
4981*fd1fabb7SAndroid Build Coastguard Worker metadataSubset == kMetadataSubset_CopyrightAndContact)
4982*fd1fabb7SAndroid Build Coastguard Worker {
4983*fd1fabb7SAndroid Build Coastguard Worker
4984*fd1fabb7SAndroid Build Coastguard Worker dng_xmp oldXMP (newXMP );
4985*fd1fabb7SAndroid Build Coastguard Worker dng_exif oldEXIF (newEXIF);
4986*fd1fabb7SAndroid Build Coastguard Worker
4987*fd1fabb7SAndroid Build Coastguard Worker // For these options, we start from nothing, and only fill in the
4988*fd1fabb7SAndroid Build Coastguard Worker // fields that we absolutely need.
4989*fd1fabb7SAndroid Build Coastguard Worker
4990*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (NULL);
4991*fd1fabb7SAndroid Build Coastguard Worker
4992*fd1fabb7SAndroid Build Coastguard Worker newEXIF.SetEmpty ();
4993*fd1fabb7SAndroid Build Coastguard Worker
4994*fd1fabb7SAndroid Build Coastguard Worker metadata.ClearMakerNote ();
4995*fd1fabb7SAndroid Build Coastguard Worker
4996*fd1fabb7SAndroid Build Coastguard Worker // Move copyright related fields over.
4997*fd1fabb7SAndroid Build Coastguard Worker
4998*fd1fabb7SAndroid Build Coastguard Worker CopyAltLangDefault (oldXMP,
4999*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5000*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_DC,
5001*fd1fabb7SAndroid Build Coastguard Worker "rights",
5002*fd1fabb7SAndroid Build Coastguard Worker &newEXIF.fCopyright);
5003*fd1fabb7SAndroid Build Coastguard Worker
5004*fd1fabb7SAndroid Build Coastguard Worker CopyAltLangDefault (oldXMP,
5005*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5006*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_XAP_RIGHTS,
5007*fd1fabb7SAndroid Build Coastguard Worker "UsageTerms");
5008*fd1fabb7SAndroid Build Coastguard Worker
5009*fd1fabb7SAndroid Build Coastguard Worker CopyString (oldXMP,
5010*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5011*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_XAP_RIGHTS,
5012*fd1fabb7SAndroid Build Coastguard Worker "WebStatement");
5013*fd1fabb7SAndroid Build Coastguard Worker
5014*fd1fabb7SAndroid Build Coastguard Worker CopyBoolean (oldXMP,
5015*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5016*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_XAP_RIGHTS,
5017*fd1fabb7SAndroid Build Coastguard Worker "Marked");
5018*fd1fabb7SAndroid Build Coastguard Worker
5019*fd1fabb7SAndroid Build Coastguard Worker #if qDNGXMPDocOps
5020*fd1fabb7SAndroid Build Coastguard Worker
5021*fd1fabb7SAndroid Build Coastguard Worker // Include basic DocOps fields, but not the full history.
5022*fd1fabb7SAndroid Build Coastguard Worker
5023*fd1fabb7SAndroid Build Coastguard Worker CopyString (oldXMP,
5024*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5025*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_MM,
5026*fd1fabb7SAndroid Build Coastguard Worker "OriginalDocumentID");
5027*fd1fabb7SAndroid Build Coastguard Worker
5028*fd1fabb7SAndroid Build Coastguard Worker CopyString (oldXMP,
5029*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5030*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_MM,
5031*fd1fabb7SAndroid Build Coastguard Worker "DocumentID");
5032*fd1fabb7SAndroid Build Coastguard Worker
5033*fd1fabb7SAndroid Build Coastguard Worker CopyString (oldXMP,
5034*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5035*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_MM,
5036*fd1fabb7SAndroid Build Coastguard Worker "InstanceID");
5037*fd1fabb7SAndroid Build Coastguard Worker
5038*fd1fabb7SAndroid Build Coastguard Worker CopyString (oldXMP,
5039*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5040*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_XAP,
5041*fd1fabb7SAndroid Build Coastguard Worker "MetadataDate");
5042*fd1fabb7SAndroid Build Coastguard Worker
5043*fd1fabb7SAndroid Build Coastguard Worker #endif
5044*fd1fabb7SAndroid Build Coastguard Worker
5045*fd1fabb7SAndroid Build Coastguard Worker // Copyright and Contact adds the contact info fields.
5046*fd1fabb7SAndroid Build Coastguard Worker
5047*fd1fabb7SAndroid Build Coastguard Worker if (metadataSubset == kMetadataSubset_CopyrightAndContact)
5048*fd1fabb7SAndroid Build Coastguard Worker {
5049*fd1fabb7SAndroid Build Coastguard Worker
5050*fd1fabb7SAndroid Build Coastguard Worker // Note: Save for Web is not including the dc:creator list, but it
5051*fd1fabb7SAndroid Build Coastguard Worker // is part of the IPTC contract info metadata panel, so I
5052*fd1fabb7SAndroid Build Coastguard Worker // think it should be copied as part of the contact info.
5053*fd1fabb7SAndroid Build Coastguard Worker
5054*fd1fabb7SAndroid Build Coastguard Worker CopyStringList (oldXMP,
5055*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5056*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_DC,
5057*fd1fabb7SAndroid Build Coastguard Worker "creator",
5058*fd1fabb7SAndroid Build Coastguard Worker false);
5059*fd1fabb7SAndroid Build Coastguard Worker
5060*fd1fabb7SAndroid Build Coastguard Worker // The first string dc:creator list is mirrored to the
5061*fd1fabb7SAndroid Build Coastguard Worker // the exif artist tag, so copy that also.
5062*fd1fabb7SAndroid Build Coastguard Worker
5063*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fArtist = oldEXIF.fArtist;
5064*fd1fabb7SAndroid Build Coastguard Worker
5065*fd1fabb7SAndroid Build Coastguard Worker // Copy other contact fields.
5066*fd1fabb7SAndroid Build Coastguard Worker
5067*fd1fabb7SAndroid Build Coastguard Worker CopyString (oldXMP,
5068*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5069*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_PHOTOSHOP,
5070*fd1fabb7SAndroid Build Coastguard Worker "AuthorsPosition");
5071*fd1fabb7SAndroid Build Coastguard Worker
5072*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5073*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5074*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5075*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5076*fd1fabb7SAndroid Build Coastguard Worker "CiEmailWork");
5077*fd1fabb7SAndroid Build Coastguard Worker
5078*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5079*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5080*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5081*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5082*fd1fabb7SAndroid Build Coastguard Worker "CiAdrExtadr");
5083*fd1fabb7SAndroid Build Coastguard Worker
5084*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5085*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5086*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5087*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5088*fd1fabb7SAndroid Build Coastguard Worker "CiAdrCity");
5089*fd1fabb7SAndroid Build Coastguard Worker
5090*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5091*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5092*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5093*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5094*fd1fabb7SAndroid Build Coastguard Worker "CiAdrRegion");
5095*fd1fabb7SAndroid Build Coastguard Worker
5096*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5097*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5098*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5099*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5100*fd1fabb7SAndroid Build Coastguard Worker "CiAdrPcode");
5101*fd1fabb7SAndroid Build Coastguard Worker
5102*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5103*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5104*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5105*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5106*fd1fabb7SAndroid Build Coastguard Worker "CiAdrCtry");
5107*fd1fabb7SAndroid Build Coastguard Worker
5108*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5109*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5110*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5111*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5112*fd1fabb7SAndroid Build Coastguard Worker "CiTelWork");
5113*fd1fabb7SAndroid Build Coastguard Worker
5114*fd1fabb7SAndroid Build Coastguard Worker CopyStructField (oldXMP,
5115*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5116*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_IPTC,
5117*fd1fabb7SAndroid Build Coastguard Worker "CreatorContactInfo",
5118*fd1fabb7SAndroid Build Coastguard Worker "CiUrlWork");
5119*fd1fabb7SAndroid Build Coastguard Worker
5120*fd1fabb7SAndroid Build Coastguard Worker CopyAltLangDefault (oldXMP,
5121*fd1fabb7SAndroid Build Coastguard Worker newXMP,
5122*fd1fabb7SAndroid Build Coastguard Worker XMP_NS_DC,
5123*fd1fabb7SAndroid Build Coastguard Worker "title");
5124*fd1fabb7SAndroid Build Coastguard Worker
5125*fd1fabb7SAndroid Build Coastguard Worker }
5126*fd1fabb7SAndroid Build Coastguard Worker
5127*fd1fabb7SAndroid Build Coastguard Worker }
5128*fd1fabb7SAndroid Build Coastguard Worker
5129*fd1fabb7SAndroid Build Coastguard Worker else if (metadataSubset == kMetadataSubset_AllExceptCameraInfo ||
5130*fd1fabb7SAndroid Build Coastguard Worker metadataSubset == kMetadataSubset_AllExceptCameraAndLocation ||
5131*fd1fabb7SAndroid Build Coastguard Worker metadataSubset == kMetadataSubset_AllExceptLocationInfo)
5132*fd1fabb7SAndroid Build Coastguard Worker {
5133*fd1fabb7SAndroid Build Coastguard Worker
5134*fd1fabb7SAndroid Build Coastguard Worker dng_xmp oldXMP (newXMP );
5135*fd1fabb7SAndroid Build Coastguard Worker dng_exif oldEXIF (newEXIF);
5136*fd1fabb7SAndroid Build Coastguard Worker
5137*fd1fabb7SAndroid Build Coastguard Worker if (metadataSubset == kMetadataSubset_AllExceptCameraInfo ||
5138*fd1fabb7SAndroid Build Coastguard Worker metadataSubset == kMetadataSubset_AllExceptCameraAndLocation)
5139*fd1fabb7SAndroid Build Coastguard Worker {
5140*fd1fabb7SAndroid Build Coastguard Worker
5141*fd1fabb7SAndroid Build Coastguard Worker // This removes most of the EXIF info, so just copy the fields
5142*fd1fabb7SAndroid Build Coastguard Worker // we are not deleting.
5143*fd1fabb7SAndroid Build Coastguard Worker
5144*fd1fabb7SAndroid Build Coastguard Worker newEXIF.SetEmpty ();
5145*fd1fabb7SAndroid Build Coastguard Worker
5146*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fImageDescription = oldEXIF.fImageDescription; // Note: Differs from SFW
5147*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fSoftware = oldEXIF.fSoftware;
5148*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fArtist = oldEXIF.fArtist;
5149*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fCopyright = oldEXIF.fCopyright;
5150*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fCopyright2 = oldEXIF.fCopyright2;
5151*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fDateTime = oldEXIF.fDateTime;
5152*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fDateTimeOriginal = oldEXIF.fDateTimeOriginal;
5153*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fDateTimeDigitized = oldEXIF.fDateTimeDigitized;
5154*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fExifVersion = oldEXIF.fExifVersion;
5155*fd1fabb7SAndroid Build Coastguard Worker newEXIF.fImageUniqueID = oldEXIF.fImageUniqueID;
5156*fd1fabb7SAndroid Build Coastguard Worker
5157*fd1fabb7SAndroid Build Coastguard Worker newEXIF.CopyGPSFrom (oldEXIF);
5158*fd1fabb7SAndroid Build Coastguard Worker
5159*fd1fabb7SAndroid Build Coastguard Worker // Remove exif info from XMP.
5160*fd1fabb7SAndroid Build Coastguard Worker
5161*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (XMP_NS_EXIF);
5162*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (XMP_NS_AUX);
5163*fd1fabb7SAndroid Build Coastguard Worker
5164*fd1fabb7SAndroid Build Coastguard Worker // Remove Camera Raw info
5165*fd1fabb7SAndroid Build Coastguard Worker
5166*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (XMP_NS_CRS);
5167*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (XMP_NS_CRSS);
5168*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (XMP_NS_CRX);
5169*fd1fabb7SAndroid Build Coastguard Worker
5170*fd1fabb7SAndroid Build Coastguard Worker // Remove DocOps history, since it contains the original
5171*fd1fabb7SAndroid Build Coastguard Worker // camera format.
5172*fd1fabb7SAndroid Build Coastguard Worker
5173*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_MM, "History");
5174*fd1fabb7SAndroid Build Coastguard Worker
5175*fd1fabb7SAndroid Build Coastguard Worker // MakerNote contains camera info.
5176*fd1fabb7SAndroid Build Coastguard Worker
5177*fd1fabb7SAndroid Build Coastguard Worker metadata.ClearMakerNote ();
5178*fd1fabb7SAndroid Build Coastguard Worker
5179*fd1fabb7SAndroid Build Coastguard Worker }
5180*fd1fabb7SAndroid Build Coastguard Worker
5181*fd1fabb7SAndroid Build Coastguard Worker if (metadataSubset == kMetadataSubset_AllExceptLocationInfo ||
5182*fd1fabb7SAndroid Build Coastguard Worker metadataSubset == kMetadataSubset_AllExceptCameraAndLocation)
5183*fd1fabb7SAndroid Build Coastguard Worker {
5184*fd1fabb7SAndroid Build Coastguard Worker
5185*fd1fabb7SAndroid Build Coastguard Worker // Remove GPS fields.
5186*fd1fabb7SAndroid Build Coastguard Worker
5187*fd1fabb7SAndroid Build Coastguard Worker dng_exif blankExif;
5188*fd1fabb7SAndroid Build Coastguard Worker
5189*fd1fabb7SAndroid Build Coastguard Worker newEXIF.CopyGPSFrom (blankExif);
5190*fd1fabb7SAndroid Build Coastguard Worker
5191*fd1fabb7SAndroid Build Coastguard Worker // Remove MakerNote just in case, because we don't know
5192*fd1fabb7SAndroid Build Coastguard Worker // all of what is in it.
5193*fd1fabb7SAndroid Build Coastguard Worker
5194*fd1fabb7SAndroid Build Coastguard Worker metadata.ClearMakerNote ();
5195*fd1fabb7SAndroid Build Coastguard Worker
5196*fd1fabb7SAndroid Build Coastguard Worker // Remove XMP & IPTC location fields.
5197*fd1fabb7SAndroid Build Coastguard Worker
5198*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_PHOTOSHOP, "City");
5199*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_PHOTOSHOP, "State");
5200*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_PHOTOSHOP, "Country");
5201*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_IPTC, "Location");
5202*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_IPTC, "CountryCode");
5203*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_IPTC_EXT, "LocationCreated");
5204*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_IPTC_EXT, "LocationShown");
5205*fd1fabb7SAndroid Build Coastguard Worker
5206*fd1fabb7SAndroid Build Coastguard Worker }
5207*fd1fabb7SAndroid Build Coastguard Worker
5208*fd1fabb7SAndroid Build Coastguard Worker }
5209*fd1fabb7SAndroid Build Coastguard Worker
5210*fd1fabb7SAndroid Build Coastguard Worker // Rebuild the legacy IPTC block, if needed.
5211*fd1fabb7SAndroid Build Coastguard Worker
5212*fd1fabb7SAndroid Build Coastguard Worker bool isTIFF = (strcmp (dstMIMI, "image/tiff") == 0);
5213*fd1fabb7SAndroid Build Coastguard Worker bool isDNG = (strcmp (dstMIMI, "image/dng" ) == 0);
5214*fd1fabb7SAndroid Build Coastguard Worker
5215*fd1fabb7SAndroid Build Coastguard Worker if (!isDNG)
5216*fd1fabb7SAndroid Build Coastguard Worker {
5217*fd1fabb7SAndroid Build Coastguard Worker
5218*fd1fabb7SAndroid Build Coastguard Worker metadata.RebuildIPTC (host.Allocator (),
5219*fd1fabb7SAndroid Build Coastguard Worker isTIFF);
5220*fd1fabb7SAndroid Build Coastguard Worker
5221*fd1fabb7SAndroid Build Coastguard Worker }
5222*fd1fabb7SAndroid Build Coastguard Worker
5223*fd1fabb7SAndroid Build Coastguard Worker else
5224*fd1fabb7SAndroid Build Coastguard Worker {
5225*fd1fabb7SAndroid Build Coastguard Worker
5226*fd1fabb7SAndroid Build Coastguard Worker metadata.ClearIPTC ();
5227*fd1fabb7SAndroid Build Coastguard Worker
5228*fd1fabb7SAndroid Build Coastguard Worker }
5229*fd1fabb7SAndroid Build Coastguard Worker
5230*fd1fabb7SAndroid Build Coastguard Worker // Clear format related XMP.
5231*fd1fabb7SAndroid Build Coastguard Worker
5232*fd1fabb7SAndroid Build Coastguard Worker newXMP.ClearOrientation ();
5233*fd1fabb7SAndroid Build Coastguard Worker
5234*fd1fabb7SAndroid Build Coastguard Worker newXMP.ClearImageInfo ();
5235*fd1fabb7SAndroid Build Coastguard Worker
5236*fd1fabb7SAndroid Build Coastguard Worker newXMP.RemoveProperties (XMP_NS_DNG);
5237*fd1fabb7SAndroid Build Coastguard Worker
5238*fd1fabb7SAndroid Build Coastguard Worker // All the formats we care about already keep the IPTC digest
5239*fd1fabb7SAndroid Build Coastguard Worker // elsewhere, do we don't need to write it to the XMP.
5240*fd1fabb7SAndroid Build Coastguard Worker
5241*fd1fabb7SAndroid Build Coastguard Worker newXMP.ClearIPTCDigest ();
5242*fd1fabb7SAndroid Build Coastguard Worker
5243*fd1fabb7SAndroid Build Coastguard Worker // Make sure that sidecar specific tags never get written to files.
5244*fd1fabb7SAndroid Build Coastguard Worker
5245*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_PHOTOSHOP, "SidecarForExtension");
5246*fd1fabb7SAndroid Build Coastguard Worker newXMP.Remove (XMP_NS_PHOTOSHOP, "EmbeddedXMPDigest");
5247*fd1fabb7SAndroid Build Coastguard Worker
5248*fd1fabb7SAndroid Build Coastguard Worker }
5249*fd1fabb7SAndroid Build Coastguard Worker
5250*fd1fabb7SAndroid Build Coastguard Worker #endif
5251*fd1fabb7SAndroid Build Coastguard Worker
5252*fd1fabb7SAndroid Build Coastguard Worker }
5253*fd1fabb7SAndroid Build Coastguard Worker
5254*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
5255*fd1fabb7SAndroid Build Coastguard Worker
WriteTIFF(dng_host & host,dng_stream & stream,const dng_image & image,uint32 photometricInterpretation,uint32 compression,dng_negative * negative,const dng_color_space * space,const dng_resolution * resolution,const dng_jpeg_preview * thumbnail,const dng_memory_block * imageResources,dng_metadata_subset metadataSubset)5256*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteTIFF (dng_host &host,
5257*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
5258*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
5259*fd1fabb7SAndroid Build Coastguard Worker uint32 photometricInterpretation,
5260*fd1fabb7SAndroid Build Coastguard Worker uint32 compression,
5261*fd1fabb7SAndroid Build Coastguard Worker dng_negative *negative,
5262*fd1fabb7SAndroid Build Coastguard Worker const dng_color_space *space,
5263*fd1fabb7SAndroid Build Coastguard Worker const dng_resolution *resolution,
5264*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *thumbnail,
5265*fd1fabb7SAndroid Build Coastguard Worker const dng_memory_block *imageResources,
5266*fd1fabb7SAndroid Build Coastguard Worker dng_metadata_subset metadataSubset)
5267*fd1fabb7SAndroid Build Coastguard Worker {
5268*fd1fabb7SAndroid Build Coastguard Worker
5269*fd1fabb7SAndroid Build Coastguard Worker WriteTIFF (host,
5270*fd1fabb7SAndroid Build Coastguard Worker stream,
5271*fd1fabb7SAndroid Build Coastguard Worker image,
5272*fd1fabb7SAndroid Build Coastguard Worker photometricInterpretation,
5273*fd1fabb7SAndroid Build Coastguard Worker compression,
5274*fd1fabb7SAndroid Build Coastguard Worker negative ? &(negative->Metadata ()) : NULL,
5275*fd1fabb7SAndroid Build Coastguard Worker space,
5276*fd1fabb7SAndroid Build Coastguard Worker resolution,
5277*fd1fabb7SAndroid Build Coastguard Worker thumbnail,
5278*fd1fabb7SAndroid Build Coastguard Worker imageResources,
5279*fd1fabb7SAndroid Build Coastguard Worker metadataSubset);
5280*fd1fabb7SAndroid Build Coastguard Worker
5281*fd1fabb7SAndroid Build Coastguard Worker }
5282*fd1fabb7SAndroid Build Coastguard Worker
5283*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
5284*fd1fabb7SAndroid Build Coastguard Worker
WriteTIFF(dng_host & host,dng_stream & stream,const dng_image & image,uint32 photometricInterpretation,uint32 compression,const dng_metadata * metadata,const dng_color_space * space,const dng_resolution * resolution,const dng_jpeg_preview * thumbnail,const dng_memory_block * imageResources,dng_metadata_subset metadataSubset)5285*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteTIFF (dng_host &host,
5286*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
5287*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
5288*fd1fabb7SAndroid Build Coastguard Worker uint32 photometricInterpretation,
5289*fd1fabb7SAndroid Build Coastguard Worker uint32 compression,
5290*fd1fabb7SAndroid Build Coastguard Worker const dng_metadata *metadata,
5291*fd1fabb7SAndroid Build Coastguard Worker const dng_color_space *space,
5292*fd1fabb7SAndroid Build Coastguard Worker const dng_resolution *resolution,
5293*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *thumbnail,
5294*fd1fabb7SAndroid Build Coastguard Worker const dng_memory_block *imageResources,
5295*fd1fabb7SAndroid Build Coastguard Worker dng_metadata_subset metadataSubset)
5296*fd1fabb7SAndroid Build Coastguard Worker {
5297*fd1fabb7SAndroid Build Coastguard Worker
5298*fd1fabb7SAndroid Build Coastguard Worker const void *profileData = NULL;
5299*fd1fabb7SAndroid Build Coastguard Worker uint32 profileSize = 0;
5300*fd1fabb7SAndroid Build Coastguard Worker
5301*fd1fabb7SAndroid Build Coastguard Worker const uint8 *data = NULL;
5302*fd1fabb7SAndroid Build Coastguard Worker uint32 size = 0;
5303*fd1fabb7SAndroid Build Coastguard Worker
5304*fd1fabb7SAndroid Build Coastguard Worker if (space && space->ICCProfile (size, data))
5305*fd1fabb7SAndroid Build Coastguard Worker {
5306*fd1fabb7SAndroid Build Coastguard Worker
5307*fd1fabb7SAndroid Build Coastguard Worker profileData = data;
5308*fd1fabb7SAndroid Build Coastguard Worker profileSize = size;
5309*fd1fabb7SAndroid Build Coastguard Worker
5310*fd1fabb7SAndroid Build Coastguard Worker }
5311*fd1fabb7SAndroid Build Coastguard Worker
5312*fd1fabb7SAndroid Build Coastguard Worker WriteTIFFWithProfile (host,
5313*fd1fabb7SAndroid Build Coastguard Worker stream,
5314*fd1fabb7SAndroid Build Coastguard Worker image,
5315*fd1fabb7SAndroid Build Coastguard Worker photometricInterpretation,
5316*fd1fabb7SAndroid Build Coastguard Worker compression,
5317*fd1fabb7SAndroid Build Coastguard Worker metadata,
5318*fd1fabb7SAndroid Build Coastguard Worker profileData,
5319*fd1fabb7SAndroid Build Coastguard Worker profileSize,
5320*fd1fabb7SAndroid Build Coastguard Worker resolution,
5321*fd1fabb7SAndroid Build Coastguard Worker thumbnail,
5322*fd1fabb7SAndroid Build Coastguard Worker imageResources,
5323*fd1fabb7SAndroid Build Coastguard Worker metadataSubset);
5324*fd1fabb7SAndroid Build Coastguard Worker
5325*fd1fabb7SAndroid Build Coastguard Worker }
5326*fd1fabb7SAndroid Build Coastguard Worker
5327*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
5328*fd1fabb7SAndroid Build Coastguard Worker
WriteTIFFWithProfile(dng_host & host,dng_stream & stream,const dng_image & image,uint32 photometricInterpretation,uint32 compression,dng_negative * negative,const void * profileData,uint32 profileSize,const dng_resolution * resolution,const dng_jpeg_preview * thumbnail,const dng_memory_block * imageResources,dng_metadata_subset metadataSubset)5329*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteTIFFWithProfile (dng_host &host,
5330*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
5331*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
5332*fd1fabb7SAndroid Build Coastguard Worker uint32 photometricInterpretation,
5333*fd1fabb7SAndroid Build Coastguard Worker uint32 compression,
5334*fd1fabb7SAndroid Build Coastguard Worker dng_negative *negative,
5335*fd1fabb7SAndroid Build Coastguard Worker const void *profileData,
5336*fd1fabb7SAndroid Build Coastguard Worker uint32 profileSize,
5337*fd1fabb7SAndroid Build Coastguard Worker const dng_resolution *resolution,
5338*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *thumbnail,
5339*fd1fabb7SAndroid Build Coastguard Worker const dng_memory_block *imageResources,
5340*fd1fabb7SAndroid Build Coastguard Worker dng_metadata_subset metadataSubset)
5341*fd1fabb7SAndroid Build Coastguard Worker {
5342*fd1fabb7SAndroid Build Coastguard Worker
5343*fd1fabb7SAndroid Build Coastguard Worker WriteTIFFWithProfile (host,
5344*fd1fabb7SAndroid Build Coastguard Worker stream,
5345*fd1fabb7SAndroid Build Coastguard Worker image,
5346*fd1fabb7SAndroid Build Coastguard Worker photometricInterpretation,
5347*fd1fabb7SAndroid Build Coastguard Worker compression,
5348*fd1fabb7SAndroid Build Coastguard Worker negative ? &(negative->Metadata ()) : NULL,
5349*fd1fabb7SAndroid Build Coastguard Worker profileData,
5350*fd1fabb7SAndroid Build Coastguard Worker profileSize,
5351*fd1fabb7SAndroid Build Coastguard Worker resolution,
5352*fd1fabb7SAndroid Build Coastguard Worker thumbnail,
5353*fd1fabb7SAndroid Build Coastguard Worker imageResources,
5354*fd1fabb7SAndroid Build Coastguard Worker metadataSubset);
5355*fd1fabb7SAndroid Build Coastguard Worker
5356*fd1fabb7SAndroid Build Coastguard Worker }
5357*fd1fabb7SAndroid Build Coastguard Worker
5358*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
5359*fd1fabb7SAndroid Build Coastguard Worker
WriteTIFFWithProfile(dng_host & host,dng_stream & stream,const dng_image & image,uint32 photometricInterpretation,uint32 compression,const dng_metadata * constMetadata,const void * profileData,uint32 profileSize,const dng_resolution * resolution,const dng_jpeg_preview * thumbnail,const dng_memory_block * imageResources,dng_metadata_subset metadataSubset)5360*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteTIFFWithProfile (dng_host &host,
5361*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
5362*fd1fabb7SAndroid Build Coastguard Worker const dng_image &image,
5363*fd1fabb7SAndroid Build Coastguard Worker uint32 photometricInterpretation,
5364*fd1fabb7SAndroid Build Coastguard Worker uint32 compression,
5365*fd1fabb7SAndroid Build Coastguard Worker const dng_metadata *constMetadata,
5366*fd1fabb7SAndroid Build Coastguard Worker const void *profileData,
5367*fd1fabb7SAndroid Build Coastguard Worker uint32 profileSize,
5368*fd1fabb7SAndroid Build Coastguard Worker const dng_resolution *resolution,
5369*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *thumbnail,
5370*fd1fabb7SAndroid Build Coastguard Worker const dng_memory_block *imageResources,
5371*fd1fabb7SAndroid Build Coastguard Worker dng_metadata_subset metadataSubset)
5372*fd1fabb7SAndroid Build Coastguard Worker {
5373*fd1fabb7SAndroid Build Coastguard Worker
5374*fd1fabb7SAndroid Build Coastguard Worker uint32 j;
5375*fd1fabb7SAndroid Build Coastguard Worker
5376*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_metadata> metadata;
5377*fd1fabb7SAndroid Build Coastguard Worker
5378*fd1fabb7SAndroid Build Coastguard Worker if (constMetadata)
5379*fd1fabb7SAndroid Build Coastguard Worker {
5380*fd1fabb7SAndroid Build Coastguard Worker
5381*fd1fabb7SAndroid Build Coastguard Worker metadata.Reset (constMetadata->Clone (host.Allocator ()));
5382*fd1fabb7SAndroid Build Coastguard Worker
5383*fd1fabb7SAndroid Build Coastguard Worker CleanUpMetadata (host,
5384*fd1fabb7SAndroid Build Coastguard Worker *metadata,
5385*fd1fabb7SAndroid Build Coastguard Worker metadataSubset,
5386*fd1fabb7SAndroid Build Coastguard Worker "image/tiff");
5387*fd1fabb7SAndroid Build Coastguard Worker
5388*fd1fabb7SAndroid Build Coastguard Worker }
5389*fd1fabb7SAndroid Build Coastguard Worker
5390*fd1fabb7SAndroid Build Coastguard Worker dng_ifd ifd;
5391*fd1fabb7SAndroid Build Coastguard Worker
5392*fd1fabb7SAndroid Build Coastguard Worker ifd.fNewSubFileType = sfMainImage;
5393*fd1fabb7SAndroid Build Coastguard Worker
5394*fd1fabb7SAndroid Build Coastguard Worker ifd.fImageWidth = image.Bounds ().W ();
5395*fd1fabb7SAndroid Build Coastguard Worker ifd.fImageLength = image.Bounds ().H ();
5396*fd1fabb7SAndroid Build Coastguard Worker
5397*fd1fabb7SAndroid Build Coastguard Worker ifd.fSamplesPerPixel = image.Planes ();
5398*fd1fabb7SAndroid Build Coastguard Worker
5399*fd1fabb7SAndroid Build Coastguard Worker ifd.fBitsPerSample [0] = TagTypeSize (image.PixelType ()) * 8;
5400*fd1fabb7SAndroid Build Coastguard Worker
5401*fd1fabb7SAndroid Build Coastguard Worker for (j = 1; j < ifd.fSamplesPerPixel; j++)
5402*fd1fabb7SAndroid Build Coastguard Worker {
5403*fd1fabb7SAndroid Build Coastguard Worker ifd.fBitsPerSample [j] = ifd.fBitsPerSample [0];
5404*fd1fabb7SAndroid Build Coastguard Worker }
5405*fd1fabb7SAndroid Build Coastguard Worker
5406*fd1fabb7SAndroid Build Coastguard Worker ifd.fPhotometricInterpretation = photometricInterpretation;
5407*fd1fabb7SAndroid Build Coastguard Worker
5408*fd1fabb7SAndroid Build Coastguard Worker ifd.fCompression = compression;
5409*fd1fabb7SAndroid Build Coastguard Worker
5410*fd1fabb7SAndroid Build Coastguard Worker if (ifd.fCompression == ccUncompressed)
5411*fd1fabb7SAndroid Build Coastguard Worker {
5412*fd1fabb7SAndroid Build Coastguard Worker
5413*fd1fabb7SAndroid Build Coastguard Worker ifd.SetSingleStrip ();
5414*fd1fabb7SAndroid Build Coastguard Worker
5415*fd1fabb7SAndroid Build Coastguard Worker }
5416*fd1fabb7SAndroid Build Coastguard Worker
5417*fd1fabb7SAndroid Build Coastguard Worker else
5418*fd1fabb7SAndroid Build Coastguard Worker {
5419*fd1fabb7SAndroid Build Coastguard Worker
5420*fd1fabb7SAndroid Build Coastguard Worker ifd.FindStripSize (128 * 1024);
5421*fd1fabb7SAndroid Build Coastguard Worker
5422*fd1fabb7SAndroid Build Coastguard Worker ifd.fPredictor = cpHorizontalDifference;
5423*fd1fabb7SAndroid Build Coastguard Worker
5424*fd1fabb7SAndroid Build Coastguard Worker }
5425*fd1fabb7SAndroid Build Coastguard Worker
5426*fd1fabb7SAndroid Build Coastguard Worker uint32 extraSamples = 0;
5427*fd1fabb7SAndroid Build Coastguard Worker
5428*fd1fabb7SAndroid Build Coastguard Worker switch (photometricInterpretation)
5429*fd1fabb7SAndroid Build Coastguard Worker {
5430*fd1fabb7SAndroid Build Coastguard Worker
5431*fd1fabb7SAndroid Build Coastguard Worker case piBlackIsZero:
5432*fd1fabb7SAndroid Build Coastguard Worker {
5433*fd1fabb7SAndroid Build Coastguard Worker extraSamples = image.Planes () - 1;
5434*fd1fabb7SAndroid Build Coastguard Worker break;
5435*fd1fabb7SAndroid Build Coastguard Worker }
5436*fd1fabb7SAndroid Build Coastguard Worker
5437*fd1fabb7SAndroid Build Coastguard Worker case piRGB:
5438*fd1fabb7SAndroid Build Coastguard Worker {
5439*fd1fabb7SAndroid Build Coastguard Worker extraSamples = image.Planes () - 3;
5440*fd1fabb7SAndroid Build Coastguard Worker break;
5441*fd1fabb7SAndroid Build Coastguard Worker }
5442*fd1fabb7SAndroid Build Coastguard Worker
5443*fd1fabb7SAndroid Build Coastguard Worker default:
5444*fd1fabb7SAndroid Build Coastguard Worker break;
5445*fd1fabb7SAndroid Build Coastguard Worker
5446*fd1fabb7SAndroid Build Coastguard Worker }
5447*fd1fabb7SAndroid Build Coastguard Worker
5448*fd1fabb7SAndroid Build Coastguard Worker ifd.fExtraSamplesCount = extraSamples;
5449*fd1fabb7SAndroid Build Coastguard Worker
5450*fd1fabb7SAndroid Build Coastguard Worker if (image.PixelType () == ttFloat)
5451*fd1fabb7SAndroid Build Coastguard Worker {
5452*fd1fabb7SAndroid Build Coastguard Worker
5453*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < ifd.fSamplesPerPixel; j++)
5454*fd1fabb7SAndroid Build Coastguard Worker {
5455*fd1fabb7SAndroid Build Coastguard Worker ifd.fSampleFormat [j] = sfFloatingPoint;
5456*fd1fabb7SAndroid Build Coastguard Worker }
5457*fd1fabb7SAndroid Build Coastguard Worker
5458*fd1fabb7SAndroid Build Coastguard Worker }
5459*fd1fabb7SAndroid Build Coastguard Worker
5460*fd1fabb7SAndroid Build Coastguard Worker dng_tiff_directory mainIFD;
5461*fd1fabb7SAndroid Build Coastguard Worker
5462*fd1fabb7SAndroid Build Coastguard Worker dng_basic_tag_set basic (mainIFD, ifd);
5463*fd1fabb7SAndroid Build Coastguard Worker
5464*fd1fabb7SAndroid Build Coastguard Worker // Resolution.
5465*fd1fabb7SAndroid Build Coastguard Worker
5466*fd1fabb7SAndroid Build Coastguard Worker dng_resolution res;
5467*fd1fabb7SAndroid Build Coastguard Worker
5468*fd1fabb7SAndroid Build Coastguard Worker if (resolution)
5469*fd1fabb7SAndroid Build Coastguard Worker {
5470*fd1fabb7SAndroid Build Coastguard Worker res = *resolution;
5471*fd1fabb7SAndroid Build Coastguard Worker }
5472*fd1fabb7SAndroid Build Coastguard Worker
5473*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagXResolution (tcXResolution, res.fXResolution);
5474*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagYResolution (tcYResolution, res.fYResolution);
5475*fd1fabb7SAndroid Build Coastguard Worker
5476*fd1fabb7SAndroid Build Coastguard Worker tag_uint16 tagResolutionUnit (tcResolutionUnit, res.fResolutionUnit);
5477*fd1fabb7SAndroid Build Coastguard Worker
5478*fd1fabb7SAndroid Build Coastguard Worker if (resolution)
5479*fd1fabb7SAndroid Build Coastguard Worker {
5480*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagXResolution );
5481*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagYResolution );
5482*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagResolutionUnit);
5483*fd1fabb7SAndroid Build Coastguard Worker }
5484*fd1fabb7SAndroid Build Coastguard Worker
5485*fd1fabb7SAndroid Build Coastguard Worker // ICC Profile.
5486*fd1fabb7SAndroid Build Coastguard Worker
5487*fd1fabb7SAndroid Build Coastguard Worker tag_icc_profile iccProfileTag (profileData, profileSize);
5488*fd1fabb7SAndroid Build Coastguard Worker
5489*fd1fabb7SAndroid Build Coastguard Worker if (iccProfileTag.Count ())
5490*fd1fabb7SAndroid Build Coastguard Worker {
5491*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&iccProfileTag);
5492*fd1fabb7SAndroid Build Coastguard Worker }
5493*fd1fabb7SAndroid Build Coastguard Worker
5494*fd1fabb7SAndroid Build Coastguard Worker // XMP metadata.
5495*fd1fabb7SAndroid Build Coastguard Worker
5496*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
5497*fd1fabb7SAndroid Build Coastguard Worker
5498*fd1fabb7SAndroid Build Coastguard Worker tag_xmp tagXMP (metadata.Get () ? metadata->GetXMP () : NULL);
5499*fd1fabb7SAndroid Build Coastguard Worker
5500*fd1fabb7SAndroid Build Coastguard Worker if (tagXMP.Count ())
5501*fd1fabb7SAndroid Build Coastguard Worker {
5502*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagXMP);
5503*fd1fabb7SAndroid Build Coastguard Worker }
5504*fd1fabb7SAndroid Build Coastguard Worker
5505*fd1fabb7SAndroid Build Coastguard Worker #endif
5506*fd1fabb7SAndroid Build Coastguard Worker
5507*fd1fabb7SAndroid Build Coastguard Worker // IPTC metadata.
5508*fd1fabb7SAndroid Build Coastguard Worker
5509*fd1fabb7SAndroid Build Coastguard Worker tag_iptc tagIPTC (metadata.Get () ? metadata->IPTCData () : NULL,
5510*fd1fabb7SAndroid Build Coastguard Worker metadata.Get () ? metadata->IPTCLength () : 0);
5511*fd1fabb7SAndroid Build Coastguard Worker
5512*fd1fabb7SAndroid Build Coastguard Worker if (tagIPTC.Count ())
5513*fd1fabb7SAndroid Build Coastguard Worker {
5514*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagIPTC);
5515*fd1fabb7SAndroid Build Coastguard Worker }
5516*fd1fabb7SAndroid Build Coastguard Worker
5517*fd1fabb7SAndroid Build Coastguard Worker // Adobe data (thumbnail and IPTC digest)
5518*fd1fabb7SAndroid Build Coastguard Worker
5519*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> adobeData (BuildAdobeData (host,
5520*fd1fabb7SAndroid Build Coastguard Worker metadata.Get (),
5521*fd1fabb7SAndroid Build Coastguard Worker thumbnail,
5522*fd1fabb7SAndroid Build Coastguard Worker imageResources));
5523*fd1fabb7SAndroid Build Coastguard Worker
5524*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagAdobe (tcAdobeData,
5525*fd1fabb7SAndroid Build Coastguard Worker adobeData->Buffer_uint8 (),
5526*fd1fabb7SAndroid Build Coastguard Worker adobeData->LogicalSize ());
5527*fd1fabb7SAndroid Build Coastguard Worker
5528*fd1fabb7SAndroid Build Coastguard Worker if (tagAdobe.Count ())
5529*fd1fabb7SAndroid Build Coastguard Worker {
5530*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagAdobe);
5531*fd1fabb7SAndroid Build Coastguard Worker }
5532*fd1fabb7SAndroid Build Coastguard Worker
5533*fd1fabb7SAndroid Build Coastguard Worker // Exif metadata.
5534*fd1fabb7SAndroid Build Coastguard Worker
5535*fd1fabb7SAndroid Build Coastguard Worker exif_tag_set exifSet (mainIFD,
5536*fd1fabb7SAndroid Build Coastguard Worker metadata.Get () && metadata->GetExif () ? *metadata->GetExif ()
5537*fd1fabb7SAndroid Build Coastguard Worker : dng_exif (),
5538*fd1fabb7SAndroid Build Coastguard Worker metadata.Get () ? metadata->IsMakerNoteSafe () : false,
5539*fd1fabb7SAndroid Build Coastguard Worker metadata.Get () ? metadata->MakerNoteData () : NULL,
5540*fd1fabb7SAndroid Build Coastguard Worker metadata.Get () ? metadata->MakerNoteLength () : 0,
5541*fd1fabb7SAndroid Build Coastguard Worker false);
5542*fd1fabb7SAndroid Build Coastguard Worker
5543*fd1fabb7SAndroid Build Coastguard Worker // Find offset to main image data.
5544*fd1fabb7SAndroid Build Coastguard Worker
5545*fd1fabb7SAndroid Build Coastguard Worker uint32 offsetMainIFD = 8;
5546*fd1fabb7SAndroid Build Coastguard Worker
5547*fd1fabb7SAndroid Build Coastguard Worker uint32 offsetExifData = offsetMainIFD + mainIFD.Size ();
5548*fd1fabb7SAndroid Build Coastguard Worker
5549*fd1fabb7SAndroid Build Coastguard Worker exifSet.Locate (offsetExifData);
5550*fd1fabb7SAndroid Build Coastguard Worker
5551*fd1fabb7SAndroid Build Coastguard Worker uint32 offsetMainData = offsetExifData + exifSet.Size ();
5552*fd1fabb7SAndroid Build Coastguard Worker
5553*fd1fabb7SAndroid Build Coastguard Worker stream.SetWritePosition (offsetMainData);
5554*fd1fabb7SAndroid Build Coastguard Worker
5555*fd1fabb7SAndroid Build Coastguard Worker // Write the main image data.
5556*fd1fabb7SAndroid Build Coastguard Worker
5557*fd1fabb7SAndroid Build Coastguard Worker WriteImage (host,
5558*fd1fabb7SAndroid Build Coastguard Worker ifd,
5559*fd1fabb7SAndroid Build Coastguard Worker basic,
5560*fd1fabb7SAndroid Build Coastguard Worker stream,
5561*fd1fabb7SAndroid Build Coastguard Worker image);
5562*fd1fabb7SAndroid Build Coastguard Worker
5563*fd1fabb7SAndroid Build Coastguard Worker // Trim the file to this length.
5564*fd1fabb7SAndroid Build Coastguard Worker
5565*fd1fabb7SAndroid Build Coastguard Worker stream.SetLength (stream.Position ());
5566*fd1fabb7SAndroid Build Coastguard Worker
5567*fd1fabb7SAndroid Build Coastguard Worker // TIFF has a 4G size limit.
5568*fd1fabb7SAndroid Build Coastguard Worker
5569*fd1fabb7SAndroid Build Coastguard Worker if (stream.Length () > 0x0FFFFFFFFL)
5570*fd1fabb7SAndroid Build Coastguard Worker {
5571*fd1fabb7SAndroid Build Coastguard Worker ThrowImageTooBigTIFF ();
5572*fd1fabb7SAndroid Build Coastguard Worker }
5573*fd1fabb7SAndroid Build Coastguard Worker
5574*fd1fabb7SAndroid Build Coastguard Worker // Write TIFF Header.
5575*fd1fabb7SAndroid Build Coastguard Worker
5576*fd1fabb7SAndroid Build Coastguard Worker stream.SetWritePosition (0);
5577*fd1fabb7SAndroid Build Coastguard Worker
5578*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (stream.BigEndian () ? byteOrderMM : byteOrderII);
5579*fd1fabb7SAndroid Build Coastguard Worker
5580*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (42);
5581*fd1fabb7SAndroid Build Coastguard Worker
5582*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (offsetMainIFD);
5583*fd1fabb7SAndroid Build Coastguard Worker
5584*fd1fabb7SAndroid Build Coastguard Worker // Write the IFDs.
5585*fd1fabb7SAndroid Build Coastguard Worker
5586*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Put (stream);
5587*fd1fabb7SAndroid Build Coastguard Worker
5588*fd1fabb7SAndroid Build Coastguard Worker exifSet.Put (stream);
5589*fd1fabb7SAndroid Build Coastguard Worker
5590*fd1fabb7SAndroid Build Coastguard Worker stream.Flush ();
5591*fd1fabb7SAndroid Build Coastguard Worker
5592*fd1fabb7SAndroid Build Coastguard Worker }
5593*fd1fabb7SAndroid Build Coastguard Worker
5594*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
5595*fd1fabb7SAndroid Build Coastguard Worker
WriteDNG(dng_host & host,dng_stream & stream,dng_negative & negative,const dng_preview_list * previewList,uint32 maxBackwardVersion,bool uncompressed)5596*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteDNG (dng_host &host,
5597*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
5598*fd1fabb7SAndroid Build Coastguard Worker dng_negative &negative,
5599*fd1fabb7SAndroid Build Coastguard Worker const dng_preview_list *previewList,
5600*fd1fabb7SAndroid Build Coastguard Worker uint32 maxBackwardVersion,
5601*fd1fabb7SAndroid Build Coastguard Worker bool uncompressed)
5602*fd1fabb7SAndroid Build Coastguard Worker {
5603*fd1fabb7SAndroid Build Coastguard Worker
5604*fd1fabb7SAndroid Build Coastguard Worker WriteDNG (host,
5605*fd1fabb7SAndroid Build Coastguard Worker stream,
5606*fd1fabb7SAndroid Build Coastguard Worker negative,
5607*fd1fabb7SAndroid Build Coastguard Worker negative.Metadata (),
5608*fd1fabb7SAndroid Build Coastguard Worker previewList,
5609*fd1fabb7SAndroid Build Coastguard Worker maxBackwardVersion,
5610*fd1fabb7SAndroid Build Coastguard Worker uncompressed);
5611*fd1fabb7SAndroid Build Coastguard Worker
5612*fd1fabb7SAndroid Build Coastguard Worker }
5613*fd1fabb7SAndroid Build Coastguard Worker
5614*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
5615*fd1fabb7SAndroid Build Coastguard Worker
WriteDNG(dng_host & host,dng_stream & stream,const dng_negative & negative,const dng_metadata & constMetadata,const dng_preview_list * previewList,uint32 maxBackwardVersion,bool uncompressed)5616*fd1fabb7SAndroid Build Coastguard Worker void dng_image_writer::WriteDNG (dng_host &host,
5617*fd1fabb7SAndroid Build Coastguard Worker dng_stream &stream,
5618*fd1fabb7SAndroid Build Coastguard Worker const dng_negative &negative,
5619*fd1fabb7SAndroid Build Coastguard Worker const dng_metadata &constMetadata,
5620*fd1fabb7SAndroid Build Coastguard Worker const dng_preview_list *previewList,
5621*fd1fabb7SAndroid Build Coastguard Worker uint32 maxBackwardVersion,
5622*fd1fabb7SAndroid Build Coastguard Worker bool uncompressed)
5623*fd1fabb7SAndroid Build Coastguard Worker {
5624*fd1fabb7SAndroid Build Coastguard Worker
5625*fd1fabb7SAndroid Build Coastguard Worker uint32 j;
5626*fd1fabb7SAndroid Build Coastguard Worker
5627*fd1fabb7SAndroid Build Coastguard Worker // Clean up metadata per MWG recommendations.
5628*fd1fabb7SAndroid Build Coastguard Worker
5629*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_metadata> metadata (constMetadata.Clone (host.Allocator ()));
5630*fd1fabb7SAndroid Build Coastguard Worker
5631*fd1fabb7SAndroid Build Coastguard Worker CleanUpMetadata (host,
5632*fd1fabb7SAndroid Build Coastguard Worker *metadata,
5633*fd1fabb7SAndroid Build Coastguard Worker kMetadataSubset_All,
5634*fd1fabb7SAndroid Build Coastguard Worker "image/dng");
5635*fd1fabb7SAndroid Build Coastguard Worker
5636*fd1fabb7SAndroid Build Coastguard Worker // Figure out the compression to use. Most of the time this is lossless
5637*fd1fabb7SAndroid Build Coastguard Worker // JPEG.
5638*fd1fabb7SAndroid Build Coastguard Worker
5639*fd1fabb7SAndroid Build Coastguard Worker uint32 compression = uncompressed ? ccUncompressed : ccJPEG;
5640*fd1fabb7SAndroid Build Coastguard Worker
5641*fd1fabb7SAndroid Build Coastguard Worker // Was the the original file lossy JPEG compressed?
5642*fd1fabb7SAndroid Build Coastguard Worker
5643*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_image *rawJPEGImage = negative.RawJPEGImage ();
5644*fd1fabb7SAndroid Build Coastguard Worker
5645*fd1fabb7SAndroid Build Coastguard Worker // If so, can we save it using the requested compression and DNG version?
5646*fd1fabb7SAndroid Build Coastguard Worker
5647*fd1fabb7SAndroid Build Coastguard Worker if (uncompressed || maxBackwardVersion < dngVersion_1_4_0_0)
5648*fd1fabb7SAndroid Build Coastguard Worker {
5649*fd1fabb7SAndroid Build Coastguard Worker
5650*fd1fabb7SAndroid Build Coastguard Worker if (rawJPEGImage || negative.RawJPEGImageDigest ().IsValid ())
5651*fd1fabb7SAndroid Build Coastguard Worker {
5652*fd1fabb7SAndroid Build Coastguard Worker
5653*fd1fabb7SAndroid Build Coastguard Worker rawJPEGImage = NULL;
5654*fd1fabb7SAndroid Build Coastguard Worker
5655*fd1fabb7SAndroid Build Coastguard Worker negative.ClearRawJPEGImageDigest ();
5656*fd1fabb7SAndroid Build Coastguard Worker
5657*fd1fabb7SAndroid Build Coastguard Worker negative.ClearRawImageDigest ();
5658*fd1fabb7SAndroid Build Coastguard Worker
5659*fd1fabb7SAndroid Build Coastguard Worker }
5660*fd1fabb7SAndroid Build Coastguard Worker
5661*fd1fabb7SAndroid Build Coastguard Worker }
5662*fd1fabb7SAndroid Build Coastguard Worker
5663*fd1fabb7SAndroid Build Coastguard Worker else if (rawJPEGImage)
5664*fd1fabb7SAndroid Build Coastguard Worker {
5665*fd1fabb7SAndroid Build Coastguard Worker
5666*fd1fabb7SAndroid Build Coastguard Worker compression = ccLossyJPEG;
5667*fd1fabb7SAndroid Build Coastguard Worker
5668*fd1fabb7SAndroid Build Coastguard Worker }
5669*fd1fabb7SAndroid Build Coastguard Worker
5670*fd1fabb7SAndroid Build Coastguard Worker // Are we saving the original size tags?
5671*fd1fabb7SAndroid Build Coastguard Worker
5672*fd1fabb7SAndroid Build Coastguard Worker bool saveOriginalDefaultFinalSize = false;
5673*fd1fabb7SAndroid Build Coastguard Worker bool saveOriginalBestQualityFinalSize = false;
5674*fd1fabb7SAndroid Build Coastguard Worker bool saveOriginalDefaultCropSize = false;
5675*fd1fabb7SAndroid Build Coastguard Worker
5676*fd1fabb7SAndroid Build Coastguard Worker {
5677*fd1fabb7SAndroid Build Coastguard Worker
5678*fd1fabb7SAndroid Build Coastguard Worker // See if we are saving a proxy image.
5679*fd1fabb7SAndroid Build Coastguard Worker
5680*fd1fabb7SAndroid Build Coastguard Worker dng_point defaultFinalSize (negative.DefaultFinalHeight (),
5681*fd1fabb7SAndroid Build Coastguard Worker negative.DefaultFinalWidth ());
5682*fd1fabb7SAndroid Build Coastguard Worker
5683*fd1fabb7SAndroid Build Coastguard Worker saveOriginalDefaultFinalSize = (negative.OriginalDefaultFinalSize () !=
5684*fd1fabb7SAndroid Build Coastguard Worker defaultFinalSize);
5685*fd1fabb7SAndroid Build Coastguard Worker
5686*fd1fabb7SAndroid Build Coastguard Worker if (saveOriginalDefaultFinalSize)
5687*fd1fabb7SAndroid Build Coastguard Worker {
5688*fd1fabb7SAndroid Build Coastguard Worker
5689*fd1fabb7SAndroid Build Coastguard Worker // If the save OriginalDefaultFinalSize tag, this changes the defaults
5690*fd1fabb7SAndroid Build Coastguard Worker // for the OriginalBestQualityFinalSize and OriginalDefaultCropSize tags.
5691*fd1fabb7SAndroid Build Coastguard Worker
5692*fd1fabb7SAndroid Build Coastguard Worker saveOriginalBestQualityFinalSize = (negative.OriginalBestQualityFinalSize () !=
5693*fd1fabb7SAndroid Build Coastguard Worker defaultFinalSize);
5694*fd1fabb7SAndroid Build Coastguard Worker
5695*fd1fabb7SAndroid Build Coastguard Worker saveOriginalDefaultCropSize = (negative.OriginalDefaultCropSizeV () !=
5696*fd1fabb7SAndroid Build Coastguard Worker dng_urational (defaultFinalSize.v, 1)) ||
5697*fd1fabb7SAndroid Build Coastguard Worker (negative.OriginalDefaultCropSizeH () !=
5698*fd1fabb7SAndroid Build Coastguard Worker dng_urational (defaultFinalSize.h, 1));
5699*fd1fabb7SAndroid Build Coastguard Worker
5700*fd1fabb7SAndroid Build Coastguard Worker }
5701*fd1fabb7SAndroid Build Coastguard Worker
5702*fd1fabb7SAndroid Build Coastguard Worker else
5703*fd1fabb7SAndroid Build Coastguard Worker {
5704*fd1fabb7SAndroid Build Coastguard Worker
5705*fd1fabb7SAndroid Build Coastguard Worker // Else these two tags default to the normal non-proxy size image values.
5706*fd1fabb7SAndroid Build Coastguard Worker
5707*fd1fabb7SAndroid Build Coastguard Worker dng_point bestQualityFinalSize (negative.BestQualityFinalHeight (),
5708*fd1fabb7SAndroid Build Coastguard Worker negative.BestQualityFinalWidth ());
5709*fd1fabb7SAndroid Build Coastguard Worker
5710*fd1fabb7SAndroid Build Coastguard Worker saveOriginalBestQualityFinalSize = (negative.OriginalBestQualityFinalSize () !=
5711*fd1fabb7SAndroid Build Coastguard Worker bestQualityFinalSize);
5712*fd1fabb7SAndroid Build Coastguard Worker
5713*fd1fabb7SAndroid Build Coastguard Worker saveOriginalDefaultCropSize = (negative.OriginalDefaultCropSizeV () !=
5714*fd1fabb7SAndroid Build Coastguard Worker negative.DefaultCropSizeV ()) ||
5715*fd1fabb7SAndroid Build Coastguard Worker (negative.OriginalDefaultCropSizeH () !=
5716*fd1fabb7SAndroid Build Coastguard Worker negative.DefaultCropSizeH ());
5717*fd1fabb7SAndroid Build Coastguard Worker
5718*fd1fabb7SAndroid Build Coastguard Worker }
5719*fd1fabb7SAndroid Build Coastguard Worker
5720*fd1fabb7SAndroid Build Coastguard Worker }
5721*fd1fabb7SAndroid Build Coastguard Worker
5722*fd1fabb7SAndroid Build Coastguard Worker // Is this a floating point image that we are saving?
5723*fd1fabb7SAndroid Build Coastguard Worker
5724*fd1fabb7SAndroid Build Coastguard Worker bool isFloatingPoint = (negative.RawImage ().PixelType () == ttFloat);
5725*fd1fabb7SAndroid Build Coastguard Worker
5726*fd1fabb7SAndroid Build Coastguard Worker // Does this image have a transparency mask?
5727*fd1fabb7SAndroid Build Coastguard Worker
5728*fd1fabb7SAndroid Build Coastguard Worker bool hasTransparencyMask = (negative.RawTransparencyMask () != NULL);
5729*fd1fabb7SAndroid Build Coastguard Worker
5730*fd1fabb7SAndroid Build Coastguard Worker // Should we save a compressed 32-bit integer file?
5731*fd1fabb7SAndroid Build Coastguard Worker
5732*fd1fabb7SAndroid Build Coastguard Worker bool isCompressed32BitInteger = (negative.RawImage ().PixelType () == ttLong) &&
5733*fd1fabb7SAndroid Build Coastguard Worker (maxBackwardVersion >= dngVersion_1_4_0_0) &&
5734*fd1fabb7SAndroid Build Coastguard Worker (!uncompressed);
5735*fd1fabb7SAndroid Build Coastguard Worker
5736*fd1fabb7SAndroid Build Coastguard Worker // Figure out what main version to use.
5737*fd1fabb7SAndroid Build Coastguard Worker
5738*fd1fabb7SAndroid Build Coastguard Worker uint32 dngVersion = dngVersion_Current;
5739*fd1fabb7SAndroid Build Coastguard Worker
5740*fd1fabb7SAndroid Build Coastguard Worker // Don't write version 1.4 files unless we actually use some feature of the 1.4 spec.
5741*fd1fabb7SAndroid Build Coastguard Worker
5742*fd1fabb7SAndroid Build Coastguard Worker if (dngVersion == dngVersion_1_4_0_0)
5743*fd1fabb7SAndroid Build Coastguard Worker {
5744*fd1fabb7SAndroid Build Coastguard Worker
5745*fd1fabb7SAndroid Build Coastguard Worker if (!rawJPEGImage &&
5746*fd1fabb7SAndroid Build Coastguard Worker !isFloatingPoint &&
5747*fd1fabb7SAndroid Build Coastguard Worker !hasTransparencyMask &&
5748*fd1fabb7SAndroid Build Coastguard Worker !isCompressed32BitInteger &&
5749*fd1fabb7SAndroid Build Coastguard Worker !saveOriginalDefaultFinalSize &&
5750*fd1fabb7SAndroid Build Coastguard Worker !saveOriginalBestQualityFinalSize &&
5751*fd1fabb7SAndroid Build Coastguard Worker !saveOriginalDefaultCropSize )
5752*fd1fabb7SAndroid Build Coastguard Worker {
5753*fd1fabb7SAndroid Build Coastguard Worker
5754*fd1fabb7SAndroid Build Coastguard Worker dngVersion = dngVersion_1_3_0_0;
5755*fd1fabb7SAndroid Build Coastguard Worker
5756*fd1fabb7SAndroid Build Coastguard Worker }
5757*fd1fabb7SAndroid Build Coastguard Worker
5758*fd1fabb7SAndroid Build Coastguard Worker }
5759*fd1fabb7SAndroid Build Coastguard Worker
5760*fd1fabb7SAndroid Build Coastguard Worker // Figure out what backward version to use.
5761*fd1fabb7SAndroid Build Coastguard Worker
5762*fd1fabb7SAndroid Build Coastguard Worker uint32 dngBackwardVersion = dngVersion_1_1_0_0;
5763*fd1fabb7SAndroid Build Coastguard Worker
5764*fd1fabb7SAndroid Build Coastguard Worker #if defined(qTestRowInterleave) || defined(qTestSubTileBlockRows) || defined(qTestSubTileBlockCols)
5765*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersion = Max_uint32 (dngBackwardVersion, dngVersion_1_2_0_0);
5766*fd1fabb7SAndroid Build Coastguard Worker #endif
5767*fd1fabb7SAndroid Build Coastguard Worker
5768*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersion = Max_uint32 (dngBackwardVersion,
5769*fd1fabb7SAndroid Build Coastguard Worker negative.OpcodeList1 ().MinVersion (false));
5770*fd1fabb7SAndroid Build Coastguard Worker
5771*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersion = Max_uint32 (dngBackwardVersion,
5772*fd1fabb7SAndroid Build Coastguard Worker negative.OpcodeList2 ().MinVersion (false));
5773*fd1fabb7SAndroid Build Coastguard Worker
5774*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersion = Max_uint32 (dngBackwardVersion,
5775*fd1fabb7SAndroid Build Coastguard Worker negative.OpcodeList3 ().MinVersion (false));
5776*fd1fabb7SAndroid Build Coastguard Worker
5777*fd1fabb7SAndroid Build Coastguard Worker if (negative.GetMosaicInfo () &&
5778*fd1fabb7SAndroid Build Coastguard Worker negative.GetMosaicInfo ()->fCFALayout >= 6)
5779*fd1fabb7SAndroid Build Coastguard Worker {
5780*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersion = Max_uint32 (dngBackwardVersion, dngVersion_1_3_0_0);
5781*fd1fabb7SAndroid Build Coastguard Worker }
5782*fd1fabb7SAndroid Build Coastguard Worker
5783*fd1fabb7SAndroid Build Coastguard Worker if (rawJPEGImage || isFloatingPoint || hasTransparencyMask || isCompressed32BitInteger)
5784*fd1fabb7SAndroid Build Coastguard Worker {
5785*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersion = Max_uint32 (dngBackwardVersion, dngVersion_1_4_0_0);
5786*fd1fabb7SAndroid Build Coastguard Worker }
5787*fd1fabb7SAndroid Build Coastguard Worker
5788*fd1fabb7SAndroid Build Coastguard Worker if (dngBackwardVersion > dngVersion)
5789*fd1fabb7SAndroid Build Coastguard Worker {
5790*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
5791*fd1fabb7SAndroid Build Coastguard Worker }
5792*fd1fabb7SAndroid Build Coastguard Worker
5793*fd1fabb7SAndroid Build Coastguard Worker // Find best thumbnail from preview list, if any.
5794*fd1fabb7SAndroid Build Coastguard Worker
5795*fd1fabb7SAndroid Build Coastguard Worker const dng_preview *thumbnail = NULL;
5796*fd1fabb7SAndroid Build Coastguard Worker
5797*fd1fabb7SAndroid Build Coastguard Worker if (previewList)
5798*fd1fabb7SAndroid Build Coastguard Worker {
5799*fd1fabb7SAndroid Build Coastguard Worker
5800*fd1fabb7SAndroid Build Coastguard Worker uint32 thumbArea = 0;
5801*fd1fabb7SAndroid Build Coastguard Worker
5802*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < previewList->Count (); j++)
5803*fd1fabb7SAndroid Build Coastguard Worker {
5804*fd1fabb7SAndroid Build Coastguard Worker
5805*fd1fabb7SAndroid Build Coastguard Worker const dng_image_preview *imagePreview = dynamic_cast<const dng_image_preview *>(&previewList->Preview (j));
5806*fd1fabb7SAndroid Build Coastguard Worker
5807*fd1fabb7SAndroid Build Coastguard Worker if (imagePreview)
5808*fd1fabb7SAndroid Build Coastguard Worker {
5809*fd1fabb7SAndroid Build Coastguard Worker
5810*fd1fabb7SAndroid Build Coastguard Worker uint32 thisArea = imagePreview->fImage->Bounds ().W () *
5811*fd1fabb7SAndroid Build Coastguard Worker imagePreview->fImage->Bounds ().H ();
5812*fd1fabb7SAndroid Build Coastguard Worker
5813*fd1fabb7SAndroid Build Coastguard Worker if (!thumbnail || thisArea < thumbArea)
5814*fd1fabb7SAndroid Build Coastguard Worker {
5815*fd1fabb7SAndroid Build Coastguard Worker
5816*fd1fabb7SAndroid Build Coastguard Worker thumbnail = &previewList->Preview (j);
5817*fd1fabb7SAndroid Build Coastguard Worker
5818*fd1fabb7SAndroid Build Coastguard Worker thumbArea = thisArea;
5819*fd1fabb7SAndroid Build Coastguard Worker
5820*fd1fabb7SAndroid Build Coastguard Worker }
5821*fd1fabb7SAndroid Build Coastguard Worker
5822*fd1fabb7SAndroid Build Coastguard Worker }
5823*fd1fabb7SAndroid Build Coastguard Worker
5824*fd1fabb7SAndroid Build Coastguard Worker const dng_jpeg_preview *jpegPreview = dynamic_cast<const dng_jpeg_preview *>(&previewList->Preview (j));
5825*fd1fabb7SAndroid Build Coastguard Worker
5826*fd1fabb7SAndroid Build Coastguard Worker if (jpegPreview)
5827*fd1fabb7SAndroid Build Coastguard Worker {
5828*fd1fabb7SAndroid Build Coastguard Worker
5829*fd1fabb7SAndroid Build Coastguard Worker uint32 thisArea = jpegPreview->fPreviewSize.h *
5830*fd1fabb7SAndroid Build Coastguard Worker jpegPreview->fPreviewSize.v;
5831*fd1fabb7SAndroid Build Coastguard Worker
5832*fd1fabb7SAndroid Build Coastguard Worker if (!thumbnail || thisArea < thumbArea)
5833*fd1fabb7SAndroid Build Coastguard Worker {
5834*fd1fabb7SAndroid Build Coastguard Worker
5835*fd1fabb7SAndroid Build Coastguard Worker thumbnail = &previewList->Preview (j);
5836*fd1fabb7SAndroid Build Coastguard Worker
5837*fd1fabb7SAndroid Build Coastguard Worker thumbArea = thisArea;
5838*fd1fabb7SAndroid Build Coastguard Worker
5839*fd1fabb7SAndroid Build Coastguard Worker }
5840*fd1fabb7SAndroid Build Coastguard Worker
5841*fd1fabb7SAndroid Build Coastguard Worker }
5842*fd1fabb7SAndroid Build Coastguard Worker
5843*fd1fabb7SAndroid Build Coastguard Worker }
5844*fd1fabb7SAndroid Build Coastguard Worker
5845*fd1fabb7SAndroid Build Coastguard Worker }
5846*fd1fabb7SAndroid Build Coastguard Worker
5847*fd1fabb7SAndroid Build Coastguard Worker // Create the main IFD
5848*fd1fabb7SAndroid Build Coastguard Worker
5849*fd1fabb7SAndroid Build Coastguard Worker dng_tiff_directory mainIFD;
5850*fd1fabb7SAndroid Build Coastguard Worker
5851*fd1fabb7SAndroid Build Coastguard Worker // Create the IFD for the raw data. If there is no thumnail, this is
5852*fd1fabb7SAndroid Build Coastguard Worker // just a reference the main IFD. Otherwise allocate a new one.
5853*fd1fabb7SAndroid Build Coastguard Worker
5854*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_tiff_directory> rawIFD_IfNotMain;
5855*fd1fabb7SAndroid Build Coastguard Worker
5856*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail)
5857*fd1fabb7SAndroid Build Coastguard Worker {
5858*fd1fabb7SAndroid Build Coastguard Worker rawIFD_IfNotMain.Reset (new dng_tiff_directory);
5859*fd1fabb7SAndroid Build Coastguard Worker }
5860*fd1fabb7SAndroid Build Coastguard Worker
5861*fd1fabb7SAndroid Build Coastguard Worker dng_tiff_directory &rawIFD (thumbnail ? *rawIFD_IfNotMain : mainIFD);
5862*fd1fabb7SAndroid Build Coastguard Worker
5863*fd1fabb7SAndroid Build Coastguard Worker // Include DNG version tags.
5864*fd1fabb7SAndroid Build Coastguard Worker
5865*fd1fabb7SAndroid Build Coastguard Worker uint8 dngVersionData [4];
5866*fd1fabb7SAndroid Build Coastguard Worker
5867*fd1fabb7SAndroid Build Coastguard Worker dngVersionData [0] = (uint8) (dngVersion >> 24);
5868*fd1fabb7SAndroid Build Coastguard Worker dngVersionData [1] = (uint8) (dngVersion >> 16);
5869*fd1fabb7SAndroid Build Coastguard Worker dngVersionData [2] = (uint8) (dngVersion >> 8);
5870*fd1fabb7SAndroid Build Coastguard Worker dngVersionData [3] = (uint8) (dngVersion );
5871*fd1fabb7SAndroid Build Coastguard Worker
5872*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagDNGVersion (tcDNGVersion, dngVersionData, 4);
5873*fd1fabb7SAndroid Build Coastguard Worker
5874*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagDNGVersion);
5875*fd1fabb7SAndroid Build Coastguard Worker
5876*fd1fabb7SAndroid Build Coastguard Worker uint8 dngBackwardVersionData [4];
5877*fd1fabb7SAndroid Build Coastguard Worker
5878*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersionData [0] = (uint8) (dngBackwardVersion >> 24);
5879*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersionData [1] = (uint8) (dngBackwardVersion >> 16);
5880*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersionData [2] = (uint8) (dngBackwardVersion >> 8);
5881*fd1fabb7SAndroid Build Coastguard Worker dngBackwardVersionData [3] = (uint8) (dngBackwardVersion );
5882*fd1fabb7SAndroid Build Coastguard Worker
5883*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagDNGBackwardVersion (tcDNGBackwardVersion, dngBackwardVersionData, 4);
5884*fd1fabb7SAndroid Build Coastguard Worker
5885*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagDNGBackwardVersion);
5886*fd1fabb7SAndroid Build Coastguard Worker
5887*fd1fabb7SAndroid Build Coastguard Worker // The main IFD contains the thumbnail, if there is a thumbnail.
5888*fd1fabb7SAndroid Build Coastguard Worker
5889*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_basic_tag_set> thmBasic;
5890*fd1fabb7SAndroid Build Coastguard Worker
5891*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail)
5892*fd1fabb7SAndroid Build Coastguard Worker {
5893*fd1fabb7SAndroid Build Coastguard Worker thmBasic.Reset (thumbnail->AddTagSet (mainIFD));
5894*fd1fabb7SAndroid Build Coastguard Worker }
5895*fd1fabb7SAndroid Build Coastguard Worker
5896*fd1fabb7SAndroid Build Coastguard Worker // Get the raw image we are writing.
5897*fd1fabb7SAndroid Build Coastguard Worker
5898*fd1fabb7SAndroid Build Coastguard Worker const dng_image &rawImage (negative.RawImage ());
5899*fd1fabb7SAndroid Build Coastguard Worker
5900*fd1fabb7SAndroid Build Coastguard Worker // For floating point, we only support ZIP compression.
5901*fd1fabb7SAndroid Build Coastguard Worker
5902*fd1fabb7SAndroid Build Coastguard Worker if (isFloatingPoint && !uncompressed)
5903*fd1fabb7SAndroid Build Coastguard Worker {
5904*fd1fabb7SAndroid Build Coastguard Worker
5905*fd1fabb7SAndroid Build Coastguard Worker compression = ccDeflate;
5906*fd1fabb7SAndroid Build Coastguard Worker
5907*fd1fabb7SAndroid Build Coastguard Worker }
5908*fd1fabb7SAndroid Build Coastguard Worker
5909*fd1fabb7SAndroid Build Coastguard Worker // For 32-bit integer images, we only support ZIP and uncompressed.
5910*fd1fabb7SAndroid Build Coastguard Worker
5911*fd1fabb7SAndroid Build Coastguard Worker if (rawImage.PixelType () == ttLong)
5912*fd1fabb7SAndroid Build Coastguard Worker {
5913*fd1fabb7SAndroid Build Coastguard Worker
5914*fd1fabb7SAndroid Build Coastguard Worker if (isCompressed32BitInteger)
5915*fd1fabb7SAndroid Build Coastguard Worker {
5916*fd1fabb7SAndroid Build Coastguard Worker compression = ccDeflate;
5917*fd1fabb7SAndroid Build Coastguard Worker }
5918*fd1fabb7SAndroid Build Coastguard Worker
5919*fd1fabb7SAndroid Build Coastguard Worker else
5920*fd1fabb7SAndroid Build Coastguard Worker {
5921*fd1fabb7SAndroid Build Coastguard Worker compression = ccUncompressed;
5922*fd1fabb7SAndroid Build Coastguard Worker }
5923*fd1fabb7SAndroid Build Coastguard Worker
5924*fd1fabb7SAndroid Build Coastguard Worker }
5925*fd1fabb7SAndroid Build Coastguard Worker
5926*fd1fabb7SAndroid Build Coastguard Worker // Get a copy of the mosaic info.
5927*fd1fabb7SAndroid Build Coastguard Worker
5928*fd1fabb7SAndroid Build Coastguard Worker dng_mosaic_info mosaicInfo;
5929*fd1fabb7SAndroid Build Coastguard Worker
5930*fd1fabb7SAndroid Build Coastguard Worker if (negative.GetMosaicInfo ())
5931*fd1fabb7SAndroid Build Coastguard Worker {
5932*fd1fabb7SAndroid Build Coastguard Worker mosaicInfo = *(negative.GetMosaicInfo ());
5933*fd1fabb7SAndroid Build Coastguard Worker }
5934*fd1fabb7SAndroid Build Coastguard Worker
5935*fd1fabb7SAndroid Build Coastguard Worker // Create a dng_ifd record for the raw image.
5936*fd1fabb7SAndroid Build Coastguard Worker
5937*fd1fabb7SAndroid Build Coastguard Worker dng_ifd info;
5938*fd1fabb7SAndroid Build Coastguard Worker
5939*fd1fabb7SAndroid Build Coastguard Worker info.fImageWidth = rawImage.Width ();
5940*fd1fabb7SAndroid Build Coastguard Worker info.fImageLength = rawImage.Height ();
5941*fd1fabb7SAndroid Build Coastguard Worker
5942*fd1fabb7SAndroid Build Coastguard Worker info.fSamplesPerPixel = rawImage.Planes ();
5943*fd1fabb7SAndroid Build Coastguard Worker
5944*fd1fabb7SAndroid Build Coastguard Worker info.fPhotometricInterpretation = mosaicInfo.IsColorFilterArray () ? piCFA
5945*fd1fabb7SAndroid Build Coastguard Worker : piLinearRaw;
5946*fd1fabb7SAndroid Build Coastguard Worker
5947*fd1fabb7SAndroid Build Coastguard Worker info.fCompression = compression;
5948*fd1fabb7SAndroid Build Coastguard Worker
5949*fd1fabb7SAndroid Build Coastguard Worker if (isFloatingPoint && compression == ccDeflate)
5950*fd1fabb7SAndroid Build Coastguard Worker {
5951*fd1fabb7SAndroid Build Coastguard Worker
5952*fd1fabb7SAndroid Build Coastguard Worker info.fPredictor = cpFloatingPoint;
5953*fd1fabb7SAndroid Build Coastguard Worker
5954*fd1fabb7SAndroid Build Coastguard Worker if (mosaicInfo.IsColorFilterArray ())
5955*fd1fabb7SAndroid Build Coastguard Worker {
5956*fd1fabb7SAndroid Build Coastguard Worker
5957*fd1fabb7SAndroid Build Coastguard Worker if (mosaicInfo.fCFAPatternSize.h == 2)
5958*fd1fabb7SAndroid Build Coastguard Worker {
5959*fd1fabb7SAndroid Build Coastguard Worker info.fPredictor = cpFloatingPointX2;
5960*fd1fabb7SAndroid Build Coastguard Worker }
5961*fd1fabb7SAndroid Build Coastguard Worker
5962*fd1fabb7SAndroid Build Coastguard Worker else if (mosaicInfo.fCFAPatternSize.h == 4)
5963*fd1fabb7SAndroid Build Coastguard Worker {
5964*fd1fabb7SAndroid Build Coastguard Worker info.fPredictor = cpFloatingPointX4;
5965*fd1fabb7SAndroid Build Coastguard Worker }
5966*fd1fabb7SAndroid Build Coastguard Worker
5967*fd1fabb7SAndroid Build Coastguard Worker }
5968*fd1fabb7SAndroid Build Coastguard Worker
5969*fd1fabb7SAndroid Build Coastguard Worker }
5970*fd1fabb7SAndroid Build Coastguard Worker
5971*fd1fabb7SAndroid Build Coastguard Worker if (isCompressed32BitInteger)
5972*fd1fabb7SAndroid Build Coastguard Worker {
5973*fd1fabb7SAndroid Build Coastguard Worker
5974*fd1fabb7SAndroid Build Coastguard Worker info.fPredictor = cpHorizontalDifference;
5975*fd1fabb7SAndroid Build Coastguard Worker
5976*fd1fabb7SAndroid Build Coastguard Worker if (mosaicInfo.IsColorFilterArray ())
5977*fd1fabb7SAndroid Build Coastguard Worker {
5978*fd1fabb7SAndroid Build Coastguard Worker
5979*fd1fabb7SAndroid Build Coastguard Worker if (mosaicInfo.fCFAPatternSize.h == 2)
5980*fd1fabb7SAndroid Build Coastguard Worker {
5981*fd1fabb7SAndroid Build Coastguard Worker info.fPredictor = cpHorizontalDifferenceX2;
5982*fd1fabb7SAndroid Build Coastguard Worker }
5983*fd1fabb7SAndroid Build Coastguard Worker
5984*fd1fabb7SAndroid Build Coastguard Worker else if (mosaicInfo.fCFAPatternSize.h == 4)
5985*fd1fabb7SAndroid Build Coastguard Worker {
5986*fd1fabb7SAndroid Build Coastguard Worker info.fPredictor = cpHorizontalDifferenceX4;
5987*fd1fabb7SAndroid Build Coastguard Worker }
5988*fd1fabb7SAndroid Build Coastguard Worker
5989*fd1fabb7SAndroid Build Coastguard Worker }
5990*fd1fabb7SAndroid Build Coastguard Worker
5991*fd1fabb7SAndroid Build Coastguard Worker }
5992*fd1fabb7SAndroid Build Coastguard Worker
5993*fd1fabb7SAndroid Build Coastguard Worker uint32 rawPixelType = rawImage.PixelType ();
5994*fd1fabb7SAndroid Build Coastguard Worker
5995*fd1fabb7SAndroid Build Coastguard Worker if (rawPixelType == ttShort)
5996*fd1fabb7SAndroid Build Coastguard Worker {
5997*fd1fabb7SAndroid Build Coastguard Worker
5998*fd1fabb7SAndroid Build Coastguard Worker // See if we are using a linearization table with <= 256 entries, in which
5999*fd1fabb7SAndroid Build Coastguard Worker // case the useful data will all fit within 8-bits.
6000*fd1fabb7SAndroid Build Coastguard Worker
6001*fd1fabb7SAndroid Build Coastguard Worker const dng_linearization_info *rangeInfo = negative.GetLinearizationInfo ();
6002*fd1fabb7SAndroid Build Coastguard Worker
6003*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo)
6004*fd1fabb7SAndroid Build Coastguard Worker {
6005*fd1fabb7SAndroid Build Coastguard Worker
6006*fd1fabb7SAndroid Build Coastguard Worker if (rangeInfo->fLinearizationTable.Get ())
6007*fd1fabb7SAndroid Build Coastguard Worker {
6008*fd1fabb7SAndroid Build Coastguard Worker
6009*fd1fabb7SAndroid Build Coastguard Worker uint32 entries = rangeInfo->fLinearizationTable->LogicalSize () >> 1;
6010*fd1fabb7SAndroid Build Coastguard Worker
6011*fd1fabb7SAndroid Build Coastguard Worker if (entries <= 256)
6012*fd1fabb7SAndroid Build Coastguard Worker {
6013*fd1fabb7SAndroid Build Coastguard Worker
6014*fd1fabb7SAndroid Build Coastguard Worker rawPixelType = ttByte;
6015*fd1fabb7SAndroid Build Coastguard Worker
6016*fd1fabb7SAndroid Build Coastguard Worker }
6017*fd1fabb7SAndroid Build Coastguard Worker
6018*fd1fabb7SAndroid Build Coastguard Worker }
6019*fd1fabb7SAndroid Build Coastguard Worker
6020*fd1fabb7SAndroid Build Coastguard Worker }
6021*fd1fabb7SAndroid Build Coastguard Worker
6022*fd1fabb7SAndroid Build Coastguard Worker }
6023*fd1fabb7SAndroid Build Coastguard Worker
6024*fd1fabb7SAndroid Build Coastguard Worker switch (rawPixelType)
6025*fd1fabb7SAndroid Build Coastguard Worker {
6026*fd1fabb7SAndroid Build Coastguard Worker
6027*fd1fabb7SAndroid Build Coastguard Worker case ttByte:
6028*fd1fabb7SAndroid Build Coastguard Worker {
6029*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] = 8;
6030*fd1fabb7SAndroid Build Coastguard Worker break;
6031*fd1fabb7SAndroid Build Coastguard Worker }
6032*fd1fabb7SAndroid Build Coastguard Worker
6033*fd1fabb7SAndroid Build Coastguard Worker case ttShort:
6034*fd1fabb7SAndroid Build Coastguard Worker {
6035*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] = 16;
6036*fd1fabb7SAndroid Build Coastguard Worker break;
6037*fd1fabb7SAndroid Build Coastguard Worker }
6038*fd1fabb7SAndroid Build Coastguard Worker
6039*fd1fabb7SAndroid Build Coastguard Worker case ttLong:
6040*fd1fabb7SAndroid Build Coastguard Worker {
6041*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] = 32;
6042*fd1fabb7SAndroid Build Coastguard Worker break;
6043*fd1fabb7SAndroid Build Coastguard Worker }
6044*fd1fabb7SAndroid Build Coastguard Worker
6045*fd1fabb7SAndroid Build Coastguard Worker case ttFloat:
6046*fd1fabb7SAndroid Build Coastguard Worker {
6047*fd1fabb7SAndroid Build Coastguard Worker
6048*fd1fabb7SAndroid Build Coastguard Worker if (negative.RawFloatBitDepth () == 16)
6049*fd1fabb7SAndroid Build Coastguard Worker {
6050*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] = 16;
6051*fd1fabb7SAndroid Build Coastguard Worker }
6052*fd1fabb7SAndroid Build Coastguard Worker
6053*fd1fabb7SAndroid Build Coastguard Worker else if (negative.RawFloatBitDepth () == 24)
6054*fd1fabb7SAndroid Build Coastguard Worker {
6055*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] = 24;
6056*fd1fabb7SAndroid Build Coastguard Worker }
6057*fd1fabb7SAndroid Build Coastguard Worker
6058*fd1fabb7SAndroid Build Coastguard Worker else
6059*fd1fabb7SAndroid Build Coastguard Worker {
6060*fd1fabb7SAndroid Build Coastguard Worker info.fBitsPerSample [0] = 32;
6061*fd1fabb7SAndroid Build Coastguard Worker }
6062*fd1fabb7SAndroid Build Coastguard Worker
6063*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < info.fSamplesPerPixel; j++)
6064*fd1fabb7SAndroid Build Coastguard Worker {
6065*fd1fabb7SAndroid Build Coastguard Worker info.fSampleFormat [j] = sfFloatingPoint;
6066*fd1fabb7SAndroid Build Coastguard Worker }
6067*fd1fabb7SAndroid Build Coastguard Worker
6068*fd1fabb7SAndroid Build Coastguard Worker break;
6069*fd1fabb7SAndroid Build Coastguard Worker
6070*fd1fabb7SAndroid Build Coastguard Worker }
6071*fd1fabb7SAndroid Build Coastguard Worker
6072*fd1fabb7SAndroid Build Coastguard Worker default:
6073*fd1fabb7SAndroid Build Coastguard Worker {
6074*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ();
6075*fd1fabb7SAndroid Build Coastguard Worker }
6076*fd1fabb7SAndroid Build Coastguard Worker
6077*fd1fabb7SAndroid Build Coastguard Worker }
6078*fd1fabb7SAndroid Build Coastguard Worker
6079*fd1fabb7SAndroid Build Coastguard Worker // For lossless JPEG compression, we often lie about the
6080*fd1fabb7SAndroid Build Coastguard Worker // actual channel count to get the predictors to work across
6081*fd1fabb7SAndroid Build Coastguard Worker // same color mosaic pixels.
6082*fd1fabb7SAndroid Build Coastguard Worker
6083*fd1fabb7SAndroid Build Coastguard Worker uint32 fakeChannels = 1;
6084*fd1fabb7SAndroid Build Coastguard Worker
6085*fd1fabb7SAndroid Build Coastguard Worker if (info.fCompression == ccJPEG)
6086*fd1fabb7SAndroid Build Coastguard Worker {
6087*fd1fabb7SAndroid Build Coastguard Worker
6088*fd1fabb7SAndroid Build Coastguard Worker if (mosaicInfo.IsColorFilterArray ())
6089*fd1fabb7SAndroid Build Coastguard Worker {
6090*fd1fabb7SAndroid Build Coastguard Worker
6091*fd1fabb7SAndroid Build Coastguard Worker if (mosaicInfo.fCFAPatternSize.h == 4)
6092*fd1fabb7SAndroid Build Coastguard Worker {
6093*fd1fabb7SAndroid Build Coastguard Worker fakeChannels = 4;
6094*fd1fabb7SAndroid Build Coastguard Worker }
6095*fd1fabb7SAndroid Build Coastguard Worker
6096*fd1fabb7SAndroid Build Coastguard Worker else if (mosaicInfo.fCFAPatternSize.h == 2)
6097*fd1fabb7SAndroid Build Coastguard Worker {
6098*fd1fabb7SAndroid Build Coastguard Worker fakeChannels = 2;
6099*fd1fabb7SAndroid Build Coastguard Worker }
6100*fd1fabb7SAndroid Build Coastguard Worker
6101*fd1fabb7SAndroid Build Coastguard Worker // However, lossless JEPG is limited to four channels,
6102*fd1fabb7SAndroid Build Coastguard Worker // so compromise might be required.
6103*fd1fabb7SAndroid Build Coastguard Worker
6104*fd1fabb7SAndroid Build Coastguard Worker while (fakeChannels * info.fSamplesPerPixel > 4 &&
6105*fd1fabb7SAndroid Build Coastguard Worker fakeChannels > 1)
6106*fd1fabb7SAndroid Build Coastguard Worker {
6107*fd1fabb7SAndroid Build Coastguard Worker
6108*fd1fabb7SAndroid Build Coastguard Worker fakeChannels >>= 1;
6109*fd1fabb7SAndroid Build Coastguard Worker
6110*fd1fabb7SAndroid Build Coastguard Worker }
6111*fd1fabb7SAndroid Build Coastguard Worker
6112*fd1fabb7SAndroid Build Coastguard Worker }
6113*fd1fabb7SAndroid Build Coastguard Worker
6114*fd1fabb7SAndroid Build Coastguard Worker }
6115*fd1fabb7SAndroid Build Coastguard Worker
6116*fd1fabb7SAndroid Build Coastguard Worker // Figure out tile sizes.
6117*fd1fabb7SAndroid Build Coastguard Worker
6118*fd1fabb7SAndroid Build Coastguard Worker if (rawJPEGImage)
6119*fd1fabb7SAndroid Build Coastguard Worker {
6120*fd1fabb7SAndroid Build Coastguard Worker
6121*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT (rawPixelType == ttByte,
6122*fd1fabb7SAndroid Build Coastguard Worker "Unexpected jpeg pixel type");
6123*fd1fabb7SAndroid Build Coastguard Worker
6124*fd1fabb7SAndroid Build Coastguard Worker DNG_ASSERT (info.fImageWidth == (uint32) rawJPEGImage->fImageSize.h &&
6125*fd1fabb7SAndroid Build Coastguard Worker info.fImageLength == (uint32) rawJPEGImage->fImageSize.v,
6126*fd1fabb7SAndroid Build Coastguard Worker "Unexpected jpeg image size");
6127*fd1fabb7SAndroid Build Coastguard Worker
6128*fd1fabb7SAndroid Build Coastguard Worker info.fTileWidth = rawJPEGImage->fTileSize.h;
6129*fd1fabb7SAndroid Build Coastguard Worker info.fTileLength = rawJPEGImage->fTileSize.v;
6130*fd1fabb7SAndroid Build Coastguard Worker
6131*fd1fabb7SAndroid Build Coastguard Worker info.fUsesStrips = rawJPEGImage->fUsesStrips;
6132*fd1fabb7SAndroid Build Coastguard Worker
6133*fd1fabb7SAndroid Build Coastguard Worker info.fUsesTiles = !info.fUsesStrips;
6134*fd1fabb7SAndroid Build Coastguard Worker
6135*fd1fabb7SAndroid Build Coastguard Worker }
6136*fd1fabb7SAndroid Build Coastguard Worker
6137*fd1fabb7SAndroid Build Coastguard Worker else if (info.fCompression == ccJPEG)
6138*fd1fabb7SAndroid Build Coastguard Worker {
6139*fd1fabb7SAndroid Build Coastguard Worker
6140*fd1fabb7SAndroid Build Coastguard Worker info.FindTileSize (128 * 1024);
6141*fd1fabb7SAndroid Build Coastguard Worker
6142*fd1fabb7SAndroid Build Coastguard Worker }
6143*fd1fabb7SAndroid Build Coastguard Worker
6144*fd1fabb7SAndroid Build Coastguard Worker else if (info.fCompression == ccDeflate)
6145*fd1fabb7SAndroid Build Coastguard Worker {
6146*fd1fabb7SAndroid Build Coastguard Worker
6147*fd1fabb7SAndroid Build Coastguard Worker info.FindTileSize (512 * 1024);
6148*fd1fabb7SAndroid Build Coastguard Worker
6149*fd1fabb7SAndroid Build Coastguard Worker }
6150*fd1fabb7SAndroid Build Coastguard Worker
6151*fd1fabb7SAndroid Build Coastguard Worker else if (info.fCompression == ccLossyJPEG)
6152*fd1fabb7SAndroid Build Coastguard Worker {
6153*fd1fabb7SAndroid Build Coastguard Worker
6154*fd1fabb7SAndroid Build Coastguard Worker ThrowProgramError ("No JPEG compressed image");
6155*fd1fabb7SAndroid Build Coastguard Worker
6156*fd1fabb7SAndroid Build Coastguard Worker }
6157*fd1fabb7SAndroid Build Coastguard Worker
6158*fd1fabb7SAndroid Build Coastguard Worker // Don't use tiles for uncompressed images.
6159*fd1fabb7SAndroid Build Coastguard Worker
6160*fd1fabb7SAndroid Build Coastguard Worker else
6161*fd1fabb7SAndroid Build Coastguard Worker {
6162*fd1fabb7SAndroid Build Coastguard Worker
6163*fd1fabb7SAndroid Build Coastguard Worker info.SetSingleStrip ();
6164*fd1fabb7SAndroid Build Coastguard Worker
6165*fd1fabb7SAndroid Build Coastguard Worker }
6166*fd1fabb7SAndroid Build Coastguard Worker
6167*fd1fabb7SAndroid Build Coastguard Worker #ifdef qTestRowInterleave
6168*fd1fabb7SAndroid Build Coastguard Worker
6169*fd1fabb7SAndroid Build Coastguard Worker info.fRowInterleaveFactor = qTestRowInterleave;
6170*fd1fabb7SAndroid Build Coastguard Worker
6171*fd1fabb7SAndroid Build Coastguard Worker #endif
6172*fd1fabb7SAndroid Build Coastguard Worker
6173*fd1fabb7SAndroid Build Coastguard Worker #if defined(qTestSubTileBlockRows) && defined(qTestSubTileBlockCols)
6174*fd1fabb7SAndroid Build Coastguard Worker
6175*fd1fabb7SAndroid Build Coastguard Worker info.fSubTileBlockRows = qTestSubTileBlockRows;
6176*fd1fabb7SAndroid Build Coastguard Worker info.fSubTileBlockCols = qTestSubTileBlockCols;
6177*fd1fabb7SAndroid Build Coastguard Worker
6178*fd1fabb7SAndroid Build Coastguard Worker if (fakeChannels == 2)
6179*fd1fabb7SAndroid Build Coastguard Worker fakeChannels = 4;
6180*fd1fabb7SAndroid Build Coastguard Worker
6181*fd1fabb7SAndroid Build Coastguard Worker #endif
6182*fd1fabb7SAndroid Build Coastguard Worker
6183*fd1fabb7SAndroid Build Coastguard Worker // Basic information.
6184*fd1fabb7SAndroid Build Coastguard Worker
6185*fd1fabb7SAndroid Build Coastguard Worker dng_basic_tag_set rawBasic (rawIFD, info);
6186*fd1fabb7SAndroid Build Coastguard Worker
6187*fd1fabb7SAndroid Build Coastguard Worker // JPEG tables, if any.
6188*fd1fabb7SAndroid Build Coastguard Worker
6189*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr tagJPEGTables (tcJPEGTables,
6190*fd1fabb7SAndroid Build Coastguard Worker ttUndefined,
6191*fd1fabb7SAndroid Build Coastguard Worker 0,
6192*fd1fabb7SAndroid Build Coastguard Worker NULL);
6193*fd1fabb7SAndroid Build Coastguard Worker
6194*fd1fabb7SAndroid Build Coastguard Worker if (rawJPEGImage && rawJPEGImage->fJPEGTables.Get ())
6195*fd1fabb7SAndroid Build Coastguard Worker {
6196*fd1fabb7SAndroid Build Coastguard Worker
6197*fd1fabb7SAndroid Build Coastguard Worker tagJPEGTables.SetData (rawJPEGImage->fJPEGTables->Buffer ());
6198*fd1fabb7SAndroid Build Coastguard Worker
6199*fd1fabb7SAndroid Build Coastguard Worker tagJPEGTables.SetCount (rawJPEGImage->fJPEGTables->LogicalSize ());
6200*fd1fabb7SAndroid Build Coastguard Worker
6201*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagJPEGTables);
6202*fd1fabb7SAndroid Build Coastguard Worker
6203*fd1fabb7SAndroid Build Coastguard Worker }
6204*fd1fabb7SAndroid Build Coastguard Worker
6205*fd1fabb7SAndroid Build Coastguard Worker // DefaultScale tag.
6206*fd1fabb7SAndroid Build Coastguard Worker
6207*fd1fabb7SAndroid Build Coastguard Worker dng_urational defaultScaleData [2];
6208*fd1fabb7SAndroid Build Coastguard Worker
6209*fd1fabb7SAndroid Build Coastguard Worker defaultScaleData [0] = negative.DefaultScaleH ();
6210*fd1fabb7SAndroid Build Coastguard Worker defaultScaleData [1] = negative.DefaultScaleV ();
6211*fd1fabb7SAndroid Build Coastguard Worker
6212*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr tagDefaultScale (tcDefaultScale,
6213*fd1fabb7SAndroid Build Coastguard Worker defaultScaleData,
6214*fd1fabb7SAndroid Build Coastguard Worker 2);
6215*fd1fabb7SAndroid Build Coastguard Worker
6216*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagDefaultScale);
6217*fd1fabb7SAndroid Build Coastguard Worker
6218*fd1fabb7SAndroid Build Coastguard Worker // Best quality scale tag.
6219*fd1fabb7SAndroid Build Coastguard Worker
6220*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagBestQualityScale (tcBestQualityScale,
6221*fd1fabb7SAndroid Build Coastguard Worker negative.BestQualityScale ());
6222*fd1fabb7SAndroid Build Coastguard Worker
6223*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagBestQualityScale);
6224*fd1fabb7SAndroid Build Coastguard Worker
6225*fd1fabb7SAndroid Build Coastguard Worker // DefaultCropOrigin tag.
6226*fd1fabb7SAndroid Build Coastguard Worker
6227*fd1fabb7SAndroid Build Coastguard Worker dng_urational defaultCropOriginData [2];
6228*fd1fabb7SAndroid Build Coastguard Worker
6229*fd1fabb7SAndroid Build Coastguard Worker defaultCropOriginData [0] = negative.DefaultCropOriginH ();
6230*fd1fabb7SAndroid Build Coastguard Worker defaultCropOriginData [1] = negative.DefaultCropOriginV ();
6231*fd1fabb7SAndroid Build Coastguard Worker
6232*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr tagDefaultCropOrigin (tcDefaultCropOrigin,
6233*fd1fabb7SAndroid Build Coastguard Worker defaultCropOriginData,
6234*fd1fabb7SAndroid Build Coastguard Worker 2);
6235*fd1fabb7SAndroid Build Coastguard Worker
6236*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagDefaultCropOrigin);
6237*fd1fabb7SAndroid Build Coastguard Worker
6238*fd1fabb7SAndroid Build Coastguard Worker // DefaultCropSize tag.
6239*fd1fabb7SAndroid Build Coastguard Worker
6240*fd1fabb7SAndroid Build Coastguard Worker dng_urational defaultCropSizeData [2];
6241*fd1fabb7SAndroid Build Coastguard Worker
6242*fd1fabb7SAndroid Build Coastguard Worker defaultCropSizeData [0] = negative.DefaultCropSizeH ();
6243*fd1fabb7SAndroid Build Coastguard Worker defaultCropSizeData [1] = negative.DefaultCropSizeV ();
6244*fd1fabb7SAndroid Build Coastguard Worker
6245*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr tagDefaultCropSize (tcDefaultCropSize,
6246*fd1fabb7SAndroid Build Coastguard Worker defaultCropSizeData,
6247*fd1fabb7SAndroid Build Coastguard Worker 2);
6248*fd1fabb7SAndroid Build Coastguard Worker
6249*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagDefaultCropSize);
6250*fd1fabb7SAndroid Build Coastguard Worker
6251*fd1fabb7SAndroid Build Coastguard Worker // DefaultUserCrop tag.
6252*fd1fabb7SAndroid Build Coastguard Worker
6253*fd1fabb7SAndroid Build Coastguard Worker dng_urational defaultUserCropData [4];
6254*fd1fabb7SAndroid Build Coastguard Worker
6255*fd1fabb7SAndroid Build Coastguard Worker defaultUserCropData [0] = negative.DefaultUserCropT ();
6256*fd1fabb7SAndroid Build Coastguard Worker defaultUserCropData [1] = negative.DefaultUserCropL ();
6257*fd1fabb7SAndroid Build Coastguard Worker defaultUserCropData [2] = negative.DefaultUserCropB ();
6258*fd1fabb7SAndroid Build Coastguard Worker defaultUserCropData [3] = negative.DefaultUserCropR ();
6259*fd1fabb7SAndroid Build Coastguard Worker
6260*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr tagDefaultUserCrop (tcDefaultUserCrop,
6261*fd1fabb7SAndroid Build Coastguard Worker defaultUserCropData,
6262*fd1fabb7SAndroid Build Coastguard Worker 4);
6263*fd1fabb7SAndroid Build Coastguard Worker
6264*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagDefaultUserCrop);
6265*fd1fabb7SAndroid Build Coastguard Worker
6266*fd1fabb7SAndroid Build Coastguard Worker // Range mapping tag set.
6267*fd1fabb7SAndroid Build Coastguard Worker
6268*fd1fabb7SAndroid Build Coastguard Worker range_tag_set rangeSet (rawIFD, negative);
6269*fd1fabb7SAndroid Build Coastguard Worker
6270*fd1fabb7SAndroid Build Coastguard Worker // Mosaic pattern information.
6271*fd1fabb7SAndroid Build Coastguard Worker
6272*fd1fabb7SAndroid Build Coastguard Worker mosaic_tag_set mosaicSet (rawIFD, mosaicInfo);
6273*fd1fabb7SAndroid Build Coastguard Worker
6274*fd1fabb7SAndroid Build Coastguard Worker // Chroma blur radius.
6275*fd1fabb7SAndroid Build Coastguard Worker
6276*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagChromaBlurRadius (tcChromaBlurRadius,
6277*fd1fabb7SAndroid Build Coastguard Worker negative.ChromaBlurRadius ());
6278*fd1fabb7SAndroid Build Coastguard Worker
6279*fd1fabb7SAndroid Build Coastguard Worker if (negative.ChromaBlurRadius ().IsValid ())
6280*fd1fabb7SAndroid Build Coastguard Worker {
6281*fd1fabb7SAndroid Build Coastguard Worker
6282*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagChromaBlurRadius);
6283*fd1fabb7SAndroid Build Coastguard Worker
6284*fd1fabb7SAndroid Build Coastguard Worker }
6285*fd1fabb7SAndroid Build Coastguard Worker
6286*fd1fabb7SAndroid Build Coastguard Worker // Anti-alias filter strength.
6287*fd1fabb7SAndroid Build Coastguard Worker
6288*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagAntiAliasStrength (tcAntiAliasStrength,
6289*fd1fabb7SAndroid Build Coastguard Worker negative.AntiAliasStrength ());
6290*fd1fabb7SAndroid Build Coastguard Worker
6291*fd1fabb7SAndroid Build Coastguard Worker if (negative.AntiAliasStrength ().IsValid ())
6292*fd1fabb7SAndroid Build Coastguard Worker {
6293*fd1fabb7SAndroid Build Coastguard Worker
6294*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagAntiAliasStrength);
6295*fd1fabb7SAndroid Build Coastguard Worker
6296*fd1fabb7SAndroid Build Coastguard Worker }
6297*fd1fabb7SAndroid Build Coastguard Worker
6298*fd1fabb7SAndroid Build Coastguard Worker // Profile and other color related tags.
6299*fd1fabb7SAndroid Build Coastguard Worker
6300*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<profile_tag_set> profileSet;
6301*fd1fabb7SAndroid Build Coastguard Worker
6302*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<color_tag_set> colorSet;
6303*fd1fabb7SAndroid Build Coastguard Worker
6304*fd1fabb7SAndroid Build Coastguard Worker dng_std_vector<uint32> extraProfileIndex;
6305*fd1fabb7SAndroid Build Coastguard Worker
6306*fd1fabb7SAndroid Build Coastguard Worker if (!negative.IsMonochrome ())
6307*fd1fabb7SAndroid Build Coastguard Worker {
6308*fd1fabb7SAndroid Build Coastguard Worker
6309*fd1fabb7SAndroid Build Coastguard Worker const dng_camera_profile &mainProfile (*negative.ComputeCameraProfileToEmbed (constMetadata));
6310*fd1fabb7SAndroid Build Coastguard Worker
6311*fd1fabb7SAndroid Build Coastguard Worker profileSet.Reset (new profile_tag_set (mainIFD,
6312*fd1fabb7SAndroid Build Coastguard Worker mainProfile));
6313*fd1fabb7SAndroid Build Coastguard Worker
6314*fd1fabb7SAndroid Build Coastguard Worker colorSet.Reset (new color_tag_set (mainIFD,
6315*fd1fabb7SAndroid Build Coastguard Worker negative));
6316*fd1fabb7SAndroid Build Coastguard Worker
6317*fd1fabb7SAndroid Build Coastguard Worker // Build list of profile indices to include in extra profiles tag.
6318*fd1fabb7SAndroid Build Coastguard Worker
6319*fd1fabb7SAndroid Build Coastguard Worker uint32 profileCount = negative.ProfileCount ();
6320*fd1fabb7SAndroid Build Coastguard Worker
6321*fd1fabb7SAndroid Build Coastguard Worker for (uint32 index = 0; index < profileCount; index++)
6322*fd1fabb7SAndroid Build Coastguard Worker {
6323*fd1fabb7SAndroid Build Coastguard Worker
6324*fd1fabb7SAndroid Build Coastguard Worker const dng_camera_profile &profile (negative.ProfileByIndex (index));
6325*fd1fabb7SAndroid Build Coastguard Worker
6326*fd1fabb7SAndroid Build Coastguard Worker if (&profile != &mainProfile)
6327*fd1fabb7SAndroid Build Coastguard Worker {
6328*fd1fabb7SAndroid Build Coastguard Worker
6329*fd1fabb7SAndroid Build Coastguard Worker if (profile.WasReadFromDNG ())
6330*fd1fabb7SAndroid Build Coastguard Worker {
6331*fd1fabb7SAndroid Build Coastguard Worker
6332*fd1fabb7SAndroid Build Coastguard Worker extraProfileIndex.push_back (index);
6333*fd1fabb7SAndroid Build Coastguard Worker
6334*fd1fabb7SAndroid Build Coastguard Worker }
6335*fd1fabb7SAndroid Build Coastguard Worker
6336*fd1fabb7SAndroid Build Coastguard Worker }
6337*fd1fabb7SAndroid Build Coastguard Worker
6338*fd1fabb7SAndroid Build Coastguard Worker }
6339*fd1fabb7SAndroid Build Coastguard Worker
6340*fd1fabb7SAndroid Build Coastguard Worker }
6341*fd1fabb7SAndroid Build Coastguard Worker
6342*fd1fabb7SAndroid Build Coastguard Worker // Extra camera profiles tag.
6343*fd1fabb7SAndroid Build Coastguard Worker
6344*fd1fabb7SAndroid Build Coastguard Worker uint32 extraProfileCount = (uint32) extraProfileIndex.size ();
6345*fd1fabb7SAndroid Build Coastguard Worker
6346*fd1fabb7SAndroid Build Coastguard Worker dng_memory_data extraProfileOffsets (extraProfileCount, sizeof (uint32));
6347*fd1fabb7SAndroid Build Coastguard Worker
6348*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr extraProfileTag (tcExtraCameraProfiles,
6349*fd1fabb7SAndroid Build Coastguard Worker extraProfileOffsets.Buffer_uint32 (),
6350*fd1fabb7SAndroid Build Coastguard Worker extraProfileCount);
6351*fd1fabb7SAndroid Build Coastguard Worker
6352*fd1fabb7SAndroid Build Coastguard Worker if (extraProfileCount)
6353*fd1fabb7SAndroid Build Coastguard Worker {
6354*fd1fabb7SAndroid Build Coastguard Worker
6355*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&extraProfileTag);
6356*fd1fabb7SAndroid Build Coastguard Worker
6357*fd1fabb7SAndroid Build Coastguard Worker }
6358*fd1fabb7SAndroid Build Coastguard Worker
6359*fd1fabb7SAndroid Build Coastguard Worker // Other tags.
6360*fd1fabb7SAndroid Build Coastguard Worker
6361*fd1fabb7SAndroid Build Coastguard Worker tag_uint16 tagOrientation (tcOrientation,
6362*fd1fabb7SAndroid Build Coastguard Worker (uint16) negative.ComputeOrientation (constMetadata).GetTIFF ());
6363*fd1fabb7SAndroid Build Coastguard Worker
6364*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOrientation);
6365*fd1fabb7SAndroid Build Coastguard Worker
6366*fd1fabb7SAndroid Build Coastguard Worker tag_srational tagBaselineExposure (tcBaselineExposure,
6367*fd1fabb7SAndroid Build Coastguard Worker negative.BaselineExposureR ());
6368*fd1fabb7SAndroid Build Coastguard Worker
6369*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagBaselineExposure);
6370*fd1fabb7SAndroid Build Coastguard Worker
6371*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagBaselineNoise (tcBaselineNoise,
6372*fd1fabb7SAndroid Build Coastguard Worker negative.BaselineNoiseR ());
6373*fd1fabb7SAndroid Build Coastguard Worker
6374*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagBaselineNoise);
6375*fd1fabb7SAndroid Build Coastguard Worker
6376*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagNoiseReductionApplied (tcNoiseReductionApplied,
6377*fd1fabb7SAndroid Build Coastguard Worker negative.NoiseReductionApplied ());
6378*fd1fabb7SAndroid Build Coastguard Worker
6379*fd1fabb7SAndroid Build Coastguard Worker if (negative.NoiseReductionApplied ().IsValid ())
6380*fd1fabb7SAndroid Build Coastguard Worker {
6381*fd1fabb7SAndroid Build Coastguard Worker
6382*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagNoiseReductionApplied);
6383*fd1fabb7SAndroid Build Coastguard Worker
6384*fd1fabb7SAndroid Build Coastguard Worker }
6385*fd1fabb7SAndroid Build Coastguard Worker
6386*fd1fabb7SAndroid Build Coastguard Worker tag_dng_noise_profile tagNoiseProfile (negative.NoiseProfile ());
6387*fd1fabb7SAndroid Build Coastguard Worker
6388*fd1fabb7SAndroid Build Coastguard Worker if (negative.NoiseProfile ().IsValidForNegative (negative))
6389*fd1fabb7SAndroid Build Coastguard Worker {
6390*fd1fabb7SAndroid Build Coastguard Worker
6391*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagNoiseProfile);
6392*fd1fabb7SAndroid Build Coastguard Worker
6393*fd1fabb7SAndroid Build Coastguard Worker }
6394*fd1fabb7SAndroid Build Coastguard Worker
6395*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagBaselineSharpness (tcBaselineSharpness,
6396*fd1fabb7SAndroid Build Coastguard Worker negative.BaselineSharpnessR ());
6397*fd1fabb7SAndroid Build Coastguard Worker
6398*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagBaselineSharpness);
6399*fd1fabb7SAndroid Build Coastguard Worker
6400*fd1fabb7SAndroid Build Coastguard Worker tag_string tagUniqueName (tcUniqueCameraModel,
6401*fd1fabb7SAndroid Build Coastguard Worker negative.ModelName (),
6402*fd1fabb7SAndroid Build Coastguard Worker true);
6403*fd1fabb7SAndroid Build Coastguard Worker
6404*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagUniqueName);
6405*fd1fabb7SAndroid Build Coastguard Worker
6406*fd1fabb7SAndroid Build Coastguard Worker tag_string tagLocalName (tcLocalizedCameraModel,
6407*fd1fabb7SAndroid Build Coastguard Worker negative.LocalName (),
6408*fd1fabb7SAndroid Build Coastguard Worker false);
6409*fd1fabb7SAndroid Build Coastguard Worker
6410*fd1fabb7SAndroid Build Coastguard Worker if (negative.LocalName ().NotEmpty ())
6411*fd1fabb7SAndroid Build Coastguard Worker {
6412*fd1fabb7SAndroid Build Coastguard Worker
6413*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagLocalName);
6414*fd1fabb7SAndroid Build Coastguard Worker
6415*fd1fabb7SAndroid Build Coastguard Worker }
6416*fd1fabb7SAndroid Build Coastguard Worker
6417*fd1fabb7SAndroid Build Coastguard Worker tag_urational tagShadowScale (tcShadowScale,
6418*fd1fabb7SAndroid Build Coastguard Worker negative.ShadowScaleR ());
6419*fd1fabb7SAndroid Build Coastguard Worker
6420*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagShadowScale);
6421*fd1fabb7SAndroid Build Coastguard Worker
6422*fd1fabb7SAndroid Build Coastguard Worker tag_uint16 tagColorimetricReference (tcColorimetricReference,
6423*fd1fabb7SAndroid Build Coastguard Worker (uint16) negative.ColorimetricReference ());
6424*fd1fabb7SAndroid Build Coastguard Worker
6425*fd1fabb7SAndroid Build Coastguard Worker if (negative.ColorimetricReference () != crSceneReferred)
6426*fd1fabb7SAndroid Build Coastguard Worker {
6427*fd1fabb7SAndroid Build Coastguard Worker
6428*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagColorimetricReference);
6429*fd1fabb7SAndroid Build Coastguard Worker
6430*fd1fabb7SAndroid Build Coastguard Worker }
6431*fd1fabb7SAndroid Build Coastguard Worker
6432*fd1fabb7SAndroid Build Coastguard Worker bool useNewDigest = (maxBackwardVersion >= dngVersion_1_4_0_0);
6433*fd1fabb7SAndroid Build Coastguard Worker
6434*fd1fabb7SAndroid Build Coastguard Worker if (compression == ccLossyJPEG)
6435*fd1fabb7SAndroid Build Coastguard Worker {
6436*fd1fabb7SAndroid Build Coastguard Worker
6437*fd1fabb7SAndroid Build Coastguard Worker negative.FindRawJPEGImageDigest (host);
6438*fd1fabb7SAndroid Build Coastguard Worker
6439*fd1fabb7SAndroid Build Coastguard Worker }
6440*fd1fabb7SAndroid Build Coastguard Worker
6441*fd1fabb7SAndroid Build Coastguard Worker else
6442*fd1fabb7SAndroid Build Coastguard Worker {
6443*fd1fabb7SAndroid Build Coastguard Worker
6444*fd1fabb7SAndroid Build Coastguard Worker if (useNewDigest)
6445*fd1fabb7SAndroid Build Coastguard Worker {
6446*fd1fabb7SAndroid Build Coastguard Worker negative.FindNewRawImageDigest (host);
6447*fd1fabb7SAndroid Build Coastguard Worker }
6448*fd1fabb7SAndroid Build Coastguard Worker else
6449*fd1fabb7SAndroid Build Coastguard Worker {
6450*fd1fabb7SAndroid Build Coastguard Worker negative.FindRawImageDigest (host);
6451*fd1fabb7SAndroid Build Coastguard Worker }
6452*fd1fabb7SAndroid Build Coastguard Worker
6453*fd1fabb7SAndroid Build Coastguard Worker }
6454*fd1fabb7SAndroid Build Coastguard Worker
6455*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagRawImageDigest (useNewDigest ? tcNewRawImageDigest : tcRawImageDigest,
6456*fd1fabb7SAndroid Build Coastguard Worker compression == ccLossyJPEG ?
6457*fd1fabb7SAndroid Build Coastguard Worker negative.RawJPEGImageDigest ().data :
6458*fd1fabb7SAndroid Build Coastguard Worker (useNewDigest ? negative.NewRawImageDigest ().data
6459*fd1fabb7SAndroid Build Coastguard Worker : negative.RawImageDigest ().data),
6460*fd1fabb7SAndroid Build Coastguard Worker 16);
6461*fd1fabb7SAndroid Build Coastguard Worker
6462*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagRawImageDigest);
6463*fd1fabb7SAndroid Build Coastguard Worker
6464*fd1fabb7SAndroid Build Coastguard Worker negative.FindRawDataUniqueID (host);
6465*fd1fabb7SAndroid Build Coastguard Worker
6466*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagRawDataUniqueID (tcRawDataUniqueID,
6467*fd1fabb7SAndroid Build Coastguard Worker negative.RawDataUniqueID ().data,
6468*fd1fabb7SAndroid Build Coastguard Worker 16);
6469*fd1fabb7SAndroid Build Coastguard Worker
6470*fd1fabb7SAndroid Build Coastguard Worker if (negative.RawDataUniqueID ().IsValid ())
6471*fd1fabb7SAndroid Build Coastguard Worker {
6472*fd1fabb7SAndroid Build Coastguard Worker
6473*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagRawDataUniqueID);
6474*fd1fabb7SAndroid Build Coastguard Worker
6475*fd1fabb7SAndroid Build Coastguard Worker }
6476*fd1fabb7SAndroid Build Coastguard Worker
6477*fd1fabb7SAndroid Build Coastguard Worker tag_string tagOriginalRawFileName (tcOriginalRawFileName,
6478*fd1fabb7SAndroid Build Coastguard Worker negative.OriginalRawFileName (),
6479*fd1fabb7SAndroid Build Coastguard Worker false);
6480*fd1fabb7SAndroid Build Coastguard Worker
6481*fd1fabb7SAndroid Build Coastguard Worker if (negative.HasOriginalRawFileName ())
6482*fd1fabb7SAndroid Build Coastguard Worker {
6483*fd1fabb7SAndroid Build Coastguard Worker
6484*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOriginalRawFileName);
6485*fd1fabb7SAndroid Build Coastguard Worker
6486*fd1fabb7SAndroid Build Coastguard Worker }
6487*fd1fabb7SAndroid Build Coastguard Worker
6488*fd1fabb7SAndroid Build Coastguard Worker negative.FindOriginalRawFileDigest ();
6489*fd1fabb7SAndroid Build Coastguard Worker
6490*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr tagOriginalRawFileData (tcOriginalRawFileData,
6491*fd1fabb7SAndroid Build Coastguard Worker ttUndefined,
6492*fd1fabb7SAndroid Build Coastguard Worker negative.OriginalRawFileDataLength (),
6493*fd1fabb7SAndroid Build Coastguard Worker negative.OriginalRawFileData ());
6494*fd1fabb7SAndroid Build Coastguard Worker
6495*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagOriginalRawFileDigest (tcOriginalRawFileDigest,
6496*fd1fabb7SAndroid Build Coastguard Worker negative.OriginalRawFileDigest ().data,
6497*fd1fabb7SAndroid Build Coastguard Worker 16);
6498*fd1fabb7SAndroid Build Coastguard Worker
6499*fd1fabb7SAndroid Build Coastguard Worker if (negative.OriginalRawFileData ())
6500*fd1fabb7SAndroid Build Coastguard Worker {
6501*fd1fabb7SAndroid Build Coastguard Worker
6502*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOriginalRawFileData);
6503*fd1fabb7SAndroid Build Coastguard Worker
6504*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOriginalRawFileDigest);
6505*fd1fabb7SAndroid Build Coastguard Worker
6506*fd1fabb7SAndroid Build Coastguard Worker }
6507*fd1fabb7SAndroid Build Coastguard Worker
6508*fd1fabb7SAndroid Build Coastguard Worker // XMP metadata.
6509*fd1fabb7SAndroid Build Coastguard Worker
6510*fd1fabb7SAndroid Build Coastguard Worker #if qDNGUseXMP
6511*fd1fabb7SAndroid Build Coastguard Worker
6512*fd1fabb7SAndroid Build Coastguard Worker tag_xmp tagXMP (metadata->GetXMP ());
6513*fd1fabb7SAndroid Build Coastguard Worker
6514*fd1fabb7SAndroid Build Coastguard Worker if (tagXMP.Count ())
6515*fd1fabb7SAndroid Build Coastguard Worker {
6516*fd1fabb7SAndroid Build Coastguard Worker
6517*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagXMP);
6518*fd1fabb7SAndroid Build Coastguard Worker
6519*fd1fabb7SAndroid Build Coastguard Worker }
6520*fd1fabb7SAndroid Build Coastguard Worker
6521*fd1fabb7SAndroid Build Coastguard Worker #endif
6522*fd1fabb7SAndroid Build Coastguard Worker
6523*fd1fabb7SAndroid Build Coastguard Worker // Exif tags.
6524*fd1fabb7SAndroid Build Coastguard Worker
6525*fd1fabb7SAndroid Build Coastguard Worker exif_tag_set exifSet (mainIFD,
6526*fd1fabb7SAndroid Build Coastguard Worker *metadata->GetExif (),
6527*fd1fabb7SAndroid Build Coastguard Worker metadata->IsMakerNoteSafe (),
6528*fd1fabb7SAndroid Build Coastguard Worker metadata->MakerNoteData (),
6529*fd1fabb7SAndroid Build Coastguard Worker metadata->MakerNoteLength (),
6530*fd1fabb7SAndroid Build Coastguard Worker true);
6531*fd1fabb7SAndroid Build Coastguard Worker
6532*fd1fabb7SAndroid Build Coastguard Worker // Private data.
6533*fd1fabb7SAndroid Build Coastguard Worker
6534*fd1fabb7SAndroid Build Coastguard Worker tag_uint8_ptr tagPrivateData (tcDNGPrivateData,
6535*fd1fabb7SAndroid Build Coastguard Worker negative.PrivateData (),
6536*fd1fabb7SAndroid Build Coastguard Worker negative.PrivateLength ());
6537*fd1fabb7SAndroid Build Coastguard Worker
6538*fd1fabb7SAndroid Build Coastguard Worker if (negative.PrivateLength ())
6539*fd1fabb7SAndroid Build Coastguard Worker {
6540*fd1fabb7SAndroid Build Coastguard Worker
6541*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagPrivateData);
6542*fd1fabb7SAndroid Build Coastguard Worker
6543*fd1fabb7SAndroid Build Coastguard Worker }
6544*fd1fabb7SAndroid Build Coastguard Worker
6545*fd1fabb7SAndroid Build Coastguard Worker // Proxy size tags.
6546*fd1fabb7SAndroid Build Coastguard Worker
6547*fd1fabb7SAndroid Build Coastguard Worker uint32 originalDefaultFinalSizeData [2];
6548*fd1fabb7SAndroid Build Coastguard Worker
6549*fd1fabb7SAndroid Build Coastguard Worker originalDefaultFinalSizeData [0] = negative.OriginalDefaultFinalSize ().h;
6550*fd1fabb7SAndroid Build Coastguard Worker originalDefaultFinalSizeData [1] = negative.OriginalDefaultFinalSize ().v;
6551*fd1fabb7SAndroid Build Coastguard Worker
6552*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr tagOriginalDefaultFinalSize (tcOriginalDefaultFinalSize,
6553*fd1fabb7SAndroid Build Coastguard Worker originalDefaultFinalSizeData,
6554*fd1fabb7SAndroid Build Coastguard Worker 2);
6555*fd1fabb7SAndroid Build Coastguard Worker
6556*fd1fabb7SAndroid Build Coastguard Worker if (saveOriginalDefaultFinalSize)
6557*fd1fabb7SAndroid Build Coastguard Worker {
6558*fd1fabb7SAndroid Build Coastguard Worker
6559*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOriginalDefaultFinalSize);
6560*fd1fabb7SAndroid Build Coastguard Worker
6561*fd1fabb7SAndroid Build Coastguard Worker }
6562*fd1fabb7SAndroid Build Coastguard Worker
6563*fd1fabb7SAndroid Build Coastguard Worker uint32 originalBestQualityFinalSizeData [2];
6564*fd1fabb7SAndroid Build Coastguard Worker
6565*fd1fabb7SAndroid Build Coastguard Worker originalBestQualityFinalSizeData [0] = negative.OriginalBestQualityFinalSize ().h;
6566*fd1fabb7SAndroid Build Coastguard Worker originalBestQualityFinalSizeData [1] = negative.OriginalBestQualityFinalSize ().v;
6567*fd1fabb7SAndroid Build Coastguard Worker
6568*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr tagOriginalBestQualityFinalSize (tcOriginalBestQualityFinalSize,
6569*fd1fabb7SAndroid Build Coastguard Worker originalBestQualityFinalSizeData,
6570*fd1fabb7SAndroid Build Coastguard Worker 2);
6571*fd1fabb7SAndroid Build Coastguard Worker
6572*fd1fabb7SAndroid Build Coastguard Worker if (saveOriginalBestQualityFinalSize)
6573*fd1fabb7SAndroid Build Coastguard Worker {
6574*fd1fabb7SAndroid Build Coastguard Worker
6575*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOriginalBestQualityFinalSize);
6576*fd1fabb7SAndroid Build Coastguard Worker
6577*fd1fabb7SAndroid Build Coastguard Worker }
6578*fd1fabb7SAndroid Build Coastguard Worker
6579*fd1fabb7SAndroid Build Coastguard Worker dng_urational originalDefaultCropSizeData [2];
6580*fd1fabb7SAndroid Build Coastguard Worker
6581*fd1fabb7SAndroid Build Coastguard Worker originalDefaultCropSizeData [0] = negative.OriginalDefaultCropSizeH ();
6582*fd1fabb7SAndroid Build Coastguard Worker originalDefaultCropSizeData [1] = negative.OriginalDefaultCropSizeV ();
6583*fd1fabb7SAndroid Build Coastguard Worker
6584*fd1fabb7SAndroid Build Coastguard Worker tag_urational_ptr tagOriginalDefaultCropSize (tcOriginalDefaultCropSize,
6585*fd1fabb7SAndroid Build Coastguard Worker originalDefaultCropSizeData,
6586*fd1fabb7SAndroid Build Coastguard Worker 2);
6587*fd1fabb7SAndroid Build Coastguard Worker
6588*fd1fabb7SAndroid Build Coastguard Worker if (saveOriginalDefaultCropSize)
6589*fd1fabb7SAndroid Build Coastguard Worker {
6590*fd1fabb7SAndroid Build Coastguard Worker
6591*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagOriginalDefaultCropSize);
6592*fd1fabb7SAndroid Build Coastguard Worker
6593*fd1fabb7SAndroid Build Coastguard Worker }
6594*fd1fabb7SAndroid Build Coastguard Worker
6595*fd1fabb7SAndroid Build Coastguard Worker // Opcode list 1.
6596*fd1fabb7SAndroid Build Coastguard Worker
6597*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> opcodeList1Data (negative.OpcodeList1 ().Spool (host));
6598*fd1fabb7SAndroid Build Coastguard Worker
6599*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr tagOpcodeList1 (tcOpcodeList1,
6600*fd1fabb7SAndroid Build Coastguard Worker ttUndefined,
6601*fd1fabb7SAndroid Build Coastguard Worker opcodeList1Data.Get () ? opcodeList1Data->LogicalSize () : 0,
6602*fd1fabb7SAndroid Build Coastguard Worker opcodeList1Data.Get () ? opcodeList1Data->Buffer () : NULL);
6603*fd1fabb7SAndroid Build Coastguard Worker
6604*fd1fabb7SAndroid Build Coastguard Worker if (opcodeList1Data.Get ())
6605*fd1fabb7SAndroid Build Coastguard Worker {
6606*fd1fabb7SAndroid Build Coastguard Worker
6607*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagOpcodeList1);
6608*fd1fabb7SAndroid Build Coastguard Worker
6609*fd1fabb7SAndroid Build Coastguard Worker }
6610*fd1fabb7SAndroid Build Coastguard Worker
6611*fd1fabb7SAndroid Build Coastguard Worker // Opcode list 2.
6612*fd1fabb7SAndroid Build Coastguard Worker
6613*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> opcodeList2Data (negative.OpcodeList2 ().Spool (host));
6614*fd1fabb7SAndroid Build Coastguard Worker
6615*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr tagOpcodeList2 (tcOpcodeList2,
6616*fd1fabb7SAndroid Build Coastguard Worker ttUndefined,
6617*fd1fabb7SAndroid Build Coastguard Worker opcodeList2Data.Get () ? opcodeList2Data->LogicalSize () : 0,
6618*fd1fabb7SAndroid Build Coastguard Worker opcodeList2Data.Get () ? opcodeList2Data->Buffer () : NULL);
6619*fd1fabb7SAndroid Build Coastguard Worker
6620*fd1fabb7SAndroid Build Coastguard Worker if (opcodeList2Data.Get ())
6621*fd1fabb7SAndroid Build Coastguard Worker {
6622*fd1fabb7SAndroid Build Coastguard Worker
6623*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagOpcodeList2);
6624*fd1fabb7SAndroid Build Coastguard Worker
6625*fd1fabb7SAndroid Build Coastguard Worker }
6626*fd1fabb7SAndroid Build Coastguard Worker
6627*fd1fabb7SAndroid Build Coastguard Worker // Opcode list 3.
6628*fd1fabb7SAndroid Build Coastguard Worker
6629*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_memory_block> opcodeList3Data (negative.OpcodeList3 ().Spool (host));
6630*fd1fabb7SAndroid Build Coastguard Worker
6631*fd1fabb7SAndroid Build Coastguard Worker tag_data_ptr tagOpcodeList3 (tcOpcodeList3,
6632*fd1fabb7SAndroid Build Coastguard Worker ttUndefined,
6633*fd1fabb7SAndroid Build Coastguard Worker opcodeList3Data.Get () ? opcodeList3Data->LogicalSize () : 0,
6634*fd1fabb7SAndroid Build Coastguard Worker opcodeList3Data.Get () ? opcodeList3Data->Buffer () : NULL);
6635*fd1fabb7SAndroid Build Coastguard Worker
6636*fd1fabb7SAndroid Build Coastguard Worker if (opcodeList3Data.Get ())
6637*fd1fabb7SAndroid Build Coastguard Worker {
6638*fd1fabb7SAndroid Build Coastguard Worker
6639*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Add (&tagOpcodeList3);
6640*fd1fabb7SAndroid Build Coastguard Worker
6641*fd1fabb7SAndroid Build Coastguard Worker }
6642*fd1fabb7SAndroid Build Coastguard Worker
6643*fd1fabb7SAndroid Build Coastguard Worker // Transparency mask, if any.
6644*fd1fabb7SAndroid Build Coastguard Worker
6645*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_ifd> maskInfo;
6646*fd1fabb7SAndroid Build Coastguard Worker
6647*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_tiff_directory> maskIFD;
6648*fd1fabb7SAndroid Build Coastguard Worker
6649*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_basic_tag_set> maskBasic;
6650*fd1fabb7SAndroid Build Coastguard Worker
6651*fd1fabb7SAndroid Build Coastguard Worker if (hasTransparencyMask)
6652*fd1fabb7SAndroid Build Coastguard Worker {
6653*fd1fabb7SAndroid Build Coastguard Worker
6654*fd1fabb7SAndroid Build Coastguard Worker // Create mask IFD.
6655*fd1fabb7SAndroid Build Coastguard Worker
6656*fd1fabb7SAndroid Build Coastguard Worker maskInfo.Reset (new dng_ifd);
6657*fd1fabb7SAndroid Build Coastguard Worker
6658*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fNewSubFileType = sfTransparencyMask;
6659*fd1fabb7SAndroid Build Coastguard Worker
6660*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fImageWidth = negative.RawTransparencyMask ()->Bounds ().W ();
6661*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fImageLength = negative.RawTransparencyMask ()->Bounds ().H ();
6662*fd1fabb7SAndroid Build Coastguard Worker
6663*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fSamplesPerPixel = 1;
6664*fd1fabb7SAndroid Build Coastguard Worker
6665*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fBitsPerSample [0] = negative.RawTransparencyMaskBitDepth ();
6666*fd1fabb7SAndroid Build Coastguard Worker
6667*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fPhotometricInterpretation = piTransparencyMask;
6668*fd1fabb7SAndroid Build Coastguard Worker
6669*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fCompression = uncompressed ? ccUncompressed : ccDeflate;
6670*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fPredictor = uncompressed ? cpNullPredictor : cpHorizontalDifference;
6671*fd1fabb7SAndroid Build Coastguard Worker
6672*fd1fabb7SAndroid Build Coastguard Worker if (negative.RawTransparencyMask ()->PixelType () == ttFloat)
6673*fd1fabb7SAndroid Build Coastguard Worker {
6674*fd1fabb7SAndroid Build Coastguard Worker
6675*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fSampleFormat [0] = sfFloatingPoint;
6676*fd1fabb7SAndroid Build Coastguard Worker
6677*fd1fabb7SAndroid Build Coastguard Worker if (maskInfo->fCompression == ccDeflate)
6678*fd1fabb7SAndroid Build Coastguard Worker {
6679*fd1fabb7SAndroid Build Coastguard Worker maskInfo->fPredictor = cpFloatingPoint;
6680*fd1fabb7SAndroid Build Coastguard Worker }
6681*fd1fabb7SAndroid Build Coastguard Worker
6682*fd1fabb7SAndroid Build Coastguard Worker }
6683*fd1fabb7SAndroid Build Coastguard Worker
6684*fd1fabb7SAndroid Build Coastguard Worker if (maskInfo->fCompression == ccDeflate)
6685*fd1fabb7SAndroid Build Coastguard Worker {
6686*fd1fabb7SAndroid Build Coastguard Worker maskInfo->FindTileSize (512 * 1024);
6687*fd1fabb7SAndroid Build Coastguard Worker }
6688*fd1fabb7SAndroid Build Coastguard Worker else
6689*fd1fabb7SAndroid Build Coastguard Worker {
6690*fd1fabb7SAndroid Build Coastguard Worker maskInfo->SetSingleStrip ();
6691*fd1fabb7SAndroid Build Coastguard Worker }
6692*fd1fabb7SAndroid Build Coastguard Worker
6693*fd1fabb7SAndroid Build Coastguard Worker // Create mask tiff directory.
6694*fd1fabb7SAndroid Build Coastguard Worker
6695*fd1fabb7SAndroid Build Coastguard Worker maskIFD.Reset (new dng_tiff_directory);
6696*fd1fabb7SAndroid Build Coastguard Worker
6697*fd1fabb7SAndroid Build Coastguard Worker // Add mask basic tag set.
6698*fd1fabb7SAndroid Build Coastguard Worker
6699*fd1fabb7SAndroid Build Coastguard Worker maskBasic.Reset (new dng_basic_tag_set (*maskIFD, *maskInfo));
6700*fd1fabb7SAndroid Build Coastguard Worker
6701*fd1fabb7SAndroid Build Coastguard Worker }
6702*fd1fabb7SAndroid Build Coastguard Worker
6703*fd1fabb7SAndroid Build Coastguard Worker // Add other subfiles.
6704*fd1fabb7SAndroid Build Coastguard Worker
6705*fd1fabb7SAndroid Build Coastguard Worker uint32 subFileCount = thumbnail ? 1 : 0;
6706*fd1fabb7SAndroid Build Coastguard Worker
6707*fd1fabb7SAndroid Build Coastguard Worker if (hasTransparencyMask)
6708*fd1fabb7SAndroid Build Coastguard Worker {
6709*fd1fabb7SAndroid Build Coastguard Worker subFileCount++;
6710*fd1fabb7SAndroid Build Coastguard Worker }
6711*fd1fabb7SAndroid Build Coastguard Worker
6712*fd1fabb7SAndroid Build Coastguard Worker // Add previews.
6713*fd1fabb7SAndroid Build Coastguard Worker
6714*fd1fabb7SAndroid Build Coastguard Worker uint32 previewCount = previewList ? previewList->Count () : 0;
6715*fd1fabb7SAndroid Build Coastguard Worker
6716*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_tiff_directory> previewIFD [kMaxDNGPreviews];
6717*fd1fabb7SAndroid Build Coastguard Worker
6718*fd1fabb7SAndroid Build Coastguard Worker AutoPtr<dng_basic_tag_set> previewBasic [kMaxDNGPreviews];
6719*fd1fabb7SAndroid Build Coastguard Worker
6720*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < previewCount; j++)
6721*fd1fabb7SAndroid Build Coastguard Worker {
6722*fd1fabb7SAndroid Build Coastguard Worker
6723*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail != &previewList->Preview (j))
6724*fd1fabb7SAndroid Build Coastguard Worker {
6725*fd1fabb7SAndroid Build Coastguard Worker
6726*fd1fabb7SAndroid Build Coastguard Worker previewIFD [j] . Reset (new dng_tiff_directory);
6727*fd1fabb7SAndroid Build Coastguard Worker
6728*fd1fabb7SAndroid Build Coastguard Worker previewBasic [j] . Reset (previewList->Preview (j).AddTagSet (*previewIFD [j]));
6729*fd1fabb7SAndroid Build Coastguard Worker
6730*fd1fabb7SAndroid Build Coastguard Worker subFileCount++;
6731*fd1fabb7SAndroid Build Coastguard Worker
6732*fd1fabb7SAndroid Build Coastguard Worker }
6733*fd1fabb7SAndroid Build Coastguard Worker
6734*fd1fabb7SAndroid Build Coastguard Worker }
6735*fd1fabb7SAndroid Build Coastguard Worker
6736*fd1fabb7SAndroid Build Coastguard Worker // And a link to the raw and JPEG image IFDs.
6737*fd1fabb7SAndroid Build Coastguard Worker
6738*fd1fabb7SAndroid Build Coastguard Worker uint32 subFileData [kMaxDNGPreviews + 2];
6739*fd1fabb7SAndroid Build Coastguard Worker
6740*fd1fabb7SAndroid Build Coastguard Worker tag_uint32_ptr tagSubFile (tcSubIFDs,
6741*fd1fabb7SAndroid Build Coastguard Worker subFileData,
6742*fd1fabb7SAndroid Build Coastguard Worker subFileCount);
6743*fd1fabb7SAndroid Build Coastguard Worker
6744*fd1fabb7SAndroid Build Coastguard Worker if (subFileCount)
6745*fd1fabb7SAndroid Build Coastguard Worker {
6746*fd1fabb7SAndroid Build Coastguard Worker
6747*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Add (&tagSubFile);
6748*fd1fabb7SAndroid Build Coastguard Worker
6749*fd1fabb7SAndroid Build Coastguard Worker }
6750*fd1fabb7SAndroid Build Coastguard Worker
6751*fd1fabb7SAndroid Build Coastguard Worker // Skip past the header and IFDs for now.
6752*fd1fabb7SAndroid Build Coastguard Worker
6753*fd1fabb7SAndroid Build Coastguard Worker uint32 currentOffset = 8;
6754*fd1fabb7SAndroid Build Coastguard Worker
6755*fd1fabb7SAndroid Build Coastguard Worker currentOffset += mainIFD.Size ();
6756*fd1fabb7SAndroid Build Coastguard Worker
6757*fd1fabb7SAndroid Build Coastguard Worker uint32 subFileIndex = 0;
6758*fd1fabb7SAndroid Build Coastguard Worker
6759*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail)
6760*fd1fabb7SAndroid Build Coastguard Worker {
6761*fd1fabb7SAndroid Build Coastguard Worker
6762*fd1fabb7SAndroid Build Coastguard Worker subFileData [subFileIndex++] = currentOffset;
6763*fd1fabb7SAndroid Build Coastguard Worker
6764*fd1fabb7SAndroid Build Coastguard Worker currentOffset += rawIFD.Size ();
6765*fd1fabb7SAndroid Build Coastguard Worker
6766*fd1fabb7SAndroid Build Coastguard Worker }
6767*fd1fabb7SAndroid Build Coastguard Worker
6768*fd1fabb7SAndroid Build Coastguard Worker if (hasTransparencyMask)
6769*fd1fabb7SAndroid Build Coastguard Worker {
6770*fd1fabb7SAndroid Build Coastguard Worker
6771*fd1fabb7SAndroid Build Coastguard Worker subFileData [subFileIndex++] = currentOffset;
6772*fd1fabb7SAndroid Build Coastguard Worker
6773*fd1fabb7SAndroid Build Coastguard Worker currentOffset += maskIFD->Size ();
6774*fd1fabb7SAndroid Build Coastguard Worker
6775*fd1fabb7SAndroid Build Coastguard Worker }
6776*fd1fabb7SAndroid Build Coastguard Worker
6777*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < previewCount; j++)
6778*fd1fabb7SAndroid Build Coastguard Worker {
6779*fd1fabb7SAndroid Build Coastguard Worker
6780*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail != &previewList->Preview (j))
6781*fd1fabb7SAndroid Build Coastguard Worker {
6782*fd1fabb7SAndroid Build Coastguard Worker
6783*fd1fabb7SAndroid Build Coastguard Worker subFileData [subFileIndex++] = currentOffset;
6784*fd1fabb7SAndroid Build Coastguard Worker
6785*fd1fabb7SAndroid Build Coastguard Worker currentOffset += previewIFD [j]->Size ();
6786*fd1fabb7SAndroid Build Coastguard Worker
6787*fd1fabb7SAndroid Build Coastguard Worker }
6788*fd1fabb7SAndroid Build Coastguard Worker
6789*fd1fabb7SAndroid Build Coastguard Worker }
6790*fd1fabb7SAndroid Build Coastguard Worker
6791*fd1fabb7SAndroid Build Coastguard Worker exifSet.Locate (currentOffset);
6792*fd1fabb7SAndroid Build Coastguard Worker
6793*fd1fabb7SAndroid Build Coastguard Worker currentOffset += exifSet.Size ();
6794*fd1fabb7SAndroid Build Coastguard Worker
6795*fd1fabb7SAndroid Build Coastguard Worker stream.SetWritePosition (currentOffset);
6796*fd1fabb7SAndroid Build Coastguard Worker
6797*fd1fabb7SAndroid Build Coastguard Worker // Write the extra profiles.
6798*fd1fabb7SAndroid Build Coastguard Worker
6799*fd1fabb7SAndroid Build Coastguard Worker if (extraProfileCount)
6800*fd1fabb7SAndroid Build Coastguard Worker {
6801*fd1fabb7SAndroid Build Coastguard Worker
6802*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < extraProfileCount; j++)
6803*fd1fabb7SAndroid Build Coastguard Worker {
6804*fd1fabb7SAndroid Build Coastguard Worker
6805*fd1fabb7SAndroid Build Coastguard Worker extraProfileOffsets.Buffer_uint32 () [j] = (uint32) stream.Position ();
6806*fd1fabb7SAndroid Build Coastguard Worker
6807*fd1fabb7SAndroid Build Coastguard Worker uint32 index = extraProfileIndex [j];
6808*fd1fabb7SAndroid Build Coastguard Worker
6809*fd1fabb7SAndroid Build Coastguard Worker const dng_camera_profile &profile (negative.ProfileByIndex (index));
6810*fd1fabb7SAndroid Build Coastguard Worker
6811*fd1fabb7SAndroid Build Coastguard Worker tiff_dng_extended_color_profile extraWriter (profile);
6812*fd1fabb7SAndroid Build Coastguard Worker
6813*fd1fabb7SAndroid Build Coastguard Worker extraWriter.Put (stream, false);
6814*fd1fabb7SAndroid Build Coastguard Worker
6815*fd1fabb7SAndroid Build Coastguard Worker }
6816*fd1fabb7SAndroid Build Coastguard Worker
6817*fd1fabb7SAndroid Build Coastguard Worker }
6818*fd1fabb7SAndroid Build Coastguard Worker
6819*fd1fabb7SAndroid Build Coastguard Worker // Write the thumbnail data.
6820*fd1fabb7SAndroid Build Coastguard Worker
6821*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail)
6822*fd1fabb7SAndroid Build Coastguard Worker {
6823*fd1fabb7SAndroid Build Coastguard Worker
6824*fd1fabb7SAndroid Build Coastguard Worker thumbnail->WriteData (host,
6825*fd1fabb7SAndroid Build Coastguard Worker *this,
6826*fd1fabb7SAndroid Build Coastguard Worker *thmBasic,
6827*fd1fabb7SAndroid Build Coastguard Worker stream);
6828*fd1fabb7SAndroid Build Coastguard Worker
6829*fd1fabb7SAndroid Build Coastguard Worker }
6830*fd1fabb7SAndroid Build Coastguard Worker
6831*fd1fabb7SAndroid Build Coastguard Worker // Write the preview data.
6832*fd1fabb7SAndroid Build Coastguard Worker
6833*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < previewCount; j++)
6834*fd1fabb7SAndroid Build Coastguard Worker {
6835*fd1fabb7SAndroid Build Coastguard Worker
6836*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail != &previewList->Preview (j))
6837*fd1fabb7SAndroid Build Coastguard Worker {
6838*fd1fabb7SAndroid Build Coastguard Worker
6839*fd1fabb7SAndroid Build Coastguard Worker previewList->Preview (j).WriteData (host,
6840*fd1fabb7SAndroid Build Coastguard Worker *this,
6841*fd1fabb7SAndroid Build Coastguard Worker *previewBasic [j],
6842*fd1fabb7SAndroid Build Coastguard Worker stream);
6843*fd1fabb7SAndroid Build Coastguard Worker
6844*fd1fabb7SAndroid Build Coastguard Worker }
6845*fd1fabb7SAndroid Build Coastguard Worker
6846*fd1fabb7SAndroid Build Coastguard Worker }
6847*fd1fabb7SAndroid Build Coastguard Worker
6848*fd1fabb7SAndroid Build Coastguard Worker // Write the raw data.
6849*fd1fabb7SAndroid Build Coastguard Worker
6850*fd1fabb7SAndroid Build Coastguard Worker if (rawJPEGImage)
6851*fd1fabb7SAndroid Build Coastguard Worker {
6852*fd1fabb7SAndroid Build Coastguard Worker
6853*fd1fabb7SAndroid Build Coastguard Worker uint32 tileCount = info.TilesAcross () *
6854*fd1fabb7SAndroid Build Coastguard Worker info.TilesDown ();
6855*fd1fabb7SAndroid Build Coastguard Worker
6856*fd1fabb7SAndroid Build Coastguard Worker for (uint32 tileIndex = 0; tileIndex < tileCount; tileIndex++)
6857*fd1fabb7SAndroid Build Coastguard Worker {
6858*fd1fabb7SAndroid Build Coastguard Worker
6859*fd1fabb7SAndroid Build Coastguard Worker // Remember this offset.
6860*fd1fabb7SAndroid Build Coastguard Worker
6861*fd1fabb7SAndroid Build Coastguard Worker uint32 tileOffset = (uint32) stream.Position ();
6862*fd1fabb7SAndroid Build Coastguard Worker
6863*fd1fabb7SAndroid Build Coastguard Worker rawBasic.SetTileOffset (tileIndex, tileOffset);
6864*fd1fabb7SAndroid Build Coastguard Worker
6865*fd1fabb7SAndroid Build Coastguard Worker // Write JPEG data.
6866*fd1fabb7SAndroid Build Coastguard Worker
6867*fd1fabb7SAndroid Build Coastguard Worker stream.Put (rawJPEGImage->fJPEGData [tileIndex]->Buffer (),
6868*fd1fabb7SAndroid Build Coastguard Worker rawJPEGImage->fJPEGData [tileIndex]->LogicalSize ());
6869*fd1fabb7SAndroid Build Coastguard Worker
6870*fd1fabb7SAndroid Build Coastguard Worker // Update tile count.
6871*fd1fabb7SAndroid Build Coastguard Worker
6872*fd1fabb7SAndroid Build Coastguard Worker uint32 tileByteCount = (uint32) stream.Position () - tileOffset;
6873*fd1fabb7SAndroid Build Coastguard Worker
6874*fd1fabb7SAndroid Build Coastguard Worker rawBasic.SetTileByteCount (tileIndex, tileByteCount);
6875*fd1fabb7SAndroid Build Coastguard Worker
6876*fd1fabb7SAndroid Build Coastguard Worker // Keep the tiles on even byte offsets.
6877*fd1fabb7SAndroid Build Coastguard Worker
6878*fd1fabb7SAndroid Build Coastguard Worker if (tileByteCount & 1)
6879*fd1fabb7SAndroid Build Coastguard Worker {
6880*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint8 (0);
6881*fd1fabb7SAndroid Build Coastguard Worker }
6882*fd1fabb7SAndroid Build Coastguard Worker
6883*fd1fabb7SAndroid Build Coastguard Worker }
6884*fd1fabb7SAndroid Build Coastguard Worker
6885*fd1fabb7SAndroid Build Coastguard Worker }
6886*fd1fabb7SAndroid Build Coastguard Worker
6887*fd1fabb7SAndroid Build Coastguard Worker else
6888*fd1fabb7SAndroid Build Coastguard Worker {
6889*fd1fabb7SAndroid Build Coastguard Worker
6890*fd1fabb7SAndroid Build Coastguard Worker #if qDNGValidate
6891*fd1fabb7SAndroid Build Coastguard Worker dng_timer timer ("Write raw image time");
6892*fd1fabb7SAndroid Build Coastguard Worker #endif
6893*fd1fabb7SAndroid Build Coastguard Worker
6894*fd1fabb7SAndroid Build Coastguard Worker WriteImage (host,
6895*fd1fabb7SAndroid Build Coastguard Worker info,
6896*fd1fabb7SAndroid Build Coastguard Worker rawBasic,
6897*fd1fabb7SAndroid Build Coastguard Worker stream,
6898*fd1fabb7SAndroid Build Coastguard Worker rawImage,
6899*fd1fabb7SAndroid Build Coastguard Worker fakeChannels);
6900*fd1fabb7SAndroid Build Coastguard Worker
6901*fd1fabb7SAndroid Build Coastguard Worker }
6902*fd1fabb7SAndroid Build Coastguard Worker
6903*fd1fabb7SAndroid Build Coastguard Worker // Write transparency mask image.
6904*fd1fabb7SAndroid Build Coastguard Worker
6905*fd1fabb7SAndroid Build Coastguard Worker if (hasTransparencyMask)
6906*fd1fabb7SAndroid Build Coastguard Worker {
6907*fd1fabb7SAndroid Build Coastguard Worker
6908*fd1fabb7SAndroid Build Coastguard Worker #if qDNGValidate
6909*fd1fabb7SAndroid Build Coastguard Worker dng_timer timer ("Write transparency mask time");
6910*fd1fabb7SAndroid Build Coastguard Worker #endif
6911*fd1fabb7SAndroid Build Coastguard Worker
6912*fd1fabb7SAndroid Build Coastguard Worker WriteImage (host,
6913*fd1fabb7SAndroid Build Coastguard Worker *maskInfo,
6914*fd1fabb7SAndroid Build Coastguard Worker *maskBasic,
6915*fd1fabb7SAndroid Build Coastguard Worker stream,
6916*fd1fabb7SAndroid Build Coastguard Worker *negative.RawTransparencyMask ());
6917*fd1fabb7SAndroid Build Coastguard Worker
6918*fd1fabb7SAndroid Build Coastguard Worker }
6919*fd1fabb7SAndroid Build Coastguard Worker
6920*fd1fabb7SAndroid Build Coastguard Worker // Trim the file to this length.
6921*fd1fabb7SAndroid Build Coastguard Worker
6922*fd1fabb7SAndroid Build Coastguard Worker stream.SetLength (stream.Position ());
6923*fd1fabb7SAndroid Build Coastguard Worker
6924*fd1fabb7SAndroid Build Coastguard Worker // DNG has a 4G size limit.
6925*fd1fabb7SAndroid Build Coastguard Worker
6926*fd1fabb7SAndroid Build Coastguard Worker if (stream.Length () > 0x0FFFFFFFFL)
6927*fd1fabb7SAndroid Build Coastguard Worker {
6928*fd1fabb7SAndroid Build Coastguard Worker ThrowImageTooBigDNG ();
6929*fd1fabb7SAndroid Build Coastguard Worker }
6930*fd1fabb7SAndroid Build Coastguard Worker
6931*fd1fabb7SAndroid Build Coastguard Worker // Write TIFF Header.
6932*fd1fabb7SAndroid Build Coastguard Worker
6933*fd1fabb7SAndroid Build Coastguard Worker stream.SetWritePosition (0);
6934*fd1fabb7SAndroid Build Coastguard Worker
6935*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (stream.BigEndian () ? byteOrderMM : byteOrderII);
6936*fd1fabb7SAndroid Build Coastguard Worker
6937*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint16 (42);
6938*fd1fabb7SAndroid Build Coastguard Worker
6939*fd1fabb7SAndroid Build Coastguard Worker stream.Put_uint32 (8);
6940*fd1fabb7SAndroid Build Coastguard Worker
6941*fd1fabb7SAndroid Build Coastguard Worker // Write the IFDs.
6942*fd1fabb7SAndroid Build Coastguard Worker
6943*fd1fabb7SAndroid Build Coastguard Worker mainIFD.Put (stream);
6944*fd1fabb7SAndroid Build Coastguard Worker
6945*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail)
6946*fd1fabb7SAndroid Build Coastguard Worker {
6947*fd1fabb7SAndroid Build Coastguard Worker
6948*fd1fabb7SAndroid Build Coastguard Worker rawIFD.Put (stream);
6949*fd1fabb7SAndroid Build Coastguard Worker
6950*fd1fabb7SAndroid Build Coastguard Worker }
6951*fd1fabb7SAndroid Build Coastguard Worker
6952*fd1fabb7SAndroid Build Coastguard Worker if (hasTransparencyMask)
6953*fd1fabb7SAndroid Build Coastguard Worker {
6954*fd1fabb7SAndroid Build Coastguard Worker
6955*fd1fabb7SAndroid Build Coastguard Worker maskIFD->Put (stream);
6956*fd1fabb7SAndroid Build Coastguard Worker
6957*fd1fabb7SAndroid Build Coastguard Worker }
6958*fd1fabb7SAndroid Build Coastguard Worker
6959*fd1fabb7SAndroid Build Coastguard Worker for (j = 0; j < previewCount; j++)
6960*fd1fabb7SAndroid Build Coastguard Worker {
6961*fd1fabb7SAndroid Build Coastguard Worker
6962*fd1fabb7SAndroid Build Coastguard Worker if (thumbnail != &previewList->Preview (j))
6963*fd1fabb7SAndroid Build Coastguard Worker {
6964*fd1fabb7SAndroid Build Coastguard Worker
6965*fd1fabb7SAndroid Build Coastguard Worker previewIFD [j]->Put (stream);
6966*fd1fabb7SAndroid Build Coastguard Worker
6967*fd1fabb7SAndroid Build Coastguard Worker }
6968*fd1fabb7SAndroid Build Coastguard Worker
6969*fd1fabb7SAndroid Build Coastguard Worker }
6970*fd1fabb7SAndroid Build Coastguard Worker
6971*fd1fabb7SAndroid Build Coastguard Worker exifSet.Put (stream);
6972*fd1fabb7SAndroid Build Coastguard Worker
6973*fd1fabb7SAndroid Build Coastguard Worker stream.Flush ();
6974*fd1fabb7SAndroid Build Coastguard Worker
6975*fd1fabb7SAndroid Build Coastguard Worker }
6976*fd1fabb7SAndroid Build Coastguard Worker
6977*fd1fabb7SAndroid Build Coastguard Worker /*****************************************************************************/
6978