File indexing completed on 2025-01-19 03:54:58
0001 /*****************************************************************************/ 0002 // Copyright 2006-2019 Adobe Systems Incorporated 0003 // All Rights Reserved. 0004 // 0005 // NOTICE: Adobe permits you to use, modify, and distribute this file in 0006 // accordance with the terms of the Adobe license agreement accompanying it. 0007 /*****************************************************************************/ 0008 0009 #include "dng_host.h" 0010 0011 #include "dng_abort_sniffer.h" 0012 #include "dng_area_task.h" 0013 #include "dng_bad_pixels.h" 0014 #include "dng_exceptions.h" 0015 #include "dng_exif.h" 0016 #include "dng_gain_map.h" 0017 #include "dng_ifd.h" 0018 #include "dng_lens_correction.h" 0019 #include "dng_memory.h" 0020 #include "dng_misc_opcodes.h" 0021 #include "dng_negative.h" 0022 #include "dng_resample.h" 0023 #include "dng_shared.h" 0024 #include "dng_simple_image.h" 0025 #include "dng_xmp.h" 0026 0027 /*****************************************************************************/ 0028 0029 dng_host::dng_host (dng_memory_allocator *allocator, 0030 dng_abort_sniffer *sniffer) 0031 0032 : fAllocator (allocator) 0033 , fSniffer (sniffer) 0034 0035 , fNeedsMeta (true) 0036 , fNeedsImage (true) 0037 , fForPreview (false) 0038 , fMinimumSize (0) 0039 , fPreferredSize (0) 0040 , fMaximumSize (0) 0041 , fCropFactor (1.0) 0042 , fSaveDNGVersion (dngVersion_None) 0043 , fSaveLinearDNG (false) 0044 , fKeepOriginalFile (false) 0045 , fForFastSaveToDNG (false) 0046 , fFastSaveToDNGSize (0) 0047 , fPreserveStage2 (false) 0048 0049 { 0050 0051 } 0052 0053 /*****************************************************************************/ 0054 0055 dng_host::~dng_host () 0056 { 0057 0058 } 0059 0060 /*****************************************************************************/ 0061 0062 dng_memory_allocator & dng_host::Allocator () 0063 { 0064 0065 if (fAllocator) 0066 { 0067 0068 return *fAllocator; 0069 0070 } 0071 0072 else 0073 { 0074 0075 return gDefaultDNGMemoryAllocator; 0076 0077 } 0078 0079 } 0080 0081 /*****************************************************************************/ 0082 0083 dng_memory_block * dng_host::Allocate (uint32 logicalSize) 0084 { 0085 0086 return Allocator ().Allocate (logicalSize); 0087 0088 } 0089 0090 /*****************************************************************************/ 0091 0092 void dng_host::SniffForAbort () 0093 { 0094 0095 dng_abort_sniffer::SniffForAbort (Sniffer ()); 0096 0097 } 0098 0099 /*****************************************************************************/ 0100 0101 void dng_host::ValidateSizes () 0102 { 0103 0104 // The maximum size limits the other two sizes. 0105 0106 if (MaximumSize ()) 0107 { 0108 SetMinimumSize (Min_uint32 (MinimumSize (), MaximumSize ())); 0109 SetPreferredSize (Min_uint32 (PreferredSize (), MaximumSize ())); 0110 } 0111 0112 // If we have a preferred size, it limits the minimum size. 0113 0114 if (PreferredSize ()) 0115 { 0116 SetMinimumSize (Min_uint32 (MinimumSize (), PreferredSize ())); 0117 } 0118 0119 // Else find default value for preferred size. 0120 0121 else 0122 { 0123 0124 // If preferred size is zero, then we want the maximim 0125 // size image. 0126 0127 if (MaximumSize ()) 0128 { 0129 SetPreferredSize (MaximumSize ()); 0130 } 0131 0132 } 0133 0134 // If we don't have a minimum size, find default. 0135 0136 if (!MinimumSize ()) 0137 { 0138 0139 // A common size for embedded thumbnails is 120 by 160 pixels, 0140 // So allow 120 by 160 pixels to be used for thumbnails when the 0141 // preferred size is 256 pixel. 0142 0143 if (PreferredSize () >= 160 && PreferredSize () <= 256) 0144 { 0145 SetMinimumSize (160); 0146 } 0147 0148 // Many sensors are near a multiple of 1024 pixels in size, but after 0149 // the default crop, they are a just under. We can get an extra factor 0150 // of size reduction if we allow a slight undershoot in the final size 0151 // when computing large previews. 0152 0153 else if (PreferredSize () >= 490 && PreferredSize () <= 512) 0154 { 0155 SetMinimumSize (490); 0156 } 0157 0158 else if (PreferredSize () >= 980 && PreferredSize () <= 1024) 0159 { 0160 SetMinimumSize (980); 0161 } 0162 0163 else if (PreferredSize () >= 1470 && PreferredSize () <= 1536) 0164 { 0165 SetMinimumSize (1470); 0166 } 0167 0168 else if (PreferredSize () >= 1960 && PreferredSize () <= 2048) 0169 { 0170 SetMinimumSize (1960); 0171 } 0172 0173 else if (PreferredSize () >= 2400 && PreferredSize () <= 2560) 0174 { 0175 SetMinimumSize (2400); 0176 } 0177 0178 // The following resolutions are typically on HiDPI displays where a 0179 // greater degree of upsampling remains visually ok for previews. The 0180 // following ratios are all based on 20% upsampling in a linear 0181 // dimension. 0182 0183 else if (PreferredSize () >= 2448 && PreferredSize () <= 2880) 0184 { 0185 SetMinimumSize (2448); 0186 } 0187 0188 // 1st-generation Surface Book. 0189 0190 else if (PreferredSize () >= 2560 && PreferredSize () <= 3000) 0191 { 0192 SetMinimumSize (2560); 0193 } 0194 0195 // 4K (actually 3840). 0196 0197 else if (PreferredSize () >= 3480 && PreferredSize () <= 4096) 0198 { 0199 SetMinimumSize (3480); 0200 } 0201 0202 // Surface Studio. 0203 0204 else if (PreferredSize () >= 3824 && PreferredSize () <= 4500) 0205 { 0206 SetMinimumSize (3824); 0207 } 0208 0209 // 5K. 0210 0211 else if (PreferredSize () >= 4352 && PreferredSize () <= 5120) 0212 { 0213 SetMinimumSize (4352); 0214 } 0215 0216 // 8K. 0217 0218 else if (PreferredSize () >= 6528 && PreferredSize () <= 7680) 0219 { 0220 SetMinimumSize (6528); 0221 } 0222 0223 // Else minimum size is same as preferred size. 0224 0225 else 0226 { 0227 SetMinimumSize (PreferredSize ()); 0228 } 0229 0230 } 0231 0232 } 0233 0234 /*****************************************************************************/ 0235 0236 uint32 dng_host::SaveDNGVersion () const 0237 { 0238 0239 return fSaveDNGVersion; 0240 0241 } 0242 0243 /*****************************************************************************/ 0244 0245 bool dng_host::SaveLinearDNG (const dng_negative & /* negative */) const 0246 { 0247 0248 return fSaveLinearDNG; 0249 0250 } 0251 0252 /*****************************************************************************/ 0253 0254 bool dng_host::IsTransientError (dng_error_code code) 0255 { 0256 0257 switch (code) 0258 { 0259 0260 case dng_error_memory: 0261 case dng_error_user_canceled: 0262 { 0263 return true; 0264 } 0265 0266 default: 0267 break; 0268 0269 } 0270 0271 return false; 0272 0273 } 0274 0275 /*****************************************************************************/ 0276 0277 void dng_host::PerformAreaTask (dng_area_task &task, 0278 const dng_rect &area, 0279 dng_area_task_progress *progress) 0280 { 0281 0282 dng_area_task::Perform (task, 0283 area, 0284 &Allocator (), 0285 Sniffer (), 0286 progress); 0287 0288 } 0289 0290 /*****************************************************************************/ 0291 0292 uint32 dng_host::PerformAreaTaskThreads () 0293 { 0294 0295 return 1; 0296 0297 } 0298 0299 /*****************************************************************************/ 0300 0301 dng_exif * dng_host::Make_dng_exif () 0302 { 0303 0304 dng_exif *result = new dng_exif (); 0305 0306 if (!result) 0307 { 0308 0309 ThrowMemoryFull (); 0310 0311 } 0312 0313 return result; 0314 0315 } 0316 0317 /*****************************************************************************/ 0318 0319 dng_xmp * dng_host::Make_dng_xmp () 0320 { 0321 0322 dng_xmp *result = new dng_xmp (Allocator ()); 0323 0324 if (!result) 0325 { 0326 0327 ThrowMemoryFull (); 0328 0329 } 0330 0331 return result; 0332 0333 } 0334 0335 /*****************************************************************************/ 0336 0337 dng_shared * dng_host::Make_dng_shared () 0338 { 0339 0340 dng_shared *result = new dng_shared (); 0341 0342 if (!result) 0343 { 0344 0345 ThrowMemoryFull (); 0346 0347 } 0348 0349 return result; 0350 0351 } 0352 0353 /*****************************************************************************/ 0354 0355 dng_ifd * dng_host::Make_dng_ifd () 0356 { 0357 0358 dng_ifd *result = new dng_ifd (); 0359 0360 if (!result) 0361 { 0362 0363 ThrowMemoryFull (); 0364 0365 } 0366 0367 return result; 0368 0369 } 0370 0371 /*****************************************************************************/ 0372 0373 dng_negative * dng_host::Make_dng_negative () 0374 { 0375 0376 return dng_negative::Make (*this); 0377 0378 } 0379 0380 /*****************************************************************************/ 0381 0382 dng_image * dng_host::Make_dng_image (const dng_rect &bounds, 0383 uint32 planes, 0384 uint32 pixelType) 0385 { 0386 0387 dng_image *result = new dng_simple_image (bounds, 0388 planes, 0389 pixelType, 0390 Allocator ()); 0391 0392 if (!result) 0393 { 0394 0395 ThrowMemoryFull (); 0396 0397 } 0398 0399 return result; 0400 0401 } 0402 0403 /*****************************************************************************/ 0404 0405 dng_opcode * dng_host::Make_dng_opcode (uint32 opcodeID, 0406 dng_stream &stream) 0407 { 0408 0409 dng_opcode *result = NULL; 0410 0411 switch (opcodeID) 0412 { 0413 0414 case dngOpcode_WarpRectilinear: 0415 { 0416 0417 result = new dng_opcode_WarpRectilinear (stream); 0418 0419 break; 0420 0421 } 0422 0423 case dngOpcode_WarpFisheye: 0424 { 0425 0426 result = new dng_opcode_WarpFisheye (stream); 0427 0428 break; 0429 0430 } 0431 0432 case dngOpcode_FixVignetteRadial: 0433 { 0434 0435 result = new dng_opcode_FixVignetteRadial (stream); 0436 0437 break; 0438 0439 } 0440 0441 case dngOpcode_FixBadPixelsConstant: 0442 { 0443 0444 result = new dng_opcode_FixBadPixelsConstant (stream); 0445 0446 break; 0447 0448 } 0449 0450 case dngOpcode_FixBadPixelsList: 0451 { 0452 0453 result = new dng_opcode_FixBadPixelsList (stream); 0454 0455 break; 0456 0457 } 0458 0459 case dngOpcode_TrimBounds: 0460 { 0461 0462 result = new dng_opcode_TrimBounds (stream); 0463 0464 break; 0465 0466 } 0467 0468 case dngOpcode_MapTable: 0469 { 0470 0471 result = new dng_opcode_MapTable (*this, 0472 stream); 0473 0474 break; 0475 0476 } 0477 0478 case dngOpcode_MapPolynomial: 0479 { 0480 0481 result = new dng_opcode_MapPolynomial (stream); 0482 0483 break; 0484 0485 } 0486 0487 case dngOpcode_GainMap: 0488 { 0489 0490 result = new dng_opcode_GainMap (*this, 0491 stream); 0492 0493 break; 0494 0495 } 0496 0497 case dngOpcode_DeltaPerRow: 0498 { 0499 0500 result = new dng_opcode_DeltaPerRow (*this, 0501 stream); 0502 0503 break; 0504 0505 } 0506 0507 case dngOpcode_DeltaPerColumn: 0508 { 0509 0510 result = new dng_opcode_DeltaPerColumn (*this, 0511 stream); 0512 0513 break; 0514 0515 } 0516 0517 case dngOpcode_ScalePerRow: 0518 { 0519 0520 result = new dng_opcode_ScalePerRow (*this, 0521 stream); 0522 0523 break; 0524 0525 } 0526 0527 case dngOpcode_ScalePerColumn: 0528 { 0529 0530 result = new dng_opcode_ScalePerColumn (*this, 0531 stream); 0532 0533 break; 0534 0535 } 0536 0537 default: 0538 { 0539 0540 result = new dng_opcode_Unknown (*this, 0541 opcodeID, 0542 stream); 0543 0544 } 0545 0546 } 0547 0548 if (!result) 0549 { 0550 0551 ThrowMemoryFull (); 0552 0553 } 0554 0555 return result; 0556 0557 } 0558 0559 /*****************************************************************************/ 0560 0561 void dng_host::ApplyOpcodeList (dng_opcode_list &list, 0562 dng_negative &negative, 0563 AutoPtr<dng_image> &image) 0564 { 0565 0566 list.Apply (*this, 0567 negative, 0568 image); 0569 0570 } 0571 0572 /*****************************************************************************/ 0573 0574 void dng_host::ResampleImage (const dng_image &srcImage, 0575 dng_image &dstImage) 0576 { 0577 0578 ::ResampleImage (*this, 0579 srcImage, 0580 dstImage, 0581 srcImage.Bounds (), 0582 dstImage.Bounds (), 0583 dng_resample_bicubic::Get ()); 0584 0585 } 0586 0587 /*****************************************************************************/