1/*****************************************************************************/
2// Copyright 2006-2012 Adobe Systems Incorporated
3// All Rights Reserved.
4//
5// NOTICE: Adobe permits you to use, modify, and distribute this file in
6// accordance with the terms of the Adobe license agreement accompanying it.
7/*****************************************************************************/
8
9/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_host.cpp#2 $ */
10/* $DateTime: 2012/06/14 20:24:41 $ */
11/* $Change: 835078 $ */
12/* $Author: tknoll $ */
13
14/*****************************************************************************/
15
16#include "dng_host.h"
17
18#include "dng_abort_sniffer.h"
19#include "dng_area_task.h"
20#include "dng_bad_pixels.h"
21#include "dng_exceptions.h"
22#include "dng_exif.h"
23#include "dng_gain_map.h"
24#include "dng_ifd.h"
25#include "dng_lens_correction.h"
26#include "dng_memory.h"
27#include "dng_misc_opcodes.h"
28#include "dng_negative.h"
29#include "dng_resample.h"
30#include "dng_shared.h"
31#include "dng_simple_image.h"
32
33#if qDNGUseXMP
34#include "dng_xmp.h"
35#endif
36
37/*****************************************************************************/
38
39dng_host::dng_host (dng_memory_allocator *allocator,
40 dng_abort_sniffer *sniffer)
41
42 : fAllocator (allocator)
43 , fSniffer (sniffer)
44
45 , fNeedsMeta (true)
46 , fNeedsImage (true)
47 , fForPreview (false)
48 , fMinimumSize (0)
49 , fPreferredSize (0)
50 , fMaximumSize (0)
51 , fCropFactor (1.0)
52 , fSaveDNGVersion (dngVersion_None)
53 , fSaveLinearDNG (false)
54 , fKeepOriginalFile (false)
55
56 {
57
58 }
59
60/*****************************************************************************/
61
62dng_host::~dng_host ()
63 {
64
65 }
66
67/*****************************************************************************/
68
69dng_memory_allocator & dng_host::Allocator ()
70 {
71
72 if (fAllocator)
73 {
74
75 return *fAllocator;
76
77 }
78
79 else
80 {
81
82 return gDefaultDNGMemoryAllocator;
83
84 }
85
86 }
87
88/*****************************************************************************/
89
90dng_memory_block * dng_host::Allocate (uint32 logicalSize)
91 {
92
93 return Allocator ().Allocate (logicalSize);
94
95 }
96
97/*****************************************************************************/
98
99void dng_host::SniffForAbort ()
100 {
101
102 dng_abort_sniffer::SniffForAbort (Sniffer ());
103
104 }
105
106/*****************************************************************************/
107
108void dng_host::ValidateSizes ()
109 {
110
111 // The maximum size limits the other two sizes.
112
113 if (MaximumSize ())
114 {
115 SetMinimumSize (Min_uint32 (MinimumSize (), MaximumSize ()));
116 SetPreferredSize (Min_uint32 (PreferredSize (), MaximumSize ()));
117 }
118
119 // If we have a preferred size, it limits the minimum size.
120
121 if (PreferredSize ())
122 {
123 SetMinimumSize (Min_uint32 (MinimumSize (), PreferredSize ()));
124 }
125
126 // Else find default value for preferred size.
127
128 else
129 {
130
131 // If preferred size is zero, then we want the maximim
132 // size image.
133
134 if (MaximumSize ())
135 {
136 SetPreferredSize (MaximumSize ());
137 }
138
139 }
140
141 // If we don't have a minimum size, find default.
142
143 if (!MinimumSize ())
144 {
145
146 // A common size for embedded thumbnails is 120 by 160 pixels,
147 // So allow 120 by 160 pixels to be used for thumbnails when the
148 // preferred size is 256 pixel.
149
150 if (PreferredSize () >= 160 && PreferredSize () <= 256)
151 {
152 SetMinimumSize (160);
153 }
154
155 // Many sensors are near a multiple of 1024 pixels in size, but after
156 // the default crop, they are a just under. We can get an extra factor
157 // of size reduction if we allow a slight undershoot in the final size
158 // when computing large previews.
159
160 else if (PreferredSize () >= 490 && PreferredSize () <= 512)
161 {
162 SetMinimumSize (490);
163 }
164
165 else if (PreferredSize () >= 980 && PreferredSize () <= 1024)
166 {
167 SetMinimumSize (980);
168 }
169
170 else if (PreferredSize () >= 1470 && PreferredSize () <= 1536)
171 {
172 SetMinimumSize (1470);
173 }
174
175 else if (PreferredSize () >= 1960 && PreferredSize () <= 2048)
176 {
177 SetMinimumSize (1960);
178 }
179
180 // Else minimum size is same as preferred size.
181
182 else
183 {
184 SetMinimumSize (PreferredSize ());
185 }
186
187 }
188
189 }
190
191/*****************************************************************************/
192
193uint32 dng_host::SaveDNGVersion () const
194 {
195
196 return fSaveDNGVersion;
197
198 }
199
200/*****************************************************************************/
201
202bool dng_host::SaveLinearDNG (const dng_negative & /* negative */) const
203 {
204
205 return fSaveLinearDNG;
206
207 }
208
209/*****************************************************************************/
210
211bool dng_host::IsTransientError (dng_error_code code)
212 {
213
214 switch (code)
215 {
216
217 case dng_error_memory:
218 case dng_error_user_canceled:
219 {
220 return true;
221 }
222
223 default:
224 break;
225
226 }
227
228 return false;
229
230 }
231
232/*****************************************************************************/
233
234void dng_host::PerformAreaTask (dng_area_task &task,
235 const dng_rect &area)
236 {
237
238 dng_area_task::Perform (task,
239 area,
240 &Allocator (),
241 Sniffer ());
242
243 }
244
245/*****************************************************************************/
246
247uint32 dng_host::PerformAreaTaskThreads ()
248 {
249
250 return 1;
251
252 }
253
254/*****************************************************************************/
255
256dng_exif * dng_host::Make_dng_exif ()
257 {
258
259 dng_exif *result = new dng_exif ();
260
261 if (!result)
262 {
263
264 ThrowMemoryFull ();
265
266 }
267
268 return result;
269
270 }
271
272/*****************************************************************************/
273
274#if qDNGUseXMP
275
276dng_xmp * dng_host::Make_dng_xmp ()
277 {
278
279 dng_xmp *result = new dng_xmp (Allocator ());
280
281 if (!result)
282 {
283
284 ThrowMemoryFull ();
285
286 }
287
288 return result;
289
290 }
291
292#endif
293
294/*****************************************************************************/
295
296dng_shared * dng_host::Make_dng_shared ()
297 {
298
299 dng_shared *result = new dng_shared ();
300
301 if (!result)
302 {
303
304 ThrowMemoryFull ();
305
306 }
307
308 return result;
309
310 }
311
312/*****************************************************************************/
313
314dng_ifd * dng_host::Make_dng_ifd ()
315 {
316
317 dng_ifd *result = new dng_ifd ();
318
319 if (!result)
320 {
321
322 ThrowMemoryFull ();
323
324 }
325
326 return result;
327
328 }
329
330/*****************************************************************************/
331
332dng_negative * dng_host::Make_dng_negative ()
333 {
334
335 return dng_negative::Make (*this);
336
337 }
338
339/*****************************************************************************/
340
341dng_image * dng_host::Make_dng_image (const dng_rect &bounds,
342 uint32 planes,
343 uint32 pixelType)
344 {
345
346 dng_image *result = new dng_simple_image (bounds,
347 planes,
348 pixelType,
349 Allocator ());
350
351 if (!result)
352 {
353
354 ThrowMemoryFull ();
355
356 }
357
358 return result;
359
360 }
361
362/*****************************************************************************/
363
364dng_opcode * dng_host::Make_dng_opcode (uint32 opcodeID,
365 dng_stream &stream)
366 {
367
368 dng_opcode *result = NULL;
369
370 switch (opcodeID)
371 {
372
373 case dngOpcode_WarpRectilinear:
374 {
375
376 result = new dng_opcode_WarpRectilinear (stream);
377
378 break;
379
380 }
381
382 case dngOpcode_WarpFisheye:
383 {
384
385 result = new dng_opcode_WarpFisheye (stream);
386
387 break;
388
389 }
390
391 case dngOpcode_FixVignetteRadial:
392 {
393
394 result = new dng_opcode_FixVignetteRadial (stream);
395
396 break;
397
398 }
399
400 case dngOpcode_FixBadPixelsConstant:
401 {
402
403 result = new dng_opcode_FixBadPixelsConstant (stream);
404
405 break;
406
407 }
408
409 case dngOpcode_FixBadPixelsList:
410 {
411
412 result = new dng_opcode_FixBadPixelsList (stream);
413
414 break;
415
416 }
417
418 case dngOpcode_TrimBounds:
419 {
420
421 result = new dng_opcode_TrimBounds (stream);
422
423 break;
424
425 }
426
427 case dngOpcode_MapTable:
428 {
429
430 result = new dng_opcode_MapTable (*this,
431 stream);
432
433 break;
434
435 }
436
437 case dngOpcode_MapPolynomial:
438 {
439
440 result = new dng_opcode_MapPolynomial (stream);
441
442 break;
443
444 }
445
446 case dngOpcode_GainMap:
447 {
448
449 result = new dng_opcode_GainMap (*this,
450 stream);
451
452 break;
453
454 }
455
456 case dngOpcode_DeltaPerRow:
457 {
458
459 result = new dng_opcode_DeltaPerRow (*this,
460 stream);
461
462 break;
463
464 }
465
466 case dngOpcode_DeltaPerColumn:
467 {
468
469 result = new dng_opcode_DeltaPerColumn (*this,
470 stream);
471
472 break;
473
474 }
475
476 case dngOpcode_ScalePerRow:
477 {
478
479 result = new dng_opcode_ScalePerRow (*this,
480 stream);
481
482 break;
483
484 }
485
486 case dngOpcode_ScalePerColumn:
487 {
488
489 result = new dng_opcode_ScalePerColumn (*this,
490 stream);
491
492 break;
493
494 }
495
496 default:
497 {
498
499 result = new dng_opcode_Unknown (*this,
500 opcodeID,
501 stream);
502
503 }
504
505 }
506
507 if (!result)
508 {
509
510 ThrowMemoryFull ();
511
512 }
513
514 return result;
515
516 }
517
518/*****************************************************************************/
519
520void dng_host::ApplyOpcodeList (dng_opcode_list &list,
521 dng_negative &negative,
522 AutoPtr<dng_image> &image)
523 {
524
525 list.Apply (*this,
526 negative,
527 image);
528
529 }
530
531/*****************************************************************************/
532
533void dng_host::ResampleImage (const dng_image &srcImage,
534 dng_image &dstImage)
535 {
536
537 ::ResampleImage (*this,
538 srcImage,
539 dstImage,
540 srcImage.Bounds (),
541 dstImage.Bounds (),
542 dng_resample_bicubic::Get ());
543
544 }
545
546/*****************************************************************************/
547