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