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 /** \file 10 * Support for writing DNG images to files. 11 */ 12 13 /*****************************************************************************/ 14 15 #ifndef __dng_image_writer__ 16 #define __dng_image_writer__ 17 18 /*****************************************************************************/ 19 20 #include "dng_area_task.h" 21 #include "dng_auto_ptr.h" 22 #include "dng_classes.h" 23 #include "dng_fingerprint.h" 24 #include "dng_memory.h" 25 #include "dng_mutex.h" 26 #include "dng_point.h" 27 #include "dng_rational.h" 28 #include "dng_safe_arithmetic.h" 29 #include "dng_sdk_limits.h" 30 #include "dng_string.h" 31 #include "dng_tag_types.h" 32 #include "dng_tag_values.h" 33 #include "dng_types.h" 34 #include "dng_uncopyable.h" 35 36 #include <atomic> 37 38 /*****************************************************************************/ 39 40 /// \brief Image resolution. 41 42 class dng_resolution 43 { 44 45 public: 46 47 dng_urational fXResolution; 48 dng_urational fYResolution; 49 50 uint16 fResolutionUnit; 51 52 public: 53 54 dng_resolution (); 55 56 }; 57 58 /*****************************************************************************/ 59 60 class tiff_tag: private dng_uncopyable 61 { 62 63 protected: 64 65 uint16 fCode; 66 67 uint16 fType; 68 69 uint32 fCount; 70 71 protected: 72 tiff_tag(uint16 code,uint16 type,uint32 count)73 tiff_tag (uint16 code, 74 uint16 type, 75 uint32 count) 76 77 : fCode (code) 78 , fType (type) 79 , fCount (count) 80 81 { 82 } 83 84 public: 85 ~tiff_tag()86 virtual ~tiff_tag () 87 { 88 } 89 Code()90 uint16 Code () const 91 { 92 return fCode; 93 } 94 Type()95 uint16 Type () const 96 { 97 return fType; 98 } 99 Count()100 uint32 Count () const 101 { 102 return fCount; 103 } 104 SetCount(uint32 count)105 void SetCount (uint32 count) 106 { 107 fCount = count; 108 } 109 Size()110 uint32 Size () const 111 { 112 return TagTypeSize (Type ()) * Count (); 113 } 114 115 virtual void Put (dng_stream &stream) const = 0; 116 117 }; 118 119 /******************************************************************************/ 120 121 class tag_data_ptr: public tiff_tag 122 { 123 124 protected: 125 126 const void *fData; 127 128 public: 129 tag_data_ptr(uint16 code,uint16 type,uint32 count,const void * data)130 tag_data_ptr (uint16 code, 131 uint16 type, 132 uint32 count, 133 const void *data) 134 135 : tiff_tag (code, type, count) 136 137 , fData (data) 138 139 { 140 } 141 SetData(const void * data)142 void SetData (const void *data) 143 { 144 fData = data; 145 } 146 147 virtual void Put (dng_stream &stream) const; 148 149 }; 150 151 /******************************************************************************/ 152 153 class tag_string: public tiff_tag 154 { 155 156 protected: 157 158 dng_string fString; 159 160 public: 161 162 tag_string (uint16 code, 163 const dng_string &s, 164 bool forceASCII = true); 165 166 virtual void Put (dng_stream &stream) const; 167 168 }; 169 170 /******************************************************************************/ 171 172 class tag_encoded_text: public tiff_tag 173 { 174 175 private: 176 177 dng_string fText; 178 179 dng_memory_data fUTF16; 180 181 public: 182 183 tag_encoded_text (uint16 code, 184 const dng_string &text); 185 186 virtual void Put (dng_stream &stream) const; 187 188 }; 189 190 /******************************************************************************/ 191 192 class tag_uint8: public tag_data_ptr 193 { 194 195 private: 196 197 uint8 fValue; 198 199 public: 200 201 tag_uint8 (uint16 code, 202 uint8 value = 0) 203 204 : tag_data_ptr (code, ttByte, 1, &fValue) 205 206 , fValue (value) 207 208 { 209 } 210 Set(uint8 value)211 void Set (uint8 value) 212 { 213 fValue = value; 214 } 215 216 }; 217 218 /******************************************************************************/ 219 220 class tag_uint8_ptr: public tag_data_ptr 221 { 222 223 public: 224 225 tag_uint8_ptr (uint16 code, 226 const uint8 *data, 227 uint32 count = 1) 228 tag_data_ptr(code,ttByte,count,data)229 : tag_data_ptr (code, ttByte, count, data) 230 231 { 232 } 233 234 }; 235 236 /******************************************************************************/ 237 238 class tag_uint16: public tag_data_ptr 239 { 240 241 private: 242 243 uint16 fValue; 244 245 public: 246 247 tag_uint16 (uint16 code, 248 uint16 value = 0) 249 250 : tag_data_ptr (code, ttShort, 1, &fValue) 251 252 , fValue (value) 253 254 { 255 } 256 Set(uint16 value)257 void Set (uint16 value) 258 { 259 fValue = value; 260 } 261 262 }; 263 264 /******************************************************************************/ 265 266 class tag_int16_ptr: public tag_data_ptr 267 { 268 269 public: 270 271 tag_int16_ptr (uint16 code, 272 const int16 *data, 273 uint32 count = 1) 274 tag_data_ptr(code,ttSShort,count,data)275 : tag_data_ptr (code, ttSShort, count, data) 276 277 { 278 } 279 280 }; 281 282 /******************************************************************************/ 283 284 class tag_uint16_ptr: public tag_data_ptr 285 { 286 287 public: 288 289 tag_uint16_ptr (uint16 code, 290 const uint16 *data, 291 uint32 count = 1) 292 tag_data_ptr(code,ttShort,count,data)293 : tag_data_ptr (code, ttShort, count, data) 294 295 { 296 } 297 298 }; 299 300 /******************************************************************************/ 301 302 class tag_uint32: public tag_data_ptr 303 { 304 305 private: 306 307 uint32 fValue; 308 309 public: 310 311 tag_uint32 (uint16 code, 312 uint32 value = 0) 313 314 : tag_data_ptr (code, ttLong, 1, &fValue) 315 316 , fValue (value) 317 318 { 319 } 320 Set(uint32 value)321 void Set (uint32 value) 322 { 323 fValue = value; 324 } 325 326 }; 327 328 /******************************************************************************/ 329 330 class tag_uint32_ptr: public tag_data_ptr 331 { 332 333 public: 334 335 tag_uint32_ptr (uint16 code, 336 const uint32 *data, 337 uint32 count = 1) 338 tag_data_ptr(code,ttLong,count,data)339 : tag_data_ptr (code, ttLong, count, data) 340 341 { 342 } 343 344 }; 345 346 /******************************************************************************/ 347 348 class tag_urational: public tag_data_ptr 349 { 350 351 private: 352 353 const dng_urational fValue; 354 355 public: 356 tag_urational(uint16 code,const dng_urational & value)357 tag_urational (uint16 code, 358 const dng_urational &value) 359 360 : tag_data_ptr (code, ttRational, 1, &fValue) 361 362 , fValue (value) 363 364 { 365 } 366 367 }; 368 369 /******************************************************************************/ 370 371 class tag_urational_ptr: public tag_data_ptr 372 { 373 374 public: 375 376 tag_urational_ptr (uint16 code, 377 const dng_urational *data = NULL, 378 uint32 count = 1) 379 tag_data_ptr(code,ttRational,count,data)380 : tag_data_ptr (code, ttRational, count, data) 381 382 { 383 } 384 385 }; 386 387 /******************************************************************************/ 388 389 class tag_srational: public tag_data_ptr 390 { 391 392 private: 393 394 const dng_srational fValue; 395 396 public: 397 tag_srational(uint16 code,const dng_srational & value)398 tag_srational (uint16 code, 399 const dng_srational &value) 400 401 : tag_data_ptr (code, ttSRational, 1, &fValue) 402 403 , fValue (value) 404 405 { 406 } 407 408 }; 409 410 /******************************************************************************/ 411 412 class tag_srational_ptr: public tag_data_ptr 413 { 414 415 public: 416 417 tag_srational_ptr (uint16 code, 418 const dng_srational *data = NULL, 419 uint32 count = 1) 420 tag_data_ptr(code,ttSRational,count,data)421 : tag_data_ptr (code, ttSRational, count, data) 422 423 { 424 } 425 426 }; 427 428 /******************************************************************************/ 429 430 class tag_real64: public tag_data_ptr 431 { 432 433 private: 434 435 real64 fValue; 436 437 public: 438 439 tag_real64 (uint16 code, 440 real64 value = 0.0) 441 442 : tag_data_ptr (code, ttDouble, 1, &fValue) 443 444 , fValue (value) 445 446 { 447 } 448 Set(real64 value)449 void Set (real64 value) 450 { 451 fValue = value; 452 } 453 454 }; 455 456 /******************************************************************************/ 457 458 class tag_matrix: public tag_srational_ptr 459 { 460 461 private: 462 463 dng_srational fEntry [kMaxColorPlanes * 464 kMaxColorPlanes]; 465 466 public: 467 468 tag_matrix (uint16 code, 469 const dng_matrix &m); 470 471 }; 472 473 /******************************************************************************/ 474 475 class tag_icc_profile: public tag_data_ptr 476 { 477 478 public: 479 480 tag_icc_profile (const void *profileData, uint32 profileSize); 481 482 }; 483 484 /******************************************************************************/ 485 486 class tag_cfa_pattern: public tiff_tag 487 { 488 489 private: 490 491 uint32 fRows; 492 uint32 fCols; 493 494 const uint8 *fPattern; 495 496 public: 497 tag_cfa_pattern(uint16 code,uint32 rows,uint32 cols,const uint8 * pattern)498 tag_cfa_pattern (uint16 code, 499 uint32 rows, 500 uint32 cols, 501 const uint8 *pattern) 502 503 : tiff_tag (code, ttUndefined, 4 + rows * cols) 504 505 , fRows (rows ) 506 , fCols (cols ) 507 , fPattern (pattern) 508 509 { 510 } 511 512 virtual void Put (dng_stream &stream) const; 513 514 }; 515 516 /******************************************************************************/ 517 518 class tag_exif_date_time: public tag_data_ptr 519 { 520 521 private: 522 523 char fData [20]; 524 525 public: 526 527 tag_exif_date_time (uint16 code, 528 const dng_date_time &dt); 529 530 }; 531 532 /******************************************************************************/ 533 534 class tag_iptc: public tiff_tag 535 { 536 537 private: 538 539 const void *fData; 540 541 uint32 fLength; 542 543 public: 544 545 tag_iptc (const void *data, 546 uint32 length); 547 548 virtual void Put (dng_stream &stream) const; 549 550 }; 551 552 /******************************************************************************/ 553 554 class tag_xmp: public tag_uint8_ptr 555 { 556 557 private: 558 559 AutoPtr<dng_memory_block> fBuffer; 560 561 public: 562 563 tag_xmp (const dng_xmp *xmp); 564 565 }; 566 567 /******************************************************************************/ 568 569 class dng_tiff_directory: private dng_uncopyable 570 { 571 572 private: 573 574 enum 575 { 576 kMaxEntries = 100 577 }; 578 579 uint32 fEntries; 580 581 const tiff_tag *fTag [kMaxEntries]; 582 583 uint32 fChained; 584 585 public: 586 dng_tiff_directory()587 dng_tiff_directory () 588 589 : fEntries (0) 590 , fChained (0) 591 592 { 593 } 594 ~dng_tiff_directory()595 virtual ~dng_tiff_directory () 596 { 597 } 598 599 void Add (const tiff_tag *tag); 600 SetChained(uint32 offset)601 void SetChained (uint32 offset) 602 { 603 fChained = offset; 604 } 605 606 uint32 Size () const; 607 608 enum OffsetsBase 609 { 610 offsetsRelativeToStream = 0, 611 offsetsRelativeToExplicitBase = 1, 612 offsetsRelativeToIFD = 2 613 }; 614 615 void Put (dng_stream &stream, 616 OffsetsBase offsetsBase = offsetsRelativeToStream, 617 uint32 explicitBase = 0) const; 618 619 }; 620 621 /******************************************************************************/ 622 623 class dng_basic_tag_set: private dng_uncopyable 624 { 625 626 private: 627 628 tag_uint32 fNewSubFileType; 629 630 tag_uint32 fImageWidth; 631 tag_uint32 fImageLength; 632 633 tag_uint16 fPhotoInterpretation; 634 635 tag_uint16 fFillOrder; 636 637 tag_uint16 fSamplesPerPixel; 638 639 uint16 fBitsPerSampleData [kMaxSamplesPerPixel]; 640 641 tag_uint16_ptr fBitsPerSample; 642 643 bool fStrips; 644 645 tag_uint32 fTileWidth; 646 tag_uint32 fTileLength; 647 648 dng_memory_data fTileInfoBuffer; 649 650 uint32 *fTileOffsetData; 651 652 tag_uint32_ptr fTileOffsets; 653 654 uint32 *fTileByteCountData; 655 656 tag_uint32_ptr fTileByteCounts; 657 658 tag_uint16 fPlanarConfiguration; 659 660 tag_uint16 fCompression; 661 662 tag_uint16 fPredictor; 663 664 uint16 fExtraSamplesData [kMaxSamplesPerPixel]; 665 666 tag_uint16_ptr fExtraSamples; 667 668 uint16 fSampleFormatData [kMaxSamplesPerPixel]; 669 670 tag_uint16_ptr fSampleFormat; 671 672 tag_uint16 fRowInterleaveFactor; 673 674 uint16 fSubTileBlockSizeData [2]; 675 676 tag_uint16_ptr fSubTileBlockSize; 677 678 public: 679 680 dng_basic_tag_set (dng_tiff_directory &directory, 681 const dng_ifd &info); 682 ~dng_basic_tag_set()683 virtual ~dng_basic_tag_set () 684 { 685 } 686 SetTileOffset(uint32 index,uint32 offset)687 void SetTileOffset (uint32 index, 688 uint32 offset) 689 { 690 fTileOffsetData [index] = offset; 691 } 692 SetTileByteCount(uint32 index,uint32 count)693 void SetTileByteCount (uint32 index, 694 uint32 count) 695 { 696 fTileByteCountData [index] = count; 697 } 698 WritingStrips()699 bool WritingStrips () const 700 { 701 return fStrips; 702 } 703 704 }; 705 706 /******************************************************************************/ 707 708 class exif_tag_set: private dng_uncopyable 709 { 710 711 protected: 712 713 dng_tiff_directory fExifIFD; 714 dng_tiff_directory fGPSIFD; 715 716 private: 717 718 tag_uint32 fExifLink; 719 tag_uint32 fGPSLink; 720 721 bool fAddedExifLink; 722 bool fAddedGPSLink; 723 724 uint8 fExifVersionData [4]; 725 726 tag_data_ptr fExifVersion; 727 728 tag_urational fExposureTime; 729 tag_srational fShutterSpeedValue; 730 731 tag_urational fFNumber; 732 tag_urational fApertureValue; 733 734 tag_srational fBrightnessValue; 735 736 tag_srational fExposureBiasValue; 737 738 tag_urational fMaxApertureValue; 739 740 tag_urational fSubjectDistance; 741 742 tag_urational fFocalLength; 743 744 tag_uint16 fISOSpeedRatings; 745 746 tag_uint16 fSensitivityType; 747 tag_uint32 fStandardOutputSensitivity; 748 tag_uint32 fRecommendedExposureIndex; 749 tag_uint32 fISOSpeed; 750 tag_uint32 fISOSpeedLatitudeyyy; 751 tag_uint32 fISOSpeedLatitudezzz; 752 753 tag_uint16 fFlash; 754 755 tag_uint16 fExposureProgram; 756 757 tag_uint16 fMeteringMode; 758 759 tag_uint16 fLightSource; 760 761 tag_uint16 fSensingMethod; 762 763 tag_uint16 fFocalLength35mm; 764 765 uint8 fFileSourceData; 766 tag_data_ptr fFileSource; 767 768 uint8 fSceneTypeData; 769 tag_data_ptr fSceneType; 770 771 tag_cfa_pattern fCFAPattern; 772 773 tag_uint16 fCustomRendered; 774 tag_uint16 fExposureMode; 775 tag_uint16 fWhiteBalance; 776 tag_uint16 fSceneCaptureType; 777 tag_uint16 fGainControl; 778 tag_uint16 fContrast; 779 tag_uint16 fSaturation; 780 tag_uint16 fSharpness; 781 tag_uint16 fSubjectDistanceRange; 782 783 tag_urational fDigitalZoomRatio; 784 785 tag_urational fExposureIndex; 786 787 tag_uint32 fImageNumber; 788 789 tag_uint16 fSelfTimerMode; 790 791 tag_string fBatteryLevelA; 792 tag_urational fBatteryLevelR; 793 794 tag_uint16 fColorSpace; 795 796 tag_urational fFocalPlaneXResolution; 797 tag_urational fFocalPlaneYResolution; 798 799 tag_uint16 fFocalPlaneResolutionUnit; 800 801 uint16 fSubjectAreaData [4]; 802 803 tag_uint16_ptr fSubjectArea; 804 805 dng_urational fLensInfoData [4]; 806 807 tag_urational_ptr fLensInfo; 808 809 tag_exif_date_time fDateTime; 810 tag_exif_date_time fDateTimeOriginal; 811 tag_exif_date_time fDateTimeDigitized; 812 813 tag_string fSubsecTime; 814 tag_string fSubsecTimeOriginal; 815 tag_string fSubsecTimeDigitized; 816 817 tag_string fOffsetTime; 818 tag_string fOffsetTimeOriginal; 819 tag_string fOffsetTimeDigitized; 820 821 tag_string fMake; 822 tag_string fModel; 823 tag_string fArtist; 824 tag_string fSoftware; 825 tag_string fCopyright; 826 tag_string fImageDescription; 827 828 tag_string fSerialNumber; 829 830 tag_uint16 fMakerNoteSafety; 831 832 tag_data_ptr fMakerNote; 833 834 tag_encoded_text fUserComment; 835 836 char fImageUniqueIDData [33]; 837 838 tag_data_ptr fImageUniqueID; 839 840 // EXIF 2.3 tags. 841 842 tag_string fCameraOwnerName; 843 tag_string fBodySerialNumber; 844 tag_urational_ptr fLensSpecification; 845 tag_string fLensMake; 846 tag_string fLensModel; 847 tag_string fLensSerialNumber; 848 849 // EXIF 2.3.1 tags. 850 851 tag_srational fTemperature; 852 tag_urational fHumidity; 853 tag_urational fPressure; 854 tag_srational fWaterDepth; 855 tag_urational fAcceleration; 856 tag_srational fCameraElevationAngle; 857 858 uint8 fGPSVersionData [4]; 859 860 tag_uint8_ptr fGPSVersionID; 861 862 tag_string fGPSLatitudeRef; 863 tag_urational_ptr fGPSLatitude; 864 865 tag_string fGPSLongitudeRef; 866 tag_urational_ptr fGPSLongitude; 867 868 tag_uint8 fGPSAltitudeRef; 869 tag_urational fGPSAltitude; 870 871 tag_urational_ptr fGPSTimeStamp; 872 873 tag_string fGPSSatellites; 874 tag_string fGPSStatus; 875 tag_string fGPSMeasureMode; 876 877 tag_urational fGPSDOP; 878 879 tag_string fGPSSpeedRef; 880 tag_urational fGPSSpeed; 881 882 tag_string fGPSTrackRef; 883 tag_urational fGPSTrack; 884 885 tag_string fGPSImgDirectionRef; 886 tag_urational fGPSImgDirection; 887 888 tag_string fGPSMapDatum; 889 890 tag_string fGPSDestLatitudeRef; 891 tag_urational_ptr fGPSDestLatitude; 892 893 tag_string fGPSDestLongitudeRef; 894 tag_urational_ptr fGPSDestLongitude; 895 896 tag_string fGPSDestBearingRef; 897 tag_urational fGPSDestBearing; 898 899 tag_string fGPSDestDistanceRef; 900 tag_urational fGPSDestDistance; 901 902 tag_encoded_text fGPSProcessingMethod; 903 tag_encoded_text fGPSAreaInformation; 904 905 tag_string fGPSDateStamp; 906 907 tag_uint16 fGPSDifferential; 908 909 tag_urational fGPSHPositioningError; 910 911 public: 912 913 exif_tag_set (dng_tiff_directory &directory, 914 const dng_exif &exif, 915 bool makerNoteSafe = false, 916 const void *makerNoteData = NULL, 917 uint32 makerNoteLength = 0, 918 bool insideDNG = false); 919 Locate(uint32 offset)920 void Locate (uint32 offset) 921 { 922 fExifLink.Set (offset); 923 fGPSLink .Set (offset + fExifIFD.Size ()); 924 } 925 Size()926 uint32 Size () const 927 { 928 return fExifIFD.Size () + 929 fGPSIFD .Size (); 930 } 931 Put(dng_stream & stream)932 void Put (dng_stream &stream) const 933 { 934 fExifIFD.Put (stream); 935 fGPSIFD .Put (stream); 936 } 937 938 protected: 939 940 void AddLinks (dng_tiff_directory &directory); 941 942 }; 943 944 /******************************************************************************/ 945 946 class tiff_dng_extended_color_profile: private dng_tiff_directory 947 { 948 949 protected: 950 951 const dng_camera_profile &fProfile; 952 953 public: 954 955 tiff_dng_extended_color_profile (const dng_camera_profile &profile); 956 957 void Put (dng_stream &stream, 958 bool includeModelRestriction = true); 959 960 }; 961 962 /*****************************************************************************/ 963 964 class tag_dng_noise_profile: public tag_data_ptr 965 { 966 967 protected: 968 969 real64 fValues [2 * kMaxColorPlanes]; 970 971 public: 972 973 explicit tag_dng_noise_profile (const dng_noise_profile &profile); 974 975 }; 976 977 /*****************************************************************************/ 978 979 // Enum to control the subset of metadata to save to a file. 980 981 enum dng_metadata_subset 982 { 983 984 kMetadataSubset_CopyrightOnly = 0, 985 kMetadataSubset_CopyrightAndContact, 986 kMetadataSubset_AllExceptCameraInfo, 987 kMetadataSubset_All, 988 kMetadataSubset_AllExceptLocationInfo, 989 kMetadataSubset_AllExceptCameraAndLocation, 990 KMetadataSubset_AllExceptCameraRawInfo, 991 KMetadataSubset_AllExceptCameraRawInfoAndLocation, 992 993 kMetadataSubset_Last = KMetadataSubset_AllExceptCameraRawInfoAndLocation 994 995 }; 996 997 /*****************************************************************************/ 998 999 /// \brief Support for writing dng_image or dng_negative instances to a 1000 /// dng_stream in TIFF or DNG format. 1001 1002 class dng_image_writer 1003 { 1004 1005 friend class dng_jpeg_image; 1006 friend class dng_jpeg_image_encode_task; 1007 friend class dng_write_tiles_task; 1008 1009 protected: 1010 1011 enum 1012 { 1013 1014 // Target size for buffer used to copy data to the image. 1015 1016 kImageBufferSize = 128 * 1024 1017 1018 }; 1019 1020 public: 1021 1022 dng_image_writer (); 1023 1024 virtual ~dng_image_writer (); 1025 1026 virtual void EncodeJPEGPreview (dng_host &host, 1027 const dng_image &image, 1028 dng_jpeg_preview &preview, 1029 int32 quality = -1); 1030 1031 virtual void WriteImage (dng_host &host, 1032 const dng_ifd &ifd, 1033 dng_basic_tag_set &basic, 1034 dng_stream &stream, 1035 const dng_image &image, 1036 uint32 fakeChannels = 1); 1037 1038 /// Write a dng_image to a dng_stream in TIFF format. 1039 /// \param host Host interface used for progress updates, abort testing, buffer allocation, etc. 1040 /// \param stream The dng_stream on which to write the TIFF. 1041 /// \param image The actual image data to be written. 1042 /// \param photometricInterpretation Either piBlackIsZero for monochrome or piRGB for RGB images. 1043 /// \param compression Must be ccUncompressed. 1044 /// \param negative or metadata If non-NULL, EXIF, IPTC, and XMP metadata from this negative is written to TIFF. 1045 /// \param space If non-null and color space has an ICC profile, TIFF will be tagged with this 1046 /// profile. No color space conversion of image data occurs. 1047 /// \param resolution If non-NULL, TIFF will be tagged with this resolution. 1048 /// \param thumbnail If non-NULL, will be stored in TIFF as preview image. 1049 /// \param imageResources If non-NULL, will image resources be stored in TIFF as well. 1050 /// \param metadataSubset The subset of metadata (e.g., copyright only) to include in the TIFF. 1051 1052 void WriteTIFF (dng_host &host, 1053 dng_stream &stream, 1054 const dng_image &image, 1055 uint32 photometricInterpretation, 1056 uint32 compression, 1057 dng_negative *negative, 1058 const dng_color_space *space = NULL, 1059 const dng_resolution *resolution = NULL, 1060 const dng_jpeg_preview *thumbnail = NULL, 1061 const dng_memory_block *imageResources = NULL, 1062 dng_metadata_subset metadataSubset = kMetadataSubset_All, 1063 bool hasTransparency = false); 1064 1065 void WriteTIFF (dng_host &host, 1066 dng_stream &stream, 1067 const dng_image &image, 1068 uint32 photometricInterpretation = piBlackIsZero, 1069 uint32 compression = ccUncompressed, 1070 const dng_metadata *metadata = NULL, 1071 const dng_color_space *space = NULL, 1072 const dng_resolution *resolution = NULL, 1073 const dng_jpeg_preview *thumbnail = NULL, 1074 const dng_memory_block *imageResources = NULL, 1075 dng_metadata_subset metadataSubset = kMetadataSubset_All, 1076 bool hasTransparency = false); 1077 1078 /// Write a dng_image to a dng_stream in TIFF format. 1079 /// \param host Host interface used for progress updates, abort testing, buffer allocation, etc. 1080 /// \param stream The dng_stream on which to write the TIFF. 1081 /// \param image The actual image data to be written. 1082 /// \param photometricInterpretation Either piBlackIsZero for monochrome or piRGB for RGB images. 1083 /// \param compression Must be ccUncompressed. 1084 /// \param negative or metadata If non-NULL, EXIF, IPTC, and XMP metadata from this negative is written to TIFF. 1085 /// \param profileData If non-null, TIFF will be tagged with this profile. No color space conversion 1086 /// of image data occurs. 1087 /// \param profileSize The size for the profile data. 1088 /// \param resolution If non-NULL, TIFF will be tagged with this resolution. 1089 /// \param thumbnail If non-NULL, will be stored in TIFF as preview image. 1090 /// \param imageResources If non-NULL, will image resources be stored in TIFF as well. 1091 /// \param metadataSubset The subset of metadata (e.g., copyright only) to include in the TIFF. 1092 1093 void WriteTIFFWithProfile (dng_host &host, 1094 dng_stream &stream, 1095 const dng_image &image, 1096 uint32 photometricInterpretation, 1097 uint32 compression, 1098 dng_negative *negative, 1099 const void *profileData = NULL, 1100 uint32 profileSize = 0, 1101 const dng_resolution *resolution = NULL, 1102 const dng_jpeg_preview *thumbnail = NULL, 1103 const dng_memory_block *imageResources = NULL, 1104 dng_metadata_subset metadataSubset = kMetadataSubset_All, 1105 bool hasTransparency = false); 1106 1107 virtual void WriteTIFFWithProfile (dng_host &host, 1108 dng_stream &stream, 1109 const dng_image &image, 1110 uint32 photometricInterpretation = piBlackIsZero, 1111 uint32 compression = ccUncompressed, 1112 const dng_metadata *metadata = NULL, 1113 const void *profileData = NULL, 1114 uint32 profileSize = 0, 1115 const dng_resolution *resolution = NULL, 1116 const dng_jpeg_preview *thumbnail = NULL, 1117 const dng_memory_block *imageResources = NULL, 1118 dng_metadata_subset metadataSubset = kMetadataSubset_All, 1119 bool hasTransparency = false); 1120 1121 /// Write a dng_image to a dng_stream in DNG format. 1122 /// \param host Host interface used for progress updates, abort testing, buffer allocation, etc. 1123 /// \param stream The dng_stream on which to write the TIFF. 1124 /// \param negative The image data and metadata (EXIF, IPTC, XMP) to be written. 1125 /// \param previewList List of previews (not counting thumbnail) to write to the file. Defaults to empty. 1126 /// \param maxBackwardVersion The DNG file should be readable by readers at least back to this version. 1127 /// \param uncompressed True to force uncompressed images. Otherwise use normal compression. 1128 1129 void WriteDNG (dng_host &host, 1130 dng_stream &stream, 1131 dng_negative &negative, 1132 const dng_preview_list *previewList = NULL, 1133 uint32 maxBackwardVersion = dngVersion_SaveDefault, 1134 bool uncompressed = false); 1135 1136 /// Write a dng_image to a dng_stream in DNG format. 1137 /// \param host Host interface used for progress updates, abort testing, buffer allocation, etc. 1138 /// \param stream The dng_stream on which to write the TIFF. 1139 /// \param negative The image data to be written. 1140 /// \param metadata The metadata (EXIF, IPTC, XMP) to be written. 1141 /// \param previewList List of previews (not counting thumbnail) to write to the file. Defaults to empty. 1142 /// \param maxBackwardVersion The DNG file should be readable by readers at least back to this version. 1143 /// \param uncompressed True to force uncompressed images. Otherwise use normal compression. 1144 1145 virtual void WriteDNGWithMetadata (dng_host &host, 1146 dng_stream &stream, 1147 const dng_negative &negative, 1148 const dng_metadata &metadata, 1149 const dng_preview_list *previewList = NULL, 1150 uint32 maxBackwardVersion = dngVersion_SaveDefault, 1151 bool uncompressed = false); 1152 1153 /// Resolve metadata conflicts and apply metadata policies in keeping 1154 /// with Metadata Working Group (MWG) guidelines. 1155 1156 virtual void CleanUpMetadata (dng_host &host, 1157 dng_metadata &metadata, 1158 dng_metadata_subset metadataSubset, 1159 const char *dstMIME, 1160 const char *software = NULL); 1161 1162 protected: 1163 1164 virtual void UpdateExifColorSpaceTag (dng_metadata &metadata, 1165 const void *profileData, 1166 const uint32 profileSize); 1167 1168 virtual uint32 CompressedBufferSize (const dng_ifd &ifd, 1169 uint32 uncompressedSize); 1170 1171 virtual void EncodePredictor (dng_host &host, 1172 const dng_ifd &ifd, 1173 dng_pixel_buffer &buffer, 1174 AutoPtr<dng_memory_block> &tempBuffer); 1175 1176 virtual void ByteSwapBuffer (dng_host &host, 1177 dng_pixel_buffer &buffer); 1178 1179 void ReorderSubTileBlocks (const dng_ifd &ifd, 1180 dng_pixel_buffer &buffer, 1181 AutoPtr<dng_memory_block> &uncompressedBuffer, 1182 AutoPtr<dng_memory_block> &subTileBlockBuffer); 1183 1184 virtual void WriteData (dng_host &host, 1185 const dng_ifd &ifd, 1186 dng_stream &stream, 1187 dng_pixel_buffer &buffer, 1188 AutoPtr<dng_memory_block> &compressedBuffer, 1189 bool usingMultipleThreads); 1190 1191 virtual void WriteTile (dng_host &host, 1192 const dng_ifd &ifd, 1193 dng_stream &stream, 1194 const dng_image &image, 1195 const dng_rect &tileArea, 1196 uint32 fakeChannels, 1197 AutoPtr<dng_memory_block> &compressedBuffer, 1198 AutoPtr<dng_memory_block> &uncompressedBuffer, 1199 AutoPtr<dng_memory_block> &subTileBlockBuffer, 1200 AutoPtr<dng_memory_block> &tempBuffer, 1201 bool usingMultipleThreads); 1202 1203 virtual void DoWriteTiles (dng_host &host, 1204 const dng_ifd &ifd, 1205 dng_basic_tag_set &basic, 1206 dng_stream &stream, 1207 const dng_image &image, 1208 uint32 fakeChannels, 1209 uint32 tilesDown, 1210 uint32 tilesAcross, 1211 uint32 compressedSize, 1212 const dng_safe_uint32 &uncompressedSize); 1213 1214 }; 1215 1216 /*****************************************************************************/ 1217 1218 class dng_write_tiles_task : public dng_area_task, 1219 private dng_uncopyable 1220 { 1221 1222 protected: 1223 1224 dng_image_writer &fImageWriter; 1225 1226 dng_host &fHost; 1227 1228 const dng_ifd &fIFD; 1229 1230 dng_basic_tag_set &fBasic; 1231 1232 dng_stream &fStream; 1233 1234 const dng_image &fImage; 1235 1236 uint32 fFakeChannels; 1237 1238 uint32 fTilesDown; 1239 1240 uint32 fTilesAcross; 1241 1242 uint32 fCompressedSize; 1243 1244 uint32 fUncompressedSize; 1245 1246 std::atomic_uint fNextTileIndex; 1247 1248 dng_mutex fMutex; 1249 1250 dng_condition fCondition; 1251 1252 bool fTaskFailed; 1253 1254 uint32 fWriteTileIndex; 1255 1256 public: 1257 1258 dng_write_tiles_task (dng_image_writer &imageWriter, 1259 dng_host &host, 1260 const dng_ifd &ifd, 1261 dng_basic_tag_set &basic, 1262 dng_stream &stream, 1263 const dng_image &image, 1264 uint32 fakeChannels, 1265 uint32 tilesDown, 1266 uint32 tilesAcross, 1267 uint32 compressedSize, 1268 uint32 uncompressedSize); 1269 1270 void Process (uint32 threadIndex, 1271 const dng_rect &tile, 1272 dng_abort_sniffer *sniffer); 1273 1274 protected: 1275 1276 void ProcessTask (uint32 tileIndex, 1277 AutoPtr<dng_memory_block> &compressedBuffer, 1278 AutoPtr<dng_memory_block> &uncompressedBuffer, 1279 AutoPtr<dng_memory_block> &subTileBlockBuffer, 1280 AutoPtr<dng_memory_block> &tempBuffer, 1281 uint32 &tileByteCount, // output 1282 dng_memory_stream &tileStream, // output 1283 dng_abort_sniffer *sniffer); 1284 1285 void WriteTask (uint32 tileIndex, 1286 uint32 tileByteCount, 1287 dng_memory_stream &tileStream, 1288 dng_abort_sniffer *sniffer); 1289 1290 }; 1291 1292 /*****************************************************************************/ 1293 1294 #endif 1295 1296 /*****************************************************************************/ 1297