|
| 1 | +/* |
| 2 | + Copyright 2017 Larry Gritz et al. All Rights Reserved. |
| 3 | +
|
| 4 | + Redistribution and use in source and binary forms, with or without |
| 5 | + modification, are permitted provided that the following conditions are |
| 6 | + met: |
| 7 | + * Redistributions of source code must retain the above copyright |
| 8 | + notice, this list of conditions and the following disclaimer. |
| 9 | + * Redistributions in binary form must reproduce the above copyright |
| 10 | + notice, this list of conditions and the following disclaimer in the |
| 11 | + documentation and/or other materials provided with the distribution. |
| 12 | + * Neither the name of the software's owners nor the names of its |
| 13 | + contributors may be used to endorse or promote products derived from |
| 14 | + this software without specific prior written permission. |
| 15 | + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 16 | + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 17 | + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 18 | + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 19 | + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 20 | + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 21 | + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 22 | + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 23 | + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 | + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 25 | + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | +
|
| 27 | + (This is the Modified BSD License) |
| 28 | +*/ |
| 29 | + |
| 30 | +///////////////////////////////////////////////////////////////////////////// |
| 31 | +/// \file |
| 32 | +/// |
| 33 | +/// Utilities for dealing with TIFF tags and data structures (common to |
| 34 | +/// plugins that have to deal with TIFF itself, Exif data blocks, and other |
| 35 | +/// miscellaneous stuff that piggy-backs off TIFF format). |
| 36 | +/// |
| 37 | +///////////////////////////////////////////////////////////////////////////// |
| 38 | + |
| 39 | + |
| 40 | +#pragma once |
| 41 | + |
| 42 | +#ifndef OIIO_TIFFUTILS_H |
| 43 | +#define OIIO_TIFFUTILS_H |
| 44 | + |
| 45 | +extern "C" { |
| 46 | +#include "tiff.h" |
| 47 | +} |
| 48 | + |
| 49 | +#include <OpenImageIO/imageio.h> |
| 50 | + |
| 51 | + |
| 52 | +#ifdef TIFF_VERSION_BIG |
| 53 | +// In old versions of TIFF, this was defined in tiff.h. It's gone from |
| 54 | +// "BIG TIFF" (libtiff 4.x), so we just define it here. |
| 55 | + |
| 56 | +struct TIFFHeader { |
| 57 | + uint16_t tiff_magic; /* magic number (defines byte order) */ |
| 58 | + uint16_t tiff_version;/* TIFF version number */ |
| 59 | + uint32_t tiff_diroff; /* byte offset to first directory */ |
| 60 | +}; |
| 61 | + |
| 62 | +struct TIFFDirEntry { |
| 63 | + uint16_t tdir_tag; /* tag ID */ |
| 64 | + uint16_t tdir_type; /* data type -- see TIFFDataType enum */ |
| 65 | + uint32_t tdir_count; /* number of items; length in spec */ |
| 66 | + uint32_t tdir_offset; /* byte offset to field data */ |
| 67 | +}; |
| 68 | +#endif |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | +OIIO_NAMESPACE_BEGIN |
| 74 | + |
| 75 | +// Define EXIF constants |
| 76 | +enum TIFFTAG { |
| 77 | + EXIF_EXPOSURETIME = 33434, |
| 78 | + EXIF_FNUMBER = 33437, |
| 79 | + EXIF_EXPOSUREPROGRAM = 34850, |
| 80 | + EXIF_SPECTRALSENSITIVITY = 34852, |
| 81 | + EXIF_PHOTOGRAPHICSENSITIVITY = 34855, |
| 82 | + EXIF_ISOSPEEDRATINGS = 34855, // old nme for PHOTOGRAPHICSENSITIVITY |
| 83 | + EXIF_OECF = 34856, |
| 84 | + EXIF_SENSITIVITYTYPE = 34864, |
| 85 | + EXIF_STANDARDOUTPUTSENSITIVITY = 34865, |
| 86 | + EXIF_RECOMMENDEDEXPOSUREINDEX = 34866, |
| 87 | + EXIF_ISOSPEED = 34867, |
| 88 | + EXIF_ISOSPEEDLATITUDEYYY = 34868, |
| 89 | + EXIF_ISOSPEEDLATITUDEZZZ = 34869, |
| 90 | + EXIF_EXIFVERSION = 36864, |
| 91 | + EXIF_DATETIMEORIGINAL = 36867, |
| 92 | + EXIF_DATETIMEDIGITIZED = 36868, |
| 93 | + EXIF_OFFSETTIME = 36880, |
| 94 | + EXIF_OFFSETTIMEORIGINAL = 36881, |
| 95 | + EXIF_OFFSETTIMEDIGITIZED = 36882, |
| 96 | + EXIF_COMPONENTSCONFIGURATION = 37121, |
| 97 | + EXIF_COMPRESSEDBITSPERPIXEL = 37122, |
| 98 | + EXIF_SHUTTERSPEEDVALUE = 37377, |
| 99 | + EXIF_APERTUREVALUE = 37378, |
| 100 | + EXIF_BRIGHTNESSVALUE = 37379, |
| 101 | + EXIF_EXPOSUREBIASVALUE = 37380, |
| 102 | + EXIF_MAXAPERTUREVALUE = 37381, |
| 103 | + EXIF_SUBJECTDISTANCE = 37382, |
| 104 | + EXIF_METERINGMODE = 37383, |
| 105 | + EXIF_LIGHTSOURCE = 37384, |
| 106 | + EXIF_FLASH = 37385, |
| 107 | + EXIF_FOCALLENGTH = 37386, |
| 108 | + EXIF_SECURITYCLASSIFICATION = 37394, |
| 109 | + EXIF_IMAGEHISTORY = 37395, |
| 110 | + EXIF_SUBJECTAREA = 37396, |
| 111 | + EXIF_MAKERNOTE = 37500, |
| 112 | + EXIF_USERCOMMENT = 37510, |
| 113 | + EXIF_SUBSECTIME = 37520, |
| 114 | + EXIF_SUBSECTIMEORIGINAL = 37521, |
| 115 | + EXIF_SUBSECTIMEDIGITIZED = 37522, |
| 116 | + EXIF_TEMPERATURE = 37888, |
| 117 | + EXIF_HUMIDITY = 37889, |
| 118 | + EXIF_PRESSURE = 37890, |
| 119 | + EXIF_WATERDEPTH = 37891, |
| 120 | + EXIF_ACCELERATION = 37892, |
| 121 | + EXIF_CAMERAELEVATIONANGLE = 37893, |
| 122 | + EXIF_FLASHPIXVERSION = 40960, |
| 123 | + EXIF_COLORSPACE = 40961, |
| 124 | + EXIF_PIXELXDIMENSION = 40962, |
| 125 | + EXIF_PIXELYDIMENSION = 40963, |
| 126 | + EXIF_RELATEDSOUNDFILE = 40964, |
| 127 | + EXIF_FLASHENERGY = 41483, |
| 128 | + EXIF_SPATIALFREQUENCYRESPONSE = 41484, |
| 129 | + EXIF_FOCALPLANEXRESOLUTION = 41486, |
| 130 | + EXIF_FOCALPLANEYRESOLUTION = 41487, |
| 131 | + EXIF_FOCALPLANERESOLUTIONUNIT = 41488, |
| 132 | + EXIF_SUBJECTLOCATION = 41492, |
| 133 | + EXIF_EXPOSUREINDEX = 41493, |
| 134 | + EXIF_SENSINGMETHOD = 41495, |
| 135 | + EXIF_FILESOURCE = 41728, |
| 136 | + EXIF_SCENETYPE = 41729, |
| 137 | + EXIF_CFAPATTERN = 41730, |
| 138 | + EXIF_CUSTOMRENDERED = 41985, |
| 139 | + EXIF_EXPOSUREMODE = 41986, |
| 140 | + EXIF_WHITEBALANCE = 41987, |
| 141 | + EXIF_DIGITALZOOMRATIO = 41988, |
| 142 | + EXIF_FOCALLENGTHIN35MMFILM = 41989, |
| 143 | + EXIF_SCENECAPTURETYPE = 41990, |
| 144 | + EXIF_GAINCONTROL = 41991, |
| 145 | + EXIF_CONTRAST = 41992, |
| 146 | + EXIF_SATURATION = 41993, |
| 147 | + EXIF_SHARPNESS = 41994, |
| 148 | + EXIF_DEVICESETTINGDESCRIPTION = 41995, |
| 149 | + EXIF_SUBJECTDISTANCERANGE = 41996, |
| 150 | + EXIF_IMAGEUNIQUEID = 42016, |
| 151 | + EXIF_CAMERAOWNERNAME = 42032, |
| 152 | + EXIF_BODYSERIALNUMBER = 42033, |
| 153 | + EXIF_LENSSPECIFICATION = 42034, |
| 154 | + EXIF_LENSMAKE = 42035, |
| 155 | + EXIF_LENSMODEL = 42036, |
| 156 | + EXIF_LENSSERIALNUMBER = 42037, |
| 157 | + EXIF_GAMMA = 42240, |
| 158 | +}; |
| 159 | + |
| 160 | + |
| 161 | + |
| 162 | +/// Given a TIFF data type code (defined in tiff.h) and a count, return the |
| 163 | +/// equivalent TypeDesc where one exists. .Return TypeUndefined if there |
| 164 | +/// is no obvious equivalent. |
| 165 | +OIIO_API TypeDesc tiff_datatype_to_typedesc (TIFFDataType tifftype, size_t tiffcount=1); |
| 166 | + |
| 167 | +inline TypeDesc tiff_datatype_to_typedesc (const TIFFDirEntry& dir) { |
| 168 | + return tiff_datatype_to_typedesc (TIFFDataType(dir.tdir_type), dir.tdir_count); |
| 169 | +} |
| 170 | + |
| 171 | +/// Return the data size (in bytes) of the TIFF type. |
| 172 | +OIIO_API size_t tiff_data_size (TIFFDataType tifftype); |
| 173 | + |
| 174 | +/// Return the data size (in bytes) of the data for the given TIFFDirEntry. |
| 175 | +OIIO_API size_t tiff_data_size (const TIFFDirEntry &dir); |
| 176 | + |
| 177 | +/// Given a TIFFDirEntry and a data arena (represented by an array view |
| 178 | +/// of unsigned bytes), return an array_view of where the values for the |
| 179 | +/// tiff dir lives. Return an empty array_view if there is an error, which |
| 180 | +/// could include a nonsensical situation where the TIFFDirEntry seems to |
| 181 | +/// point outside the data arena. |
| 182 | +OIIO_API array_view<const uint8_t> |
| 183 | +OIIO_API tiff_dir_data (const TIFFDirEntry &td, array_view<const uint8_t> data); |
| 184 | + |
| 185 | +/// Decode a raw Exif data block and save all the metadata in an |
| 186 | +/// ImageSpec. Return true if all is ok, false if the exif block was |
| 187 | +/// somehow malformed. The binary data pointed to by 'exif' should |
| 188 | +/// start with a TIFF directory header. |
| 189 | +OIIO_API bool decode_exif (array_view<const uint8_t> exif, ImageSpec &spec); |
| 190 | +OIIO_API bool decode_exif (string_view exif, ImageSpec &spec); |
| 191 | +OIIO_API bool decode_exif (const void *exif, int length, ImageSpec &spec); // DEPRECATED (1.8) |
| 192 | + |
| 193 | +/// Construct an Exif data block from the ImageSpec, appending the Exif |
| 194 | +/// data as a big blob to the char vector. |
| 195 | +OIIO_API void encode_exif (const ImageSpec &spec, std::vector<char> &blob); |
| 196 | + |
| 197 | +/// Helper: For the given OIIO metadata attribute name, look up the Exif tag |
| 198 | +/// ID, TIFFDataType (expressed as an int), and count. Return true and fill |
| 199 | +/// in the fields if found, return false if not found. |
| 200 | +OIIO_API bool exif_tag_lookup (string_view name, int &tag, |
| 201 | + int &tifftype, int &count); |
| 202 | + |
| 203 | +/// Add metadata to spec based on raw IPTC (International Press |
| 204 | +/// Telecommunications Council) metadata in the form of an IIM |
| 205 | +/// (Information Interchange Model). Return true if all is ok, false if |
| 206 | +/// the iptc block was somehow malformed. This is a utility function to |
| 207 | +/// make it easy for multiple format plugins to support embedding IPTC |
| 208 | +/// metadata without having to duplicate functionality within each |
| 209 | +/// plugin. Note that IIM is actually considered obsolete and is |
| 210 | +/// replaced by an XML scheme called XMP. |
| 211 | +OIIO_API bool decode_iptc_iim (const void *iptc, int length, ImageSpec &spec); |
| 212 | + |
| 213 | +/// Find all the IPTC-amenable metadata in spec and assemble it into an |
| 214 | +/// IIM data block in iptc. This is a utility function to make it easy |
| 215 | +/// for multiple format plugins to support embedding IPTC metadata |
| 216 | +/// without having to duplicate functionality within each plugin. Note |
| 217 | +/// that IIM is actually considered obsolete and is replaced by an XML |
| 218 | +/// scheme called XMP. |
| 219 | +OIIO_API void encode_iptc_iim (const ImageSpec &spec, std::vector<char> &iptc); |
| 220 | + |
| 221 | +/// Add metadata to spec based on XMP data in an XML block. Return true |
| 222 | +/// if all is ok, false if the xml was somehow malformed. This is a |
| 223 | +/// utility function to make it easy for multiple format plugins to |
| 224 | +/// support embedding XMP metadata without having to duplicate |
| 225 | +/// functionality within each plugin. |
| 226 | +OIIO_API bool decode_xmp (const std::string &xml, ImageSpec &spec); |
| 227 | + |
| 228 | +/// Find all the relavant metadata (IPTC, Exif, etc.) in spec and |
| 229 | +/// assemble it into an XMP XML string. This is a utility function to |
| 230 | +/// make it easy for multiple format plugins to support embedding XMP |
| 231 | +/// metadata without having to duplicate functionality within each |
| 232 | +/// plugin. If 'minimal' is true, then don't encode things that would |
| 233 | +/// be part of ordinary TIFF or exif tags. |
| 234 | +OIIO_API std::string encode_xmp (const ImageSpec &spec, bool minimal=false); |
| 235 | + |
| 236 | + |
| 237 | +/// Handy structure to hold information mapping TIFF/EXIF tags to their |
| 238 | +/// names and actions. |
| 239 | +struct TagInfo { |
| 240 | + typedef void (*HandlerFunc)(const TagInfo& taginfo, const TIFFDirEntry& dir, |
| 241 | + array_view<const uint8_t> buf, ImageSpec& spec, |
| 242 | + bool swapendian, int offset_adjustment); |
| 243 | + |
| 244 | + TagInfo (int tag, const char *name, TIFFDataType type, |
| 245 | + int count, HandlerFunc handler = nullptr) |
| 246 | + : tifftag(tag), name(name), tifftype(type), tiffcount(count), |
| 247 | + handler(handler) {} |
| 248 | + |
| 249 | + int tifftag = -1; // TIFF tag used for this info |
| 250 | + const char *name = nullptr; // OIIO attribute name we use |
| 251 | + TIFFDataType tifftype = TIFF_NOTYPE; // Data type that TIFF wants |
| 252 | + int tiffcount = 0; // Number of items |
| 253 | + HandlerFunc handler = nullptr; // Special decoding handler |
| 254 | +}; |
| 255 | + |
| 256 | +/// Return an array_view of a TagInfo array for the corresponding table. |
| 257 | +/// Valid names are "Exif", "GPS", and "TIFF". This can be handy for |
| 258 | +/// iterating through all possible tags for each category. |
| 259 | +OIIO_API array_view<const TagInfo> tag_table (string_view tablename); |
| 260 | + |
| 261 | +/// Look up the TagInfo of a numbered or named tag from a named domain |
| 262 | +/// ("TIFF", "Exif", or "GPS"). Return nullptr if it is not known. |
| 263 | +OIIO_API const TagInfo* tag_lookup (string_view domain, int tag); |
| 264 | +OIIO_API const TagInfo* tag_lookup (string_view domain, string_view tagname); |
| 265 | + |
| 266 | + |
| 267 | + |
| 268 | +OIIO_NAMESPACE_END |
| 269 | + |
| 270 | +#endif // OIIO_TIFFUTILS_H |
0 commit comments