File indexing completed on 2025-01-19 03:55:19

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 // Process exit codes
0010 // ------------------
0011 //
0012 // As usual, 0 indicates success.
0013 //
0014 // If an exception occurs, the exit code will be equal to:
0015 //
0016 //    DNG SDK error code - 100000 + 100
0017 //
0018 // For example, the error dng_error_memory, which has a DNG SDK error code of
0019 // 100005, is returned as an exit code of 105.
0020 //
0021 // This convention accounts for the fact that the shell truncates process exit
0022 // codes to 8 bits and that the exit code 1 is used by ASAN to signal that a
0023 // memory error occurred (so mapping the first DNG SDK error code to an exit
0024 // code of 1 would not be a good idea).
0025 
0026 /*****************************************************************************/
0027 
0028 #include "dng_color_space.h"
0029 #include "dng_date_time.h"
0030 #include "dng_exceptions.h"
0031 #include "dng_file_stream.h"
0032 #include "dng_globals.h"
0033 #include "dng_host.h"
0034 #include "dng_ifd.h"
0035 #include "dng_image_writer.h"
0036 #include "dng_info.h"
0037 #include "dng_linearization_info.h"
0038 #include "dng_mosaic_info.h"
0039 #include "dng_negative.h"
0040 #include "dng_preview.h"
0041 #include "dng_render.h"
0042 #include "dng_simple_image.h"
0043 #include "dng_tag_codes.h"
0044 #include "dng_tag_types.h"
0045 #include "dng_tag_values.h"
0046 #include "dng_xmp.h"
0047 #include "dng_xmp_sdk.h"
0048 
0049 /*****************************************************************************/
0050 
0051 #if qDNGValidateTarget
0052 
0053 /*****************************************************************************/
0054 
0055 #define kDNGValidateVersion "1.5"
0056 
0057 /*****************************************************************************/
0058 
0059 static bool gFourColorBayer = false;
0060 
0061 static int32 gMosaicPlane = -1;
0062 
0063 static bool gIgnoreEnhanced = false;
0064 
0065 static uint32 gPreferredSize = 0;
0066 static uint32 gMinimumSize   = 0;
0067 static uint32 gMaximumSize   = 0;
0068 
0069 static uint32 gProxyDNGSize = 0;
0070 
0071 static const dng_color_space *gFinalSpace = &dng_space_sRGB::Get ();
0072 
0073 static uint32 gFinalPixelType = ttByte;
0074 
0075 static dng_string gDumpStage1;
0076 static dng_string gDumpStage2;
0077 static dng_string gDumpStage3;
0078 static dng_string gDumpTransparency;
0079 static dng_string gDumpDepthMap;
0080 static dng_string gDumpTIF;
0081 static dng_string gDumpDNG;
0082 
0083 /*****************************************************************************/
0084 
0085 static dng_error_code dng_validate (const char *filename)
0086     {
0087 
0088     printf ("Validating \"%s\"...\n", filename);
0089 
0090     try
0091         {
0092 
0093         dng_file_stream stream (filename);
0094 
0095         dng_host host;
0096 
0097         host.SetPreferredSize (gPreferredSize);
0098         host.SetMinimumSize   (gMinimumSize  );
0099         host.SetMaximumSize   (gMaximumSize  );
0100 
0101         host.ValidateSizes ();
0102 
0103         if (host.MinimumSize ())
0104             {
0105 
0106             host.SetForPreview (true);
0107 
0108             gDumpDNG.Clear ();
0109 
0110             }
0111 
0112         if (gDumpDNG.NotEmpty ())
0113             {
0114 
0115             host.SetSaveDNGVersion (dngVersion_SaveDefault);
0116 
0117             host.SetSaveLinearDNG (false);
0118 
0119             host.SetKeepOriginalFile (false);
0120 
0121             }
0122 
0123         // Read into the negative.
0124 
0125         AutoPtr<dng_negative> negative;
0126 
0127             {
0128 
0129             dng_info info;
0130 
0131             info.Parse (host, stream);
0132 
0133             info.PostParse (host);
0134 
0135             if (!info.IsValidDNG ())
0136                 {
0137                 return dng_error_bad_format;
0138                 }
0139 
0140             negative.Reset (host.Make_dng_negative ());
0141 
0142             negative->Parse (host, stream, info);
0143 
0144             negative->PostParse (host, stream, info);
0145 
0146             if (info.fEnhancedIndex != -1 && !gIgnoreEnhanced)
0147                 {
0148 
0149                 dng_timer timer ("Read enhanced image time");
0150 
0151                 negative->ReadEnhancedImage (host, stream, info);
0152 
0153                 }
0154 
0155             else
0156                 {
0157 
0158                 dng_timer timer ("Raw image read time");
0159 
0160                 negative->ReadStage1Image (host, stream, info);
0161 
0162                 }
0163 
0164             if (info.fMaskIndex != -1)
0165                 {
0166 
0167                 dng_timer timer ("Transparency mask read time");
0168 
0169                 negative->ReadTransparencyMask (host, stream, info);
0170 
0171                 }
0172 
0173             if (info.fDepthIndex != -1)
0174                 {
0175 
0176                 dng_timer timer ("Depth map read time");
0177 
0178                 negative->ReadDepthMap (host, stream, info);
0179 
0180                 }
0181 
0182             negative->ValidateRawImageDigest (host);
0183 
0184             }
0185 
0186         // Option to write stage 1 image.
0187 
0188         if (gDumpStage1.NotEmpty ())
0189             {
0190 
0191             if (negative->Stage1Image ())
0192                 {
0193 
0194                 dng_file_stream stream2 (gDumpStage1.Get (), true);
0195 
0196                 const dng_image &stage1 = *negative->Stage1Image ();
0197 
0198                 dng_image_writer writer;
0199 
0200                 writer.WriteTIFF (host,
0201                                   stream2,
0202                                   stage1,
0203                                   stage1.Planes () >= 3 ? piRGB
0204                                                         : piBlackIsZero);
0205 
0206                 }
0207 
0208             gDumpStage1.Clear ();
0209 
0210             }
0211 
0212         // Metadata.
0213 
0214         negative->SynchronizeMetadata ();
0215 
0216         // Build stage 2 image.
0217 
0218         if (negative->Stage1Image ())
0219             {
0220 
0221             dng_timer timer ("Linearization time");
0222 
0223             negative->BuildStage2Image (host);
0224 
0225             }
0226 
0227         if (gDumpStage2.NotEmpty ())
0228             {
0229 
0230             dng_file_stream stream2 (gDumpStage2.Get (), true);
0231 
0232             if (negative->Stage2Image ())
0233                 {
0234 
0235                 const dng_image &stage2 = *negative->Stage2Image ();
0236 
0237                 dng_image_writer writer;
0238 
0239                 writer.WriteTIFF (host,
0240                                   stream2,
0241                                   stage2,
0242                                   stage2.Planes () >= 3 ? piRGB
0243                                                         : piBlackIsZero);
0244 
0245                 }
0246 
0247             gDumpStage2.Clear ();
0248 
0249             }
0250 
0251         // Four color Bayer option.
0252 
0253         if (gFourColorBayer)
0254             {
0255             negative->SetFourColorBayer ();
0256             }
0257 
0258         // Build stage 3 image.
0259 
0260         if (negative->Stage2Image ())
0261             {
0262 
0263             dng_timer timer ("Interpolate time");
0264 
0265             negative->BuildStage3Image (host,
0266                                         gMosaicPlane);
0267 
0268             }
0269 
0270         else
0271             {
0272 
0273             negative->ResizeTransparencyToMatchStage3 (host);
0274 
0275             negative->ResizeDepthToMatchStage3 (host);
0276 
0277             }
0278 
0279         // Convert to proxy, if requested.
0280 
0281         if (gProxyDNGSize)
0282             {
0283 
0284             dng_timer timer ("ConvertToProxy time");
0285 
0286             dng_image_writer writer;
0287 
0288             negative->ConvertToProxy (host,
0289                                       writer,
0290                                       gProxyDNGSize);
0291 
0292             }
0293 
0294         // Flatten transparency, if required.
0295 
0296         if (negative->NeedFlattenTransparency (host))
0297             {
0298 
0299             dng_timer timer ("FlattenTransparency time");
0300 
0301             negative->FlattenTransparency (host);
0302 
0303             }
0304 
0305         if (gDumpStage3.NotEmpty ())
0306             {
0307 
0308             dng_file_stream stream2 (gDumpStage3.Get (), true);
0309 
0310             const dng_image &stage3 = *negative->Stage3Image ();
0311 
0312             dng_image_writer writer;
0313 
0314             writer.WriteTIFF (host,
0315                               stream2,
0316                               stage3,
0317                               stage3.Planes () >= 3 ? piRGB
0318                                                     : piBlackIsZero);
0319 
0320             gDumpStage3.Clear ();
0321 
0322             }
0323 
0324         if (gDumpTransparency.NotEmpty ())
0325             {
0326 
0327             if (negative->TransparencyMask ())
0328                 {
0329 
0330                 dng_file_stream stream2 (gDumpTransparency.Get (), true);
0331 
0332                 const dng_image &transparencyMask = *negative->TransparencyMask ();
0333 
0334                 dng_image_writer writer;
0335 
0336                 writer.WriteTIFF (host,
0337                                   stream2,
0338                                   transparencyMask,
0339                                   piBlackIsZero);
0340 
0341                 }
0342 
0343             gDumpTransparency.Clear ();
0344 
0345             }
0346 
0347         if (gDumpDepthMap.NotEmpty ())
0348             {
0349 
0350             if (negative->HasDepthMap ())
0351                 {
0352 
0353                 dng_file_stream stream2 (gDumpDepthMap.Get (), true);
0354 
0355                 const dng_image &depthMap = *negative->DepthMap ();
0356 
0357                 dng_image_writer writer;
0358 
0359                 writer.WriteTIFF (host,
0360                                   stream2,
0361                                   depthMap,
0362                                   piBlackIsZero);
0363 
0364                 }
0365 
0366             gDumpDepthMap.Clear ();
0367 
0368             }
0369 
0370         // Output DNG file if requested.
0371 
0372         if (gDumpDNG.NotEmpty ())
0373             {
0374 
0375             // Build the preview list.
0376 
0377             dng_preview_list previewList;
0378 
0379             dng_date_time_info dateTimeInfo;
0380 
0381             CurrentDateTimeAndZone (dateTimeInfo);
0382 
0383             for (uint32 previewIndex = 0; previewIndex < 2; previewIndex++)
0384                 {
0385 
0386                 // Skip preview if writing a compresssed main image to save space
0387                 // in this example code.
0388 
0389                 if (negative->RawJPEGImage () != NULL && previewIndex > 0)
0390                     {
0391                     break;
0392                     }
0393 
0394                 // Report timing.
0395 
0396                 dng_timer timer (previewIndex == 0 ? "Build thumbnail time"
0397                                                    : "Build preview time");
0398 
0399                 // Render a preview sized image.
0400 
0401                 AutoPtr<dng_image> previewImage;
0402 
0403                     {
0404 
0405                     dng_render render (host, *negative);
0406 
0407                     render.SetFinalSpace (negative->IsMonochrome () ? dng_space_GrayGamma22::Get ()
0408                                                                     : dng_space_sRGB       ::Get ());
0409 
0410                     render.SetFinalPixelType (ttByte);
0411 
0412                     render.SetMaximumSize (previewIndex == 0 ? 256 : 1024);
0413 
0414                     previewImage.Reset (render.Render ());
0415 
0416                     }
0417 
0418                 // Don't write the preview if it is same size as thumbnail.
0419 
0420                 if (previewIndex > 0 &&
0421                     Max_uint32 (previewImage->Bounds ().W (),
0422                                 previewImage->Bounds ().H ()) <= 256)
0423                     {
0424                     break;
0425                     }
0426 
0427                 // If we have compressed JPEG data, create a compressed thumbnail.  Otherwise
0428                 // save a uncompressed thumbnail.
0429 
0430                 bool useCompressedPreview = (negative->RawJPEGImage () != NULL) ||
0431                                             (previewIndex > 0);
0432 
0433                 AutoPtr<dng_preview> preview (useCompressedPreview ?
0434                                               (dng_preview *) new dng_jpeg_preview :
0435                                               (dng_preview *) new dng_image_preview);
0436 
0437                 // Setup up preview info.
0438 
0439                 preview->fInfo.fApplicationName   .Set ("dng_validate");
0440                 preview->fInfo.fApplicationVersion.Set (kDNGValidateVersion);
0441 
0442                 preview->fInfo.fSettingsName.Set ("Default");
0443 
0444                 preview->fInfo.fColorSpace = previewImage->Planes () == 1 ?
0445                                              previewColorSpace_GrayGamma22 :
0446                                              previewColorSpace_sRGB;
0447 
0448                 preview->fInfo.fDateTime = dateTimeInfo.Encode_ISO_8601 ();
0449 
0450                 if (!useCompressedPreview)
0451                     {
0452 
0453                     dng_image_preview *imagePreview = dynamic_cast<dng_image_preview *> (preview.Get ());
0454 
0455                     imagePreview->fImage.Reset (previewImage.Release ());
0456 
0457                     }
0458 
0459                 else
0460                     {
0461 
0462                     dng_jpeg_preview *jpegPreview = dynamic_cast<dng_jpeg_preview *> (preview.Get ());
0463 
0464                     int32 quality = (previewIndex == 0 ? 8 : 5);
0465 
0466                     dng_image_writer writer;
0467 
0468                     writer.EncodeJPEGPreview (host,
0469                                               *previewImage,
0470                                               *jpegPreview,
0471                                               quality);
0472 
0473                     }
0474 
0475                 previewList.Append (preview);
0476 
0477                 }
0478 
0479             // Write DNG file.
0480 
0481             dng_file_stream stream2 (gDumpDNG.Get (), true);
0482 
0483                 {
0484 
0485                 dng_timer timer ("Write DNG time");
0486 
0487                 dng_image_writer writer;
0488 
0489                 writer.WriteDNG (host,
0490                                  stream2,
0491                                  *negative.Get (),
0492                                  &previewList,
0493                                  dngVersion_Current,
0494                                  false);
0495 
0496                 }
0497 
0498             gDumpDNG.Clear ();
0499 
0500             }
0501 
0502         // Output TIF file if requested.
0503 
0504         if (gDumpTIF.NotEmpty ())
0505             {
0506 
0507             // Render final image.
0508 
0509             dng_render render (host, *negative);
0510 
0511             render.SetFinalSpace     (*gFinalSpace   );
0512             render.SetFinalPixelType (gFinalPixelType);
0513 
0514             if (host.MinimumSize ())
0515                 {
0516 
0517                 dng_point stage3Size = negative->Stage3Image ()->Size ();
0518 
0519                 render.SetMaximumSize (Max_uint32 (stage3Size.v,
0520                                                    stage3Size.h));
0521 
0522                 }
0523 
0524             AutoPtr<dng_image> finalImage;
0525 
0526                 {
0527 
0528                 dng_timer timer ("Render time");
0529 
0530                 finalImage.Reset (render.Render ());
0531 
0532                 }
0533 
0534             finalImage->Rotate (negative->Orientation ());
0535 
0536             // Now that Camera Raw supports non-raw formats, we should
0537             // not keep any Camera Raw settings in the XMP around when
0538             // writing rendered files.
0539 
0540             if (negative->GetXMP ())
0541                 {
0542 
0543                 negative->GetXMP ()->RemoveProperties (XMP_NS_CRS);
0544                 negative->GetXMP ()->RemoveProperties (XMP_NS_CRSS);
0545                 negative->GetXMP ()->RemoveProperties (XMP_NS_CRD);
0546 
0547                 }
0548 
0549             // Write TIF file.
0550 
0551             dng_file_stream stream2 (gDumpTIF.Get (), true);
0552 
0553                 {
0554 
0555                 dng_timer timer ("Write TIFF time");
0556 
0557                 dng_image_writer writer;
0558 
0559                 writer.WriteTIFF (host,
0560                                   stream2,
0561                                   *finalImage.Get (),
0562                                   finalImage->Planes () >= 3 ? piRGB
0563                                                              : piBlackIsZero,
0564                                   ccUncompressed,
0565                                   negative.Get (),
0566                                   &render.FinalSpace ());
0567 
0568                 }
0569 
0570             gDumpTIF.Clear ();
0571 
0572             }
0573 
0574         }
0575 
0576     catch (const dng_exception &except)
0577         {
0578 
0579         return except.ErrorCode ();
0580 
0581         }
0582 
0583     catch (...)
0584         {
0585 
0586         return dng_error_unknown;
0587 
0588         }
0589 
0590     printf ("Validation complete\n");
0591 
0592     return dng_error_none;
0593 
0594     }
0595 
0596 /*****************************************************************************/
0597 
0598 int main (int argc, char *argv [])
0599     {
0600 
0601     try
0602         {
0603 
0604         if (argc == 1)
0605             {
0606 
0607             fprintf (stderr,
0608                      "\n"
0609                      "dng_validate, version " kDNGValidateVersion " "
0610                      #if qDNG64Bit
0611                      "(64-bit)"
0612                      #else
0613                      "(32-bit)"
0614                      #endif
0615                      "\n"
0616                      "Copyright 2005-2019 Adobe Systems, Inc.\n"
0617                      "\n"
0618                      "Usage:  %s [options] file1 file2 ...\n"
0619                      "\n"
0620                      "Valid options:\n"
0621                      "-v                    Verbose mode\n"
0622                      "-d <num>              Dump line limit (implies -v)\n"
0623                      "-b4                   Use four-color Bayer interpolation\n"
0624                      "-s <num>              Use this sample of multi-sample CFAs\n"
0625                      "-ignoreEnhanced       Ignore the enhanced image IFD\n"
0626                      "-size <num>           Preferred preview image size\n"
0627                      "-min <num>            Minimum preview image size\n"
0628                      "-max <num>            Maximum preview image size\n"
0629                      "-proxy <num>          Target size for proxy DNG\n"
0630                      "-cs1                  Color space: \"sRGB\" (default)\n"
0631                      "-cs2                  Color space: \"Adobe RGB\"\n"
0632                      "-cs3                  Color space: \"ProPhoto RGB\"\n"
0633                      "-cs4                  Color space: \"ColorMatch RGB\"\n"
0634                      "-cs5                  Color space: \"Gray Gamma 1.8\"\n"
0635                      "-cs6                  Color space: \"Gray Gamma 2.2\"\n"
0636                      "-16                   16-bits/channel output\n"
0637                      "-1 <file>             Write stage 1 image to \"<file>.tif\"\n"
0638                      "-2 <file>             Write stage 2 image to \"<file>.tif\"\n"
0639                      "-3 <file>             Write stage 3 image to \"<file>.tif\"\n"
0640                      "-transparency <file>  Write transparency mask to \"<file>.tif\"\n"
0641                      "-depthMap <file>      Write depth map to \"<file>.tif\"\n"
0642                      "-tif <file>           Write TIF image to \"<file>.tif\"\n"
0643                      "-dng <file>           Write DNG image to \"<file>.dng\"\n"
0644                      "\n",
0645                      argv [0]);
0646 
0647             return 1;
0648 
0649             }
0650 
0651         int index;
0652 
0653         for (index = 1; index < argc && argv [index] [0] == '-'; index++)
0654             {
0655 
0656             dng_string option;
0657 
0658             option.Set (&argv [index] [1]);
0659 
0660             if (option.Matches ("v", true))
0661                 {
0662                 gVerbose = true;
0663                 }
0664 
0665             else if (option.Matches ("d", true))
0666                 {
0667 
0668                 gVerbose = true;
0669 
0670                 gDumpLineLimit = 0;
0671 
0672                 if (index + 1 < argc)
0673                     {
0674                     gDumpLineLimit = atoi (argv [++index]);
0675                     }
0676 
0677                 if (!gDumpLineLimit)
0678                     {
0679                     fprintf (stderr, "*** Invalid number after -d\n");
0680                     return 1;
0681                     }
0682 
0683                 }
0684 
0685             else if (option.Matches ("s", true))
0686                 {
0687 
0688                 if (index + 1 < argc)
0689                     {
0690                     gMosaicPlane = atoi (argv [++index]);
0691                     }
0692 
0693                 else
0694                     {
0695                     fprintf (stderr, "*** Missing number after -s\n");
0696                     return 1;
0697                     }
0698 
0699                 }
0700 
0701             else if (option.Matches ("b4", true))
0702                 {
0703                 gFourColorBayer = true;
0704                 }
0705 
0706             else if (option.Matches ("ignoreEnhanced", true))
0707                 {
0708                 gIgnoreEnhanced = true;
0709                 }
0710 
0711             else if (option.Matches ("size", true))
0712                 {
0713 
0714                 if (index + 1 < argc)
0715                     {
0716                     gPreferredSize = (uint32) atoi (argv [++index]);
0717                     }
0718 
0719                 else
0720                     {
0721                     fprintf (stderr, "*** Missing number after -size\n");
0722                     return 1;
0723                     }
0724 
0725                 }
0726 
0727             else if (option.Matches ("min", true))
0728                 {
0729 
0730                 if (index + 1 < argc)
0731                     {
0732                     gMinimumSize = (uint32) atoi (argv [++index]);
0733                     }
0734 
0735                 else
0736                     {
0737                     fprintf (stderr, "*** Missing number after -min\n");
0738                     return 1;
0739                     }
0740 
0741                 }
0742 
0743             else if (option.Matches ("max", true))
0744                 {
0745 
0746                 if (index + 1 < argc)
0747                     {
0748                     gMaximumSize = (uint32) atoi (argv [++index]);
0749                     }
0750 
0751                 else
0752                     {
0753                     fprintf (stderr, "*** Missing number after -max\n");
0754                     return 1;
0755                     }
0756 
0757                 }
0758 
0759             else if (option.Matches ("proxy", true))
0760                 {
0761 
0762                 if (index + 1 < argc)
0763                     {
0764                     gProxyDNGSize = (uint32) atoi (argv [++index]);
0765                     }
0766 
0767                 else
0768                     {
0769                     fprintf (stderr, "*** Missing number after -proxy\n");
0770                     return 1;
0771                     }
0772 
0773                 }
0774 
0775             else if (option.Matches ("cs1", true))
0776                 {
0777 
0778                 gFinalSpace = &dng_space_sRGB::Get ();
0779 
0780                 }
0781 
0782             else if (option.Matches ("cs2", true))
0783                 {
0784 
0785                 gFinalSpace = &dng_space_AdobeRGB::Get ();
0786 
0787                 }
0788 
0789             else if (option.Matches ("cs3", true))
0790                 {
0791 
0792                 gFinalSpace = &dng_space_ProPhoto::Get ();
0793 
0794                 }
0795 
0796             else if (option.Matches ("cs4", true))
0797                 {
0798 
0799                 gFinalSpace = &dng_space_ColorMatch::Get ();
0800 
0801                 }
0802 
0803             else if (option.Matches ("cs5", true))
0804                 {
0805 
0806                 gFinalSpace = &dng_space_GrayGamma18::Get ();
0807 
0808                 }
0809 
0810             else if (option.Matches ("cs6", true))
0811                 {
0812 
0813                 gFinalSpace = &dng_space_GrayGamma22::Get ();
0814 
0815                 }
0816 
0817             else if (option.Matches ("16"))
0818                 {
0819 
0820                 gFinalPixelType = ttShort;
0821 
0822                 }
0823 
0824             else if (option.Matches ("1"))
0825                 {
0826 
0827                 gDumpStage1.Clear ();
0828 
0829                 if (index + 1 < argc)
0830                     {
0831                     gDumpStage1.Set (argv [++index]);
0832                     }
0833 
0834                 if (gDumpStage1.IsEmpty () || gDumpStage1.StartsWith ("-"))
0835                     {
0836                     fprintf (stderr, "*** Missing file name after -1\n");
0837                     return 1;
0838                     }
0839 
0840                 if (!gDumpStage1.EndsWith (".tif"))
0841                     {
0842                     gDumpStage1.Append (".tif");
0843                     }
0844 
0845                 }
0846 
0847             else if (option.Matches ("2"))
0848                 {
0849 
0850                 gDumpStage2.Clear ();
0851 
0852                 if (index + 1 < argc)
0853                     {
0854                     gDumpStage2.Set (argv [++index]);
0855                     }
0856 
0857                 if (gDumpStage2.IsEmpty () || gDumpStage2.StartsWith ("-"))
0858                     {
0859                     fprintf (stderr, "*** Missing file name after -2\n");
0860                     return 1;
0861                     }
0862 
0863                 if (!gDumpStage2.EndsWith (".tif"))
0864                     {
0865                     gDumpStage2.Append (".tif");
0866                     }
0867 
0868                 }
0869 
0870             else if (option.Matches ("3"))
0871                 {
0872 
0873                 gDumpStage3.Clear ();
0874 
0875                 if (index + 1 < argc)
0876                     {
0877                     gDumpStage3.Set (argv [++index]);
0878                     }
0879 
0880                 if (gDumpStage3.IsEmpty () || gDumpStage3.StartsWith ("-"))
0881                     {
0882                     fprintf (stderr, "*** Missing file name after -3\n");
0883                     return 1;
0884                     }
0885 
0886                 if (!gDumpStage3.EndsWith (".tif"))
0887                     {
0888                     gDumpStage3.Append (".tif");
0889                     }
0890 
0891                 }
0892 
0893             else if (option.Matches ("transparency"))
0894                 {
0895 
0896                 gDumpTransparency.Clear ();
0897 
0898                 if (index + 1 < argc)
0899                     {
0900                     gDumpTransparency.Set (argv [++index]);
0901                     }
0902 
0903                 if (gDumpTransparency.IsEmpty () || gDumpTransparency.StartsWith ("-"))
0904                     {
0905                     fprintf (stderr, "*** Missing file name after -transparency\n");
0906                     return 1;
0907                     }
0908 
0909                 if (!gDumpTransparency.EndsWith (".tif"))
0910                     {
0911                     gDumpTransparency.Append (".tif");
0912                     }
0913 
0914                 }
0915 
0916             else if (option.Matches ("depthMap"))
0917                 {
0918 
0919                 gDumpDepthMap.Clear ();
0920 
0921                 if (index + 1 < argc)
0922                     {
0923                     gDumpDepthMap.Set (argv [++index]);
0924                     }
0925 
0926                 if (gDumpDepthMap.IsEmpty () || gDumpDepthMap.StartsWith ("-"))
0927                     {
0928                     fprintf (stderr, "*** Missing file name after -depthMap\n");
0929                     return 1;
0930                     }
0931 
0932                 if (!gDumpDepthMap.EndsWith (".tif"))
0933                     {
0934                     gDumpDepthMap.Append (".tif");
0935                     }
0936 
0937                 }
0938 
0939             else if (option.Matches ("tif", true))
0940                 {
0941 
0942                 gDumpTIF.Clear ();
0943 
0944                 if (index + 1 < argc)
0945                     {
0946                     gDumpTIF.Set (argv [++index]);
0947                     }
0948 
0949                 if (gDumpTIF.IsEmpty () || gDumpTIF.StartsWith ("-"))
0950                     {
0951                     fprintf (stderr, "*** Missing file name after -tif\n");
0952                     return 1;
0953                     }
0954 
0955                 if (!gDumpTIF.EndsWith (".tif"))
0956                     {
0957                     gDumpTIF.Append (".tif");
0958                     }
0959 
0960                 }
0961 
0962             else if (option.Matches ("dng", true))
0963                 {
0964 
0965                 gDumpDNG.Clear ();
0966 
0967                 if (index + 1 < argc)
0968                     {
0969                     gDumpDNG.Set (argv [++index]);
0970                     }
0971 
0972                 if (gDumpDNG.IsEmpty () || gDumpDNG.StartsWith ("-"))
0973                     {
0974                     fprintf (stderr, "*** Missing file name after -dng\n");
0975                     return 1;
0976                     }
0977 
0978                 if (!gDumpDNG.EndsWith (".dng"))
0979                     {
0980                     gDumpDNG.Append (".dng");
0981                     }
0982 
0983                 }
0984 
0985             else
0986                 {
0987                 fprintf (stderr, "*** Unknown option \"-%s\"\n", option.Get ());
0988                 return 1;
0989                 }
0990 
0991             }
0992 
0993         if (index == argc)
0994             {
0995             fprintf (stderr, "*** No file specified\n");
0996             return 1;
0997             }
0998 
0999         dng_xmp_sdk::InitializeSDK ();
1000 
1001         int result = 0;
1002 
1003         while (index < argc)
1004             {
1005 
1006             dng_error_code error_code = dng_validate (argv [index++]);
1007 
1008             if (error_code != dng_error_none)
1009                 {
1010 
1011                 result = error_code - dng_error_unknown + 100;
1012 
1013                 }
1014 
1015             }
1016 
1017         dng_xmp_sdk::TerminateSDK ();
1018 
1019         return result;
1020 
1021         }
1022 
1023     catch (...)
1024         {
1025 
1026         }
1027 
1028     fprintf (stderr, "*** Exception thrown in main routine\n");
1029 
1030     return 1;
1031 
1032     }
1033 
1034 /*****************************************************************************/
1035 
1036 #endif
1037 
1038 /*****************************************************************************/