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 /*****************************************************************************/