blob: beb8bc84b22024d8c64f005d1e3b3c83abf642ff [file] [log] [blame]
// ==========================================================
// Tag manipulation functions
//
// Design and implementation by
// - Hervé Drolon <drolon@infonie.fr>
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================
#ifndef FREEIMAGETAG_H
#define FREEIMAGETAG_H
// ==========================================================
// Exif JPEG tags
// ==========================================================
// ----------------------------------------------------------
// TIFF Rev. 6.0 Attribute Information Used in Exif
// ----------------------------------------------------------
// Tags relating to image data structure
#define TAG_IMAGE_WIDTH 0x0100
#define TAG_IMAGE_HEIGHT 0x0101
#define TAG_BITS_PER_SAMPLE 0x0102
#define TAG_COMPRESSION 0x0103
#define TAG_PHOTOMETRIC_INTERPRETATION 0x0106
#define TAG_ORIENTATION 0x0112
#define TAG_SAMPLES_PER_PIXEL 0x0115
#define TAG_PLANAR_CONFIGURATION 0x011C
#define TAG_YCBCR_SUBSAMPLING 0x0212
#define TAG_YCBCR_POSITIONING 0x0213
#define TAG_X_RESOLUTION 0x011A
#define TAG_Y_RESOLUTION 0x011B
#define TAG_RESOLUTION_UNIT 0x0128
// LibTIF compression modes
#define TAG_COMPRESSION_NONE 1 /* dump mode */
#define TAG_COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */
#define TAG_COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */
#define TAG_COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */
#define TAG_COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */
#define TAG_COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */
#define TAG_COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
#define TAG_COMPRESSION_OJPEG 6 /* !6.0 JPEG */
#define TAG_COMPRESSION_JPEG 7 /* %JPEG DCT compression */
#define TAG_COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
#define TAG_COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
#define TAG_COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
#define TAG_COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */
/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
#define TAG_COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */
#define TAG_COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */
#define TAG_COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */
#define TAG_COMPRESSION_IT8BL 32898 /* IT8 Binary line art */
/* compression codes 32908-32911 are reserved for Pixar */
#define TAG_COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
#define TAG_COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */
#define TAG_COMPRESSION_DEFLATE 32946 /* Deflate compression */
#define TAG_COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression,
as recognized by Adobe */
/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
#define TAG_COMPRESSION_DCS 32947 /* Kodak DCS encoding */
#define TAG_COMPRESSION_JBIG 34661 /* ISO JBIG */
#define TAG_COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */
#define TAG_COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */
#define TAG_COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */
#define TAG_COMPRESSION_LZMA 34925 /* LZMA2 */
// Tags relating to recording offset
#define TAG_STRIP_OFFSETS 0x0111
#define TAG_ROWS_PER_STRIP 0x0116
#define TAG_STRIP_BYTE_COUNTS 0x0117
#define TAG_JPEG_INTERCHANGE_FORMAT 0x0201
#define TAG_JPEG_INTERCHANGE_FORMAT_LENGTH 0x0202
// Tags relating to image data characteristics
#define TAG_TRANSFER_FUNCTION 0x012D
#define TAG_WHITE_POINT 0x013E
#define TAG_PRIMARY_CHROMATICITIES 0x013F
#define TAG_YCBCR_COEFFICIENTS 0x0211
#define TAG_REFERENCE_BLACK_WHITE 0x0214
// Other tags
#define TAG_DATETIME 0x0132
#define TAG_IMAGE_DESCRIPTION 0x010E
#define TAG_MAKE 0x010F
#define TAG_MODEL 0x0110
#define TAG_SOFTWARE 0x0131
#define TAG_ARTIST 0x013B
#define TAG_COPYRIGHT 0x8298
// ----------------------------------------------------------
// Exif IFD Attribute Information
// ----------------------------------------------------------
// Tags relating to version
#define TAG_EXIF_VERSION 0x9000
#define TAG_FLASHPIX_VERSION 0xA000
// Tag relating to image data characteristics
#define TAG_COLOR_SPACE 0xA001
// Tags relating to image configuration
#define TAG_COMPONENTS_CONFIGURATION 0x9101
#define TAG_COMPRESSED_BITS_PER_PIXEL 0x9102
#define TAG_PIXEL_X_DIMENSION 0xA002
#define TAG_PIXEL_Y_DIMENSION 0xA003
// Tags relating to user information
#define TAG_MARKER_NOTE 0x927C
#define TAG_USER_COMMENT 0x9286
// Tag relating to related file information
#define TAG_RELATED_SOUND_FILE 0xA004
// Tags relating to date and time
#define TAG_DATETIME_ORIGINAL 0x9003
#define TAG_DATETIME_DIGITIZED 0x9004
#define TAG_SUBSECOND_TIME 0x9290
#define TAG_SUBSECOND_TIME_ORIGINAL 0x9291
#define TAG_SUBSECOND_TIME_DIGITIZED 0x9292
// Tags relating to picture-taking conditions
#define TAG_EXPOSURE_TIME 0x829A
#define TAG_FNUMBER 0x829D
#define TAG_EXPOSURE_PROGRAM 0x8822
#define TAG_SPECTRAL_SENSITIVITY 0x8824
#define TAG_ISO_SPEED_RATINGS 0x8827
#define TAG_OECF 0x8828
#define TAG_SHUTTER_SPEED_VALUE 0x9201
#define TAG_APERTURE_VALUE 0x9202
#define TAG_BRIGHTNESS_VALUE 0x9203
#define TAG_EXPOSURE_BIAS_VALUE 0x9204
#define TAG_MAX_APERTURE_VALUE 0x9205
#define TAG_SUBJECT_DISTANCE 0x9206
#define TAG_METERING_MODE 0x9207
#define TAG_LIGHT_SOURCE 0x9208
#define TAG_FLASH 0x9209
#define TAG_FOCAL_LENGTH 0x920A
#define TAG_SUBJECT_AREA 0x9214
#define TAG_FLASH_ENERGY 0xA20B
#define TAG_SPATIAL_FREQ_RESPONSE 0xA20C
#define TAG_FOCAL_PLANE_X_RES 0xA20E
#define TAG_FOCAL_PLANE_Y_RES 0xA20F
#define TAG_FOCAL_PLANE_UNIT 0xA210
#define TAG_SUBJECT_LOCATION 0xA214
#define TAG_EXPOSURE_INDEX 0xA215
#define TAG_SENSING_METHOD 0xA217
#define TAG_FILE_SOURCE 0xA300
#define TAG_SCENE_TYPE 0xA301
#define TAG_CFA_PATTERN 0xA302
#define TAG_CUSTOM_RENDERED 0xA401
#define TAG_EXPOSURE_MODE 0xA402
#define TAG_WHITE_BALANCE 0xA403
#define TAG_DIGITAL_ZOOM_RATIO 0xA404
#define TAG_FOCAL_LENGTH_IN_35MM_FILM 0xA405
#define TAG_SCENE_CAPTURE_TYPE 0xA406
#define TAG_GAIN_CONTROL 0xA407
#define TAG_CONTRAST 0xA408
#define TAG_SATURATION 0xA409
#define TAG_SHARPNESS 0xA40A
#define TAG_DEVICE_SETTING_DESCRIPTION 0xA40B
#define TAG_SUBJECT_DISTANCE_RANGE 0xA40C
// Other tags
#define TAG_IMAGE_UNIQUE_ID 0xA420
// ----------------------------------------------------------
// GPS Attribute Information
// ----------------------------------------------------------
#define TAG_GPS_VERSION_ID 0x0000
#define TAG_GPS_LATITUDE_REF 0x0001
#define TAG_GPS_LATITUDE 0x0002
#define TAG_GPS_LONGITUDE_REF 0x0003
#define TAG_GPS_LONGITUDE 0x0004
#define TAG_GPS_ALTITUDE_REF 0x0005
#define TAG_GPS_ALTITUDE 0x0006
#define TAG_GPS_TIME_STAMP 0x0007
#define TAG_GPS_SATELLITES 0x0008
#define TAG_GPS_STATUS 0x0009
#define TAG_GPS_MEASURE_MODE 0x000A
#define TAG_GPS_DOP 0x000B
#define TAG_GPS_SPEED_REF 0x000C
#define TAG_GPS_SPEED 0x000D
#define TAG_GPS_TRACK_REF 0x000E
#define TAG_GPS_TRACK 0x000F
#define TAG_GPS_IMG_DIRECTION_REF 0x0010
#define TAG_GPS_IMG_DIRECTION 0x0011
#define TAG_GPS_MAP_DATUM 0x0012
#define TAG_GPS_DEST_LATITUDE_REF 0x0013
#define TAG_GPS_DEST_LATITUDE 0x0014
#define TAG_GPS_DEST_LONGITUDE_REF 0x0015
#define TAG_GPS_DEST_LONGITUDE 0x0016
#define TAG_GPS_DEST_BEARING_REF 0x0017
#define TAG_GPS_DEST_BEARING 0x0018
#define TAG_GPS_DEST_DISTANCE_REF 0x0019
#define TAG_GPS_DEST_DISTANCE 0x001A
#define TAG_GPS_PROCESSING_METHOD 0x001B
#define TAG_GPS_AREA_INFORMATION 0x001C
#define TAG_GPS_DATE_STAMP 0x001D
#define TAG_GPS_DIFFERENTIAL 0x001E
// ==========================================================
// IPTC/NAA tags
// ==========================================================
#define TAG_RECORD_VERSION 0x0200
#define TAG_CAPTION 0x0278
#define TAG_WRITER 0x027A
#define TAG_HEADLINE 0x0269
#define TAG_SPECIAL_INSTRUCTIONS 0x0228
#define TAG_BY_LINE 0x0250
#define TAG_BY_LINE_TITLE 0x0255
#define TAG_CREDIT 0x026E
#define TAG_SOURCE 0x0273
#define TAG_OBJECT_NAME 0x0205
#define TAG_DATE_CREATED 0x0237
#define TAG_CITY 0x025A
#define TAG_PROVINCE_OR_STATE 0x025F
#define TAG_COUNTRY_OR_PRIMARY_LOCATION 0x0265
#define TAG_ORIGINAL_TRANSMISSION_REFERENCE 0x0267
#define TAG_CATEGORY 0x020F
#define TAG_SUPPLEMENTAL_CATEGORIES 0x0214
#define TAG_URGENCY 0x020A
#define TAG_KEYWORDS 0x0219
#define TAG_COPYRIGHT_NOTICE 0x0274
#define TAG_RELEASE_DATE 0x021E
#define TAG_RELEASE_TIME 0x0223
#define TAG_TIME_CREATED 0x023C
#define TAG_ORIGINATING_PROGRAM 0x0241
// ==========================================================
// GeoTIFF tags
// ==========================================================
// tags 33550 is a private tag registered to SoftDesk, Inc
#define TIFFTAG_GEOPIXELSCALE 33550
// tags 33920-33921 are private tags registered to Intergraph, Inc
#define TIFFTAG_INTERGRAPH_MATRIX 33920
#define TIFFTAG_GEOTIEPOINTS 33922
// tags 34263-34264 are private tags registered to NASA-JPL Carto Group
#define TIFFTAG_JPL_CARTO_IFD 34263
#define TIFFTAG_GEOTRANSMATRIX 34264 /* New Matrix Tag replaces 33920 */
// tags 34735-3438 are private tags registered to SPOT Image, Inc
#define TIFFTAG_GEOKEYDIRECTORY 34735
#define TIFFTAG_GEODOUBLEPARAMS 34736
#define TIFFTAG_GEOASCIIPARAMS 34737
// ==========================================================
// FreeImage Animation tags
// ==========================================================
#define ANIMTAG_LOGICALWIDTH 0x0001
#define ANIMTAG_LOGICALHEIGHT 0x0002
#define ANIMTAG_GLOBALPALETTE 0x0003
#define ANIMTAG_LOOP 0x0004
#define ANIMTAG_FRAMELEFT 0x1001
#define ANIMTAG_FRAMETOP 0x1002
#define ANIMTAG_NOLOCALPALETTE 0x1003
#define ANIMTAG_INTERLACED 0x1004
#define ANIMTAG_FRAMETIME 0x1005
#define ANIMTAG_DISPOSALMETHOD 0x1006
// --------------------------------------------------------------------------
// Helper functions to deal with the FITAG structure
// --------------------------------------------------------------------------
/**
Describes the tag format descriptor
Given a FREE_IMAGE_MDTYPE, calculate the size of this type in bytes unit
@param type Tag data type
@return Returns the size of the data type, in bytes
@see FREE_IMAGE_MDTYPE
*/
unsigned FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type);
/**
Calculate the memory size required by a tag, including the size of the structure
@param tag The tag to examine
@return Retuns the memory size used by a tag
*/
size_t FreeImage_GetTagMemorySize(FITAG *tag);
// --------------------------------------------------------------------------
/**
Structure to hold a tag information
*/
typedef struct tagTagInfo {
WORD tag; // Tag ID (required)
char *fieldname; // Field name (required)
char *description; // Field description (may be NULL)
} TagInfo;
/**
Class to hold tag information (based on MeyersÂ’ Singleton).<br>
Sample usage :<br>
<code>
TagLib& s = TagLib::instance();
TagInfo *tag_info = s.getTagInfo(EXIF_MAIN, 0x0100);
</code>
Note on multi-threaded applications :
The singleton pattern must be carefully constructed in multi-threaded applications.
If two threads are to execute the creation method at the same time when a singleton
does not yet exist, they both must check for an instance of the singleton and then
only one should create the new one.
The classic solution to this problem is to use mutual exclusion on the class that
indicates that the object is being instantiated.
The FreeImage solution is to instantiate the singleton before any other thread is launched,
i.e. inside the FreeImage_Initialise function (see Plugin.cpp).
*/
class TagLib {
public:
/**
internal tag info tables registered in TagLib
*/
enum MDMODEL {
UNKNOWN,
EXIF_MAIN,
EXIF_EXIF,
EXIF_GPS,
EXIF_INTEROP,
EXIF_MAKERNOTE_CANON,
EXIF_MAKERNOTE_CASIOTYPE1,
EXIF_MAKERNOTE_CASIOTYPE2,
EXIF_MAKERNOTE_FUJIFILM,
EXIF_MAKERNOTE_KYOCERA,
EXIF_MAKERNOTE_MINOLTA,
EXIF_MAKERNOTE_NIKONTYPE1,
EXIF_MAKERNOTE_NIKONTYPE2,
EXIF_MAKERNOTE_NIKONTYPE3,
EXIF_MAKERNOTE_OLYMPUSTYPE1,
EXIF_MAKERNOTE_PANASONIC,
EXIF_MAKERNOTE_ASAHI,
EXIF_MAKERNOTE_PENTAX,
EXIF_MAKERNOTE_SONY,
EXIF_MAKERNOTE_SIGMA_SD1,
EXIF_MAKERNOTE_SIGMA_FOVEON,
IPTC,
GEOTIFF,
ANIMATION
};
private:
typedef std::map<WORD, TagInfo*> TAGINFO;
typedef std::map<int, TAGINFO*> TABLEMAP;
/// store hash tables for all known tag info tables
TABLEMAP _table_map;
private:
/**
Constructor (private)<br>
This is where the tag info tables are initialized.
@see addMetadataModel
*/
TagLib();
/// Assignement operator (disabled)
void operator=(TagLib&);
/// Copy constructor (disabled)
TagLib(const TagLib&);
/**
Used in the constructor to initialize the tag tables
@param md_model Internal metadata model
@param tag_table Tag info table
@return Returns TRUE if successful, returns FALSE otherwise
*/
BOOL addMetadataModel(MDMODEL md_model, TagInfo *tag_table);
public:
/// Destructor
~TagLib();
/**
@return Returns a reference to the TagLib instance
*/
static TagLib& instance();
/**
Given a tag ID, returns its TagInfo descriptor
@param md_model Internal metadata model
@param tagID tag ID
@return Returns the TagInfo descriptor if successful, returns NULL otherwise
*/
const TagInfo* getTagInfo(MDMODEL md_model, WORD tagID);
/**
Given a tag ID, returns its tag field name.
When the tag is unknown and defaultKey is not NULL, a string such as "Tag 0x1234" is returned.
This string is contained in the provided defaultKey buffer (assumed to be an array of at least 16 chars).
@param md_model Internal metadata model
@param tagID tag ID
@param defaultKey Assumed to be an array of 16 chars. If not NULL, build a key for unknown tags
@return Returns the tag field name if successful, returns an 'unknown tag' string contained in defaultKey otherwise
*/
const char* getTagFieldName(MDMODEL md_model, WORD tagID, char *defaultKey);
/**
Given a tag ID, returns its description.
When the tag has no description, a NULL value is returned.
@param md_model Internal metadata model
@param tagID tag ID
@return Returns the tag description if successful, returns NULL otherwise
*/
const char* getTagDescription(MDMODEL md_model, WORD tagID);
/**
Given a tag field name, returns its tag ID.
When the tag doesn't exists, a value '-1' is returned.
@param md_model Internal metadata model
@param key tag field name
@return Returns the tag ID if successful, returns -1 otherwise
*/
int getTagID(MDMODEL md_model, const char *key);
/**
Perform a conversion between internal metadata models and FreeImage public metadata models
@param md_model Internal metadata model
*/
FREE_IMAGE_MDMODEL getFreeImageModel(MDMODEL model);
};
// --------------------------------------------------------------------------
// Constant strings
// --------------------------------------------------------------------------
/// Name of the XMP field
static const char *g_TagLib_XMPFieldName = "XMLPacket";
/// Name of the Exif raw field
static const char *g_TagLib_ExifRawFieldName = "ExifRaw";
// --------------------------------------------------------------------------
// Metadata routines
// --------------------------------------------------------------------------
#if defined(__cplusplus)
extern "C" {
#endif
// JPEG / JPEG-XR Exif profile (see Exif.cpp)
// --------------------------------------------------------------------------
BOOL jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned datalen);
BOOL jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length);
BOOL jpegxr_read_exif_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset);
BOOL jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset);
BOOL tiff_get_ifd_profile(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, BYTE **ppbProfile, unsigned *uProfileLength);
// JPEG / TIFF IPTC profile (see IPTC.cpp)
// --------------------------------------------------------------------------
BOOL read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen);
BOOL write_iptc_profile(FIBITMAP *dib, BYTE **profile, unsigned *profile_size);
#if defined(__cplusplus)
}
#endif
#endif // FREEIMAGETAG_H