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