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 
dng_host(dng_memory_allocator * allocator,dng_abort_sniffer * sniffer)39 dng_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 
~dng_host()62 dng_host::~dng_host ()
63 	{
64 
65 	}
66 
67 /*****************************************************************************/
68 
Allocator()69 dng_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 
Allocate(uint32 logicalSize)90 dng_memory_block * dng_host::Allocate (uint32 logicalSize)
91 	{
92 
93 	return Allocator ().Allocate (logicalSize);
94 
95 	}
96 
97 /*****************************************************************************/
98 
SniffForAbort()99 void dng_host::SniffForAbort ()
100 	{
101 
102 	dng_abort_sniffer::SniffForAbort (Sniffer ());
103 
104 	}
105 
106 /*****************************************************************************/
107 
ValidateSizes()108 void 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 
SaveDNGVersion() const193 uint32 dng_host::SaveDNGVersion () const
194 	{
195 
196 	return fSaveDNGVersion;
197 
198 	}
199 
200 /*****************************************************************************/
201 
SaveLinearDNG(const dng_negative &) const202 bool dng_host::SaveLinearDNG (const dng_negative & /* negative */) const
203 	{
204 
205 	return fSaveLinearDNG;
206 
207 	}
208 
209 /*****************************************************************************/
210 
IsTransientError(dng_error_code code)211 bool 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 
PerformAreaTask(dng_area_task & task,const dng_rect & area)234 void 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 
PerformAreaTaskThreads()247 uint32 dng_host::PerformAreaTaskThreads ()
248 	{
249 
250 	return 1;
251 
252 	}
253 
254 /*****************************************************************************/
255 
Make_dng_exif()256 dng_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 
Make_dng_xmp()276 dng_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 
Make_dng_shared()296 dng_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 
Make_dng_ifd()314 dng_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 
Make_dng_negative()332 dng_negative * dng_host::Make_dng_negative ()
333 	{
334 
335 	return dng_negative::Make (*this);
336 
337 	}
338 
339 /*****************************************************************************/
340 
Make_dng_image(const dng_rect & bounds,uint32 planes,uint32 pixelType)341 dng_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 
Make_dng_opcode(uint32 opcodeID,dng_stream & stream)364 dng_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 
ApplyOpcodeList(dng_opcode_list & list,dng_negative & negative,AutoPtr<dng_image> & image)520 void 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 
ResampleImage(const dng_image & srcImage,dng_image & dstImage)533 void 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