From dea9c030340e50324eba97c72a27c151bed12e1c Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 26 Jan 2018 17:38:31 +0300 Subject: AdvaImg: - freeimage extracted to the separate library; - FI_INTERFACE removed, all references to it are replaced with direct calls of FreeImage_* functions; - unified project for AdvaImg --- plugins/AdvaImg/src/Metadata/Exif.cpp | 1253 ------------------ plugins/AdvaImg/src/Metadata/FIRational.cpp | 176 --- plugins/AdvaImg/src/Metadata/FIRational.h | 108 -- plugins/AdvaImg/src/Metadata/FreeImageTag.cpp | 353 ------ plugins/AdvaImg/src/Metadata/FreeImageTag.h | 499 -------- plugins/AdvaImg/src/Metadata/IPTC.cpp | 342 ----- plugins/AdvaImg/src/Metadata/TagConversion.cpp | 1094 ---------------- plugins/AdvaImg/src/Metadata/TagLib.cpp | 1617 ------------------------ plugins/AdvaImg/src/Metadata/XTIFF.cpp | 766 ----------- 9 files changed, 6208 deletions(-) delete mode 100644 plugins/AdvaImg/src/Metadata/Exif.cpp delete mode 100644 plugins/AdvaImg/src/Metadata/FIRational.cpp delete mode 100644 plugins/AdvaImg/src/Metadata/FIRational.h delete mode 100644 plugins/AdvaImg/src/Metadata/FreeImageTag.cpp delete mode 100644 plugins/AdvaImg/src/Metadata/FreeImageTag.h delete mode 100644 plugins/AdvaImg/src/Metadata/IPTC.cpp delete mode 100644 plugins/AdvaImg/src/Metadata/TagConversion.cpp delete mode 100644 plugins/AdvaImg/src/Metadata/TagLib.cpp delete mode 100644 plugins/AdvaImg/src/Metadata/XTIFF.cpp (limited to 'plugins/AdvaImg/src/Metadata') diff --git a/plugins/AdvaImg/src/Metadata/Exif.cpp b/plugins/AdvaImg/src/Metadata/Exif.cpp deleted file mode 100644 index 35d83c4dbc..0000000000 --- a/plugins/AdvaImg/src/Metadata/Exif.cpp +++ /dev/null @@ -1,1253 +0,0 @@ -// ========================================================== -// Metadata functions implementation -// Exif metadata model -// -// Design and implementation by -// - Hervé Drolon (drolon@infonie.fr) -// - Mihail Naydenov (mnaydenov@users.sourceforge.net) -// -// Based on the following implementations: -// - metadata-extractor : http://www.drewnoakes.com/code/exif/ -// - jhead : http://www.sentex.net/~mwandel/jhead/ -// - ImageMagick : http://www.imagemagick.org/ -// -// 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! -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "FreeImage.h" -#include "Utilities.h" -#include "FreeImageTag.h" - -// ========================================================== -// Exif JPEG routines -// ========================================================== - -#define EXIF_NUM_FORMATS 12 - -#define TAG_EXIF_OFFSET 0x8769 // Exif IFD Pointer -#define TAG_GPS_OFFSET 0x8825 // GPS Info IFD Pointer -#define TAG_INTEROP_OFFSET 0xA005 // Interoperability IFD Pointer -#define TAG_MAKER_NOTE 0x927C // Maker note - -// CANON cameras have some funny bespoke fields that need further processing... -#define TAG_CANON_CAMERA_STATE_0x01 0x0001 // tags under tag 0x001 (CameraSettings) -#define TAG_CANON_CAMERA_STATE_0x02 0x0002 // tags under tag 0x002 (FocalLength) -#define TAG_CANON_CAMERA_STATE_0x04 0x0004 // tags under tag 0x004 (ShotInfo) -#define TAG_CANON_CAMERA_STATE_0x12 0x0012 // tags under tag 0x012 (AFInfo) -#define TAG_CANON_CAMERA_STATE_0xA0 0x00A0 // tags under tag 0x0A0 (ProcessingInfo) -#define TAG_CANON_CAMERA_STATE_0xE0 0x00E0 // tags under tag 0x0E0 (SensorInfo) - - -// ===================================================================== -// Reimplementation of strnicmp (it is not supported on some systems) -// ===================================================================== - -/** -Compare characters of two strings without regard to case. -@param s1 Null-terminated string to compare. -@param s2 Null-terminated string to compare. -@param len Number of characters to compare -@return Returns 0 if s1 substring identical to s2 substring -*/ -static int -FreeImage_strnicmp(const char *s1, const char *s2, size_t len) { - unsigned char c1, c2; - - if(!s1 || !s2) return -1; - - c1 = 0; c2 = 0; - if(len) { - do { - c1 = *s1; c2 = *s2; - s1++; s2++; - if (!c1) - break; - if (!c2) - break; - if (c1 == c2) - continue; - c1 = (BYTE)tolower(c1); - c2 = (BYTE)tolower(c2); - if (c1 != c2) - break; - } while (--len); - } - return (int)c1 - (int)c2; -} - - -// ---------------------------------------------------------- -// Little Endian / Big Endian io routines -// ---------------------------------------------------------- - -static short -ReadInt16(BOOL msb_order, const void *buffer) { - short value; - - if(msb_order) { - value = (short)((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]); - return value; - } - value = (short)((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]); - return value; -} - -static LONG -ReadInt32(BOOL msb_order, const void *buffer) { - LONG value; - - if(msb_order) { - value = (LONG)((((BYTE*) buffer)[0] << 24) | (((BYTE*) buffer)[1] << 16) | (((BYTE*) buffer)[2] << 8) | (((BYTE*) buffer)[3])); - return value; - } - value = (LONG)((((BYTE*) buffer)[3] << 24) | (((BYTE*) buffer)[2] << 16) | (((BYTE*) buffer)[1] << 8 ) | (((BYTE*) buffer)[0])); - return value; -} - -static WORD -ReadUint16(BOOL msb_order, const void *buffer) { - WORD value; - - if(msb_order) { - value = (WORD) ((((BYTE*) buffer)[0] << 8) | ((BYTE*) buffer)[1]); - return value; - } - value = (WORD) ((((BYTE*) buffer)[1] << 8) | ((BYTE*) buffer)[0]); - return value; -} - -static DWORD -ReadUint32(BOOL msb_order, const void *buffer) { - return ((DWORD) ReadInt32(msb_order, buffer) & 0xFFFFFFFF); -} - -// ---------------------------------------------------------- -// Exif JPEG markers routines -// ---------------------------------------------------------- - -/** -Process a IFD offset -Returns the offset and the metadata model for this tag -*/ -static void -processIFDOffset(FITAG *tag, const char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) { - // get the IFD offset - *subdirOffset = ReadUint32(msb_order, pval); - - // select a tag info table - switch(FreeImage_GetTagID(tag)) { - case TAG_EXIF_OFFSET: - *md_model = TagLib::EXIF_EXIF; - break; - case TAG_GPS_OFFSET: - *md_model = TagLib::EXIF_GPS; - break; - case TAG_INTEROP_OFFSET: - *md_model = TagLib::EXIF_INTEROP; - break; - } -} - -/** -Process a maker note IFD offset -Returns the offset and the metadata model for this tag -*/ -static void -processMakerNote(FIBITMAP *dib, const char *pval, BOOL msb_order, DWORD *subdirOffset, TagLib::MDMODEL *md_model) { - FITAG *tagMake = NULL; - - *subdirOffset = 0; - *md_model = TagLib::UNKNOWN; - - // Determine the camera model and makernote format - // WARNING: note that Maker may be NULL sometimes so check its value before using it - // (NULL pointer checking is done by FreeImage_strnicmp) - FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "Make", &tagMake); - const char *Maker = (char*)FreeImage_GetTagValue(tagMake); - - if((memcmp("OLYMP\x00\x01", pval, 7) == 0) || (memcmp("OLYMP\x00\x02", pval, 7) == 0) || (memcmp("EPSON", pval, 5) == 0) || (memcmp("AGFA", pval, 4) == 0)) { - // Olympus Type 1 Makernote - // Epson and Agfa use Olympus maker note standard, - // see: http://www.ozhiker.com/electronics/pjmt/jpeg_info/ - *md_model = TagLib::EXIF_MAKERNOTE_OLYMPUSTYPE1; - *subdirOffset = 8; - } - else if(memcmp("OLYMPUS\x00\x49\x49\x03\x00", pval, 12) == 0) { - // Olympus Type 2 Makernote - // !!! NOT YET SUPPORTED !!! - *subdirOffset = 0; - *md_model = TagLib::UNKNOWN; - } - else if(memcmp("Nikon", pval, 5) == 0) { - /* There are two scenarios here: - * Type 1: - * :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon........... - * :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................ - * Type 3: - * :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*... - * :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200 - */ - if (pval[6] == 1) { - // Nikon type 1 Makernote - *md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE1; - *subdirOffset = 8; - } else if (pval[6] == 2) { - // Nikon type 3 Makernote - *md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE3; - *subdirOffset = 18; - } else { - // Unsupported makernote data ignored - *subdirOffset = 0; - *md_model = TagLib::UNKNOWN; - } - } else if(Maker && (FreeImage_strnicmp("NIKON", Maker, 5) == 0)) { - // Nikon type 2 Makernote - *md_model = TagLib::EXIF_MAKERNOTE_NIKONTYPE2; - *subdirOffset = 0; - } else if(Maker && (FreeImage_strnicmp("Canon", Maker, 5) == 0)) { - // Canon Makernote - *md_model = TagLib::EXIF_MAKERNOTE_CANON; - *subdirOffset = 0; - } else if(Maker && (FreeImage_strnicmp("Casio", Maker, 5) == 0)) { - // Casio Makernote - if(memcmp("QVC\x00\x00\x00", pval, 6) == 0) { - // Casio Type 2 Makernote - *md_model = TagLib::EXIF_MAKERNOTE_CASIOTYPE2; - *subdirOffset = 6; - } else { - // Casio Type 1 Makernote - *md_model = TagLib::EXIF_MAKERNOTE_CASIOTYPE1; - *subdirOffset = 0; - } - } else if ((memcmp("FUJIFILM", pval, 8) == 0) || (Maker && (FreeImage_strnicmp("Fujifilm", Maker, 8) == 0))) { - // Fujifile Makernote - // Fujifilm's Makernote always use little-endian order altough the Exif section maybe in little-endian order or in big-endian order. - // If msb_order == TRUE, the Makernote won't be read: - // the value of ifdStart will be 0x0c000000 instead of 0x0000000c and the MakerNote section will be discarded later - // in jpeg_read_exif_dir because the IFD is too high - *md_model = TagLib::EXIF_MAKERNOTE_FUJIFILM; - DWORD ifdStart = ReadUint32(msb_order, pval + 8); - *subdirOffset = ifdStart; - } - else if(memcmp("KYOCERA\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00", pval, 22) == 0) { - *md_model = TagLib::EXIF_MAKERNOTE_KYOCERA; - *subdirOffset = 22; - } - else if(Maker && (FreeImage_strnicmp("Minolta", Maker, 7) == 0)) { - // Minolta maker note - *md_model = TagLib::EXIF_MAKERNOTE_MINOLTA; - *subdirOffset = 0; - } - else if(memcmp("Panasonic\x00\x00\x00", pval, 12) == 0) { - // Panasonic maker note - *md_model = TagLib::EXIF_MAKERNOTE_PANASONIC; - *subdirOffset = 12; - } - else if(Maker && (FreeImage_strnicmp("LEICA", Maker, 5) == 0)) { - // Leica maker note - if(memcmp("LEICA\x00\x00\x00", pval, 8) == 0) { - // not yet supported makernote data ignored - *subdirOffset = 0; - *md_model = TagLib::UNKNOWN; - } - } - else if(Maker && ((FreeImage_strnicmp("Pentax", Maker, 6) == 0) || (FreeImage_strnicmp("Asahi", Maker, 5) == 0))) { - // Pentax maker note - if(memcmp("AOC\x00", pval, 4) == 0) { - // Type 2 Pentax Makernote - *md_model = TagLib::EXIF_MAKERNOTE_PENTAX; - *subdirOffset = 6; - } else { - // Type 1 Pentax Makernote - *md_model = TagLib::EXIF_MAKERNOTE_ASAHI; - *subdirOffset = 0; - } - } - else if((memcmp("SONY CAM\x20\x00\x00\x00", pval, 12) == 0) || (memcmp("SONY DSC\x20\x00\x00\x00", pval, 12) == 0)) { - *md_model = TagLib::EXIF_MAKERNOTE_SONY; - *subdirOffset = 12; - } - else if((memcmp("SIGMA\x00\x00\x00", pval, 8) == 0) || (memcmp("FOVEON\x00\x00", pval, 8) == 0)) { - FITAG *tagModel = NULL; - FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, "Model", &tagModel); - const char *Model = (char*)FreeImage_GetTagValue(tagModel); - if(Model && (memcmp("SIGMA SD1\x00", Model, 10) == 0)) { - // Sigma SD1 maker note - *subdirOffset = 10; - *md_model = TagLib::EXIF_MAKERNOTE_SIGMA_SD1; - } else { - // Sigma / Foveon makernote - *subdirOffset = 10; - *md_model = TagLib::EXIF_MAKERNOTE_SIGMA_FOVEON; - } - } -} - -/** -Process a Canon maker note tag. -A single Canon tag may contain many other tags within. -*/ -static BOOL -processCanonMakerNoteTag(FIBITMAP *dib, FITAG *tag) { - char defaultKey[16]; - DWORD startIndex = 0; - TagLib& s = TagLib::instance(); - - WORD tag_id = FreeImage_GetTagID(tag); - - int subTagTypeBase = 0; - - switch(tag_id) { - case TAG_CANON_CAMERA_STATE_0x01: - subTagTypeBase = 0xC100; - startIndex = 1; - break; - case TAG_CANON_CAMERA_STATE_0x02: - subTagTypeBase = 0xC200; - startIndex = 0; - break; - case TAG_CANON_CAMERA_STATE_0x04: - subTagTypeBase = 0xC400; - startIndex = 1; - break; - case TAG_CANON_CAMERA_STATE_0x12: - subTagTypeBase = 0x1200; - startIndex = 0; - break; - case TAG_CANON_CAMERA_STATE_0xA0: - subTagTypeBase = 0xCA00; - startIndex = 1; - break; - case TAG_CANON_CAMERA_STATE_0xE0: - subTagTypeBase = 0xCE00; - startIndex = 1; - break; - - default: - { - // process as a normal tag - - // get the tag key and description - const char *key = s.getTagFieldName(TagLib::EXIF_MAKERNOTE_CANON, tag_id, defaultKey); - FreeImage_SetTagKey(tag, key); - const char *description = s.getTagDescription(TagLib::EXIF_MAKERNOTE_CANON, tag_id); - FreeImage_SetTagDescription(tag, description); - - // store the tag - if(key) { - FreeImage_SetMetadata(FIMD_EXIF_MAKERNOTE, dib, key, tag); - } - - return TRUE; - } - break; - - } - - WORD *pvalue = (WORD*)FreeImage_GetTagValue(tag); - - // create a tag - FITAG *canonTag = FreeImage_CreateTag(); - if(!canonTag) return FALSE; - - // we intentionally skip the first array member (if needed) - for (DWORD i = startIndex; i < FreeImage_GetTagCount(tag); i++) { - - tag_id = (WORD)(subTagTypeBase + i); - - FreeImage_SetTagID(canonTag, tag_id); - FreeImage_SetTagType(canonTag, FIDT_SHORT); - FreeImage_SetTagCount(canonTag, 1); - FreeImage_SetTagLength(canonTag, 2); - FreeImage_SetTagValue(canonTag, &pvalue[i]); - - // get the tag key and description - const char *key = s.getTagFieldName(TagLib::EXIF_MAKERNOTE_CANON, tag_id, defaultKey); - FreeImage_SetTagKey(canonTag, key); - const char *description = s.getTagDescription(TagLib::EXIF_MAKERNOTE_CANON, tag_id); - FreeImage_SetTagDescription(canonTag, description); - - // store the tag - if(key) { - FreeImage_SetMetadata(FIMD_EXIF_MAKERNOTE, dib, key, canonTag); - } - } - - // delete the tag - FreeImage_DeleteTag(canonTag); - - return TRUE; -} - -/** -Process a standard Exif tag -*/ -static void -processExifTag(FIBITMAP *dib, FITAG *tag, char *pval, BOOL msb_order, TagLib::MDMODEL md_model) { - char defaultKey[16]; - int n; - DWORD i; - - // allocate a buffer to store the tag value - BYTE *exif_value = (BYTE*)malloc(FreeImage_GetTagLength(tag) * sizeof(BYTE)); - if(NULL == exif_value) { - // out of memory ... - return; - } - memset(exif_value, 0, FreeImage_GetTagLength(tag) * sizeof(BYTE)); - - // get the tag value - switch(FreeImage_GetTagType(tag)) { - - case FIDT_SHORT: - { - WORD *value = (WORD*)&exif_value[0]; - for(i = 0; i < FreeImage_GetTagCount(tag); i++) { - value[i] = ReadUint16(msb_order, pval + i * sizeof(WORD)); - } - FreeImage_SetTagValue(tag, value); - break; - } - case FIDT_SSHORT: - { - short *value = (short*)&exif_value[0]; - for(i = 0; i < FreeImage_GetTagCount(tag); i++) { - value[i] = ReadInt16(msb_order, pval + i * sizeof(short)); - } - FreeImage_SetTagValue(tag, value); - break; - } - case FIDT_LONG: - { - DWORD *value = (DWORD*)&exif_value[0]; - for(i = 0; i < FreeImage_GetTagCount(tag); i++) { - value[i] = ReadUint32(msb_order, pval + i * sizeof(DWORD)); - } - FreeImage_SetTagValue(tag, value); - break; - } - case FIDT_SLONG: - { - LONG *value = (LONG*)&exif_value[0]; - for(i = 0; i < FreeImage_GetTagCount(tag); i++) { - value[i] = ReadInt32(msb_order, pval + i * sizeof(LONG)); - } - FreeImage_SetTagValue(tag, value); - break; - } - case FIDT_RATIONAL: - { - n = sizeof(DWORD); - - DWORD *value = (DWORD*)&exif_value[0]; - for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) { - // read a sequence of (numerator, denominator) - value[i] = ReadUint32(msb_order, n*i + (char*)pval); - } - FreeImage_SetTagValue(tag, value); - break; - } - case FIDT_SRATIONAL: - { - n = sizeof(LONG); - - LONG *value = (LONG*)&exif_value[0]; - for(i = 0; i < 2 * FreeImage_GetTagCount(tag); i++) { - // read a sequence of (numerator, denominator) - value[i] = ReadInt32(msb_order, n*i + (char*)pval); - } - FreeImage_SetTagValue(tag, value); - break; - } - case FIDT_BYTE: - case FIDT_ASCII: - case FIDT_SBYTE: - case FIDT_UNDEFINED: - case FIDT_FLOAT: - case FIDT_DOUBLE: - default: - FreeImage_SetTagValue(tag, pval); - break; - } - - if(md_model == TagLib::EXIF_MAKERNOTE_CANON) { - // A single Canon tag can have multiple values within - processCanonMakerNoteTag(dib, tag); - } - else { - TagLib& s = TagLib::instance(); - - WORD tag_id = FreeImage_GetTagID(tag); - - // get the tag key and description - const char *key = s.getTagFieldName(md_model, tag_id, defaultKey); - FreeImage_SetTagKey(tag, key); - const char *description = s.getTagDescription(md_model, tag_id); - FreeImage_SetTagDescription(tag, description); - - // store the tag - if(key) { - FreeImage_SetMetadata(s.getFreeImageModel(md_model), dib, key, tag); - } - } - - - // free the temporary buffer - free(exif_value); - -} - -/** -Process Exif directory - -@param dib Input FIBITMAP -@param tiffp Pointer to the TIFF header -@param dwOffsetIfd0 Offset to the 0th IFD (first IFD) -@param dwLength Length of the Exif file -@param dwProfileOffset File offset to be used when reading 'offset/value' tags -@param msb_order Endianness order of the Exif file (TRUE if big-endian, FALSE if little-endian) -@param starting_md_model Metadata model of the IFD (should be TagLib::EXIF_MAIN for a jpeg) -@return Returns TRUE if sucessful, returns FALSE otherwise -*/ -static BOOL -jpeg_read_exif_dir(FIBITMAP *dib, const BYTE *tiffp, DWORD dwOffsetIfd0, DWORD dwLength, DWORD dwProfileOffset, BOOL msb_order, TagLib::MDMODEL starting_md_model) { - WORD de, nde; - - std::stack destack; // directory entries stack - std::stack ifdstack; // IFD stack - std::stack modelstack; // metadata model stack - - // Keep a list of already visited IFD to avoid stack overflows - // when recursive/cyclic directory structures exist. - // This kind of recursive Exif file was encountered with Kodak images coming from - // KODAK PROFESSIONAL DCS Photo Desk JPEG Export v3.2 W - std::map visitedIFD; - - /* - "An Image File Directory (IFD) consists of a 2-byte count of the number of directory - entries (i.e. the number of fields), followed by a sequence of 12-byte field - entries, followed by a 4-byte offset of the next IFD (or 0 if none)." - The "next IFD" (1st IFD) is the thumbnail. - */ - #define DIR_ENTRY_ADDR(_start, _entry) (_start + 2 + (12 * _entry)) - - // set the metadata model to Exif - - TagLib::MDMODEL md_model = starting_md_model; - - // set the pointer to the first IFD (0th IFD) and follow it were it leads. - - const BYTE *ifd0th = (BYTE*)tiffp + (size_t)dwOffsetIfd0; - - const BYTE *ifdp = ifd0th; - - de = 0; - - do { - // if there is anything on the stack then pop it off - if(!destack.empty()) { - ifdp = ifdstack.top(); ifdstack.pop(); - de = destack.top(); destack.pop(); - md_model = modelstack.top(); modelstack.pop(); - } - - // remember that we've visited this directory and entry so that we don't visit it again later - DWORD visited = (DWORD)( (((size_t)ifdp & 0xFFFF) << 16) | (size_t)de ); - if(visitedIFD.find(visited) != visitedIFD.end()) { - continue; - } else { - visitedIFD[visited] = 1; // processed - } - - // determine how many entries there are in the current IFD - nde = ReadUint16(msb_order, ifdp); - if (((size_t)(ifdp - tiffp) + 12 * nde) > (size_t)dwLength) { - // suspicious IFD offset, ignore - continue; - } - - for(; de < nde; de++) { - char *pde = NULL; // pointer to the directory entry - char *pval = NULL; // pointer to the tag value - - // create a tag - FITAG *tag = FreeImage_CreateTag(); - if(!tag) return FALSE; - - // point to the directory entry - pde = (char*) DIR_ENTRY_ADDR(ifdp, de); - - // get the tag ID - WORD tag_id = ReadUint16(msb_order, pde); - FreeImage_SetTagID(tag, tag_id); - - // get the tag type - WORD tag_type = (WORD)ReadUint16(msb_order, pde + 2); - if((tag_type - 1) >= EXIF_NUM_FORMATS) { - // a problem occured : delete the tag (not free'd after) - FreeImage_DeleteTag(tag); - // break out of the for loop - break; - } - FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)tag_type); - - // get number of components - DWORD tag_count = ReadUint32(msb_order, pde + 4); - FreeImage_SetTagCount(tag, tag_count); - - // check that tag length (size of the tag value in bytes) will fit in a DWORD - unsigned tag_data_width = FreeImage_TagDataWidth(FreeImage_GetTagType(tag)); - if (tag_data_width != 0 && FreeImage_GetTagCount(tag) > ~(DWORD)0 / tag_data_width) { - FreeImage_DeleteTag(tag); - // jump to next entry - continue; - } - FreeImage_SetTagLength(tag, FreeImage_GetTagCount(tag) * tag_data_width); - - if(FreeImage_GetTagLength(tag) <= 4) { - // 4 bytes or less and value is in the dir entry itself - pval = pde + 8; - } else { - // if its bigger than 4 bytes, the directory entry contains an offset - DWORD offset_value = ReadUint32(msb_order, pde + 8); - // the offset can be relative to tiffp or to an external reference (see JPEG-XR) - if(dwProfileOffset) { - offset_value -= dwProfileOffset; - } - // first check if offset exceeds buffer, at this stage FreeImage_GetTagLength may return invalid data - if(offset_value > dwLength) { - // a problem occured : delete the tag (not free'd after) - FreeImage_DeleteTag(tag); - // jump to next entry - continue; - } - // now check that length does not exceed the buffer size - if(FreeImage_GetTagLength(tag) > dwLength - offset_value){ - // a problem occured : delete the tag (not free'd after) - FreeImage_DeleteTag(tag); - // jump to next entry - continue; - } - pval = (char*)(tiffp + offset_value); - } - - // check for a IFD offset - BOOL isIFDOffset = FALSE; - switch(FreeImage_GetTagID(tag)) { - case TAG_EXIF_OFFSET: - case TAG_GPS_OFFSET: - case TAG_INTEROP_OFFSET: - case TAG_MAKER_NOTE: - isIFDOffset = TRUE; - break; - } - if(isIFDOffset) { - DWORD sub_offset = 0; - TagLib::MDMODEL next_mdmodel = md_model; - const BYTE *next_ifd = ifdp; - - // get offset and metadata model - if (FreeImage_GetTagID(tag) == TAG_MAKER_NOTE) { - processMakerNote(dib, pval, msb_order, &sub_offset, &next_mdmodel); - next_ifd = (BYTE*)pval + sub_offset; - } else { - processIFDOffset(tag, pval, msb_order, &sub_offset, &next_mdmodel); - next_ifd = (BYTE*)tiffp + sub_offset; - } - - if((sub_offset < dwLength) && (next_mdmodel != TagLib::UNKNOWN)) { - // push our current directory state onto the stack - ifdstack.push(ifdp); - // jump to the next entry - de++; - destack.push(de); - - // push our current metadata model - modelstack.push(md_model); - - // push new state onto of stack to cause a jump - ifdstack.push(next_ifd); - destack.push(0); - - // select a new metadata model - modelstack.push(next_mdmodel); - - // delete the tag as it won't be stored nor deleted in the for() loop - FreeImage_DeleteTag(tag); - - break; // break out of the for loop - } - else { - // unsupported camera model, canon maker tag or something unknown - // process as a standard tag - processExifTag(dib, tag, pval, msb_order, md_model); - } - - } else { - // process as a standard tag - processExifTag(dib, tag, pval, msb_order, md_model); - } - - // delete the tag - FreeImage_DeleteTag(tag); - - } // for(nde) - - // additional thumbnail data is skipped - - } while (!destack.empty()); - - // - // --- handle thumbnail data --- - // - - const WORD entriesCount0th = ReadUint16(msb_order, ifd0th); - - DWORD next_offset = ReadUint32(msb_order, DIR_ENTRY_ADDR(ifd0th, entriesCount0th)); - if((next_offset == 0) || (next_offset >= dwLength)) { - return TRUE; //< no thumbnail - } - - const BYTE* const ifd1st = (BYTE*)tiffp + next_offset; - const WORD entriesCount1st = ReadUint16(msb_order, ifd1st); - - unsigned thCompression = 0; - unsigned thOffset = 0; - unsigned thSize = 0; - - for(int e = 0; e < entriesCount1st; e++) { - - // point to the directory entry - const BYTE* base = DIR_ENTRY_ADDR(ifd1st, e); - - // check for buffer overflow - const size_t remaining = (size_t)base + 12 - (size_t)tiffp; - if(remaining >= dwLength) { - // bad IFD1 directory, ignore it - return FALSE; - } - - // get the tag ID - WORD tag = ReadUint16(msb_order, base); - // get the tag type - /*WORD type = */ReadUint16(msb_order, base + sizeof(WORD)); - // get number of components - /*DWORD count = */ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD)); - // get the tag value - DWORD offset = ReadUint32(msb_order, base + sizeof(WORD) + sizeof(WORD) + sizeof(DWORD)); - - switch(tag) { - case TAG_COMPRESSION: - // Tiff Compression Tag (should be COMPRESSION_OJPEG (6), but is not always respected) - thCompression = offset; - break; - case TAG_JPEG_INTERCHANGE_FORMAT: - // Tiff JPEGInterchangeFormat Tag - thOffset = offset; - break; - case TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: - // Tiff JPEGInterchangeFormatLength Tag - thSize = offset; - break; - // ### X and Y Resolution ignored, orientation ignored - case TAG_X_RESOLUTION: // XResolution - case TAG_Y_RESOLUTION: // YResolution - case TAG_RESOLUTION_UNIT: // ResolutionUnit - case TAG_ORIENTATION: // Orientation - break; - default: - break; - } - } - - if(/*thCompression != 6 ||*/ thOffset == 0 || thSize == 0) { - return TRUE; - } - - if(thOffset + thSize > dwLength) { - return TRUE; - } - - // load the thumbnail - - const BYTE *thLocation = tiffp + thOffset; - - FIMEMORY* hmem = FreeImage_OpenMemory(const_cast(thLocation), thSize); - FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem); - FreeImage_CloseMemory(hmem); - - // store the thumbnail - FreeImage_SetThumbnail(dib, thumbnail); - // then delete it - FreeImage_Unload(thumbnail); - - return TRUE; -} - -// -------------------------------------------------------------------------- - -/** -Read and decode JPEG_APP1 marker (Exif profile) -@param dib Input FIBITMAP -@param data Pointer to the APP1 marker -@param length APP1 marker length -@return Returns TRUE if successful, FALSE otherwise -*/ -BOOL -jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *data, unsigned length) { - // marker identifying string for Exif = "Exif\0\0" - BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; - BYTE lsb_first[4] = { 0x49, 0x49, 0x2A, 0x00 }; // Classic TIFF signature - little-endian order - BYTE msb_first[4] = { 0x4D, 0x4D, 0x00, 0x2A }; // Classic TIFF signature - big-endian order - - // profile size is up to 32-bit - DWORD dwProfileLength = (DWORD)length; - BYTE *pbProfile = (BYTE*)data; - - // verify the identifying string - if(memcmp(exif_signature, pbProfile, sizeof(exif_signature)) == 0) { - // This is an Exif profile - // should contain a TIFF header with up to 2 IFDs (IFD stands for 'Image File Directory') - // 0th IFD : the image attributes, 1st IFD : may be used for thumbnail - - pbProfile += sizeof(exif_signature); - dwProfileLength -= sizeof(exif_signature); - - // read the TIFF header (8 bytes) - - // check the endianess order - - BOOL bBigEndian = TRUE; - - if(memcmp(pbProfile, lsb_first, sizeof(lsb_first)) == 0) { - // Exif section is in little-endian order - bBigEndian = FALSE; - } else { - if(memcmp(pbProfile, msb_first, sizeof(msb_first)) == 0) { - // Exif section is in big-endian order - bBigEndian = TRUE; - } else { - // Invalid Exif alignment marker - return FALSE; - } - } - - // this is the offset to the first IFD (Image File Directory) - DWORD dwFirstOffset = ReadUint32(bBigEndian, pbProfile + 4); - if (dwFirstOffset > dwProfileLength) { - // bad Exif data - return FALSE; - } - - /* - Note: as FreeImage 3.14.0, this test is no longer needed for images with similar suspicious offset - => tested with Pentax Optio 230, FujiFilm SP-2500 and Canon EOS 300D - if (dwFirstOffset < 8 || dwFirstOffset > 16) { - // This is usually set to 8 - // but PENTAX Optio 230 has it set differently, and uses it as offset. - FreeImage_OutputMessageProc(FIF_JPEG, "Exif: Suspicious offset of first IFD value"); - return FALSE; - } - */ - - // process Exif directories, starting with Exif-TIFF IFD - return jpeg_read_exif_dir(dib, pbProfile, dwFirstOffset, dwProfileLength, 0, bBigEndian, TagLib::EXIF_MAIN); - } - - return FALSE; -} - -// ========================================================== -// Exif JPEG helper routines -// ========================================================== - -/** -Read JPEG_APP1 marker (Exif profile) -@param dib Input FIBITMAP -@param dataptr Pointer to the APP1 marker -@param datalen APP1 marker length -@return Returns TRUE if successful, FALSE otherwise -*/ -BOOL -jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length) { - // marker identifying string for Exif = "Exif\0\0" - BYTE exif_signature[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; - - // verify the identifying string - if(memcmp(exif_signature, profile, sizeof(exif_signature)) != 0) { - // not an Exif profile - return FALSE; - } - - // create a tag - FITAG *tag = FreeImage_CreateTag(); - if(tag) { - FreeImage_SetTagKey(tag, g_TagLib_ExifRawFieldName); - FreeImage_SetTagLength(tag, (DWORD)length); - FreeImage_SetTagCount(tag, (DWORD)length); - FreeImage_SetTagType(tag, FIDT_BYTE); - FreeImage_SetTagValue(tag, profile); - - // store the tag - FreeImage_SetMetadata(FIMD_EXIF_RAW, dib, FreeImage_GetTagKey(tag), tag); - - // destroy the tag - FreeImage_DeleteTag(tag); - - return TRUE; - } - - return FALSE; -} - -// ========================================================== -// Exif JPEG-XR helper routines -// ========================================================== - -/** -Read and decode JPEG-XR Exif IFD -@param dib Input FIBITMAP -@param profile Pointer to the Exif marker -@param length Exif marker length -@param file_offset Reference offset in the original file of each tag value whose length is > 4 -@return Returns TRUE if successful, FALSE otherwise -*/ -BOOL -jpegxr_read_exif_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) { - // assume Little Endian order - BOOL bBigEndian = FALSE; - - // process Exif specific IFD - return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_EXIF); -} - -/** -Read and decode JPEG-XR Exif-GPS IFD -@param dib Input FIBITMAP -@param profile Pointer to the Exif-GPS profile -@param length Exif-GPS profile length -@param file_offset Reference offset in the original file of each tag value whose length is > 4 -@return Returns TRUE if successful, FALSE otherwise -*/ -BOOL -jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset) { - // assume Little Endian order - BOOL bBigEndian = FALSE; - - // process Exif GPS IFD - return jpeg_read_exif_dir(dib, profile, 0, length, file_offset, bBigEndian, TagLib::EXIF_GPS); -} - -// ========================================================== -// Exif common helper routines -// ========================================================== - -/** -Rotate a dib according to Exif info -@param dib Input / Output dib to rotate -@see PluginJPEG.cpp -*/ -void -RotateExif(FIBITMAP **dib) { - // check for Exif rotation - if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, *dib)) { - FIBITMAP *rotated = NULL; - // process Exif rotation - FITAG *tag = NULL; - FreeImage_GetMetadata(FIMD_EXIF_MAIN, *dib, "Orientation", &tag); - if((tag != NULL) && (FreeImage_GetTagID(tag) == TAG_ORIENTATION)) { - const WORD orientation = *((WORD *)FreeImage_GetTagValue(tag)); - switch (orientation) { - case 1: // "top, left side" => 0° - break; - case 2: // "top, right side" => flip left-right - FreeImage_FlipHorizontal(*dib); - break; - case 3: // "bottom, right side" => -180° - rotated = FreeImage_Rotate(*dib, 180); - FreeImage_Unload(*dib); - *dib = rotated; - break; - case 4: // "bottom, left side" => flip up-down - FreeImage_FlipVertical(*dib); - break; - case 5: // "left side, top" => +90° + flip up-down - rotated = FreeImage_Rotate(*dib, 90); - FreeImage_Unload(*dib); - *dib = rotated; - FreeImage_FlipVertical(*dib); - break; - case 6: // "right side, top" => -90° - rotated = FreeImage_Rotate(*dib, -90); - FreeImage_Unload(*dib); - *dib = rotated; - break; - case 7: // "right side, bottom" => -90° + flip up-down - rotated = FreeImage_Rotate(*dib, -90); - FreeImage_Unload(*dib); - *dib = rotated; - FreeImage_FlipVertical(*dib); - break; - case 8: // "left side, bottom" => +90° - rotated = FreeImage_Rotate(*dib, 90); - FreeImage_Unload(*dib); - *dib = rotated; - break; - default: - break; - } - } - } -} - -// ========================================================== -// Exif TIFF JPEG-XR helper routines -// ========================================================== - -class PredicateTagIDCompare { -public: - bool operator()(FITAG *a, FITAG *b) { - WORD tag_id_a = FreeImage_GetTagID(a); - WORD tag_id_b = FreeImage_GetTagID(b); - return (tag_id_a < tag_id_b); - } -}; - -/** -Write a metadata model as a TIF IFD to a FIMEMORY handle. -The entries in the TIF IFD are sorted in ascending order by tag id. -The last entry is written as 0 (4 bytes) which means no more IFD to follow. -Supported metadata models are -
    -
  • FIMD_EXIF_MAIN -
  • FIMD_EXIF_EXIF -
  • FIMD_EXIF_GPS -
  • FIMD_EXIF_INTEROP -
-The end of the buffer is filled with 4 bytes equal to 0 (end of IFD offset) - -@param dib Input FIBITMAP -@param md_model Metadata model to write -@param hmem Memory handle -@return Returns TRUE if successful, FALSE otherwise -@see tiff_get_ifd_profile -*/ -static BOOL -tiff_write_ifd(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, FIMEMORY *hmem) { - FITAG *tag = NULL; - FIMETADATA *mdhandle = NULL; - std::vector vTagList; - TagLib::MDMODEL internal_md_model; - - DWORD ifd_offset = 0; // WORD-aligned IFD value offset - - const BYTE empty_byte = 0; - - // start of the file - const long start_of_file = FreeImage_TellMemory(hmem); - - // get the metadata count - unsigned metadata_count = FreeImage_GetMetadataCount(md_model, dib); - if(metadata_count == 0) { - return FALSE; - } - - TagLib& s = TagLib::instance(); - - // check for supported metadata models - switch(md_model) { - case FIMD_EXIF_MAIN: - internal_md_model = TagLib::EXIF_MAIN; - break; - case FIMD_EXIF_EXIF: - internal_md_model = TagLib::EXIF_EXIF; - break; - case FIMD_EXIF_GPS: - internal_md_model = TagLib::EXIF_GPS; - break; - case FIMD_EXIF_INTEROP: - internal_md_model = TagLib::EXIF_INTEROP; - break; - default: - return FALSE; - } - - try { - // 1) according to the TIFF specifications, - // the entries in a TIF IFD must be sorted in ascending order by tag id - - // store the tags into a vector - vTagList.reserve(metadata_count); - mdhandle = FreeImage_FindFirstMetadata(md_model, dib, &tag); - if(mdhandle) { - // parse the tags and store them inside vTagList - do { - // rewrite the tag id using FreeImage internal database - // (in case the tag id is wrong or missing) - const char *key = FreeImage_GetTagKey(tag); - int tag_id = s.getTagID(internal_md_model, key); - if(tag_id != -1) { - // this is a known tag, set the tag ID - FreeImage_SetTagID(tag, (WORD)tag_id); - // record the tag - vTagList.push_back(tag); - } - // else ignore this tag - } while(FreeImage_FindNextMetadata(mdhandle, &tag)); - - FreeImage_FindCloseMetadata(mdhandle); - - // sort the vector by tag id - std::sort(vTagList.begin(), vTagList.end(), PredicateTagIDCompare()); - - // update the metadata_count - metadata_count = (unsigned)vTagList.size(); - - } else { - throw(1); - } - - // 2) prepare the place for each IFD entries. - - /* - An Image File Directory (IFD) consists of a 2-byte count of the number of directory entries (i.e., the number of fields), - followed by a sequence of 12-byte field entries, - followed by a 4-byte offset of the next IFD (or 0 if none). Do not forget to write the 4 bytes of 0 after the last IFD. - */ - - { - // prepare place for 2 bytes for number of entries + 12 bytes for each entry - unsigned ifd_size = 2 + 12 * metadata_count; - FreeImage_WriteMemory(&empty_byte, 1, ifd_size, hmem); - // record the offset used to write values > 4-bytes - ifd_offset = FreeImage_TellMemory(hmem); - // rewind - FreeImage_SeekMemory(hmem, start_of_file, SEEK_SET); - } - - // 3) write each IFD entry in tag id ascending order - - // number of directory entries - WORD nde = (WORD)metadata_count; - FreeImage_WriteMemory(&nde, 1, 2, hmem); - - // for each entry ... - for(unsigned i = 0; i < metadata_count; i++) { - FITAG *tag = vTagList[i]; - // tag id - WORD tag_id = FreeImage_GetTagID(tag); - FreeImage_WriteMemory(&tag_id, 1, 2, hmem); - // tag type (compliant with TIFF specification) - WORD tag_type = (WORD)FreeImage_GetTagType(tag); - FreeImage_WriteMemory(&tag_type, 1, 2, hmem); - // tag count - DWORD tag_count = FreeImage_GetTagCount(tag); - FreeImage_WriteMemory(&tag_count, 1, 4, hmem); - // tag value or offset (results are in BYTE's units) - unsigned tag_length = FreeImage_GetTagLength(tag); - if(tag_length <= 4) { - // 4 bytes or less, write the value (left justified) - const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag); - FreeImage_WriteMemory(tag_value, 1, tag_length, hmem); - for(unsigned k = tag_length; k < 4; k++) { - FreeImage_WriteMemory(&empty_byte, 1, 1, hmem); - } - } else { - // write an offset - FreeImage_WriteMemory(&ifd_offset, 1, 4, hmem); - // write the value - long current_position = FreeImage_TellMemory(hmem); - FreeImage_SeekMemory(hmem, ifd_offset, SEEK_SET); - FreeImage_WriteMemory(FreeImage_GetTagValue(tag), 1, tag_length, hmem); - if(tag_length & 1) { - // align to the next WORD boundary - FreeImage_WriteMemory(&empty_byte, 1, 1, hmem); - } - // next offset to use - ifd_offset = FreeImage_TellMemory(hmem); - // rewind - FreeImage_SeekMemory(hmem, current_position, SEEK_SET); - } - } - - // end-of-IFD or next IFD (0 == none) - FreeImage_SeekMemory(hmem, ifd_offset, SEEK_SET); - FreeImage_WriteMemory(&empty_byte, 1, 4, hmem); - - return TRUE; - } - catch(int) { - return FALSE; - } -} - -/** -Write a metadata model as a TIF IFD, returns the IFD as a buffer. -The buffer is allocated by the function and must be freed by the caller, using 'free'. -@param dib Input FIBITMAP -@param md_model Metadata model to write -@param ppbProfile Returned buffer -@param uProfileLength Returned buffer size -@return Returns TRUE if successful, FALSE otherwise -@see tiff_write_ifd -*/ -BOOL -tiff_get_ifd_profile(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, BYTE **ppbProfile, unsigned *uProfileLength) { - FIMEMORY *hmem = NULL; - - try { - // open a memory stream - hmem = FreeImage_OpenMemory(NULL, 0); - if(!hmem) { - throw(1); - } - - // write the metadata model as a TIF IFD - BOOL bResult = tiff_write_ifd(dib, md_model, hmem); - - if(bResult) { - BYTE *data = NULL; - DWORD size_in_bytes = 0; - - // get a pointer to the stream buffer - FreeImage_AcquireMemory(hmem, &data, &size_in_bytes); - - // (re-)allocate output buffer - BYTE *pbProfile = *ppbProfile; - pbProfile = (BYTE*)realloc(pbProfile, size_in_bytes); - if(!pbProfile) { - throw(1); - } else { - // copy IFD - memcpy(pbProfile, data, size_in_bytes); - *ppbProfile = pbProfile; - *uProfileLength = size_in_bytes; - } - } - - // free the memory stream - FreeImage_CloseMemory(hmem); - - return bResult; - - } catch(int) { - FreeImage_CloseMemory(hmem); - return FALSE; - } -} diff --git a/plugins/AdvaImg/src/Metadata/FIRational.cpp b/plugins/AdvaImg/src/Metadata/FIRational.cpp deleted file mode 100644 index 4213840bb1..0000000000 --- a/plugins/AdvaImg/src/Metadata/FIRational.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// ========================================================== -// Helper class for rational numbers -// -// Design and implementation by -// - Hervé Drolon -// -// 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! -// ========================================================== - -#include "FreeImage.h" -#include "Utilities.h" -#include "FIRational.h" - -/// Initialize and normalize a rational number -void FIRational::initialize(LONG n, LONG d) { - if(d) { - _numerator = n; - _denominator = d; - // normalize rational - normalize(); - } else { - _numerator = 0; - _denominator = 0; - } -} - -/// Default constructor -FIRational::FIRational() { - _numerator = 0; - _denominator = 0; -} - -/// Constructor with longs -FIRational::FIRational(LONG n, LONG d) { - initialize(n, d); -} - -/// Constructor with FITAG -FIRational::FIRational(const FITAG *tag) { - switch(FreeImage_GetTagType((FITAG*)tag)) { - case FIDT_RATIONAL: // 64-bit unsigned fraction - { - DWORD *pvalue = (DWORD*)FreeImage_GetTagValue((FITAG*)tag); - initialize((LONG)pvalue[0], (LONG)pvalue[1]); - break; - } - - case FIDT_SRATIONAL: // 64-bit signed fraction - { - LONG *pvalue = (LONG*)FreeImage_GetTagValue((FITAG*)tag); - initialize((LONG)pvalue[0], (LONG)pvalue[1]); - break; - } - } -} - -FIRational::FIRational(float value) { - if (value == (float)((LONG)value)) { - _numerator = (LONG)value; - _denominator = 1L; - } else { - int k, count; - LONG n[4]; - - float x = fabs(value); - int sign = (value > 0) ? 1 : -1; - - // make a continued-fraction expansion of x - count = -1; - for(k = 0; k < 4; k++) { - n[k] = (LONG)floor(x); - count++; - x -= (float)n[k]; - if(x == 0) break; - x = 1 / x; - } - // compute the rational - _numerator = 1; - _denominator = n[count]; - - for(int i = count - 1; i >= 0; i--) { - if(n[i] == 0) break; - LONG _num = (n[i] * _numerator + _denominator); - LONG _den = _numerator; - _numerator = _num; - _denominator = _den; - } - _numerator *= sign; - } -} - -/// Copy constructor -FIRational::FIRational (const FIRational& r) { - initialize(r._numerator, r._denominator); -} - -/// Destructor -FIRational::~FIRational() { -} - -/// Assignement operator -FIRational& FIRational::operator=(FIRational& r) { - if(this != &r) { - initialize(r._numerator, r._denominator); - } - return *this; -} - -/// Get the numerator -LONG FIRational::getNumerator() { - return _numerator; -} - -/// Get the denominator -LONG FIRational::getDenominator() { - return _denominator; -} - -/// Calculate GCD -LONG FIRational::gcd(LONG a, LONG b) { - LONG temp; - while (b) { // While non-zero value - temp = b; // Save current value - b = a % b; // Assign remainder of division - a = temp; // Copy old value - } - return a; // Return GCD of numbers -} - -/// Normalize numerator / denominator -void FIRational::normalize() { - if (_numerator != 1 && _denominator != 1) { // Is there something to do? - // Calculate GCD - LONG common = gcd(_numerator, _denominator); - if (common != 1) { // If GCD is not one - _numerator /= common; // Calculate new numerator - _denominator /= common; // Calculate new denominator - } - } - if(_denominator < 0) { // If sign is in denominator - _numerator *= -1; // Multiply num and den by -1 - _denominator *= -1; // To keep sign in numerator - } -} - -/// Checks if this rational number is an Integer, either positive or negative -BOOL FIRational::isInteger() { - if(_denominator == 1 || (_denominator != 0 && (_numerator % _denominator == 0)) || (_denominator == 0 && _numerator == 0)) - return TRUE; - return FALSE; -} - -/// Convert as "numerator/denominator" -std::string FIRational::toString() { - std::ostringstream s; - if(isInteger()) { - s << intValue(); - } else { - s << _numerator << "/" << _denominator; - } - return s.str(); -} - - diff --git a/plugins/AdvaImg/src/Metadata/FIRational.h b/plugins/AdvaImg/src/Metadata/FIRational.h deleted file mode 100644 index 4fe2a6305a..0000000000 --- a/plugins/AdvaImg/src/Metadata/FIRational.h +++ /dev/null @@ -1,108 +0,0 @@ -// ========================================================== -// Helper class for rational numbers -// -// Design and implementation by -// - Hervé Drolon -// -// 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 FIRATIONAL_H -#define FIRATIONAL_H - -/** -Helper class to deal with rational numbers. -NB: LONG data type is assumed to be a signed 32-bit number. -*/ -class FIRational { -private: - /// numerator - LONG _numerator; - /// denominator - LONG _denominator; - -public: - /// Default constructor - FIRational(); - - /// Constructor with longs - FIRational(LONG n, LONG d = 1); - - /// Constructor with FITAG - FIRational(const FITAG *tag); - - /// Constructor with a float - FIRational(float value); - - /// Copy constructor - FIRational (const FIRational& r); - - /// Destructor - ~FIRational(); - - /// Assignement operator - FIRational& operator=(FIRational& r); - - /// Get the numerator - LONG getNumerator(); - - /// Get the denominator - LONG getDenominator(); - - /// Converts rational value by truncating towards zero - LONG truncate() { - // Return truncated rational - return _denominator ? (LONG) (_numerator / _denominator) : 0; - } - - /**@name Implicit conversions */ - //@{ - short shortValue() { - return (short)truncate(); - } - int intValue() { - return (int)truncate(); - } - LONG longValue() { - return (LONG)truncate(); - } - float floatValue() { - return _denominator ? ((float)_numerator)/((float)_denominator) : 0; - } - double doubleValue() { - return _denominator ? ((double)_numerator)/((double)_denominator) : 0; - } - //@} - - /// Checks if this rational number is an integer, either positive or negative - BOOL isInteger(); - - /// Convert as "numerator/denominator" - std::string toString(); - -private: - /// Initialize and normalize a rational number - void initialize(LONG n, LONG d); - - /// Calculate GCD - LONG gcd(LONG a, LONG b); - - /// Normalize numerator / denominator - void normalize(); - -}; - -#endif // FIRATIONAL_H - diff --git a/plugins/AdvaImg/src/Metadata/FreeImageTag.cpp b/plugins/AdvaImg/src/Metadata/FreeImageTag.cpp deleted file mode 100644 index 1eba0ca007..0000000000 --- a/plugins/AdvaImg/src/Metadata/FreeImageTag.cpp +++ /dev/null @@ -1,353 +0,0 @@ -// ========================================================== -// Tag manipulation functions -// -// Design and implementation by -// - Hervé Drolon -// -// 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! -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "FreeImage.h" -#include "Utilities.h" -#include "FreeImageTag.h" - -// -------------------------------------------------------------------------- -// FITAG header definition -// -------------------------------------------------------------------------- - -FI_STRUCT (FITAGHEADER) { - char *key; // tag field name - char *description; // tag description - WORD id; // tag ID - WORD type; // tag data type (see FREE_IMAGE_MDTYPE) - DWORD count; // number of components (in 'tag data types' units) - DWORD length; // value length in bytes - void *value; // tag value -}; - -// -------------------------------------------------------------------------- -// FITAG creation / destruction -// -------------------------------------------------------------------------- - -FITAG * DLL_CALLCONV -FreeImage_CreateTag() { - FITAG *tag = (FITAG *)malloc(sizeof(FITAG)); - - if (tag != NULL) { - unsigned tag_size = sizeof(FITAGHEADER); - tag->data = (BYTE *)malloc(tag_size * sizeof(BYTE)); - if (tag->data != NULL) { - memset(tag->data, 0, tag_size); - return tag; - } - free(tag); - } - - return NULL; -} - -void DLL_CALLCONV -FreeImage_DeleteTag(FITAG *tag) { - if (NULL != tag) { - if (NULL != tag->data) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - // delete tag members - free(tag_header->key); - free(tag_header->description); - free(tag_header->value); - // delete the tag - free(tag->data); - } - // and the wrapper - free(tag); - } -} - -FITAG * DLL_CALLCONV -FreeImage_CloneTag(FITAG *tag) { - if(!tag) return NULL; - - // allocate a new tag - FITAG *clone = FreeImage_CreateTag(); - if(!clone) return NULL; - - try { - // copy the tag - FITAGHEADER *src_tag = (FITAGHEADER *)tag->data; - FITAGHEADER *dst_tag = (FITAGHEADER *)clone->data; - - // tag ID - dst_tag->id = src_tag->id; - // tag key - if(src_tag->key) { - dst_tag->key = (char*)malloc((strlen(src_tag->key) + 1) * sizeof(char)); - if(!dst_tag->key) { - throw FI_MSG_ERROR_MEMORY; - } - strcpy(dst_tag->key, src_tag->key); - } - // tag description - if(src_tag->description) { - dst_tag->description = (char*)malloc((strlen(src_tag->description) + 1) * sizeof(char)); - if(!dst_tag->description) { - throw FI_MSG_ERROR_MEMORY; - } - strcpy(dst_tag->description, src_tag->description); - } - // tag data type - dst_tag->type = src_tag->type; - // tag count - dst_tag->count = src_tag->count; - // tag length - dst_tag->length = src_tag->length; - // tag value - switch(dst_tag->type) { - case FIDT_ASCII: - dst_tag->value = (BYTE*)malloc((src_tag->length + 1) * sizeof(BYTE)); - if(!dst_tag->value) { - throw FI_MSG_ERROR_MEMORY; - } - memcpy(dst_tag->value, src_tag->value, src_tag->length); - ((BYTE*)dst_tag->value)[src_tag->length] = 0; - break; - default: - dst_tag->value = (BYTE*)malloc(src_tag->length * sizeof(BYTE)); - if(!dst_tag->value) { - throw FI_MSG_ERROR_MEMORY; - } - memcpy(dst_tag->value, src_tag->value, src_tag->length); - break; - } - - return clone; - - } catch(const char *message) { - FreeImage_DeleteTag(clone); - FreeImage_OutputMessageProc(FIF_UNKNOWN, message); - return NULL; - } -} - -// -------------------------------------------------------------------------- -// FITAG getters / setters -// -------------------------------------------------------------------------- - -const char * DLL_CALLCONV -FreeImage_GetTagKey(FITAG *tag) { - return tag ? ((FITAGHEADER *)tag->data)->key : 0; -} - -const char * DLL_CALLCONV -FreeImage_GetTagDescription(FITAG *tag) { - return tag ? ((FITAGHEADER *)tag->data)->description : 0; -} - -WORD DLL_CALLCONV -FreeImage_GetTagID(FITAG *tag) { - return tag ? ((FITAGHEADER *)tag->data)->id : 0; -} - -FREE_IMAGE_MDTYPE DLL_CALLCONV -FreeImage_GetTagType(FITAG *tag) { - return tag ? (FREE_IMAGE_MDTYPE)(((FITAGHEADER *)tag->data)->type) : FIDT_NOTYPE; -} - -DWORD DLL_CALLCONV -FreeImage_GetTagCount(FITAG *tag) { - return tag ? ((FITAGHEADER *)tag->data)->count : 0; -} - -DWORD DLL_CALLCONV -FreeImage_GetTagLength(FITAG *tag) { - return tag ? ((FITAGHEADER *)tag->data)->length : 0; -} - -const void *DLL_CALLCONV -FreeImage_GetTagValue(FITAG *tag) { - return tag ? ((FITAGHEADER *)tag->data)->value : 0; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagKey(FITAG *tag, const char *key) { - if(tag && key) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - if(tag_header->key) free(tag_header->key); - tag_header->key = (char*)malloc(strlen(key) + 1); - strcpy(tag_header->key, key); - return TRUE; - } - return FALSE; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagDescription(FITAG *tag, const char *description) { - if(tag && description) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - if(tag_header->description) free(tag_header->description); - tag_header->description = (char*)malloc(strlen(description) + 1); - strcpy(tag_header->description, description); - return TRUE; - } - return FALSE; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagID(FITAG *tag, WORD id) { - if(tag) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - tag_header->id = id; - return TRUE; - } - return FALSE; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type) { - if(tag) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - tag_header->type = (WORD)type; - return TRUE; - } - return FALSE; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagCount(FITAG *tag, DWORD count) { - if(tag) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - tag_header->count = count; - return TRUE; - } - return FALSE; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagLength(FITAG *tag, DWORD length) { - if(tag) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - tag_header->length = length; - return TRUE; - } - return FALSE; -} - -BOOL DLL_CALLCONV -FreeImage_SetTagValue(FITAG *tag, const void *value) { - if(tag && value) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - // first, check the tag - if(tag_header->count * FreeImage_TagDataWidth((FREE_IMAGE_MDTYPE)tag_header->type) != tag_header->length) { - // invalid data count ? - return FALSE; - } - - if(tag_header->value) { - free(tag_header->value); - } - - switch(tag_header->type) { - case FIDT_ASCII: - { - tag_header->value = (char*)malloc((tag_header->length + 1) * sizeof(char)); - if(!tag_header->value) { - return FALSE; - } - char *src_data = (char*)value; - char *dst_data = (char*)tag_header->value; - for(DWORD i = 0; i < tag_header->length; i++) { - dst_data[i] = src_data[i]; - } - dst_data[tag_header->length] = '\0'; - } - break; - - default: - tag_header->value = malloc(tag_header->length * sizeof(BYTE)); - if(!tag_header->value) { - return FALSE; - } - memcpy(tag_header->value, value, tag_header->length); - break; - } - return TRUE; - } - return FALSE; -} - - -// -------------------------------------------------------------------------- -// FITAG internal helper functions -// -------------------------------------------------------------------------- - -unsigned -FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type) { - static const unsigned format_bytes[] = { - 0, // FIDT_NOTYPE = 0, // placeholder - 1, // FIDT_BYTE = 1, // 8-bit unsigned integer - 1, // FIDT_ASCII = 2, // 8-bit bytes w/ last byte null - 2, // FIDT_SHORT = 3, // 16-bit unsigned integer - 4, // FIDT_LONG = 4, // 32-bit unsigned integer - 8, // FIDT_RATIONAL = 5, // 64-bit unsigned fraction - 1, // FIDT_SBYTE = 6, // 8-bit signed integer - 1, // FIDT_UNDEFINED= 7, // 8-bit untyped data - 2, // FIDT_SSHORT = 8, // 16-bit signed integer - 4, // FIDT_SLONG = 9, // 32-bit signed integer - 8, // FIDT_SRATIONAL= 10, // 64-bit signed fraction - 4, // FIDT_FLOAT = 11, // 32-bit IEEE floating point - 8, // FIDT_DOUBLE = 12, // 64-bit IEEE floating point - 4, // FIDT_IFD = 13, // 32-bit unsigned integer (offset) - 4, // FIDT_PALETTE = 14 // 32-bit RGBQUAD - 0, // placeholder (15) - 8, // FIDT_LONG8 = 16, // 64-bit unsigned integer - 8, // FIDT_SLONG8 = 17, // 64-bit signed integer - 8 // FIDT_IFD8 = 18 // 64-bit unsigned integer (offset) - }; - - return (type < (sizeof(format_bytes)/sizeof(format_bytes[0]))) ? - format_bytes[type] : 0; -} - -size_t -FreeImage_GetTagMemorySize(FITAG *tag) { - size_t size = 0; - if (tag) { - FITAGHEADER *tag_header = (FITAGHEADER *)tag->data; - size += sizeof(FITAG); - size += sizeof(FITAGHEADER); - if (tag_header->key) { - size += strlen(tag_header->key) + 1; - } - if (tag_header->description) { - size += strlen(tag_header->description) + 1; - } - if (tag_header->value) { - switch (tag_header->type) { - case FIDT_ASCII: - // for ASCII strings, the value of the count part of an ASCII tag entry includes the NULL. - // however, FreeImage adds another '\0' to be sure that this last character is present. - size += tag_header->length + 1; - break; - default: - size += tag_header->length; - break; - } - } - } - return size; -} diff --git a/plugins/AdvaImg/src/Metadata/FreeImageTag.h b/plugins/AdvaImg/src/Metadata/FreeImageTag.h deleted file mode 100644 index 5a6e4f99f6..0000000000 --- a/plugins/AdvaImg/src/Metadata/FreeImageTag.h +++ /dev/null @@ -1,499 +0,0 @@ -// ========================================================== -// Tag manipulation functions -// -// Design and implementation by -// - Hervé Drolon -// -// 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 */ -#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).
- -Sample usage :
- -TagLib& s = TagLib::instance(); -TagInfo *tag_info = s.getTagInfo(EXIF_MAIN, 0x0100); - - -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 TAGINFO; - typedef std::map TABLEMAP; - - /// store hash tables for all known tag info tables - TABLEMAP _table_map; - -private: - /// 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: - /** - Constructor (private)
- This is where the tag info tables are initialized. - @see addMetadataModel - */ - TagLib(); - /// 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 - - diff --git a/plugins/AdvaImg/src/Metadata/IPTC.cpp b/plugins/AdvaImg/src/Metadata/IPTC.cpp deleted file mode 100644 index 659d0b8bec..0000000000 --- a/plugins/AdvaImg/src/Metadata/IPTC.cpp +++ /dev/null @@ -1,342 +0,0 @@ -// ========================================================== -// Metadata functions implementation -// -// 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! -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "FreeImage.h" -#include "Utilities.h" -#include "FreeImageTag.h" - -// ---------------------------------------------------------- -// IPTC JPEG / TIFF markers routines -// ---------------------------------------------------------- - -static const char* IPTC_DELIMITER = ";"; // keywords/supplemental category delimiter -/** - Read and decode IPTC binary data -*/ -BOOL -read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) { - char defaultKey[16]; - size_t length = datalen; - BYTE *profile = (BYTE*)dataptr; - - const char *JPEG_AdobeCM_Tag = "Adobe_CM"; - - std::string Keywords; - std::string SupplementalCategory; - - WORD tag_id; - - if(!dataptr || (datalen == 0)) { - return FALSE; - } - - if(datalen > 8) { - if(memcmp(JPEG_AdobeCM_Tag, dataptr, 8) == 0) { - // the "Adobe_CM" APP13 segment presumably contains color management information, - // but the meaning of the data is currently unknown. - // If anyone has an idea about what this means, please let me know. - return FALSE; - } - } - - - // create a tag - - FITAG *tag = FreeImage_CreateTag(); - - TagLib& tag_lib = TagLib::instance(); - - // find start of the BIM portion of the binary data - size_t offset = 0; - while(offset < length - 1) { - if((profile[offset] == 0x1C) && (profile[offset+1] == 0x02)) - break; - offset++; - } - - // for each tag - while (offset < length) { - - // identifies start of a tag - if (profile[offset] != 0x1c) { - break; - } - // we need at least five bytes left to read a tag - if ((offset + 5) >= length) { - break; - } - - offset++; - - int directoryType = profile[offset++]; - int tagType = profile[offset++];; - int tagByteCount = ((profile[offset] & 0xFF) << 8) | (profile[offset + 1] & 0xFF); - offset += 2; - - if ((offset + tagByteCount) > length) { - // data for tag extends beyond end of iptc segment - break; - } - - if(tagByteCount == 0) { - // go to next tag - continue; - } - - // process the tag - - tag_id = (WORD)(tagType | (directoryType << 8)); - - FreeImage_SetTagID(tag, tag_id); - FreeImage_SetTagLength(tag, tagByteCount); - - // allocate a buffer to store the tag value - BYTE *iptc_value = (BYTE*)malloc((tagByteCount + 1) * sizeof(BYTE)); - memset(iptc_value, 0, (tagByteCount + 1) * sizeof(BYTE)); - - // get the tag value - - switch (tag_id) { - case TAG_RECORD_VERSION: - { - // short - FreeImage_SetTagType(tag, FIDT_SSHORT); - FreeImage_SetTagCount(tag, 1); - short *pvalue = (short*)&iptc_value[0]; - *pvalue = (short)((profile[offset] << 8) | profile[offset + 1]); - FreeImage_SetTagValue(tag, pvalue); - break; - } - - case TAG_RELEASE_DATE: - case TAG_DATE_CREATED: - // Date object - case TAG_RELEASE_TIME: - case TAG_TIME_CREATED: - // time - default: - { - // string - FreeImage_SetTagType(tag, FIDT_ASCII); - FreeImage_SetTagCount(tag, tagByteCount); - for(int i = 0; i < tagByteCount; i++) { - iptc_value[i] = profile[offset + i]; - } - iptc_value[tagByteCount] = '\0'; - FreeImage_SetTagValue(tag, (char*)&iptc_value[0]); - break; - } - } - - if(tag_id == TAG_SUPPLEMENTAL_CATEGORIES) { - // concatenate the categories - if(SupplementalCategory.length() == 0) { - SupplementalCategory.append((char*)iptc_value); - } else { - SupplementalCategory.append(IPTC_DELIMITER); - SupplementalCategory.append((char*)iptc_value); - } - } - else if(tag_id == TAG_KEYWORDS) { - // concatenate the keywords - if(Keywords.length() == 0) { - Keywords.append((char*)iptc_value); - } else { - Keywords.append(IPTC_DELIMITER); - Keywords.append((char*)iptc_value); - } - } - else { - // get the tag key and description - const char *key = tag_lib.getTagFieldName(TagLib::IPTC, tag_id, defaultKey); - FreeImage_SetTagKey(tag, key); - const char *description = tag_lib.getTagDescription(TagLib::IPTC, tag_id); - FreeImage_SetTagDescription(tag, description); - - // store the tag - if(key) { - FreeImage_SetMetadata(FIMD_IPTC, dib, key, tag); - } - } - - free(iptc_value); - - // next tag - offset += tagByteCount; - - } - - // store the 'keywords' tag - if(Keywords.length()) { - FreeImage_SetTagType(tag, FIDT_ASCII); - FreeImage_SetTagID(tag, TAG_KEYWORDS); - FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::IPTC, TAG_KEYWORDS, defaultKey)); - FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::IPTC, TAG_KEYWORDS)); - FreeImage_SetTagLength(tag, (DWORD)Keywords.length()); - FreeImage_SetTagCount(tag, (DWORD)Keywords.length()); - FreeImage_SetTagValue(tag, (char*)Keywords.c_str()); - FreeImage_SetMetadata(FIMD_IPTC, dib, FreeImage_GetTagKey(tag), tag); - } - - // store the 'supplemental category' tag - if(SupplementalCategory.length()) { - FreeImage_SetTagType(tag, FIDT_ASCII); - FreeImage_SetTagID(tag, TAG_SUPPLEMENTAL_CATEGORIES); - FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::IPTC, TAG_SUPPLEMENTAL_CATEGORIES, defaultKey)); - FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::IPTC, TAG_SUPPLEMENTAL_CATEGORIES)); - FreeImage_SetTagLength(tag, (DWORD)SupplementalCategory.length()); - FreeImage_SetTagCount(tag, (DWORD)SupplementalCategory.length()); - FreeImage_SetTagValue(tag, (char*)SupplementalCategory.c_str()); - FreeImage_SetMetadata(FIMD_IPTC, dib, FreeImage_GetTagKey(tag), tag); - } - - // delete the tag - - FreeImage_DeleteTag(tag); - - return TRUE; -} - -// -------------------------------------------------------------------------- - -static BYTE* -append_iptc_tag(BYTE *profile, unsigned *profile_size, WORD id, DWORD length, const void *value) { - BYTE *buffer = NULL; - - // calculate the new buffer size - size_t buffer_size = (5 + *profile_size + length) * sizeof(BYTE); - buffer = (BYTE*)malloc(buffer_size); - if(!buffer) - return NULL; - - // add the header - buffer[0] = 0x1C; - buffer[1] = 0x02; - // add the tag type - buffer[2] = (BYTE)(id & 0x00FF); - // add the tag length - buffer[3] = (BYTE)(length >> 8); - buffer[4] = (BYTE)(length & 0xFF); - // add the tag value - memcpy(buffer + 5, (BYTE*)value, length); - // append the previous profile - if(NULL == profile) { - *profile_size = (5 + length); - } - else { - memcpy(buffer + 5 + length, profile, *profile_size); - *profile_size += (5 + length); - free(profile); - } - - return buffer; -} - -/** -Encode IPTC metadata into a binary buffer. -The buffer is allocated by the function and must be freed by the caller. -*/ -BOOL -write_iptc_profile(FIBITMAP *dib, BYTE **profile, unsigned *profile_size) { - FITAG *tag = NULL; - FIMETADATA *mdhandle = NULL; - - BYTE *buffer = NULL; - unsigned buffer_size = 0; - - // parse all IPTC tags and rebuild a IPTC profile - mdhandle = FreeImage_FindFirstMetadata(FIMD_IPTC, dib, &tag); - - if(mdhandle) { - do { - WORD tag_id = FreeImage_GetTagID(tag); - - // append the tag to the profile - - switch(tag_id) { - case TAG_RECORD_VERSION: - // ignore (already handled) - break; - - case TAG_SUPPLEMENTAL_CATEGORIES: - case TAG_KEYWORDS: - if(FreeImage_GetTagType(tag) == FIDT_ASCII) { - std::string value = (const char*)FreeImage_GetTagValue(tag); - - // split the tag value - std::vector output; - std::string delimiter = IPTC_DELIMITER; - - size_t offset = 0; - size_t delimiterIndex = 0; - - delimiterIndex = value.find(delimiter, offset); - while (delimiterIndex != std::string::npos) { - output.push_back(value.substr(offset, delimiterIndex - offset)); - offset += delimiterIndex - offset + delimiter.length(); - delimiterIndex = value.find(delimiter, offset); - } - output.push_back(value.substr(offset)); - - // add as many tags as there are comma separated strings - for(int i = 0; i < (int)output.size(); i++) { - std::string& tag_value = output[i]; - buffer = append_iptc_tag(buffer, &buffer_size, tag_id, (DWORD)tag_value.length(), tag_value.c_str()); - } - - } - break; - - case TAG_URGENCY: - if(FreeImage_GetTagType(tag) == FIDT_ASCII) { - DWORD length = 1; // keep the first octet only - buffer = append_iptc_tag(buffer, &buffer_size, tag_id, length, FreeImage_GetTagValue(tag)); - } - break; - - default: - if(FreeImage_GetTagType(tag) == FIDT_ASCII) { - DWORD length = FreeImage_GetTagLength(tag); - buffer = append_iptc_tag(buffer, &buffer_size, tag_id, length, FreeImage_GetTagValue(tag)); - } - break; - } - - } while(FreeImage_FindNextMetadata(mdhandle, &tag)); - - FreeImage_FindCloseMetadata(mdhandle); - - // add the DirectoryVersion tag - const short version = 0x0200; - buffer = append_iptc_tag(buffer, &buffer_size, TAG_RECORD_VERSION, sizeof(version), &version); - - *profile = buffer; - *profile_size = buffer_size; - - return TRUE; - } - - return FALSE; -} diff --git a/plugins/AdvaImg/src/Metadata/TagConversion.cpp b/plugins/AdvaImg/src/Metadata/TagConversion.cpp deleted file mode 100644 index 1fb2b55f00..0000000000 --- a/plugins/AdvaImg/src/Metadata/TagConversion.cpp +++ /dev/null @@ -1,1094 +0,0 @@ -// ========================================================== -// Tag to string conversion functions -// -// Design and implementation by -// - Hervé Drolon -// -// 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! -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "FreeImage.h" -#include "Utilities.h" -#include "FreeImageTag.h" -#include "FIRational.h" - -#define MAX_TEXT_EXTENT 512 - -/** -Convert a tag to a C string -*/ -static const char* -ConvertAnyTag(FITAG *tag) { - char format[MAX_TEXT_EXTENT]; - static std::string buffer; - DWORD i; - - if(!tag) - return NULL; - - buffer.erase(); - - // convert the tag value to a string buffer - - FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag); - DWORD tag_count = FreeImage_GetTagCount(tag); - - switch(tag_type) { - case FIDT_BYTE: // N x 8-bit unsigned integer - { - BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag); - - sprintf(format, "%ld", (LONG) pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %ld", (LONG) pvalue[i]); - buffer += format; - } - break; - } - case FIDT_SHORT: // N x 16-bit unsigned integer - { - unsigned short *pvalue = (unsigned short *)FreeImage_GetTagValue(tag); - - sprintf(format, "%hu", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %hu", pvalue[i]); - buffer += format; - } - break; - } - case FIDT_LONG: // N x 32-bit unsigned integer - { - DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag); - - sprintf(format, "%lu", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %lu", pvalue[i]); - buffer += format; - } - break; - } - case FIDT_RATIONAL: // N x 64-bit unsigned fraction - { - DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag); - - sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]); - buffer += format; - } - break; - } - case FIDT_SBYTE: // N x 8-bit signed integer - { - char *pvalue = (char*)FreeImage_GetTagValue(tag); - - sprintf(format, "%ld", (LONG) pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %ld", (LONG) pvalue[i]); - buffer += format; - } - break; - } - case FIDT_SSHORT: // N x 16-bit signed integer - { - short *pvalue = (short *)FreeImage_GetTagValue(tag); - - sprintf(format, "%hd", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %hd", pvalue[i]); - buffer += format; - } - break; - } - case FIDT_SLONG: // N x 32-bit signed integer - { - LONG *pvalue = (LONG *)FreeImage_GetTagValue(tag); - - sprintf(format, "%ld", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %ld", pvalue[i]); - buffer += format; - } - break; - } - case FIDT_SRATIONAL:// N x 64-bit signed fraction - { - LONG *pvalue = (LONG*)FreeImage_GetTagValue(tag); - - sprintf(format, "%ld/%ld", pvalue[0], pvalue[1]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %ld/%ld", pvalue[2*i], pvalue[2*i+1]); - buffer += format; - } - break; - } - case FIDT_FLOAT: // N x 32-bit IEEE floating point - { - float *pvalue = (float *)FreeImage_GetTagValue(tag); - - sprintf(format, "%f", (double) pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, "%f", (double) pvalue[i]); - buffer += format; - } - break; - } - case FIDT_DOUBLE: // N x 64-bit IEEE floating point - { - double *pvalue = (double *)FreeImage_GetTagValue(tag); - - sprintf(format, "%f", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, "%f", pvalue[i]); - buffer += format; - } - break; - } - case FIDT_IFD: // N x 32-bit unsigned integer (offset) - { - DWORD *pvalue = (DWORD *)FreeImage_GetTagValue(tag); - - sprintf(format, "%X", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " %X", pvalue[i]); - buffer += format; - } - break; - } - case FIDT_PALETTE: // N x 32-bit RGBQUAD - { - RGBQUAD *pvalue = (RGBQUAD *)FreeImage_GetTagValue(tag); - - sprintf(format, "(%d,%d,%d,%d)", pvalue[0].rgbRed, pvalue[0].rgbGreen, pvalue[0].rgbBlue, pvalue[0].rgbReserved); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, " (%d,%d,%d,%d)", pvalue[i].rgbRed, pvalue[i].rgbGreen, pvalue[i].rgbBlue, pvalue[i].rgbReserved); - buffer += format; - } - break; - } - - case FIDT_LONG8: // N x 64-bit unsigned integer - { - UINT64 *pvalue = (UINT64 *)FreeImage_GetTagValue(tag); - - sprintf(format, "%lld", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, "%lld", pvalue[i]); - buffer += format; - } - break; - } - - case FIDT_IFD8: // N x 64-bit unsigned integer (offset) - { - UINT64 *pvalue = (UINT64 *)FreeImage_GetTagValue(tag); - - sprintf(format, "%llX", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, "%llX", pvalue[i]); - buffer += format; - } - break; - } - - case FIDT_SLONG8: // N x 64-bit signed integer - { - INT64 *pvalue = (INT64 *)FreeImage_GetTagValue(tag); - - sprintf(format, "%lld", pvalue[0]); - buffer += format; - for(i = 1; i < tag_count; i++) { - sprintf(format, "%lld", pvalue[i]); - buffer += format; - } - break; - } - - case FIDT_ASCII: // 8-bit bytes w/ last byte null - case FIDT_UNDEFINED:// 8-bit untyped data - default: - { - int max_size = MIN((int)FreeImage_GetTagLength(tag), (int)MAX_TEXT_EXTENT); - if(max_size == MAX_TEXT_EXTENT) - max_size--; - memcpy(format, (char*)FreeImage_GetTagValue(tag), max_size); - format[max_size] = '\0'; - buffer += format; - break; - } - } - - return buffer.c_str(); -} - -/** -Convert a Exif tag to a C string -*/ -static const char* -ConvertExifTag(FITAG *tag) { - char format[MAX_TEXT_EXTENT]; - static std::string buffer; - - if(!tag) - return NULL; - - buffer.erase(); - - // convert the tag value to a string buffer - - switch(FreeImage_GetTagID(tag)) { - case TAG_ORIENTATION: - { - unsigned short orientation = *((unsigned short *)FreeImage_GetTagValue(tag)); - switch (orientation) { - case 1: - return "top, left side"; - case 2: - return "top, right side"; - case 3: - return "bottom, right side"; - case 4: - return "bottom, left side"; - case 5: - return "left side, top"; - case 6: - return "right side, top"; - case 7: - return "right side, bottom"; - case 8: - return "left side, bottom"; - default: - break; - } - } - break; - - case TAG_REFERENCE_BLACK_WHITE: - { - DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag); - if(FreeImage_GetTagLength(tag) == 48) { - // reference black point value and reference white point value (ReferenceBlackWhite) - int blackR = 0, whiteR = 0, blackG = 0, whiteG = 0, blackB = 0, whiteB = 0; - if(pvalue[1]) - blackR = (int)(pvalue[0] / pvalue[1]); - if(pvalue[3]) - whiteR = (int)(pvalue[2] / pvalue[3]); - if(pvalue[5]) - blackG = (int)(pvalue[4] / pvalue[5]); - if(pvalue[7]) - whiteG = (int)(pvalue[6] / pvalue[7]); - if(pvalue[9]) - blackB = (int)(pvalue[8] / pvalue[9]); - if(pvalue[11]) - whiteB = (int)(pvalue[10] / pvalue[11]); - - sprintf(format, "[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB); - buffer += format; - return buffer.c_str(); - } - - } - break; - - case TAG_COLOR_SPACE: - { - unsigned short colorSpace = *((unsigned short *)FreeImage_GetTagValue(tag)); - if (colorSpace == 1) { - return "sRGB"; - } else if (colorSpace == 65535) { - return "Undefined"; - } else { - return "Unknown"; - } - } - break; - - case TAG_COMPONENTS_CONFIGURATION: - { - const char *componentStrings[7] = {"", "Y", "Cb", "Cr", "R", "G", "B"}; - BYTE *pvalue = (BYTE*)FreeImage_GetTagValue(tag); - for(DWORD i = 0; i < MIN((DWORD)4, FreeImage_GetTagCount(tag)); i++) { - int j = pvalue[i]; - if(j > 0 && j < 7) - buffer += componentStrings[j]; - } - return buffer.c_str(); - } - break; - - case TAG_COMPRESSED_BITS_PER_PIXEL: - { - FIRational r(tag); - buffer = r.toString(); - if(buffer == "1") - buffer += " bit/pixel"; - else - buffer += " bits/pixel"; - return buffer.c_str(); - } - break; - - case TAG_X_RESOLUTION: - case TAG_Y_RESOLUTION: - case TAG_FOCAL_PLANE_X_RES: - case TAG_FOCAL_PLANE_Y_RES: - case TAG_BRIGHTNESS_VALUE: - case TAG_EXPOSURE_BIAS_VALUE: - { - FIRational r(tag); - buffer = r.toString(); - return buffer.c_str(); - } - break; - - case TAG_RESOLUTION_UNIT: - case TAG_FOCAL_PLANE_UNIT: - { - unsigned short resolutionUnit = *((unsigned short *)FreeImage_GetTagValue(tag)); - switch (resolutionUnit) { - case 1: - return "(No unit)"; - case 2: - return "inches"; - case 3: - return "cm"; - default: - break; - } - } - break; - - case TAG_YCBCR_POSITIONING: - { - unsigned short yCbCrPosition = *((unsigned short *)FreeImage_GetTagValue(tag)); - switch (yCbCrPosition) { - case 1: - return "Center of pixel array"; - case 2: - return "Datum point"; - default: - break; - } - } - break; - - case TAG_EXPOSURE_TIME: - { - FIRational r(tag); - buffer = r.toString(); - buffer += " sec"; - return buffer.c_str(); - } - break; - - case TAG_SHUTTER_SPEED_VALUE: - { - FIRational r(tag); - LONG apexValue = r.longValue(); - LONG apexPower = 1 << apexValue; - sprintf(format, "1/%d sec", (int)apexPower); - buffer += format; - return buffer.c_str(); - } - break; - - case TAG_APERTURE_VALUE: - case TAG_MAX_APERTURE_VALUE: - { - FIRational r(tag); - double apertureApex = r.doubleValue(); - double rootTwo = sqrt((double)2); - double fStop = pow(rootTwo, apertureApex); - sprintf(format, "F%.1f", fStop); - buffer += format; - return buffer.c_str(); - } - break; - - case TAG_FNUMBER: - { - FIRational r(tag); - double fnumber = r.doubleValue(); - sprintf(format, "F%.1f", fnumber); - buffer += format; - return buffer.c_str(); - } - break; - - case TAG_FOCAL_LENGTH: - { - FIRational r(tag); - double focalLength = r.doubleValue(); - sprintf(format, "%.1f mm", focalLength); - buffer += format; - return buffer.c_str(); - } - break; - - case TAG_FOCAL_LENGTH_IN_35MM_FILM: - { - unsigned short focalLength = *((unsigned short *)FreeImage_GetTagValue(tag)); - sprintf(format, "%hu mm", focalLength); - buffer += format; - return buffer.c_str(); - } - break; - - case TAG_FLASH: - { - unsigned short flash = *((unsigned short *)FreeImage_GetTagValue(tag)); - switch(flash) { - case 0x0000: - return "Flash did not fire"; - case 0x0001: - return "Flash fired"; - case 0x0005: - return "Strobe return light not detected"; - case 0x0007: - return "Strobe return light detected"; - case 0x0009: - return "Flash fired, compulsory flash mode"; - case 0x000D: - return "Flash fired, compulsory flash mode, return light not detected"; - case 0x000F: - return "Flash fired, compulsory flash mode, return light detected"; - case 0x0010: - return "Flash did not fire, compulsory flash mode"; - case 0x0018: - return "Flash did not fire, auto mode"; - case 0x0019: - return "Flash fired, auto mode"; - case 0x001D: - return "Flash fired, auto mode, return light not detected"; - case 0x001F: - return "Flash fired, auto mode, return light detected"; - case 0x0020: - return "No flash function"; - case 0x0041: - return "Flash fired, red-eye reduction mode"; - case 0x0045: - return "Flash fired, red-eye reduction mode, return light not detected"; - case 0x0047: - return "Flash fired, red-eye reduction mode, return light detected"; - case 0x0049: - return "Flash fired, compulsory flash mode, red-eye reduction mode"; - case 0x004D: - return "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected"; - case 0x004F: - return "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected"; - case 0x0059: - return "Flash fired, auto mode, red-eye reduction mode"; - case 0x005D: - return "Flash fired, auto mode, return light not detected, red-eye reduction mode"; - case 0x005F: - return "Flash fired, auto mode, return light detected, red-eye reduction mode"; - default: - sprintf(format, "Unknown (%d)", flash); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_SCENE_TYPE: - { - BYTE sceneType = *((BYTE*)FreeImage_GetTagValue(tag)); - if (sceneType == 1) { - return "Directly photographed image"; - } else { - sprintf(format, "Unknown (%d)", sceneType); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_SUBJECT_DISTANCE: - { - FIRational r(tag); - if(r.getNumerator() == 0xFFFFFFFF) { - return "Infinity"; - } else if(r.getNumerator() == 0) { - return "Distance unknown"; - } else { - double distance = r.doubleValue(); - sprintf(format, "%.3f meters", distance); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_METERING_MODE: - { - unsigned short meteringMode = *((unsigned short *)FreeImage_GetTagValue(tag)); - switch (meteringMode) { - case 0: - return "Unknown"; - case 1: - return "Average"; - case 2: - return "Center weighted average"; - case 3: - return "Spot"; - case 4: - return "Multi-spot"; - case 5: - return "Multi-segment"; - case 6: - return "Partial"; - case 255: - return "(Other)"; - default: - return ""; - } - } - break; - - case TAG_LIGHT_SOURCE: - { - unsigned short lightSource = *((unsigned short *)FreeImage_GetTagValue(tag)); - switch (lightSource) { - case 0: - return "Unknown"; - case 1: - return "Daylight"; - case 2: - return "Fluorescent"; - case 3: - return "Tungsten (incandescent light)"; - case 4: - return "Flash"; - case 9: - return "Fine weather"; - case 10: - return "Cloudy weather"; - case 11: - return "Shade"; - case 12: - return "Daylight fluorescent (D 5700 - 7100K)"; - case 13: - return "Day white fluorescent (N 4600 - 5400K)"; - case 14: - return "Cool white fluorescent (W 3900 - 4500K)"; - case 15: - return "White fluorescent (WW 3200 - 3700K)"; - case 17: - return "Standard light A"; - case 18: - return "Standard light B"; - case 19: - return "Standard light C"; - case 20: - return "D55"; - case 21: - return "D65"; - case 22: - return "D75"; - case 23: - return "D50"; - case 24: - return "ISO studio tungsten"; - case 255: - return "(Other)"; - default: - return ""; - } - } - break; - - case TAG_SENSING_METHOD: - { - unsigned short sensingMethod = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (sensingMethod) { - case 1: - return "(Not defined)"; - case 2: - return "One-chip color area sensor"; - case 3: - return "Two-chip color area sensor"; - case 4: - return "Three-chip color area sensor"; - case 5: - return "Color sequential area sensor"; - case 7: - return "Trilinear sensor"; - case 8: - return "Color sequential linear sensor"; - default: - return ""; - } - } - break; - - case TAG_FILE_SOURCE: - { - BYTE fileSource = *((BYTE*)FreeImage_GetTagValue(tag)); - if (fileSource == 3) { - return "Digital Still Camera (DSC)"; - } else { - sprintf(format, "Unknown (%d)", fileSource); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_EXPOSURE_PROGRAM: - { - unsigned short exposureProgram = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (exposureProgram) { - case 1: - return "Manual control"; - case 2: - return "Program normal"; - case 3: - return "Aperture priority"; - case 4: - return "Shutter priority"; - case 5: - return "Program creative (slow program)"; - case 6: - return "Program action (high-speed program)"; - case 7: - return "Portrait mode"; - case 8: - return "Landscape mode"; - default: - sprintf(format, "Unknown program (%d)", exposureProgram); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_CUSTOM_RENDERED: - { - unsigned short customRendered = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (customRendered) { - case 0: - return "Normal process"; - case 1: - return "Custom process"; - default: - sprintf(format, "Unknown rendering (%d)", customRendered); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_EXPOSURE_MODE: - { - unsigned short exposureMode = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (exposureMode) { - case 0: - return "Auto exposure"; - case 1: - return "Manual exposure"; - case 2: - return "Auto bracket"; - default: - sprintf(format, "Unknown mode (%d)", exposureMode); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_WHITE_BALANCE: - { - unsigned short whiteBalance = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (whiteBalance) { - case 0: - return "Auto white balance"; - case 1: - return "Manual white balance"; - default: - sprintf(format, "Unknown (%d)", whiteBalance); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_SCENE_CAPTURE_TYPE: - { - unsigned short sceneType = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (sceneType) { - case 0: - return "Standard"; - case 1: - return "Landscape"; - case 2: - return "Portrait"; - case 3: - return "Night scene"; - default: - sprintf(format, "Unknown (%d)", sceneType); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_GAIN_CONTROL: - { - unsigned short gainControl = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (gainControl) { - case 0: - return "None"; - case 1: - return "Low gain up"; - case 2: - return "High gain up"; - case 3: - return "Low gain down"; - case 4: - return "High gain down"; - default: - sprintf(format, "Unknown (%d)", gainControl); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_CONTRAST: - { - unsigned short contrast = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (contrast) { - case 0: - return "Normal"; - case 1: - return "Soft"; - case 2: - return "Hard"; - default: - sprintf(format, "Unknown (%d)", contrast); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_SATURATION: - { - unsigned short saturation = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (saturation) { - case 0: - return "Normal"; - case 1: - return "Low saturation"; - case 2: - return "High saturation"; - default: - sprintf(format, "Unknown (%d)", saturation); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_SHARPNESS: - { - unsigned short sharpness = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (sharpness) { - case 0: - return "Normal"; - case 1: - return "Soft"; - case 2: - return "Hard"; - default: - sprintf(format, "Unknown (%d)", sharpness); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_SUBJECT_DISTANCE_RANGE: - { - unsigned short distanceRange = *((unsigned short *)FreeImage_GetTagValue(tag)); - - switch (distanceRange) { - case 0: - return "unknown"; - case 1: - return "Macro"; - case 2: - return "Close view"; - case 3: - return "Distant view"; - default: - sprintf(format, "Unknown (%d)", distanceRange); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_ISO_SPEED_RATINGS: - { - unsigned short isoEquiv = *((unsigned short *)FreeImage_GetTagValue(tag)); - if (isoEquiv < 50) { - isoEquiv *= 200; - } - sprintf(format, "%d", isoEquiv); - buffer += format; - return buffer.c_str(); - } - break; - - case TAG_USER_COMMENT: - { - // first 8 bytes are used to define an ID code - // we assume this is an ASCII string - const BYTE *userComment = (BYTE*)FreeImage_GetTagValue(tag); - for(DWORD i = 8; i < FreeImage_GetTagLength(tag); i++) { - buffer += userComment[i]; - } - buffer += '\0'; - return buffer.c_str(); - } - break; - - case TAG_COMPRESSION: - { - WORD compression = *((WORD*)FreeImage_GetTagValue(tag)); - switch(compression) { - case TAG_COMPRESSION_NONE: - sprintf(format, "dump mode (%d)", compression); - break; - case TAG_COMPRESSION_CCITTRLE: - sprintf(format, "CCITT modified Huffman RLE (%d)", compression); - break; - case TAG_COMPRESSION_CCITTFAX3: - sprintf(format, "CCITT Group 3 fax encoding (%d)", compression); - break; - /* - case TAG_COMPRESSION_CCITT_T4: - sprintf(format, "CCITT T.4 (TIFF 6 name) (%d)", compression); - break; - */ - case TAG_COMPRESSION_CCITTFAX4: - sprintf(format, "CCITT Group 4 fax encoding (%d)", compression); - break; - /* - case TAG_COMPRESSION_CCITT_T6: - sprintf(format, "CCITT T.6 (TIFF 6 name) (%d)", compression); - break; - */ - case TAG_COMPRESSION_LZW: - sprintf(format, "LZW (%d)", compression); - break; - case TAG_COMPRESSION_OJPEG: - sprintf(format, "!6.0 JPEG (%d)", compression); - break; - case TAG_COMPRESSION_JPEG: - sprintf(format, "JPEG (%d)", compression); - break; - case TAG_COMPRESSION_NEXT: - sprintf(format, "NeXT 2-bit RLE (%d)", compression); - break; - case TAG_COMPRESSION_CCITTRLEW: - sprintf(format, "CCITTRLEW (%d)", compression); - break; - case TAG_COMPRESSION_PACKBITS: - sprintf(format, "PackBits Macintosh RLE (%d)", compression); - break; - case TAG_COMPRESSION_THUNDERSCAN: - sprintf(format, "ThunderScan RLE (%d)", compression); - break; - case TAG_COMPRESSION_PIXARFILM: - sprintf(format, "Pixar companded 10bit LZW (%d)", compression); - break; - case TAG_COMPRESSION_PIXARLOG: - sprintf(format, "Pixar companded 11bit ZIP (%d)", compression); - break; - case TAG_COMPRESSION_DEFLATE: - sprintf(format, "Deflate compression (%d)", compression); - break; - case TAG_COMPRESSION_ADOBE_DEFLATE: - sprintf(format, "Adobe Deflate compression (%d)", compression); - break; - case TAG_COMPRESSION_DCS: - sprintf(format, "Kodak DCS encoding (%d)", compression); - break; - case TAG_COMPRESSION_JBIG: - sprintf(format, "ISO JBIG (%d)", compression); - break; - case TAG_COMPRESSION_SGILOG: - sprintf(format, "SGI Log Luminance RLE (%d)", compression); - break; - case TAG_COMPRESSION_SGILOG24: - sprintf(format, "SGI Log 24-bit packed (%d)", compression); - break; - case TAG_COMPRESSION_JP2000: - sprintf(format, "Leadtools JPEG2000 (%d)", compression); - break; - case TAG_COMPRESSION_LZMA: - sprintf(format, "LZMA2 (%d)", compression); - break; - default: - sprintf(format, "Unknown type (%d)", compression); - break; - } - - buffer += format; - return buffer.c_str(); - } - break; - } - - return ConvertAnyTag(tag); -} - -/** -Convert a Exif GPS tag to a C string -*/ -static const char* -ConvertExifGPSTag(FITAG *tag) { - char format[MAX_TEXT_EXTENT]; - static std::string buffer; - - if(!tag) - return NULL; - - buffer.erase(); - - // convert the tag value to a string buffer - - switch(FreeImage_GetTagID(tag)) { - case TAG_GPS_LATITUDE: - case TAG_GPS_LONGITUDE: - case TAG_GPS_TIME_STAMP: - { - DWORD *pvalue = (DWORD*)FreeImage_GetTagValue(tag); - if(FreeImage_GetTagLength(tag) == 24) { - // dd:mm:ss or hh:mm:ss - int dd = 0, mm = 0; - double ss = 0; - - // convert to seconds - if(pvalue[1]) - ss += ((double)pvalue[0] / (double)pvalue[1]) * 3600; - if(pvalue[3]) - ss += ((double)pvalue[2] / (double)pvalue[3]) * 60; - if(pvalue[5]) - ss += ((double)pvalue[4] / (double)pvalue[5]); - - // convert to dd:mm:ss.ss - dd = (int)(ss / 3600); - mm = (int)(ss / 60) - dd * 60; - ss = ss - dd * 3600 - mm * 60; - - sprintf(format, "%d:%d:%.2f", dd, mm, ss); - buffer += format; - return buffer.c_str(); - } - } - break; - - case TAG_GPS_VERSION_ID: - case TAG_GPS_LATITUDE_REF: - case TAG_GPS_LONGITUDE_REF: - case TAG_GPS_ALTITUDE_REF: - case TAG_GPS_ALTITUDE: - case TAG_GPS_SATELLITES: - case TAG_GPS_STATUS: - case TAG_GPS_MEASURE_MODE: - case TAG_GPS_DOP: - case TAG_GPS_SPEED_REF: - case TAG_GPS_SPEED: - case TAG_GPS_TRACK_REF: - case TAG_GPS_TRACK: - case TAG_GPS_IMG_DIRECTION_REF: - case TAG_GPS_IMG_DIRECTION: - case TAG_GPS_MAP_DATUM: - case TAG_GPS_DEST_LATITUDE_REF: - case TAG_GPS_DEST_LATITUDE: - case TAG_GPS_DEST_LONGITUDE_REF: - case TAG_GPS_DEST_LONGITUDE: - case TAG_GPS_DEST_BEARING_REF: - case TAG_GPS_DEST_BEARING: - case TAG_GPS_DEST_DISTANCE_REF: - case TAG_GPS_DEST_DISTANCE: - case TAG_GPS_PROCESSING_METHOD: - case TAG_GPS_AREA_INFORMATION: - case TAG_GPS_DATE_STAMP: - case TAG_GPS_DIFFERENTIAL: - break; - } - - return ConvertAnyTag(tag); -} - -// ========================================================== -// Tag to string conversion function -// - -const char* DLL_CALLCONV -FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make) { - switch(model) { - case FIMD_EXIF_MAIN: - case FIMD_EXIF_EXIF: - return ConvertExifTag(tag); - - case FIMD_EXIF_GPS: - return ConvertExifGPSTag(tag); - - case FIMD_EXIF_MAKERNOTE: - // We should use the Make string to select an appropriate conversion function - // TO DO ... - break; - - case FIMD_EXIF_INTEROP: - default: - break; - } - - return ConvertAnyTag(tag); -} - diff --git a/plugins/AdvaImg/src/Metadata/TagLib.cpp b/plugins/AdvaImg/src/Metadata/TagLib.cpp deleted file mode 100644 index f0aba628e6..0000000000 --- a/plugins/AdvaImg/src/Metadata/TagLib.cpp +++ /dev/null @@ -1,1617 +0,0 @@ -// ========================================================== -// Tag library -// -// Design and implementation by -// - Hervé Drolon -// -// 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! -// ========================================================== - -// ========================================================== -// Implementation notes : -// ---------------------- -// The tag info tables declared in this file should probably -// be loaded from an XML file. -// This would allow internationalization features and also -// more extensibility. -// Maybe in a future release ? -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "FreeImage.h" -#include "Utilities.h" -#include "FreeImageTag.h" - -/** - HOW-TO : add a new TagInfo table - -------------------------------------------------------------------------- - 1) add a table identifier in the TagLib class definition (see enum MDMODEL) - 2) declare the tag table as static and use a 0/NULL value as last entry - 3) initialize the table in TagLib::TagLib - 4) provide a conversion in TagLib::getFreeImageModel -*/ - -// -------------------------------------------------------------------------- -// EXIF standard tags definition -// -------------------------------------------------------------------------- - -static TagInfo - exif_exif_tag_table[] = - { - { 0x0100, (char *) "ImageWidth", (char *) "Image width"}, - { 0x0101, (char *) "ImageLength", (char *) "Image height"}, - { 0x0102, (char *) "BitsPerSample", (char *) "Number of bits per component"}, - { 0x0103, (char *) "Compression", (char *) "Compression scheme"}, - { 0x0106, (char *) "PhotometricInterpretation", (char *) "Pixel composition"}, - { 0x010A, (char *) "FillOrder", (char*) NULL}, - { 0x010D, (char *) "DocumentName", (char *) NULL}, - { 0x010E, (char *) "ImageDescription", (char *) "Image title"}, - { 0x010F, (char *) "Make", (char *) "Image input equipment manufacturer"}, - { 0x0110, (char *) "Model", (char *) "Image input equipment model"}, - { 0x0111, (char *) "StripOffsets", (char *) "Image data location"}, - { 0x0112, (char *) "Orientation", (char *) "Orientation of image"}, - { 0x0115, (char *) "SamplesPerPixel", (char *) "Number of components"}, - { 0x0116, (char *) "RowsPerStrip", (char *) "Number of rows per strip"}, - { 0x0117, (char *) "StripByteCounts", (char *) "Bytes per compressed strip"}, - { 0x011A, (char *) "XResolution", (char *) "Image resolution in width direction"}, - { 0x011B, (char *) "YResolution", (char *) "Image resolution in height direction"}, - { 0x011C, (char *) "PlanarConfiguration", (char *) "Image data arrangement"}, - { 0x011D, (char *) "PageName", (char *) "Name of the page"}, - { 0x011E, (char *) "XPosition", (char *) "X position of the image"}, - { 0x011F, (char *) "YPosition", (char *) "Y position of the image"}, - { 0x0128, (char *) "ResolutionUnit", (char *) "Unit of X and Y resolution"}, - { 0x0129, (char *) "PageNumber", (char *) "Page number"}, - { 0x012D, (char *) "TransferFunction", (char *) "Transfer function"}, - { 0x0131, (char *) "Software", (char *) "Software used"}, - { 0x0132, (char *) "DateTime", (char *) "File change date and time"}, - { 0x013B, (char *) "Artist", (char *) "Person who created the image"}, - { 0x013C, (char *) "HostComputer", (char *) "Host computer used to generate the image"}, - { 0x013E, (char *) "WhitePoint", (char *) "White point chromaticity"}, - { 0x013F, (char *) "PrimaryChromaticities", (char *) "Chromaticities of primaries"}, - { 0x0156, (char *) "TransferRange", (char *) NULL}, - { 0x0200, (char *) "JPEGProc", (char *) NULL}, - { 0x0201, (char *) "JPEGInterchangeFormat", (char *) "Offset to JPEG SOI"}, - { 0x0202, (char *) "JPEGInterchangeFormatLength", (char *) "Bytes of JPEG data"}, - { 0x0211, (char *) "YCbCrCoefficients", (char *) "Color space transformation matrix coefficients"}, - { 0x0212, (char *) "YCbCrSubSampling", (char *) "Subsampling ratio of Y to C"}, - { 0x0213, (char *) "YCbCrPositioning", (char *) "Y and C positioning"}, - { 0x0214, (char *) "ReferenceBlackWhite", (char *) "Pair of black and white reference values"}, - { 0x828D, (char *) "CFARepeatPatternDim", (char *) NULL}, - { 0x828E, (char *) "CFAPattern", (char *) NULL}, - { 0x828F, (char *) "BatteryLevel", (char *) NULL}, - { 0x8298, (char *) "Copyright", (char *) "Copyright holder"}, - { 0x829A, (char *) "ExposureTime", (char *) "Exposure time"}, - { 0x829D, (char *) "FNumber", (char *) "F number"}, - { 0x83BB, (char *) "IPTC/NAA", (char *) NULL}, - { 0x8773, (char *) "InterColorProfile", (char *) NULL}, - { 0x8822, (char *) "ExposureProgram", (char *) "Exposure program"}, - { 0x8824, (char *) "SpectralSensitivity", (char *) "Spectral sensitivity"}, - { 0x8825, (char *) "GPSInfo", (char *) NULL}, - { 0x8827, (char *) "ISOSpeedRatings", (char *) "ISO speed rating"}, - { 0x8828, (char *) "OECF", (char *) "Optoelectric conversion factor"}, - { 0x9000, (char *) "ExifVersion", (char *) "Exif version"}, - { 0x9003, (char *) "DateTimeOriginal", (char *) "Date and time of original data generation"}, - { 0x9004, (char *) "DateTimeDigitized", (char *) "Date and time of digital data generation"}, - { 0x9101, (char *) "ComponentsConfiguration", (char *) "Meaning of each component"}, - { 0x9102, (char *) "CompressedBitsPerPixel", (char *) "Image compression mode"}, - { 0x9201, (char *) "ShutterSpeedValue", (char *) "Shutter speed"}, - { 0x9202, (char *) "ApertureValue", (char *) "Aperture"}, - { 0x9203, (char *) "BrightnessValue", (char *) "Brightness"}, - { 0x9204, (char *) "ExposureBiasValue", (char *) "Exposure bias"}, - { 0x9205, (char *) "MaxApertureValue", (char *) "Maximum lens aperture"}, - { 0x9206, (char *) "SubjectDistance", (char *) "Subject distance"}, - { 0x9207, (char *) "MeteringMode", (char *) "Metering mode"}, - { 0x9208, (char *) "LightSource", (char *) "Light source"}, - { 0x9209, (char *) "Flash", (char *) "Flash"}, - { 0x920A, (char *) "FocalLength", (char *) "Lens focal length"}, - { 0x9214, (char *) "SubjectArea", (char *) "Subject area"}, - { 0x927C, (char *) "MakerNote", (char *) "Manufacturer notes"}, - { 0x9286, (char *) "UserComment", (char *) "User comments"}, - { 0x9290, (char *) "SubSecTime", (char *) "DateTime subseconds"}, - { 0x9291, (char *) "SubSecTimeOriginal", (char *) "DateTimeOriginal subseconds"}, - { 0x9292, (char *) "SubSecTimeDigitized", (char *) "DateTimeDigitized subseconds"}, - { 0xA000, (char *) "FlashPixVersion", (char *) "Supported Flashpix version"}, - { 0xA001, (char *) "ColorSpace", (char *) "Color space information"}, - { 0xA002, (char *) "PixelXDimension", (char *) "Valid image width"}, - { 0xA003, (char *) "PixelYDimension", (char *) "Valid image height"}, - { 0xA004, (char *) "RelatedSoundFile", (char *) "Related audio file"}, - { 0xA005, (char *) "InteroperabilityOffset", (char *) NULL}, - { 0xA20B, (char *) "FlashEnergy", (char *) "Flash energy"}, - { 0xA20C, (char *) "SpatialFrequencyResponse", (char *) "Spatial frequency response"}, - { 0xA20E, (char *) "FocalPlaneXResolution", (char *) "Focal plane X resolution"}, - { 0xA20F, (char *) "FocalPlaneYResolution", (char *) "Focal plane Y resolution"}, - { 0xA210, (char *) "FocalPlaneResolutionUnit", (char *) "Focal plane resolution unit"}, - { 0xA214, (char *) "SubjectLocation", (char *) "Subject location"}, - { 0xA215, (char *) "ExposureIndex", (char *) "Exposure index"}, - { 0xA217, (char *) "SensingMethod", (char *) "Sensing method"}, - { 0xA300, (char *) "FileSrc", (char *) "File source"}, - { 0xA301, (char *) "SceneType", (char *) "Scene type"}, - { 0xA302, (char *) "CFAPattern", (char *) "CFA pattern"}, - { 0xA401, (char *) "CustomRendered", (char *) "Custom image processing"}, - { 0xA402, (char *) "ExposureMode", (char *) "Exposure mode"}, - { 0xA403, (char *) "WhiteBalance", (char *) "White balance"}, - { 0xA404, (char *) "DigitalZoomRatio", (char *) "Digital zoom ratio"}, - { 0xA405, (char *) "FocalLengthIn35mmFilm", (char *) "Focal length in 35 mm film"}, - { 0xA406, (char *) "SceneCaptureType", (char *) "Scene capture type"}, - { 0xA407, (char *) "GainControl", (char *) "Gain control"}, - { 0xA408, (char *) "Contrast", (char *) "Contrast"}, - { 0xA409, (char *) "Saturation", (char *) "Saturation"}, - { 0xA40A, (char *) "Sharpness", (char *) "Sharpness"}, - { 0xA40B, (char *) "DeviceSettingDescription", (char *) "Device settings description"}, - { 0xA40C, (char *) "SubjectDistanceRange", (char *) "Subject distance range"}, - { 0xA420, (char *) "ImageUniqueID", (char *) "Unique image ID"}, - { 0xA430, (char *) "CameraOwnerName", (char *) "Camera owner name"}, - { 0xA431, (char *) "BodySerialNumber", (char *) "Body serial number"}, - { 0xA432, (char *) "LensSpecification", (char *) "Lens specification"}, - { 0xA433, (char *) "LensMake", (char *) "Lens make"}, - { 0xA434, (char *) "LensModel", (char *) "Lens model"}, - { 0xA435, (char *) "LensSerialNumber", (char *) "Lens serial number"}, - - // These tags are not part of the Exiv v2.3 specifications but are often loaded by applications as Exif data - { 0x4746, (char *) "Rating", (char *) "Rating tag used by Windows"}, - { 0x4749, (char *) "RatingPercent", (char *) "Rating tag used by Windows, value in percent"}, - { 0x9C9B, (char *) "XPTitle", (char *) "Title tag used by Windows, encoded in UCS2"}, - { 0x9C9C, (char *) "XPComment", (char *) "Comment tag used by Windows, encoded in UCS2"}, - { 0x9C9D, (char *) "XPAuthor", (char *) "Author tag used by Windows, encoded in UCS2"}, - { 0x9C9E, (char *) "XPKeywords", (char *) "Keywords tag used by Windows, encoded in UCS2"}, - { 0x9C9F, (char *) "XPSubject", (char *) "Subject tag used by Windows, encoded in UCS2"}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// EXIF GPS tags definition -// -------------------------------------------------------------------------- - -static TagInfo - exif_gps_tag_table[] = - { - { 0x0000, (char *) "GPSVersionID", (char *) "GPS tag version"}, - { 0x0001, (char *) "GPSLatitudeRef", (char *) "North or South Latitude"}, - { 0x0002, (char *) "GPSLatitude", (char *) "Latitude"}, - { 0x0003, (char *) "GPSLongitudeRef", (char *) "East or West Longitude"}, - { 0x0004, (char *) "GPSLongitude", (char *) "Longitude"}, - { 0x0005, (char *) "GPSAltitudeRef", (char *) "Altitude reference"}, - { 0x0006, (char *) "GPSAltitude", (char *) "Altitude"}, - { 0x0007, (char *) "GPSTimeStamp", (char *) "GPS time (atomic clock)"}, - { 0x0008, (char *) "GPSSatellites", (char *) "GPS satellites used for measurement"}, - { 0x0009, (char *) "GPSStatus", (char *) "GPS receiver status"}, - { 0x000A, (char *) "GPSMeasureMode", (char *) "GPS measurement mode"}, - { 0x000B, (char *) "GPSDOP", (char *) "Measurement precision"}, - { 0x000C, (char *) "GPSSpeedRef", (char *) "Speed unit"}, - { 0x000D, (char *) "GPSSpeed", (char *) "Speed of GPS receiver"}, - { 0x000E, (char *) "GPSTrackRef", (char *) "Reference for direction of movement"}, - { 0x000F, (char *) "GPSTrack", (char *) "Direction of movement"}, - { 0x0010, (char *) "GPSImgDirectionRef", (char *) "Reference for direction of image"}, - { 0x0011, (char *) "GPSImgDirection", (char *) "Direction of image"}, - { 0x0012, (char *) "GPSMapDatum", (char *) "Geodetic survey data used"}, - { 0x0013, (char *) "GPSDestLatitudeRef", (char *) "Reference for latitude of destination"}, - { 0x0014, (char *) "GPSDestLatitude", (char *) "Latitude of destination"}, - { 0x0015, (char *) "GPSDestLongitudeRef", (char *) "Reference for longitude of destination"}, - { 0x0016, (char *) "GPSDestLongitude", (char *) "Longitude of destination"}, - { 0x0017, (char *) "GPSDestBearingRef", (char *) "Reference for bearing of destination"}, - { 0x0018, (char *) "GPSDestBearing", (char *) "Bearing of destination"}, - { 0x0019, (char *) "GPSDestDistanceRef", (char *) "Reference for distance to destination"}, - { 0x001A, (char *) "GPSDestDistance", (char *) "Distance to destination"}, - { 0x001B, (char *) "GPSProcessingMethod", (char *) "Name of GPS processing method"}, - { 0x001C, (char *) "GPSAreaInformation", (char *) "Name of GPS area"}, - { 0x001D, (char *) "GPSDateStamp", (char *) "GPS date"}, - { 0x001E, (char *) "GPSDifferential", (char *) "GPS differential correction"}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// EXIF interoperability tags definition -// -------------------------------------------------------------------------- - -static TagInfo - exif_interop_tag_table[] = - { - { 0x0001, (char *) "InteroperabilityIndex", (char *) "Interoperability Identification"}, - { 0x0002, (char *) "InteroperabilityVersion", (char *) "Interoperability version"}, - { 0x1000, (char *) "RelatedImageFileFormat", (char *) "File format of image file"}, - { 0x1001, (char *) "RelatedImageWidth", (char *) "Image width"}, - { 0x1002, (char *) "RelatedImageLength", (char *) "Image height"}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// EXIF maker note tags definition -// -------------------------------------------------------------------------- - -/** -Canon maker note -*/ -static TagInfo - exif_canon_tag_table[] = - { - { 0x0001, (char *) "CanonCameraSettings", (char *) "Canon CameraSettings Tags"}, - { 0x0002, (char *) "CanonFocalLength", (char *) "Canon FocalLength Tags"}, - { 0x0003, (char *) "CanonFlashInfo?", (char *) NULL}, - { 0x0004, (char *) "CanonShotInfo", (char *) "Canon ShotInfo Tags"}, - { 0x0005, (char *) "CanonPanorama", (char *) "Canon Panorama Tags"}, - { 0x0006, (char *) "CanonImageType", (char *) NULL}, - { 0x0007, (char *) "CanonFirmwareVersion", (char *) NULL}, - { 0x0008, (char *) "FileNumber", (char *) NULL}, - { 0x0009, (char *) "OwnerName", (char *) NULL}, - { 0x000A, (char *) "UnknownD30", (char *) "Canon UnknownD30 Tags"}, - { 0x000C, (char *) "SerialNumber", (char *) NULL}, - { 0x000D, (char *) "CanonCameraInfo", (char *) "Canon CameraInfo Tags"}, - { 0x000E, (char *) "CanonFileLength", (char *) NULL}, - { 0x000F, (char *) "CanonCustomFunctions", (char *) "Custom Functions"}, - { 0x0010, (char *) "CanonModelID", (char *) NULL}, - { 0x0012, (char *) "CanonAFInfo", (char *) "Canon AFInfo Tags"}, - { 0x0013, (char *) "ThumbnailImageValidArea", (char *) NULL}, - { 0x0015, (char *) "SerialNumberFormat", (char *) NULL}, - { 0x001A, (char *) "SuperMacro", (char *) NULL}, - { 0x001C, (char *) "DateStampMode", (char *) NULL}, - { 0x001D, (char *) "MyColors", (char *) NULL}, - { 0x001E, (char *) "FirmwareRevision", (char *) NULL}, - { 0x0023, (char *) "Categories", (char *) NULL}, - { 0x0024, (char *) "FaceDetect1", (char *) NULL}, - { 0x0025, (char *) "FaceDetect2", (char *) NULL}, - { 0x0026, (char *) "CanonAFInfo2", (char *) "Canon AFInfo2 Tags"}, - { 0x0028, (char *) "ImageUniqueID", (char *) NULL}, - { 0x0081, (char *) "RawDataOffset", (char *) NULL}, - { 0x0083, (char *) "OriginalDecisionDataOffset", (char *) NULL}, - { 0x0090, (char *) "CustomFunctions1D", (char *) "CanonCustom Functions1D Tags"}, - { 0x0091, (char *) "PersonalFunctions", (char *) "CanonCustom PersonalFuncs Tags"}, - { 0x0092, (char *) "PersonalFunctionValues", (char *) "CanonCustom PersonalFuncValues Tags"}, - { 0x0093, (char *) "CanonFileInfo", (char *) "Canon FileInfo Tags"}, - { 0x0094, (char *) "AFPointsInFocus1D", (char *) NULL}, - { 0x0095, (char *) "LensModel", (char *) NULL}, - { 0x0096, (char *) "SerialInfo", (char *) NULL}, - { 0x0097, (char *) "DustRemovalData", (char *) NULL}, - { 0x0098, (char *) "CropInfo", (char *) NULL}, - { 0x0099, (char *) "CustomFunctions2", (char *) NULL}, - { 0x009A, (char *) "AspectInfo", (char *) NULL}, - { 0x00A0, (char *) "ProcessingInfo", (char *) NULL}, - { 0x00A1, (char *) "ToneCurveTable", (char *) NULL}, - { 0x00A2, (char *) "SharpnessTable", (char *) NULL}, - { 0x00A3, (char *) "SharpnessFreqTable", (char *) NULL}, - { 0x00A4, (char *) "WhiteBalanceTable", (char *) NULL}, - { 0x00A9, (char *) "ColorBalance", (char *) NULL}, - { 0x00AA, (char *) "MeasuredColor", (char *) NULL}, - { 0x00AE, (char *) "ColorTemperature", (char *) NULL}, - { 0x00B0, (char *) "CanonFlags", (char *) NULL}, - { 0x00B1, (char *) "ModifiedInfo", (char *) NULL}, - { 0x00B2, (char *) "ToneCurveMatching", (char *) NULL}, - { 0x00B3, (char *) "WhiteBalanceMatching", (char *) NULL}, - { 0x00B4, (char *) "ColorSpace", (char *) NULL}, - { 0x00B6, (char *) "PreviewImageInfo", (char *) NULL}, - { 0x00D0, (char *) "VRDOffset", (char *) "Offset of VRD 'recipe data' if it exists"}, - { 0x00E0, (char *) "SensorInfo", (char *) NULL}, - { 0x4001, (char *) "ColorData", (char *) "Canon ColorData Tags"}, - { 0x4002, (char *) "CRWParam?", (char *) NULL}, - { 0x4003, (char *) "ColorInfo", (char *) NULL}, - { 0x4005, (char *) "Flavor?", (char *) NULL}, - { 0x4008, (char *) "BlackLevel?", (char *) NULL}, - { 0x4010, (char *) "CustomPictureStyleFileName", (char *) NULL}, - { 0x4013, (char *) "AFMicroAdj", (char *) NULL}, - { 0x4015, (char *) "VignettingCorr", (char *) NULL}, - { 0x4016, (char *) "VignettingCorr2", (char *) NULL}, - { 0x4018, (char *) "LightingOpt", (char *) NULL}, - { 0x4019, (char *) "LensInfo", (char *) NULL}, - { 0x4020, (char *) "AmbienceInfo", (char *) NULL}, - { 0x4024, (char *) "FilterInfo", (char *) NULL}, - - // These 'sub'-tag values have been created for consistency -- they don't exist within the exif segment - - // Fields under tag 0x0001 (we add 0xC100 to make unique tag id) - { 0xC100 + 1, (char *) "CameraSettings:MacroMode", (char *) NULL}, - { 0xC100 + 2, (char *) "CameraSettings:SelfTimer", (char *) NULL}, - { 0xC100 + 3, (char *) "CameraSettings:Quality", (char *) NULL}, - { 0xC100 + 4, (char *) "CameraSettings:CanonFlashMode", (char *) NULL}, - { 0xC100 + 5, (char *) "CameraSettings:ContinuousDrive", (char *) NULL}, - { 0xC100 + 6, (char *) "CameraSettings:0x0006", (char *) NULL}, - { 0xC100 + 7, (char *) "CameraSettings:FocusMode", (char *) NULL}, - { 0xC100 + 8, (char *) "CameraSettings:0x0008", (char *) NULL}, - { 0xC100 + 9, (char *) "CameraSettings:RecordMode", (char *) NULL}, - { 0xC100 + 10, (char *) "CameraSettings:CanonImageSize", (char *) NULL}, - { 0xC100 + 11, (char *) "CameraSettings:EasyMode", (char *) NULL}, - { 0xC100 + 12, (char *) "CameraSettings:DigitalZoom", (char *) NULL}, - { 0xC100 + 13, (char *) "CameraSettings:Contrast", (char *) NULL}, - { 0xC100 + 14, (char *) "CameraSettings:Saturation", (char *) NULL}, - { 0xC100 + 15, (char *) "CameraSettings:Sharpness", (char *) NULL}, - { 0xC100 + 16, (char *) "CameraSettings:CameraISO", (char *) NULL}, - { 0xC100 + 17, (char *) "CameraSettings:MeteringMode", (char *) NULL}, - { 0xC100 + 18, (char *) "CameraSettings:FocusRange", (char *) NULL}, - { 0xC100 + 19, (char *) "CameraSettings:AFPoint", (char *) NULL}, - { 0xC100 + 20, (char *) "CameraSettings:CanonExposureMode", (char *) NULL}, - { 0xC100 + 21, (char *) "CameraSettings:0x0015", (char *) NULL}, - { 0xC100 + 22, (char *) "CameraSettings:LensType", (char *) NULL}, - { 0xC100 + 23, (char *) "CameraSettings:LongFocal", (char *) NULL}, - { 0xC100 + 24, (char *) "CameraSettings:ShortFocal", (char *) NULL}, - { 0xC100 + 25, (char *) "CameraSettings:FocalUnits", (char *) "Focal Units per mm"}, - { 0xC100 + 26, (char *) "CameraSettings:MaxAperture", (char *) NULL}, - { 0xC100 + 27, (char *) "CameraSettings:MinAperture", (char *) NULL}, - { 0xC100 + 28, (char *) "CameraSettings:FlashActivity", (char *) NULL}, - { 0xC100 + 29, (char *) "CameraSettings:FlashBits", (char *) NULL}, - { 0xC100 + 30, (char *) "CameraSettings:0x001E", (char *) NULL}, - { 0xC100 + 31, (char *) "CameraSettings:0x001F", (char *) NULL}, - { 0xC100 + 32, (char *) "CameraSettings:FocusContinuous", (char *) NULL}, - { 0xC100 + 33, (char *) "CameraSettings:AESetting", (char *) NULL}, - { 0xC100 + 34, (char *) "CameraSettings:ImageStabilization", (char *) NULL}, - { 0xC100 + 35, (char *) "CameraSettings:DisplayAperture", (char *) NULL}, - { 0xC100 + 36, (char *) "CameraSettings:ZoomSourceWidth", (char *) NULL}, - { 0xC100 + 37, (char *) "CameraSettings:ZoomTargetWidth", (char *) NULL}, - { 0xC100 + 38, (char *) "CameraSettings:0x0026", (char *) NULL}, - { 0xC100 + 39, (char *) "CameraSettings:SpotMeteringMode", (char *) NULL}, - { 0xC100 + 40, (char *) "CameraSettings:PhotoEffect", (char *) NULL}, - { 0xC100 + 41, (char *) "CameraSettings:ManualFlashOutput", (char *) NULL}, - { 0xC100 + 42, (char *) "CameraSettings:ColorTone", (char *) NULL}, - { 0xC100 + 43, (char *) "CameraSettings:0x002B", (char *) NULL}, - { 0xC100 + 44, (char *) "CameraSettings:0x002C", (char *) NULL}, - { 0xC100 + 45, (char *) "CameraSettings:0x002D", (char *) NULL}, - { 0xC100 + 46, (char *) "CameraSettings:SRAWQuality", (char *) NULL}, - { 0xC100 + 47, (char *) "CameraSettings:0x002F", (char *) NULL}, - { 0xC100 + 48, (char *) "CameraSettings:0x0030", (char *) NULL}, - - // Fields under tag 0x0002 (we add 0xC200 to make unique tag id) - { 0xC200 + 0, (char *) "FocalLength:FocalType", (char *) NULL}, - { 0xC200 + 1, (char *) "FocalLength:FocalLength", (char *) NULL}, - { 0xC200 + 2, (char *) "FocalLength:FocalPlaneXSize", (char *) NULL}, - { 0xC200 + 3, (char *) "FocalLength:FocalPlaneYSize", (char *) NULL}, - - // Fields under tag 0x0004 (we add 0xC400 to make unique tag id) - { 0xC400 + 1, (char *) "ShotInfo:AutoISO", (char *) NULL}, - { 0xC400 + 2, (char *) "ShotInfo:BaseISO", (char *) NULL}, - { 0xC400 + 3, (char *) "ShotInfo:MeasuredEV", (char *) NULL}, - { 0xC400 + 4, (char *) "ShotInfo:TargetAperture", (char *) NULL}, - { 0xC400 + 5, (char *) "ShotInfo:TargetExposureTime", (char *) NULL}, - { 0xC400 + 6, (char *) "ShotInfo:ExposureCompensation", (char *) NULL}, - { 0xC400 + 7, (char *) "ShotInfo:WhiteBalance", (char *) NULL}, - { 0xC400 + 8, (char *) "ShotInfo:SlowShutter", (char *) NULL}, - { 0xC400 + 9, (char *) "ShotInfo:SequenceNumber", (char *) NULL}, - { 0xC400 + 10, (char *) "ShotInfo:OpticalZoomCode", (char *) NULL}, - { 0xC400 + 11, (char *) "ShotInfo:0x000B", (char *) NULL}, - { 0xC400 + 12, (char *) "ShotInfo:CameraTemperature", (char *) NULL}, - { 0xC400 + 13, (char *) "ShotInfo:FlashGuideNumber", (char *) NULL}, - { 0xC400 + 14, (char *) "ShotInfo:AFPointsInFocus", (char *) NULL}, - { 0xC400 + 15, (char *) "ShotInfo:FlashExposureComp", (char *) NULL}, - { 0xC400 + 16, (char *) "ShotInfo:AutoExposureBracketing", (char *) NULL}, - { 0xC400 + 17, (char *) "ShotInfo:AEBBracketValue", (char *) NULL}, - { 0xC400 + 18, (char *) "ShotInfo:ControlMode", (char *) NULL}, - { 0xC400 + 19, (char *) "ShotInfo:FocusDistanceUpper", (char *) NULL}, - { 0xC400 + 20, (char *) "ShotInfo:FocusDistanceLower", (char *) NULL}, - { 0xC400 + 21, (char *) "ShotInfo:FNumber", (char *) NULL}, - { 0xC400 + 22, (char *) "ShotInfo:ExposureTime", (char *) NULL}, - { 0xC400 + 23, (char *) "ShotInfo:MeasuredEV2", (char *) NULL}, - { 0xC400 + 24, (char *) "ShotInfo:BulbDuration", (char *) NULL}, - { 0xC400 + 25, (char *) "ShotInfo:0x0019", (char *) NULL}, - { 0xC400 + 26, (char *) "ShotInfo:CameraType", (char *) NULL}, - { 0xC400 + 27, (char *) "ShotInfo:AutoRotate", (char *) NULL}, - { 0xC400 + 28, (char *) "ShotInfo:NDFilter", (char *) NULL}, - { 0xC400 + 29, (char *) "ShotInfo:SelfTimer2", (char *) NULL}, - { 0xC400 + 30, (char *) "ShotInfo:0x001E", (char *) NULL}, - { 0xC400 + 31, (char *) "ShotInfo:0x001F", (char *) NULL}, - { 0xC400 + 32, (char *) "ShotInfo:0x0020", (char *) NULL}, - { 0xC400 + 33, (char *) "ShotInfo:FlashOutput", (char *) NULL}, - - // Fields under tag 0x0012 (we add 0x1200 to make unique tag id) - { 0x1200 + 0, (char *) "AFInfo:NumAFPoints", (char *) NULL}, - { 0x1200 + 1, (char *) "AFInfo:ValidAFPoints", (char *) NULL}, - { 0x1200 + 2, (char *) "AFInfo:CanonImageWidth", (char *) NULL}, - { 0x1200 + 3, (char *) "AFInfo:CanonImageHeight", (char *) NULL}, - { 0x1200 + 4, (char *) "AFInfo:AFImageWidth", (char *) NULL}, - { 0x1200 + 5, (char *) "AFInfo:AFImageHeight", (char *) NULL}, - { 0x1200 + 6, (char *) "AFInfo:AFAreaWidth", (char *) NULL}, - { 0x1200 + 7, (char *) "AFInfo:AFAreaHeight", (char *) NULL}, - { 0x1200 + 8, (char *) "AFInfo:AFAreaXPositions", (char *) NULL}, - { 0x1200 + 9, (char *) "AFInfo:AFAreaYPositions", (char *) NULL}, - { 0x1200 + 10, (char *) "AFInfo:AFPointsInFocus", (char *) NULL}, - { 0x1200 + 11, (char *) "AFInfo:PrimaryAFPoint?", (char *) NULL}, - { 0x1200 + 12, (char *) "AFInfo:PrimaryAFPoint", (char *) NULL}, - { 0x1200 + 13, (char *) "AFInfo:0x000D", (char *) NULL}, - { 0x1200 + 14, (char *) "AFInfo:0x000E", (char *) NULL}, - { 0x1200 + 15, (char *) "AFInfo:0x000F", (char *) NULL}, - { 0x1200 + 16, (char *) "AFInfo:0x0010", (char *) NULL}, - { 0x1200 + 17, (char *) "AFInfo:0x0011", (char *) NULL}, - { 0x1200 + 18, (char *) "AFInfo:0x0012", (char *) NULL}, - { 0x1200 + 19, (char *) "AFInfo:0x0013", (char *) NULL}, - { 0x1200 + 20, (char *) "AFInfo:0x0014", (char *) NULL}, - { 0x1200 + 21, (char *) "AFInfo:0x0015", (char *) NULL}, - { 0x1200 + 22, (char *) "AFInfo:0x0016", (char *) NULL}, - { 0x1200 + 23, (char *) "AFInfo:0x0017", (char *) NULL}, - { 0x1200 + 24, (char *) "AFInfo:0x0018", (char *) NULL}, - { 0x1200 + 25, (char *) "AFInfo:0x0019", (char *) NULL}, - { 0x1200 + 26, (char *) "AFInfo:0x001A", (char *) NULL}, - { 0x1200 + 27, (char *) "AFInfo:0x001B", (char *) NULL}, - - // Fields under tag 0x00A0 (we add 0xCA00 to make unique tag id) - { 0xCA00 + 1, (char *) "ProcessingInfo:ToneCurve", (char *) NULL}, - { 0xCA00 + 2, (char *) "ProcessingInfo:Sharpness", (char *) NULL}, - { 0xCA00 + 3, (char *) "ProcessingInfo:SharpnessFrequency", (char *) NULL}, - { 0xCA00 + 4, (char *) "ProcessingInfo:SensorRedLevel", (char *) NULL}, - { 0xCA00 + 5, (char *) "ProcessingInfo:SensorBlueLevel", (char *) NULL}, - { 0xCA00 + 6, (char *) "ProcessingInfo:WhiteBalanceRed", (char *) NULL}, - { 0xCA00 + 7, (char *) "ProcessingInfo:WhiteBalanceBlue", (char *) NULL}, - { 0xCA00 + 8, (char *) "ProcessingInfo:WhiteBalance", (char *) NULL}, - { 0xCA00 + 9, (char *) "ProcessingInfo:ColorTemperature", (char *) NULL}, - { 0xCA00 + 10, (char *) "ProcessingInfo:PictureStyle", (char *) NULL}, - { 0xCA00 + 11, (char *) "ProcessingInfo:DigitalGain", (char *) NULL}, - { 0xCA00 + 12, (char *) "ProcessingInfo:WBShiftAB", (char *) NULL}, - { 0xCA00 + 13, (char *) "ProcessingInfo:WBShiftGM", (char *) NULL}, - - // Fields under tag 0x00E0 (we add 0xCE00 to make unique tag id) - { 0xCE00 + 1, (char *) "SensorInfo:SensorWidth", (char *) NULL}, - { 0xCE00 + 2, (char *) "SensorInfo:SensorHeight", (char *) NULL}, - { 0xCE00 + 3, (char *) "SensorInfo:0x0003", (char *) NULL}, - { 0xCE00 + 4, (char *) "SensorInfo:0x0004", (char *) NULL}, - { 0xCE00 + 5, (char *) "SensorInfo:SensorLeftBorder", (char *) NULL}, - { 0xCE00 + 6, (char *) "SensorInfo:SensorTopBorder", (char *) NULL}, - { 0xCE00 + 7, (char *) "SensorInfo:SensorRightBorder", (char *) NULL}, - { 0xCE00 + 8, (char *) "SensorInfo:SensorBottomBorder", (char *) NULL}, - { 0xCE00 + 9, (char *) "SensorInfo:BlackMaskLeftBorder", (char *) NULL}, - { 0xCE00 + 10, (char *) "SensorInfo:BlackMaskTopBorder", (char *) NULL}, - { 0xCE00 + 11, (char *) "SensorInfo:BlackMaskRightBorder", (char *) NULL}, - { 0xCE00 + 12, (char *) "SensorInfo:BlackMaskBottomBorder", (char *) NULL}, - { 0xCE00 + 13, (char *) "SensorInfo:0x000D", (char *) NULL}, - { 0xCE00 + 14, (char *) "SensorInfo:0x000E", (char *) NULL}, - { 0xCE00 + 15, (char *) "SensorInfo:0x000F", (char *) NULL}, - { 0xCE00 + 16, (char *) "SensorInfo:0x0010", (char *) NULL}, - - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Casio type 1 maker note -*/ -static TagInfo - exif_casio_type1_tag_table[] = - { - { 0x0001, (char *) "RecordingMode", (char *) NULL}, - { 0x0002, (char *) "Quality", (char *) NULL}, - { 0x0003, (char *) "FocusMode", (char *) NULL}, - { 0x0004, (char *) "FlashMode", (char *) NULL}, - { 0x0005, (char *) "FlashIntensity", (char *) NULL}, - { 0x0006, (char *) "ObjectDistance", (char *) NULL}, - { 0x0007, (char *) "WhiteBalance", (char *) NULL}, - { 0x000A, (char *) "DigitalZoom", (char *) NULL}, - { 0x000B, (char *) "Sharpness", (char *) NULL}, - { 0x000C, (char *) "Contrast", (char *) NULL}, - { 0x000D, (char *) "Saturation", (char *) NULL}, - { 0x0014, (char *) "ISO", (char *) NULL}, - { 0x0015, (char *) "FirmwareDate", (char *) NULL}, - { 0x0016, (char *) "Enhancement", (char *) NULL}, - { 0x0017, (char *) "ColorFilter", (char *) NULL}, - { 0x0018, (char *) "AFPoint", (char *) NULL}, - { 0x0019, (char *) "FlashIntensity", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Casio type 2 maker note -*/ -static TagInfo - exif_casio_type2_tag_table[] = - { - { 0x0002, (char *) "PreviewImageSize", (char *) NULL}, - { 0x0003, (char *) "PreviewImageLength", (char *) NULL}, - { 0x0004, (char *) "PreviewImageStart", (char *) NULL}, - { 0x0008, (char *) "QualityMode", (char *) NULL}, - { 0x0009, (char *) "CasioImageSize", (char *) NULL}, - { 0x000D, (char *) "FocusMode", (char *) NULL}, - { 0x0014, (char *) "ISO", (char *) NULL}, - { 0x0019, (char *) "WhiteBalance", (char *) NULL}, - { 0x001D, (char *) "FocalLength", (char *) NULL}, - { 0x001F, (char *) "Saturation", (char *) NULL}, - { 0x0020, (char *) "Contrast", (char *) NULL}, - { 0x0021, (char *) "Sharpness", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x2000, (char *) "PreviewImage", (char *) NULL}, - { 0x2001, (char *) "FirmwareDate", (char *) NULL}, - { 0x2011, (char *) "WhiteBalanceBias", (char *) NULL}, - { 0x2012, (char *) "WhiteBalance", (char *) NULL}, - { 0x2021, (char *) "AFPointPosition", (char *) NULL}, - { 0x2022, (char *) "ObjectDistance", (char *) NULL}, - { 0x2034, (char *) "FlashDistance", (char *) NULL}, - { 0x2076, (char *) "SpecialEffectMode", (char *) NULL}, - { 0x3000, (char *) "RecordMode", (char *) NULL}, - { 0x3001, (char *) "ReleaseMode", (char *) NULL}, - { 0x3002, (char *) "Quality", (char *) NULL}, - { 0x3003, (char *) "FocusMode", (char *) NULL}, - { 0x3006, (char *) "HometownCity", (char *) NULL}, - { 0x3007, (char *) "BestShotMode", (char *) NULL}, - { 0x3008, (char *) "AutoISO", (char *) NULL}, - { 0x3009, (char *) "AFMode", (char *) NULL}, - { 0x3011, (char *) "Sharpness", (char *) NULL}, - { 0x3012, (char *) "Contrast", (char *) NULL}, - { 0x3013, (char *) "Saturation", (char *) NULL}, - { 0x3014, (char *) "ISO", (char *) NULL}, - { 0x3015, (char *) "ColorMode", (char *) NULL}, - { 0x3016, (char *) "Enhancement", (char *) NULL}, - { 0x3017, (char *) "ColorFilter", (char *) NULL}, - { 0x301B, (char *) "ArtMode", (char *) NULL}, - { 0x301C, (char *) "SequenceNumber", (char *) NULL}, - { 0x301D, (char *) "BracketSequence", (char *) NULL}, - { 0x3020, (char *) "ImageStabilization", (char *) NULL}, - { 0x302A, (char *) "LightingMode", (char *) NULL}, - { 0x302B, (char *) "PortraitRefiner", (char *) NULL}, - { 0x3030, (char *) "SpecialEffectLevel", (char *) NULL}, - { 0x3031, (char *) "SpecialEffectSetting", (char *) NULL}, - { 0x3103, (char *) "DriveMode", (char *) NULL}, - { 0x4001, (char *) "CaptureFrameRate", (char *) NULL}, - { 0x4003, (char *) "VideoQuality", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -FujiFilm maker note -*/ -static TagInfo - exif_fujifilm_tag_table[] = - { - { 0x0000, (char *) "Version", (char *) NULL}, - { 0x0010, (char *) "InternalSerialNumber", (char *) NULL}, - { 0x1000, (char *) "Quality", (char *) NULL}, - { 0x1001, (char *) "Sharpness", (char *) NULL}, - { 0x1002, (char *) "WhiteBalance", (char *) NULL}, - { 0x1003, (char *) "Saturation", (char *) NULL}, - { 0x1004, (char *) "Contrast", (char *) NULL}, - { 0x1005, (char *) "ColorTemperature", (char *) NULL}, - { 0x100A, (char *) "WhiteBalanceFineTune", (char *) NULL}, - { 0x100B, (char *) "NoiseReduction", (char *) NULL}, - { 0x1010, (char *) "FujiFlashMode", (char *) NULL}, - { 0x1011, (char *) "FlashExposureComp", (char *) NULL}, - { 0x1020, (char *) "Macro", (char *) NULL}, - { 0x1021, (char *) "FocusMode", (char *) NULL}, - { 0x1023, (char *) "FocusPixel", (char *) NULL}, - { 0x1030, (char *) "SlowSync", (char *) NULL}, - { 0x1031, (char *) "PictureMode", (char *) NULL}, - { 0x1033, (char *) "EXRAuto", (char *) NULL}, - { 0x1034, (char *) "EXRMode", (char *) NULL}, - { 0x1100, (char *) "AutoBracketting", (char *) NULL}, - { 0x1101, (char *) "SequenceNumber", (char *) NULL}, - { 0x1210, (char *) "ColorMode", (char *) NULL}, - { 0x1300, (char *) "BlurWarning", (char *) NULL}, - { 0x1301, (char *) "FocusWarning", (char *) NULL}, - { 0x1302, (char *) "ExposureWarning", (char *) NULL}, - { 0x1400, (char *) "DynamicRange", (char *) NULL}, - { 0x1401, (char *) "FilmMode", (char *) NULL}, - { 0x1402, (char *) "DynamicRangeSetting", (char *) NULL}, - { 0x1403, (char *) "DevelopmentDynamicRange", (char *) NULL}, - { 0x1404, (char *) "MinFocalLength", (char *) NULL}, - { 0x1405, (char *) "MaxFocalLength", (char *) NULL}, - { 0x1406, (char *) "MaxApertureAtMinFocal", (char *) NULL}, - { 0x1407, (char *) "MaxApertureAtMaxFocal", (char *) NULL}, - { 0x4100, (char *) "FacesDetected", (char *) NULL}, - { 0x4103, (char *) "FacePositions", (char *) NULL}, - { 0x8000, (char *) "FileSource", (char *) NULL}, - { 0x8002, (char *) "OrderNumber", (char *) NULL}, - { 0x8003, (char *) "FrameNumber", (char *) NULL}, - { 0xB211, (char *) "Parallax", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Kyocera maker note -*/ -static TagInfo - exif_kyocera_tag_table[] = - { - { 0x0001, (char *) "ThumbnailImage", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) "Print Image Matching Info"}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Olympus Type 1 / Epson / Agfa maker note -*/ -static TagInfo - exif_olympus_type1_tag_table[] = - { - { 0x0000, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x0001, (char *) "MinoltaCameraSettingsOld", (char *) NULL}, - { 0x0003, (char *) "MinoltaCameraSettings", (char *) NULL}, - { 0x0040, (char *) "CompressedImageSize", (char *) NULL}, - { 0x0081, (char *) "PreviewImageData", (char *) NULL}, - { 0x0088, (char *) "PreviewImageStart", (char *) NULL}, - { 0x0089, (char *) "PreviewImageLength", (char *) NULL}, - { 0x0100, (char *) "ThumbnailImage", (char *) NULL}, - { 0x0104, (char *) "BodyFirmwareVersion", (char *) NULL}, - { 0x0200, (char *) "SpecialMode", (char *) NULL}, - { 0x0201, (char *) "Quality", (char *) NULL}, - { 0x0202, (char *) "Macro", (char *) NULL}, - { 0x0203, (char *) "BWMode", (char *) NULL}, - { 0x0204, (char *) "DigitalZoom", (char *) NULL}, - { 0x0205, (char *) "FocalPlaneDiagonal", (char *) NULL}, - { 0x0206, (char *) "LensDistortionParams", (char *) NULL}, - { 0x0207, (char *) "CameraType", (char *) NULL}, - { 0x0208, (char *) "TextInfo", (char *) "Olympus TextInfo Tags"}, - { 0x0209, (char *) "CameraID", (char *) NULL}, - { 0x020B, (char *) "EpsonImageWidth", (char *) NULL}, - { 0x020C, (char *) "EpsonImageHeight", (char *) NULL}, - { 0x020D, (char *) "EpsonSoftware", (char *) NULL}, - { 0x0280, (char *) "PreviewImage", (char *) NULL}, - { 0x0300, (char *) "PreCaptureFrames", (char *) NULL}, - { 0x0301, (char *) "WhiteBoard", (char *) NULL}, - { 0x0302, (char *) "OneTouchWB", (char *) NULL}, - { 0x0303, (char *) "WhiteBalanceBracket", (char *) NULL}, - { 0x0304, (char *) "WhiteBalanceBias", (char *) NULL}, - { 0x0403, (char *) "SceneMode", (char *) NULL}, - { 0x0404, (char *) "SerialNumber", (char *) NULL}, - { 0x0405, (char *) "Firmware", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) "PrintIM Tags"}, - { 0x0F00, (char *) "DataDump", (char *) NULL}, - { 0x0F01, (char *) "DataDump2", (char *) NULL}, - { 0x1000, (char *) "ShutterSpeedValue", (char *) NULL}, - { 0x1001, (char *) "ISOValue", (char *) NULL}, - { 0x1002, (char *) "ApertureValue", (char *) NULL}, - { 0x1003, (char *) "BrightnessValue", (char *) NULL}, - { 0x1004, (char *) "FlashMode", (char *) NULL}, - { 0x1005, (char *) "FlashDevice", (char *) NULL}, - { 0x1006, (char *) "ExposureCompensation", (char *) NULL}, - { 0x1007, (char *) "SensorTemperature", (char *) NULL}, - { 0x1008, (char *) "LensTemperature", (char *) NULL}, - { 0x1009, (char *) "LightCondition", (char *) NULL}, - { 0x100A, (char *) "FocusRange", (char *) NULL}, - { 0x100B, (char *) "FocusMode", (char *) NULL}, - { 0x100C, (char *) "ManualFocusDistance", (char *) NULL}, - { 0x100D, (char *) "ZoomStepCount", (char *) NULL}, - { 0x100E, (char *) "FocusStepCount", (char *) NULL}, - { 0x100F, (char *) "Sharpness", (char *) NULL}, - { 0x1010, (char *) "FlashChargeLevel", (char *) NULL}, - { 0x1011, (char *) "ColorMatrix", (char *) NULL}, - { 0x1012, (char *) "BlackLevel", (char *) NULL}, - { 0x1015, (char *) "WBMode", (char *) NULL}, - { 0x1017, (char *) "RedBalance", (char *) NULL}, - { 0x1018, (char *) "BlueBalance", (char *) NULL}, - { 0x1019, (char *) "ColorMatrixNumber", (char *) NULL}, - { 0x101A, (char *) "SerialNumber", (char *) NULL}, - { 0x1023, (char *) "FlashExposureComp", (char *) NULL}, - { 0x1024, (char *) "InternalFlashTable", (char *) NULL}, - { 0x1025, (char *) "ExternalFlashGValue", (char *) NULL}, - { 0x1026, (char *) "ExternalFlashBounce", (char *) NULL}, - { 0x1027, (char *) "ExternalFlashZoom", (char *) NULL}, - { 0x1028, (char *) "ExternalFlashMode", (char *) NULL}, - { 0x1029, (char *) "Contrast", (char *) NULL}, - { 0x102A, (char *) "SharpnessFactor", (char *) NULL}, - { 0x102B, (char *) "ColorControl", (char *) NULL}, - { 0x102C, (char *) "ValidBits", (char *) NULL}, - { 0x102D, (char *) "CoringFilter", (char *) NULL}, - { 0x102E, (char *) "OlympusImageWidth", (char *) NULL}, - { 0x102F, (char *) "OlympusImageHeight", (char *) NULL}, - { 0x1030, (char *) "SceneDetect", (char *) NULL}, - { 0x1031, (char *) "SceneArea?", (char *) NULL}, - { 0x1033, (char *) "SceneDetectData?", (char *) NULL}, - { 0x1034, (char *) "CompressionRatio", (char *) NULL}, - { 0x1035, (char *) "PreviewImageValid", (char *) NULL}, - { 0x1036, (char *) "PreviewImageStart", (char *) NULL}, - { 0x1037, (char *) "PreviewImageLength", (char *) NULL}, - { 0x1038, (char *) "AFResult", (char *) NULL}, - { 0x1039, (char *) "CCDScanMode", (char *) NULL}, - { 0x103A, (char *) "NoiseReduction", (char *) NULL}, - { 0x103B, (char *) "InfinityLensStep", (char *) NULL}, - { 0x103C, (char *) "NearLensStep", (char *) NULL}, - { 0x103D, (char *) "LightValueCenter", (char *) NULL}, - { 0x103E, (char *) "LightValuePeriphery", (char *) NULL}, - { 0x2010, (char *) "Equipment", (char *) "Olympus Equipment Tags"}, - { 0x2020, (char *) "CameraSettings", (char *) "Olympus CameraSettings Tags"}, - { 0x2030, (char *) "RawDevelopment", (char *) "Olympus RawDevelopment Tags"}, - { 0x2040, (char *) "ImageProcessing", (char *) "Olympus ImageProcessing Tags"}, - { 0x2050, (char *) "FocusInfo", (char *) "Olympus FocusInfo Tags"}, - { 0x2100, (char *) "Olympus2100", (char *) "Olympus FE Tags"}, - { 0x2200, (char *) "Olympus2200", (char *) "Olympus FE Tags"}, - { 0x2300, (char *) "Olympus2300", (char *) "Olympus FE Tags"}, - { 0x2400, (char *) "Olympus2400", (char *) "Olympus FE Tags"}, - { 0x2500, (char *) "Olympus2500", (char *) "Olympus FE Tags"}, - { 0x2600, (char *) "Olympus2600", (char *) "Olympus FE Tags"}, - { 0x2700, (char *) "Olympus2700", (char *) "Olympus FE Tags"}, - { 0x2800, (char *) "Olympus2800", (char *) "Olympus FE Tags"}, - { 0x2900, (char *) "Olympus2900", (char *) "Olympus FE Tags"}, - { 0x3000, (char *) "RawInfo", (char *) "Olympus RawInfo Tags"}, - { 0x4000, (char *) "MainInfo", (char *) "Olympus MainInfo Tags"}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Minolta maker note -*/ -static TagInfo - exif_minolta_tag_table[] = - { - { 0x0000, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x0001, (char *) "MinoltaCameraSettingsOld", (char *) NULL}, - { 0x0003, (char *) "MinoltaCameraSettings", (char *) NULL}, - { 0x0004, (char *) "MinoltaCameraSettings7D", (char *) NULL}, - { 0x0018, (char *) "ImageStabilization", (char *) NULL}, - { 0x0040, (char *) "CompressedImageSize", (char *) NULL}, - { 0x0081, (char *) "PreviewImage", (char *) NULL}, - { 0x0088, (char *) "PreviewImageStart", (char *) NULL}, - { 0x0089, (char *) "PreviewImageLength", (char *) NULL}, - { 0x0100, (char *) "SceneMode", (char *) NULL}, - { 0x0101, (char *) "ColorMode", (char *) NULL}, - { 0x0102, (char *) "MinoltaQuality", (char *) NULL}, - { 0x0103, (char *) "MinoltaImageSize", (char *) NULL}, - { 0x0104, (char *) "FlashExposureComp", (char *) NULL}, - { 0x0105, (char *) "Teleconverter", (char *) NULL}, - { 0x0107, (char *) "ImageStabilization", (char *) NULL}, - { 0x0109, (char *) "RawAndJpgRecording", (char *) NULL}, - { 0x010A, (char *) "ZoneMatching", (char *) NULL}, - { 0x010B, (char *) "ColorTemperature", (char *) NULL}, - { 0x010C, (char *) "LensType", (char *) NULL}, - { 0x0111, (char *) "ColorCompensationFilter", (char *) NULL}, - { 0x0112, (char *) "WhiteBalanceFineTune", (char *) NULL}, - { 0x0113, (char *) "ImageStabilization", (char *) NULL}, - { 0x0114, (char *) "MinoltaCameraSettings5D", (char *) NULL}, - { 0x0115, (char *) "WhiteBalance", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x0F00, (char *) "MinoltaCameraSettings2", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -There are 3 formats of Nikon's MakerNote. MakerNote of E700/E800/E900/E900S/E910/E950 -starts from ASCII string "Nikon". Data format is the same as IFD, but it starts from -offset 0x08. This is the same as Olympus except start string. -*/ - -/** -TYPE 1 is for E-Series cameras prior to (not including) E990 -*/ -static TagInfo - exif_nikon_type1_tag_table[] = - { - { 0x0002, (char *) "FamilyID", (char *) NULL}, - { 0x0003, (char *) "Quality", (char *) NULL}, - { 0x0004, (char *) "ColorMode", (char *) NULL}, - { 0x0005, (char *) "ImageAdjustment", (char *) NULL}, - { 0x0006, (char *) "CCDSensitivity", (char *) NULL}, - { 0x0007, (char *) "WhiteBalance", (char *) NULL}, - { 0x0008, (char *) "Focus", (char *) NULL}, - { 0x000A, (char *) "DigitalZoom", (char *) NULL}, - { 0x000B, (char *) "FisheyeConverter", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Nikon type 2 maker note -*/ -static TagInfo - exif_nikon_type2_tag_table[] = - { - { 0x0001, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x0002, (char *) "ISO", (char *) NULL}, - { 0x0003, (char *) "ColorMode", (char *) NULL}, - { 0x0004, (char *) "Quality", (char *) NULL}, - { 0x0005, (char *) "WhiteBalance", (char *) NULL}, - { 0x0006, (char *) "Sharpness", (char *) NULL}, - { 0x0007, (char *) "FocusMode", (char *) NULL}, - { 0x0008, (char *) "FlashSetting", (char *) NULL}, - { 0x0009, (char *) "FlashType", (char *) NULL}, - { 0x000B, (char *) "WhiteBalanceFineTune", (char *) NULL}, - { 0x000F, (char *) "ISOSelection", (char *) NULL}, - { 0x0010, (char *) "DataDump", (char *) NULL}, - { 0x0080, (char *) "ImageAdjustment", (char *) NULL}, - { 0x0082, (char *) "AuxiliaryLens", (char *) NULL}, - { 0x0085, (char *) "ManualFocusDistance", (char *) NULL}, - { 0x0086, (char *) "DigitalZoom", (char *) NULL}, - { 0x0088, (char *) "AFInfo", (char *) NULL}, - { 0x0089, (char *) "ShootingMode", (char *) NULL}, - { 0x008D, (char *) "ColorMode", (char *) NULL}, - { 0x008F, (char *) "SceneMode", (char *) NULL}, - { 0x0092, (char *) "HueAdjustment", (char *) NULL}, - { 0x0094, (char *) "Saturation", (char *) NULL}, - { 0x0095, (char *) "NoiseReduction", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -The type-3 directory is for D-Series cameras such as the D1 and D100. -see http://www.timelesswanderings.net/equipment/D100/NEF.html -*/ -static TagInfo - exif_nikon_type3_tag_table[] = - { - { 0x0001, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x0002, (char *) "ISO", (char *) NULL}, - { 0x0003, (char *) "ColorMode", (char *) NULL}, - { 0x0004, (char *) "Quality", (char *) NULL}, - { 0x0005, (char *) "WhiteBalance", (char *) NULL}, - { 0x0006, (char *) "Sharpness", (char *) NULL}, - { 0x0007, (char *) "FocusMode", (char *) NULL}, - { 0x0008, (char *) "FlashSetting", (char *) NULL}, - { 0x0009, (char *) "FlashType", (char *) NULL}, - { 0x000B, (char *) "WhiteBalanceFineTune", (char *) NULL}, - { 0x000C, (char *) "WB_RBLevels", (char *) NULL}, - { 0x000D, (char *) "ProgramShift", (char *) NULL}, - { 0x000E, (char *) "ExposureDifference", (char *) NULL}, - { 0x000F, (char *) "ISOSelection", (char *) NULL}, - { 0x0010, (char *) "DataDump", (char *) NULL}, - { 0x0011, (char *) "PreviewIFD", (char *) NULL}, - { 0x0012, (char *) "FlashExposureComp", (char *) NULL}, - { 0x0013, (char *) "ISOSetting", (char *) NULL}, - { 0x0014, (char *) "ColorBalanceA", (char *) NULL}, - { 0x0016, (char *) "ImageBoundary", (char *) NULL}, - { 0x0017, (char *) "FlashExposureComp", (char *) NULL}, - { 0x0018, (char *) "FlashExposureBracketValue", (char *) NULL}, - { 0x0019, (char *) "ExposureBracketValue", (char *) NULL}, - { 0x001A, (char *) "ImageProcessing", (char *) NULL}, - { 0x001B, (char *) "CropHiSpeed", (char *) NULL}, - { 0x001C, (char *) "ExposureTuning", (char *) NULL}, - { 0x001D, (char *) "SerialNumber", (char *) NULL}, - { 0x001E, (char *) "ColorSpace", (char *) NULL}, - { 0x001F, (char *) "VRInfo", (char *) NULL}, - { 0x0020, (char *) "ImageAuthentication", (char *) NULL}, - { 0x0022, (char *) "ActiveD-Lighting", (char *) NULL}, - { 0x0023, (char *) "PictureControl", (char *) NULL}, - { 0x0024, (char *) "WorldTime", (char *) NULL}, - { 0x0025, (char *) "ISOInfo", (char *) NULL}, - { 0x002A, (char *) "VignetteControl", (char *) NULL}, - { 0x002B, (char *) "DistortInfo", (char *) NULL}, - { 0x0080, (char *) "ImageAdjustment", (char *) NULL}, - { 0x0081, (char *) "ToneComp", (char *) NULL}, - { 0x0082, (char *) "AuxiliaryLens", (char *) NULL}, - { 0x0083, (char *) "LensType", (char *) NULL}, - { 0x0084, (char *) "Lens", (char *) NULL}, - { 0x0085, (char *) "ManualFocusDistance", (char *) NULL}, - { 0x0086, (char *) "DigitalZoom", (char *) NULL}, - { 0x0087, (char *) "FlashMode", (char *) NULL}, - { 0x0088, (char *) "AFInfo", (char *) NULL}, - { 0x0089, (char *) "ShootingMode", (char *) NULL}, - { 0x008B, (char *) "LensFStops", (char *) NULL}, - { 0x008C, (char *) "ContrastCurve", (char *) NULL}, - { 0x008D, (char *) "ColorHue", (char *) NULL}, - { 0x008F, (char *) "SceneMode", (char *) NULL}, - { 0x0090, (char *) "LightSource", (char *) NULL}, - { 0x0091, (char *) "ShotInfo", (char *) NULL}, - { 0x0092, (char *) "HueAdjustment", (char *) NULL}, - { 0x0093, (char *) "NEFCompression", (char *) NULL}, - { 0x0094, (char *) "Saturation", (char *) NULL}, - { 0x0095, (char *) "NoiseReduction", (char *) NULL}, - { 0x0096, (char *) "LinearizationTable", (char *) NULL}, - { 0x0097, (char *) "ColorBalance", (char *) NULL}, - { 0x0098, (char *) "LensData", (char *) NULL}, - { 0x0099, (char *) "RawImageCenter", (char *) NULL}, - { 0x009A, (char *) "SensorPixelSize", (char *) NULL}, - { 0x009C, (char *) "SceneAssist", (char *) NULL}, - { 0x009E, (char *) "RetouchHistory", (char *) NULL}, - { 0x00A0, (char *) "SerialNumber", (char *) NULL}, - { 0x00A2, (char *) "ImageDataSize", (char *) NULL}, - { 0x00A5, (char *) "ImageCount", (char *) NULL}, - { 0x00A6, (char *) "DeletedImageCount", (char *) NULL}, - { 0x00A7, (char *) "ShutterCount", (char *) NULL}, - { 0x00A8, (char *) "FlashInfo", (char *) NULL}, - { 0x00A9, (char *) "ImageOptimization", (char *) NULL}, - { 0x00AA, (char *) "Saturation", (char *) NULL}, - { 0x00AB, (char *) "VariProgram", (char *) NULL}, - { 0x00AC, (char *) "ImageStabilization", (char *) NULL}, - { 0x00AD, (char *) "AFResponse", (char *) NULL}, - { 0x00B0, (char *) "MultiExposure", (char *) NULL}, - { 0x00B1, (char *) "HighISONoiseReduction", (char *) NULL}, - { 0x00B3, (char *) "ToningEffect", (char *) NULL}, - { 0x00B6, (char *) "PowerUpTime", (char *) NULL}, - { 0x00B7, (char *) "AFInfo2", (char *) NULL}, - { 0x00B8, (char *) "FileInfo", (char *) NULL}, - { 0x00B9, (char *) "AFTune", (char *) NULL}, - { 0x00BD, (char *) "PictureControl", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x0E01, (char *) "NikonCaptureData", (char *) NULL}, - { 0x0E09, (char *) "NikonCaptureVersion", (char *) NULL}, - { 0x0E0E, (char *) "NikonCaptureOffsets", (char *) NULL}, - { 0x0E10, (char *) "NikonScanIFD", (char *) NULL}, - { 0x0E1D, (char *) "NikonICCProfile", (char *) NULL}, - { 0x0E1E, (char *) "NikonCaptureOutput", (char *) NULL}, - { 0x0E22, (char *) "NEFBitDepth", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Panasonic / Leica maker note -*/ -static TagInfo - exif_panasonic_tag_table[] = - { - { 0x0001, (char *) "ImageQuality", (char *) NULL}, - { 0x0002, (char *) "FirmwareVersion", (char *) NULL}, - { 0x0003, (char *) "WhiteBalance", (char *) NULL}, - { 0x0007, (char *) "FocusMode", (char *) NULL}, - { 0x000F, (char *) "AFAreaMode", (char *) NULL}, - { 0x001A, (char *) "ImageStabilization", (char *) NULL}, - { 0x001C, (char *) "MacroMode", (char *) NULL}, - { 0x001F, (char *) "ShootingMode", (char *) NULL}, - { 0x0020, (char *) "Audio", (char *) NULL}, - { 0x0021, (char *) "DataDump", (char *) NULL}, - { 0x0022, (char *) "EasyMode", (char *) NULL}, - { 0x0023, (char *) "WhiteBalanceBias", (char *) NULL}, - { 0x0024, (char *) "FlashBias", (char *) NULL}, - { 0x0025, (char *) "InternalSerialNumber", (char *) NULL}, - { 0x0026, (char *) "PanasonicExifVersion", (char *) NULL}, - { 0x0028, (char *) "ColorEffect", (char *) NULL}, - { 0x0029, (char *) "TimeSincePowerOn", (char *) NULL}, - { 0x002A, (char *) "BurstMode", (char *) NULL}, - { 0x002B, (char *) "SequenceNumber", (char *) NULL}, - { 0x002C, (char *) "ContrastMode", (char *) NULL}, - { 0x002D, (char *) "NoiseReduction", (char *) NULL}, - { 0x002E, (char *) "SelfTimer", (char *) NULL}, - { 0x0030, (char *) "Rotation", (char *) NULL}, - { 0x0031, (char *) "AFAssistLamp", (char *) NULL}, - { 0x0032, (char *) "ColorMode", (char *) NULL}, - { 0x0033, (char *) "BabyAge_0x0033", (char *) NULL}, - { 0x0034, (char *) "OpticalZoomMode", (char *) NULL}, - { 0x0035, (char *) "ConversionLens", (char *) NULL}, - { 0x0036, (char *) "TravelDay", (char *) NULL}, - { 0x0039, (char *) "Contrast", (char *) NULL}, - { 0x003A, (char *) "WorldTimeLocation", (char *) NULL}, - { 0x003B, (char *) "TextStamp_0x003B", (char *) NULL}, - { 0x003C, (char *) "ProgramISO", (char *) NULL}, - { 0x003D, (char *) "AdvancedSceneMode", (char *) NULL}, - { 0x003E, (char *) "TextStamp_0x003E", (char *) NULL}, - { 0x003F, (char *) "FacesDetected", (char *) NULL}, - { 0x0040, (char *) "Saturation", (char *) NULL}, - { 0x0041, (char *) "Sharpness", (char *) NULL}, - { 0x0042, (char *) "FilmMode", (char *) NULL}, - { 0x0046, (char *) "WBAdjustAB", (char *) NULL}, - { 0x0047, (char *) "WBAdjustGM", (char *) NULL}, - { 0x004B, (char *) "PanasonicImageWidth", (char *) NULL}, - { 0x004C, (char *) "PanasonicImageHeight", (char *) NULL}, - { 0x004D, (char *) "AFPointPosition", (char *) NULL}, - { 0x004E, (char *) "FaceDetInfo", (char *) "Panasonic FaceDetInfo Tags"}, - { 0x0051, (char *) "LensType", (char *) NULL}, - { 0x0052, (char *) "LensSerialNumber", (char *) NULL}, - { 0x0053, (char *) "AccessoryType", (char *) NULL}, - { 0x0059, (char *) "Transform", (char *) NULL}, - { 0x005D, (char *) "IntelligentExposure", (char *) NULL}, - { 0x0061, (char *) "FaceRecInfo", (char *) "Panasonic FaceRecInfo Tags"}, - { 0x0062, (char *) "FlashWarning", (char *) NULL}, - { 0x0063, (char *) "RecognizedFaceFlags?", (char *) NULL}, - { 0x0065, (char *) "Title", (char *) NULL}, - { 0x0066, (char *) "BabyName", (char *) NULL}, - { 0x0067, (char *) "Location", (char *) NULL}, - { 0x0069, (char *) "Country", (char *) NULL}, - { 0x006B, (char *) "State", (char *) NULL}, - { 0x006D, (char *) "City", (char *) NULL}, - { 0x006F, (char *) "Landmark", (char *) NULL}, - { 0x0070, (char *) "IntelligentResolution", (char *) NULL}, - { 0x0079, (char *) "IntelligentD-Range", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x8000, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x8001, (char *) "SceneMode", (char *) NULL}, - { 0x8004, (char *) "WBRedLevel", (char *) NULL}, - { 0x8005, (char *) "WBGreenLevel", (char *) NULL}, - { 0x8006, (char *) "WBBlueLevel", (char *) NULL}, - { 0x8007, (char *) "FlashFired", (char *) NULL}, - { 0x8008, (char *) "TextStamp_0x8008", (char *) NULL}, - { 0x8009, (char *) "TextStamp_0x8009", (char *) NULL}, - { 0x8010, (char *) "BabyAge_0x8010", (char *) NULL}, - { 0x8012, (char *) "Transform", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Pentax (Asahi) maker note type 1 -*/ -static TagInfo - exif_asahi_tag_table[] = - { - { 0x0001, (char *) "Capture Mode", (char *) NULL}, - { 0x0002, (char *) "Quality Level", (char *) NULL}, - { 0x0003, (char *) "Focus Mode", (char *) NULL}, - { 0x0004, (char *) "Flash Mode", (char *) NULL}, - { 0x0007, (char *) "White Balance", (char *) NULL}, - { 0x000A, (char *) "Digital Zoom", (char *) NULL}, - { 0x000B, (char *) "Sharpness", (char *) NULL}, - { 0x000C, (char *) "Contrast", (char *) NULL}, - { 0x000D, (char *) "Saturation", (char *) NULL}, - { 0x0014, (char *) "ISO Speed", (char *) NULL}, - { 0x0017, (char *) "Color", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x1000, (char *) "Time Zone", (char *) NULL}, - { 0x1001, (char *) "Daylight Savings", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Pentax maker note type 2 -*/ -static TagInfo - exif_pentax_tag_table[] = - { - { 0x0000, (char *) "PentaxVersion", (char *) NULL}, - { 0x0001, (char *) "PentaxMode", (char *) NULL}, - { 0x0002, (char *) "PreviewImageSize", (char *) NULL}, - { 0x0003, (char *) "PreviewImageLength", (char *) NULL}, - { 0x0004, (char *) "PreviewImageStart", (char *) NULL}, - { 0x0005, (char *) "PentaxModelID", (char *) "Pentax PentaxModelID Values"}, - { 0x0006, (char *) "Date", (char *) NULL}, - { 0x0007, (char *) "Time", (char *) NULL}, - { 0x0008, (char *) "Quality", (char *) NULL}, - { 0x0009, (char *) "PentaxImageSize", (char *) NULL}, - { 0x000B, (char *) "PictureMode", (char *) NULL}, - { 0x000C, (char *) "FlashMode", (char *) NULL}, - { 0x000D, (char *) "FocusMode", (char *) NULL}, - { 0x000E, (char *) "AFPointSelected", (char *) NULL}, - { 0x000F, (char *) "AFPointsInFocus", (char *) NULL}, - { 0x0010, (char *) "FocusPosition", (char *) NULL}, - { 0x0012, (char *) "ExposureTime", (char *) NULL}, - { 0x0013, (char *) "FNumber", (char *) NULL}, - { 0x0014, (char *) "ISO", (char *) NULL}, - { 0x0015, (char *) "LightReading", (char *) NULL}, - { 0x0016, (char *) "ExposureCompensation", (char *) NULL}, - { 0x0017, (char *) "MeteringMode", (char *) NULL}, - { 0x0018, (char *) "AutoBracketing", (char *) NULL}, - { 0x0019, (char *) "WhiteBalance", (char *) NULL}, - { 0x001A, (char *) "WhiteBalanceMode", (char *) NULL}, - { 0x001B, (char *) "BlueBalance", (char *) NULL}, - { 0x001C, (char *) "RedBalance", (char *) NULL}, - { 0x001D, (char *) "FocalLength", (char *) NULL}, - { 0x001E, (char *) "DigitalZoom", (char *) NULL}, - { 0x001F, (char *) "Saturation", (char *) NULL}, - { 0x0020, (char *) "Contrast", (char *) NULL}, - { 0x0021, (char *) "Sharpness", (char *) NULL}, - { 0x0022, (char *) "WorldTimeLocation", (char *) NULL}, - { 0x0023, (char *) "HometownCity", (char *) "Pentax City Values"}, - { 0x0024, (char *) "DestinationCity", (char *) "Pentax City Values"}, - { 0x0025, (char *) "HometownDST", (char *) NULL}, - { 0x0026, (char *) "DestinationDST", (char *) NULL}, - { 0x0027, (char *) "DSPFirmwareVersion", (char *) NULL}, - { 0x0028, (char *) "CPUFirmwareVersion", (char *) NULL}, - { 0x0029, (char *) "FrameNumber", (char *) NULL}, - { 0x002D, (char *) "EffectiveLV", (char *) NULL}, - { 0x0032, (char *) "ImageProcessing", (char *) NULL}, - { 0x0033, (char *) "PictureMode", (char *) NULL}, - { 0x0034, (char *) "DriveMode", (char *) NULL}, - { 0x0035, (char *) "SensorSize", (char *) NULL}, - { 0x0037, (char *) "ColorSpace", (char *) NULL}, - { 0x0039, (char *) "RawImageSize", (char *) NULL}, - { 0x003C, (char *) "AFPointsInFocus", (char *) NULL}, - { 0x003E, (char *) "PreviewImageBorders", (char *) NULL}, - { 0x003F, (char *) "LensType", (char *) "Pentax LensType Values"}, - { 0x0040, (char *) "SensitivityAdjust", (char *) NULL}, - { 0x0041, (char *) "ImageProcessingCount", (char *) NULL}, - { 0x0047, (char *) "CameraTemperature", (char *) NULL}, - { 0x0048, (char *) "AELock", (char *) NULL}, - { 0x0049, (char *) "NoiseReduction", (char *) NULL}, - { 0x004D, (char *) "FlashExposureComp", (char *) NULL}, - { 0x004F, (char *) "ImageTone", (char *) NULL}, - { 0x0050, (char *) "ColorTemperature", (char *) NULL}, - { 0x005C, (char *) "ShakeReductionInfo", (char *) "Pentax SRInfo Tags"}, - { 0x005D, (char *) "ShutterCount", (char *) NULL}, - { 0x0060, (char *) "FaceInfo", (char *) "Pentax FaceInfo Tags"}, - { 0x0067, (char *) "Hue", (char *) NULL}, - { 0x0068, (char *) "AWBInfo", (char *) "Pentax AWBInfo Tags"}, - { 0x0069, (char *) "DynamicRangeExpansion", (char *) NULL}, - { 0x006B, (char *) "TimeInfo", (char *) "Pentax TimeInfo Tags"}, - { 0x006C, (char *) "HighLowKeyAdj", (char *) NULL}, - { 0x006D, (char *) "ContrastHighlight", (char *) NULL}, - { 0x006E, (char *) "ContrastShadow", (char *) NULL}, - { 0x006F, (char *) "ContrastHighlightShadowAdj", (char *) NULL}, - { 0x0070, (char *) "FineSharpness", (char *) NULL}, - { 0x0071, (char *) "HighISONoiseReduction", (char *) NULL}, - { 0x0072, (char *) "AFAdjustment", (char *) NULL}, - { 0x0073, (char *) "MonochromeFilterEffect", (char *) NULL}, - { 0x0074, (char *) "MonochromeToning", (char *) NULL}, - { 0x0076, (char *) "FaceDetect", (char *) NULL}, - { 0x0077, (char *) "FaceDetectFrameSize", (char *) NULL}, - { 0x0079, (char *) "ShadowCompensation", (char *) NULL}, - { 0x007A, (char *) "ISOAutoParameters", (char *) NULL}, - { 0x007B, (char *) "CrossProcess", (char *) NULL}, - { 0x007D, (char *) "LensCorr", (char *) "Pentax LensCorr Tags"}, - { 0x007F, (char *) "BleachBypassToning", (char *) NULL}, - { 0x0200, (char *) "BlackPoint", (char *) NULL}, - { 0x0201, (char *) "WhitePoint", (char *) NULL}, - { 0x0203, (char *) "ColorMatrixA", (char *) NULL}, - { 0x0204, (char *) "ColorMatrixB", (char *) NULL}, - { 0x0205, (char *) "CameraSettings", (char *) "Pentax CameraSettings Tags"}, - { 0x0206, (char *) "AEInfo", (char *) "Pentax AEInfo Tags"}, - { 0x0207, (char *) "LensInfo", (char *) "Pentax LensInfo Tags"}, - { 0x0208, (char *) "FlashInfo", (char *) "Pentax FlashInfo Tags"}, - { 0x0209, (char *) "AEMeteringSegments", (char *) NULL}, - { 0x020A, (char *) "FlashMeteringSegments", (char *) NULL}, - { 0x020B, (char *) "SlaveFlashMeteringSegments", (char *) NULL}, - { 0x020D, (char *) "WB_RGGBLevelsDaylight", (char *) NULL}, - { 0x020E, (char *) "WB_RGGBLevelsShade", (char *) NULL}, - { 0x020F, (char *) "WB_RGGBLevelsCloudy", (char *) NULL}, - { 0x0210, (char *) "WB_RGGBLevelsTungsten", (char *) NULL}, - { 0x0211, (char *) "WB_RGGBLevelsFluorescentD", (char *) NULL}, - { 0x0212, (char *) "WB_RGGBLevelsFluorescentN", (char *) NULL}, - { 0x0213, (char *) "WB_RGGBLevelsFluorescentW", (char *) NULL}, - { 0x0214, (char *) "WB_RGGBLevelsFlash", (char *) NULL}, - { 0x0215, (char *) "CameraInfo", (char *) "Pentax CameraInfo Tags"}, - { 0x0216, (char *) "BatteryInfo", (char *) "Pentax BatteryInfo Tags"}, - { 0x021B, (char *) "SaturationInfo", (char *) NULL}, - { 0x021F, (char *) "AFInfo", (char *) "Pentax AFInfo Tags"}, - { 0x0222, (char *) "ColorInfo", (char *) "Pentax ColorInfo Tags"}, - { 0x0224, (char *) "EVStepInfo", (char *) "Pentax EVStepInfo Tags"}, - { 0x0226, (char *) "ShotInfo", (char *) "Pentax ShotInfo Tags"}, - { 0x0227, (char *) "FacePos", (char *) "Pentax FacePos Tags"}, - { 0x0228, (char *) "FaceSize", (char *) "Pentax FaceSize Tags"}, - { 0x0229, (char *) "SerialNumber", (char *) NULL}, - { 0x022A, (char *) "FilterInfo", (char *) "Pentax FilterInfo Tags"}, - { 0x022B, (char *) "LevelInfo", (char *) "Pentax LevelInfo Tags"}, - { 0x022E, (char *) "Artist", (char *) NULL}, - { 0x022F, (char *) "Copyright", (char *) NULL}, - { 0x0230, (char *) "FirmwareVersion", (char *) NULL}, - { 0x0231, (char *) "ContrastDetectAFArea", (char *) NULL}, - { 0x0235, (char *) "CrossProcessParams", (char *) NULL}, - { 0x03FE, (char *) "DataDump", (char *) NULL}, - { 0x0402, (char *) "ToneCurve", (char *) NULL}, - { 0x0403, (char *) "ToneCurves", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x1000, (char *) "HometownCityCode", (char *) NULL}, - { 0x1001, (char *) "DestinationCityCode", (char *) NULL}, - { 0x2000, (char *) "PreviewImageData", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Sony maker note -*/ -static TagInfo - exif_sony_tag_table[] = - { - { 0x0102, (char *) "Quality", (char *) NULL}, - { 0x0104, (char *) "FlashExposureComp", (char *) NULL}, - { 0x0105, (char *) "Teleconverter", (char *) NULL}, - { 0x0112, (char *) "WhiteBalanceFineTune", (char *) NULL}, - { 0x0114, (char *) "CameraSettings", (char *) NULL}, - { 0x0115, (char *) "WhiteBalance", (char *) NULL}, - { 0x0E00, (char *) "PrintIM", (char *) NULL}, - { 0x1000, (char *) "MultiBurstMode", (char *) NULL}, - { 0x1001, (char *) "MultiBurstImageWidth", (char *) NULL}, - { 0x1002, (char *) "MultiBurstImageHeight", (char *) NULL}, - { 0x1003, (char *) "Panorama", (char *) NULL}, - { 0x2001, (char *) "PreviewImage", (char *) NULL}, - { 0x2004, (char *) "Contrast", (char *) NULL}, - { 0x2005, (char *) "Saturation", (char *) NULL}, - { 0x2006, (char *) "Sharpness", (char *) NULL}, - { 0x2007, (char *) "Brightness", (char *) NULL}, - { 0x2008, (char *) "LongExposureNoiseReduction", (char *) NULL}, - { 0x2009, (char *) "HighISONoiseReduction", (char *) NULL}, - { 0x200A, (char *) "HDR", (char *) NULL}, - { 0x200B, (char *) "MultiFrameNoiseReduction", (char *) NULL}, - { 0x3000, (char *) "ShotInfo", (char *) NULL}, - { 0xB000, (char *) "FileFormat", (char *) NULL}, - { 0xB001, (char *) "SonyModelID", (char *) NULL}, - { 0xB020, (char *) "ColorReproduction", (char *) NULL}, - { 0xB021, (char *) "ColorTemperature", (char *) NULL}, - { 0xB022, (char *) "ColorCompensationFilter", (char *) NULL}, - { 0xB023, (char *) "SceneMode", (char *) NULL}, - { 0xB024, (char *) "ZoneMatching", (char *) NULL}, - { 0xB025, (char *) "DynamicRangeOptimizer", (char *) NULL}, - { 0xB026, (char *) "ImageStabilization", (char *) NULL}, - { 0xB027, (char *) "LensType", (char *) NULL}, - { 0xB028, (char *) "MinoltaMakerNote", (char *) NULL}, - { 0xB029, (char *) "ColorMode", (char *) NULL}, - { 0xB02B, (char *) "FullImageSize", (char *) NULL}, - { 0xB02C, (char *) "PreviewImageSize", (char *) NULL}, - { 0xB040, (char *) "Macro", (char *) NULL}, - { 0xB041, (char *) "ExposureMode", (char *) NULL}, - { 0xB042, (char *) "FocusMode", (char *) NULL}, - { 0xB043, (char *) "AFMode", (char *) NULL}, - { 0xB044, (char *) "AFIlluminator", (char *) NULL}, - { 0xB047, (char *) "Quality2", (char *) NULL}, - { 0xB048, (char *) "FlashLevel", (char *) NULL}, - { 0xB049, (char *) "ReleaseMode", (char *) NULL}, - { 0xB04A, (char *) "SequenceNumber", (char *) NULL}, - { 0xB04B, (char *) "Anti-Blur", (char *) NULL}, - { 0xB04E, (char *) "LongExposureNoiseReduction", (char *) NULL}, - { 0xB04F, (char *) "DynamicRangeOptimizer", (char *) NULL}, - { 0xB052, (char *) "IntelligentAuto", (char *) NULL}, - { 0xB054, (char *) "WhiteBalance2", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Sigma SD1 maker note -*/ -static TagInfo - exif_sigma_sd1_tag_table[] = - { - { 0x0002, (char *) "SerialNumber", (char *) NULL}, - { 0x0003, (char *) "DriveMode", (char *) NULL}, - { 0x0004, (char *) "ResolutionMode", (char *) NULL}, - { 0x0005, (char *) "AFMode", (char *) NULL}, - { 0x0006, (char *) "FocusSetting", (char *) NULL}, - { 0x0007, (char *) "WhiteBalance", (char *) NULL}, - { 0x0008, (char *) "ExposureMode", (char *) NULL}, - { 0x0009, (char *) "MeteringMode", (char *) NULL}, - { 0x000A, (char *) "LensFocalRange", (char *) NULL}, - { 0x000B, (char *) "ColorSpace", (char *) NULL}, - { 0x000C, (char *) "ExposureCompensation", (char *) NULL}, - { 0x000D, (char *) "Contrast", (char *) NULL}, - { 0x000E, (char *) "Shadow", (char *) NULL}, - { 0x000F, (char *) "Highlight", (char *) NULL}, - { 0x0010, (char *) "Saturation", (char *) NULL}, - { 0x0011, (char *) "Sharpness", (char *) NULL}, - { 0x0012, (char *) "X3FillLight", (char *) NULL}, - { 0x0014, (char *) "ColorAdjustment", (char *) NULL}, - { 0x0015, (char *) "AdjustmentMode", (char *) NULL}, - { 0x0016, (char *) "Quality", (char *) NULL}, - { 0x0017, (char *) "Firmware", (char *) NULL}, - { 0x0018, (char *) "Software", (char *) NULL}, - { 0x0019, (char *) "AutoBracket", (char *) NULL}, - { 0x001A, (char *) "ChrominanceNoiseReduction", (char *) NULL}, - { 0x001B, (char *) "LuminanceNoiseReduction", (char *) NULL}, - { 0x001C, (char *) "PreviewImageStart", (char *) NULL}, - { 0x001D, (char *) "PreviewImageLength", (char *) NULL}, - { 0x001F, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x0026, (char *) "FileFormat", (char *) NULL}, - { 0x002C, (char *) "ColorMode", (char *) NULL}, - { 0x0030, (char *) "Calibration", (char *) NULL}, - { 0x0048, (char *) "LensApertureRange", (char *) NULL}, - { 0x0049, (char *) "FNumber", (char *) NULL}, - { 0x004A, (char *) "ExposureTime", (char *) NULL}, - { 0x004B, (char *) "ExposureTime2", (char *) NULL}, - { 0x004D, (char *) "ExposureCompensation_SD1", (char *) NULL}, - { 0x0055, (char *) "SensorTemperature", (char *) NULL}, - { 0x0056, (char *) "FlashExposureComp", (char *) NULL}, - { 0x0057, (char *) "Firmware_SD1", (char *) NULL}, - { 0x0058, (char *) "WhiteBalance", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -/** -Sigma / Foveon maker note (others than SD1 models) -NB: many tags are not consistent between different models -*/ -static TagInfo - exif_sigma_foveon_tag_table[] = - { - { 0x0002, (char *) "SerialNumber", (char *) NULL}, - { 0x0003, (char *) "DriveMode", (char *) NULL}, - { 0x0004, (char *) "ResolutionMode", (char *) NULL}, - { 0x0005, (char *) "AFMode", (char *) NULL}, - { 0x0006, (char *) "FocusSetting", (char *) NULL}, - { 0x0007, (char *) "WhiteBalance", (char *) NULL}, - { 0x0008, (char *) "ExposureMode", (char *) NULL}, - { 0x0009, (char *) "MeteringMode", (char *) NULL}, - { 0x000A, (char *) "LensFocalRange", (char *) NULL}, - { 0x000B, (char *) "ColorSpace", (char *) NULL}, - { 0x000C, (char *) "ExposureCompensation", (char *) NULL}, - { 0x000D, (char *) "Contrast", (char *) NULL}, - { 0x000E, (char *) "Shadow", (char *) NULL}, - { 0x000F, (char *) "Highlight", (char *) NULL}, - { 0x0010, (char *) "Saturation", (char *) NULL}, - { 0x0011, (char *) "Sharpness", (char *) NULL}, - { 0x0012, (char *) "X3FillLight", (char *) NULL}, - { 0x0014, (char *) "ColorAdjustment", (char *) NULL}, - { 0x0015, (char *) "AdjustmentMode", (char *) NULL}, - { 0x0016, (char *) "Quality", (char *) NULL}, - { 0x0017, (char *) "Firmware", (char *) NULL}, - { 0x0018, (char *) "Software", (char *) NULL}, - { 0x0019, (char *) "AutoBracket", (char *) NULL}, - { 0x001A, (char *) "PreviewImageStart", (char *) NULL}, - { 0x001B, (char *) "PreviewImageLength", (char *) NULL}, - { 0x001C, (char *) "PreviewImageSize", (char *) NULL}, - { 0x001D, (char *) "MakerNoteVersion", (char *) NULL}, - { 0x001F, (char *) "AFPoint", (char *) NULL}, - { 0x0022, (char *) "FileFormat", (char *) NULL}, - { 0x0024, (char *) "Calibration", (char *) NULL}, - { 0x002C, (char *) "ColorMode", (char *) NULL}, - { 0x0030, (char *) "LensApertureRange", (char *) NULL}, - { 0x0031, (char *) "FNumber", (char *) NULL}, - { 0x0032, (char *) "ExposureTime", (char *) NULL}, - { 0x0033, (char *) "ExposureTime2", (char *) NULL}, - { 0x0034, (char *) "BurstShot", (char *) NULL}, - { 0x0035, (char *) "ExposureCompensation", (char *) NULL}, - { 0x0039, (char *) "SensorTemperature", (char *) NULL}, - { 0x003A, (char *) "FlashExposureComp", (char *) NULL}, - { 0x003B, (char *) "Firmware", (char *) NULL}, - { 0x003C, (char *) "WhiteBalance", (char *) NULL}, - { 0x003D, (char *) "PictureMode", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// IPTC tags definition -// -------------------------------------------------------------------------- - -static TagInfo - iptc_tag_table[] = - { - // IPTC-NAA IIM version 4 - { 0x0200 + 0, (char *) "ApplicationRecordVersion", (char *) "Application Record Version"}, - { 0x0200 + 3, (char *) "ObjectTypeReference", (char *) "Object Type Reference"}, - { 0x0200 + 4, (char *) "ObjectAttributeReference", (char *) "Object Attribute Reference"}, - { 0x0200 + 5, (char *) "ObjectName", (char *) "Title"}, - { 0x0200 + 7, (char *) "EditStatus", (char *) "Edit Status"}, - { 0x0200 + 8, (char *) "EditorialUpdate", (char *) "Editorial Update"}, - { 0x0200 + 10, (char *) "Urgency", (char *) "Urgency"}, - { 0x0200 + 12, (char *) "SubjectReference", (char *) "Subject Reference"}, - { 0x0200 + 15, (char *) "Category", (char *) "Category"}, - { 0x0200 + 20, (char *) "SupplementalCategories", (char *) "Supplemental Categories"}, - { 0x0200 + 22, (char *) "FixtureIdentifier", (char *) "Fixture Identifier"}, - { 0x0200 + 25, (char *) "Keywords", (char *) "Keywords"}, - { 0x0200 + 26, (char *) "ContentLocationCode", (char *) "Content Location Code"}, - { 0x0200 + 27, (char *) "ContentLocationName", (char *) "Content Location Name"}, - { 0x0200 + 30, (char *) "ReleaseDate", (char *) "Release Date"}, - { 0x0200 + 35, (char *) "ReleaseTime", (char *) "Release Time"}, - { 0x0200 + 37, (char *) "ExpirationDate", (char *) "Expiration Date"}, - { 0x0200 + 38, (char *) "ExpirationTime", (char *) "Expiration Time"}, - { 0x0200 + 40, (char *) "SpecialInstructions", (char *) "Instructions"}, - { 0x0200 + 42, (char *) "ActionAdvised", (char *) "Action Advised"}, - { 0x0200 + 45, (char *) "ReferenceService", (char *) "Reference Service"}, - { 0x0200 + 47, (char *) "ReferenceDate", (char *) "Reference Date"}, - { 0x0200 + 50, (char *) "ReferenceNumber", (char *) "Reference Number"}, - { 0x0200 + 55, (char *) "DateCreated", (char *) "Date Created"}, - { 0x0200 + 60, (char *) "TimeCreated", (char *) "Time Created"}, - { 0x0200 + 62, (char *) "DigitalCreationDate", (char *) "Digital Creation Date"}, - { 0x0200 + 63, (char *) "DigitalCreationTime", (char *) "Digital Creation Time"}, - { 0x0200 + 65, (char *) "OriginatingProgram", (char *) "Originating Program"}, - { 0x0200 + 70, (char *) "ProgramVersion", (char *) "Program Version"}, - { 0x0200 + 75, (char *) "ObjectCycle", (char *) "Object Cycle"}, - { 0x0200 + 80, (char *) "By-line", (char *) "Author"}, - { 0x0200 + 85, (char *) "By-lineTitle", (char *) "Author's Position"}, - { 0x0200 + 90, (char *) "City", (char *) "City"}, - { 0x0200 + 92, (char *) "SubLocation", (char *) "Sub-Location"}, - { 0x0200 + 95, (char *) "Province-State", (char *) "State/Province"}, - { 0x0200 + 100, (char *) "Country-PrimaryLocationCode", (char *) "Country Code"}, - { 0x0200 + 101, (char *) "Country-PrimaryLocationName", (char *) "Country Name"}, - { 0x0200 + 103, (char *) "OriginalTransmissionReference", (char *) "Transmission Reference"}, - { 0x0200 + 105, (char *) "Headline", (char *) "Headline"}, - { 0x0200 + 110, (char *) "Credit", (char *) "Credit"}, - { 0x0200 + 115, (char *) "Source", (char *) "Source"}, - { 0x0200 + 116, (char *) "CopyrightNotice", (char *) "Copyright Notice"}, - { 0x0200 + 118, (char *) "Contact", (char *) "Contact"}, - { 0x0200 + 120, (char *) "Caption-Abstract", (char *) "Caption"}, - { 0x0200 + 122, (char *) "Writer-Editor", (char *) "Caption Writer"}, - { 0x0200 + 125, (char *) "RasterizedCaption", (char *) "Rasterized Caption"}, - { 0x0200 + 130, (char *) "ImageType", (char *) "Image Type"}, - { 0x0200 + 131, (char *) "ImageOrientation", (char *) "Image Orientation"}, - { 0x0200 + 135, (char *) "LanguageIdentifier", (char *) "Language Identifier"}, - { 0x0200 + 150, (char *) "AudioType", (char *) "Audio Type"}, - { 0x0200 + 151, (char *) "AudioSamplingRate", (char *) "Audio Sampling Rate"}, - { 0x0200 + 152, (char *) "AudioSamplingResolution", (char *) "Audio Sampling Resolution"}, - { 0x0200 + 153, (char *) "AudioDuration", (char *) "Audio Duration"}, - { 0x0200 + 154, (char *) "AudioOutcue", (char *) "Audio Outcue"}, - // Metadata seen in other softwares (see also http://owl.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html#ApplicationRecord) - { 0x0200 + 184, (char *) "JobID", (char *) "Job ID"}, - { 0x0200 + 185, (char *) "MasterDocumentID", (char *) "Master Document ID"}, - { 0x0200 + 186, (char *) "ShortDocumentID", (char *) "Short Document ID"}, - { 0x0200 + 187, (char *) "UniqueDocumentID", (char *) "Unique Document ID"}, - { 0x0200 + 188, (char *) "OwnerID", (char *) "Owner ID"}, - // IPTC-NAA IIM version 4 - { 0x0200 + 200, (char *) "ObjectPreviewFileFormat", (char *) "Object Preview File Format"}, - { 0x0200 + 201, (char *) "ObjectPreviewFileVersion", (char *) "Object Preview File Version"}, - { 0x0200 + 202, (char *) "ObjectPreviewData", (char *) "Audio Outcue"}, - // Metadata seen in other softwares (see also http://owl.phy.queensu.ca/~phil/exiftool/TagNames/IPTC.html#ApplicationRecord) - { 0x0200 + 221, (char *) "Prefs", (char *) "PhotoMechanic preferences"}, - { 0x0200 + 225, (char *) "ClassifyState", (char *) "Classify State"}, - { 0x0200 + 228, (char *) "SimilarityIndex", (char *) "Similarity Index"}, - { 0x0200 + 230, (char *) "DocumentNotes", (char *) "Document Notes"}, - { 0x0200 + 231, (char *) "DocumentHistory", (char *) "Document History"}, - { 0x0200 + 232, (char *) "ExifCameraInfo", (char *) "Exif Camera Info"}, - - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// GeoTIFF tags definition -// -------------------------------------------------------------------------- - -static TagInfo - geotiff_tag_table[] = - { - { 0x830E, (char *) "GeoPixelScale", (char *) NULL}, - { 0x8480, (char *) "Intergraph TransformationMatrix", (char *) NULL}, - { 0x8482, (char *) "GeoTiePoints", (char *) NULL}, - { 0x85D7, (char *) "JPL Carto IFD offset", (char *) NULL}, - { 0x85D8, (char *) "GeoTransformationMatrix", (char *) NULL}, - { 0x87AF, (char *) "GeoKeyDirectory", (char *) NULL}, - { 0x87B0, (char *) "GeoDoubleParams", (char *) NULL}, - { 0x87B1, (char *) "GeoASCIIParams", (char *) NULL}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// Animation tags definition -// -------------------------------------------------------------------------- - -static TagInfo - animation_tag_table[] = - { - { 0x0001, (char *) "LogicalWidth", (char *) "Logical width"}, - { 0x0002, (char *) "LogicalHeight", (char *) "Logical height"}, - { 0x0003, (char *) "GlobalPalette", (char *) "Global Palette"}, - { 0x0004, (char *) "Loop", (char *) "loop"}, - { 0x1001, (char *) "FrameLeft", (char *) "Frame left"}, - { 0x1002, (char *) "FrameTop", (char *) "Frame top"}, - { 0x1003, (char *) "NoLocalPalette", (char *) "No Local Palette"}, - { 0x1004, (char *) "Interlaced", (char *) "Interlaced"}, - { 0x1005, (char *) "FrameTime", (char *) "Frame display time"}, - { 0x1006, (char *) "DisposalMethod", (char *) "Frame disposal method"}, - { 0x0000, (char *) NULL, (char *) NULL} - }; - -// -------------------------------------------------------------------------- -// TagLib class definition -// -------------------------------------------------------------------------- - - -/** -This is where the tag info tables are initialized -*/ -TagLib::TagLib() { - // initialize all known metadata models - // ==================================== - - // Exif - addMetadataModel(TagLib::EXIF_MAIN, exif_exif_tag_table); - addMetadataModel(TagLib::EXIF_EXIF, exif_exif_tag_table); - addMetadataModel(TagLib::EXIF_GPS, exif_gps_tag_table); - addMetadataModel(TagLib::EXIF_INTEROP, exif_interop_tag_table); - - // Exif maker note - addMetadataModel(TagLib::EXIF_MAKERNOTE_CANON, exif_canon_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_CASIOTYPE1, exif_casio_type1_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_CASIOTYPE2, exif_casio_type2_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_FUJIFILM, exif_fujifilm_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_KYOCERA, exif_kyocera_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_MINOLTA, exif_minolta_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_NIKONTYPE1, exif_nikon_type1_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_NIKONTYPE2, exif_nikon_type2_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_NIKONTYPE3, exif_nikon_type3_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_OLYMPUSTYPE1, exif_olympus_type1_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_PANASONIC, exif_panasonic_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_ASAHI, exif_asahi_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_PENTAX, exif_pentax_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_SONY, exif_sony_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_SIGMA_SD1, exif_sigma_sd1_tag_table); - addMetadataModel(TagLib::EXIF_MAKERNOTE_SIGMA_FOVEON, exif_sigma_foveon_tag_table); - - // IPTC/NAA - addMetadataModel(TagLib::IPTC, iptc_tag_table); - - // GeoTIFF - addMetadataModel(TagLib::GEOTIFF, geotiff_tag_table); - - // Animation - addMetadataModel(TagLib::ANIMATION, animation_tag_table); -} - -BOOL TagLib::addMetadataModel(MDMODEL md_model, TagInfo *tag_table) { - // check that the model doesn't already exist - if((_table_map.find(md_model) == _table_map.end()) && (tag_table != NULL)) { - - // add the tag description table - TAGINFO *info_map = new(std::nothrow) TAGINFO(); - if(!info_map) return FALSE; - - for(int i = 0; ; i++) { - if((tag_table[i].tag == 0) && (tag_table[i].fieldname == NULL)) - break; - (*info_map)[tag_table[i].tag] = &tag_table[i]; - } - - // add the metadata model - _table_map[md_model] = info_map; - - return TRUE; - } - - return FALSE; -} - -TagLib::~TagLib() { - // delete metadata models - for(TABLEMAP::iterator i = _table_map.begin(); i != _table_map.end(); i++) { - TAGINFO *info_map = (*i).second; - delete info_map; - } -} - - -static TagLib g_hInstance; - -TagLib& TagLib::instance() { - return g_hInstance; -} - -const TagInfo* -TagLib::getTagInfo(MDMODEL md_model, WORD tagID) { - - if(_table_map.find(md_model) != _table_map.end()) { - - TAGINFO *info_map = (TAGINFO*)_table_map[md_model]; - if(info_map->find(tagID) != info_map->end()) { - return (*info_map)[tagID]; - } - } - return NULL; -} - -const char* -TagLib::getTagFieldName(MDMODEL md_model, WORD tagID, char *defaultKey) { - - const TagInfo *info = getTagInfo(md_model, tagID); - if(NULL == info) { - if(defaultKey != NULL) { - sprintf(defaultKey, "Tag 0x%04X", tagID); - return &defaultKey[0]; - } else { - return NULL; - } - } - - return info->fieldname; -} - -const char* -TagLib::getTagDescription(MDMODEL md_model, WORD tagID) { - - const TagInfo *info = getTagInfo(md_model, tagID); - if(info) { - return info->description; - } - - return NULL; -} - -int TagLib::getTagID(MDMODEL md_model, const char *key) { - - if(_table_map.find(md_model) != _table_map.end()) { - - TAGINFO *info_map = (TAGINFO*)_table_map[md_model]; - for(TAGINFO::iterator i = info_map->begin(); i != info_map->end(); i++) { - const TagInfo *info = (*i).second; - if(info && (strcmp(info->fieldname, key) == 0)) { - return (int)info->tag; - } - } - } - return -1; -} - -FREE_IMAGE_MDMODEL -TagLib::getFreeImageModel(MDMODEL model) { - switch(model) { - case EXIF_MAIN: - return FIMD_EXIF_MAIN; - - case EXIF_EXIF: - return FIMD_EXIF_EXIF; - - case EXIF_GPS: - return FIMD_EXIF_GPS; - - case EXIF_INTEROP: - return FIMD_EXIF_INTEROP; - - case EXIF_MAKERNOTE_CANON: - case EXIF_MAKERNOTE_CASIOTYPE1: - case EXIF_MAKERNOTE_CASIOTYPE2: - case EXIF_MAKERNOTE_FUJIFILM: - case EXIF_MAKERNOTE_KYOCERA: - case EXIF_MAKERNOTE_MINOLTA: - case EXIF_MAKERNOTE_NIKONTYPE1: - case EXIF_MAKERNOTE_NIKONTYPE2: - case EXIF_MAKERNOTE_NIKONTYPE3: - case EXIF_MAKERNOTE_OLYMPUSTYPE1: - case EXIF_MAKERNOTE_PANASONIC: - case EXIF_MAKERNOTE_ASAHI: - case EXIF_MAKERNOTE_PENTAX: - case EXIF_MAKERNOTE_SONY: - case EXIF_MAKERNOTE_SIGMA_SD1: - case EXIF_MAKERNOTE_SIGMA_FOVEON: - return FIMD_EXIF_MAKERNOTE; - - case IPTC: - return FIMD_IPTC; - - case GEOTIFF: - return FIMD_GEOTIFF; - - case ANIMATION: - return FIMD_ANIMATION; - } - - return FIMD_NODATA; -} diff --git a/plugins/AdvaImg/src/Metadata/XTIFF.cpp b/plugins/AdvaImg/src/Metadata/XTIFF.cpp deleted file mode 100644 index d5be902ad4..0000000000 --- a/plugins/AdvaImg/src/Metadata/XTIFF.cpp +++ /dev/null @@ -1,766 +0,0 @@ -// ========================================================== -// Metadata functions implementation -// Extended TIFF Directory GEO Tag Support -// -// Design and implementation by -// - Hervé Drolon (drolon@infonie.fr) -// - Thorsten Radde (support@IdealSoftware.com) -// - Berend Engelbrecht (softwarecave@users.sourceforge.net) -// - Mihail Naydenov (mnaydenov@users.sourceforge.net) -// -// Based on the LibTIFF xtiffio sample and on LibGeoTIFF -// -// 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! -// ========================================================== - -#ifdef _MSC_VER -#pragma warning (disable : 4786) // identifier was truncated to 'number' characters -#endif - -#include "../LibTIFF4/tiffiop.h" - -#include "FreeImage.h" -#include "Utilities.h" -#include "FreeImageTag.h" -#include "FIRational.h" - -// ---------------------------------------------------------- -// Extended TIFF Directory GEO Tag Support -// ---------------------------------------------------------- - -/** - Tiff info structure. - Entry format: - { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, OkToChange, PassDirCountOnSet, AsciiName } - - For ReadCount, WriteCount, -1 = unknown. -*/ -static const TIFFFieldInfo xtiffFieldInfo[] = { - { TIFFTAG_GEOPIXELSCALE, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoPixelScale" }, - { TIFFTAG_INTERGRAPH_MATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"Intergraph TransformationMatrix" }, - { TIFFTAG_GEOTRANSMATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoTransformationMatrix" }, - { TIFFTAG_GEOTIEPOINTS, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoTiePoints" }, - { TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoKeyDirectory" }, - { TIFFTAG_GEODOUBLEPARAMS, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*)"GeoDoubleParams" }, - { TIFFTAG_GEOASCIIPARAMS, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, (char*) "GeoASCIIParams" }, - { TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, TRUE, TRUE, (char*)"JPL Carto IFD offset" } /** Don't use this! **/ -}; - -static void -_XTIFFLocalDefaultDirectory(TIFF *tif) { - int tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]); - // Install the extended Tag field info - TIFFMergeFieldInfo(tif, xtiffFieldInfo, tag_size); -} - -static TIFFExtendProc _ParentExtender; - -/** -This is the callback procedure, and is -called by the DefaultDirectory method -every time a new TIFF directory is opened. -*/ -static void -_XTIFFDefaultDirectory(TIFF *tif) { - // set up our own defaults - _XTIFFLocalDefaultDirectory(tif); - - /* - Since an XTIFF client module may have overridden - the default directory method, we call it now to - allow it to set up the rest of its own methods. - */ - if (_ParentExtender) { - (*_ParentExtender)(tif); - } -} - -/** -XTIFF Initializer -- sets up the callback procedure for the TIFF module. -@see PluginTIFF::InitTIFF -*/ -void -XTIFFInitialize(void) { - static int first_time = 1; - - if (! first_time) { - return; /* Been there. Done that. */ - } - first_time = 0; - - // Grab the inherited method and install - _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory); -} - -// ---------------------------------------------------------- -// GeoTIFF tag reading / writing -// ---------------------------------------------------------- - -BOOL -tiff_read_geotiff_profile(TIFF *tif, FIBITMAP *dib) { - char defaultKey[16]; - - // first check for a mandatory tag - { - short tag_count = 0; - void* data = NULL; - - if(!TIFFGetField(tif, TIFFTAG_GEOKEYDIRECTORY, &tag_count, &data)) { - // no GeoTIFF tag here - return TRUE; - } - } - - // next, read GeoTIFF tags - - const size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]); - - TagLib& tag_lib = TagLib::instance(); - - for(size_t i = 0; i < tag_size; i++) { - - const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i]; - - if(fieldInfo->field_type == TIFF_ASCII) { - char *params = NULL; - - if(TIFFGetField(tif, fieldInfo->field_tag, ¶ms)) { - // create a tag - FITAG *tag = FreeImage_CreateTag(); - if(!tag) { - return FALSE; - } - - WORD tag_id = (WORD)fieldInfo->field_tag; - - FreeImage_SetTagType(tag, (FREE_IMAGE_MDTYPE)fieldInfo->field_type); - FreeImage_SetTagID(tag, tag_id); - FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey)); - FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id)); - FreeImage_SetTagLength(tag, (DWORD)strlen(params) + 1); - FreeImage_SetTagCount(tag, FreeImage_GetTagLength(tag)); - FreeImage_SetTagValue(tag, params); - FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag); - - // delete the tag - FreeImage_DeleteTag(tag); - } - } else { - short tag_count = 0; - void* data = NULL; - - if(TIFFGetField(tif, fieldInfo->field_tag, &tag_count, &data)) { - // create a tag - FITAG *tag = FreeImage_CreateTag(); - if(!tag) { - return FALSE; - } - - WORD tag_id = (WORD)fieldInfo->field_tag; - FREE_IMAGE_MDTYPE tag_type = (FREE_IMAGE_MDTYPE)fieldInfo->field_type; - - FreeImage_SetTagType(tag, tag_type); - FreeImage_SetTagID(tag, tag_id); - FreeImage_SetTagKey(tag, tag_lib.getTagFieldName(TagLib::GEOTIFF, tag_id, defaultKey)); - FreeImage_SetTagDescription(tag, tag_lib.getTagDescription(TagLib::GEOTIFF, tag_id)); - FreeImage_SetTagLength(tag, FreeImage_TagDataWidth(tag_type) * tag_count); - FreeImage_SetTagCount(tag, tag_count); - FreeImage_SetTagValue(tag, data); - FreeImage_SetMetadata(FIMD_GEOTIFF, dib, FreeImage_GetTagKey(tag), tag); - - // delete the tag - FreeImage_DeleteTag(tag); - } - } - } // for(tag_size) - - return TRUE; -} - -BOOL -tiff_write_geotiff_profile(TIFF *tif, FIBITMAP *dib) { - char defaultKey[16]; - - if(FreeImage_GetMetadataCount(FIMD_GEOTIFF, dib) == 0) { - // no GeoTIFF tag here - return TRUE; - } - - const size_t tag_size = sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]); - - TagLib& tag_lib = TagLib::instance(); - - for(size_t i = 0; i < tag_size; i++) { - const TIFFFieldInfo *fieldInfo = &xtiffFieldInfo[i]; - - FITAG *tag = NULL; - const char *key = tag_lib.getTagFieldName(TagLib::GEOTIFF, (WORD)fieldInfo->field_tag, defaultKey); - - if(FreeImage_GetMetadata(FIMD_GEOTIFF, dib, key, &tag)) { - if(FreeImage_GetTagType(tag) == FIDT_ASCII) { - TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagValue(tag)); - } else { - TIFFSetField(tif, fieldInfo->field_tag, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag)); - } - } - } - - return TRUE; -} - -// ---------------------------------------------------------- -// TIFF EXIF tag reading & writing -// ---------------------------------------------------------- - -/** -Read a single Exif tag - -@param tif TIFF handle -@param tag_id TIFF Tag ID -@param dib Image being read -@param md_model Metadata model where to store the tag -@return Returns TRUE if successful, returns FALSE otherwise -*/ -static BOOL -tiff_read_exif_tag(TIFF *tif, uint32 tag_id, FIBITMAP *dib, TagLib::MDMODEL md_model) { - uint32 value_count = 0; - int mem_alloc = 0; - void *raw_data = NULL; - - if(tag_id == TIFFTAG_EXIFIFD) { - // Exif IFD offset - skip this tag - // md_model should be EXIF_MAIN, the Exif IFD is processed later using the EXIF_EXIF metadata model - return TRUE; - } - if((tag_id == TIFFTAG_GPSIFD) && (md_model == TagLib::EXIF_MAIN)) { - // Exif GPS IFD offset - skip this tag - // should be processed in another way ... - return TRUE; - } - - TagLib& tagLib = TagLib::instance(); - - // get the tag key - use NULL to avoid reading GeoTIFF tags - const char *key = tagLib.getTagFieldName(md_model, (WORD)tag_id, NULL); - if(key == NULL) { - return TRUE; - } - - const TIFFField *fip = TIFFFieldWithTag(tif, tag_id); - if(fip == NULL) { - return TRUE; - } - - if(TIFFFieldPassCount(fip)) { - // a count value is required for 'TIFFGetField' - - if (TIFFFieldReadCount(fip) != TIFF_VARIABLE2) { - // a count is required, it will be of type uint16 - uint16 value_count16 = 0; - if(TIFFGetField(tif, tag_id, &value_count16, &raw_data) != 1) { - // stop, ignore error - return TRUE; - } - value_count = value_count16; - } else { - // a count is required, it will be of type uint32 - uint32 value_count32 = 0; - if(TIFFGetField(tif, tag_id, &value_count32, &raw_data) != 1) { - // stop, ignore error - return TRUE; - } - value_count = value_count32; - } - - } else { - // determine count - - if (TIFFFieldReadCount(fip) == TIFF_VARIABLE || TIFFFieldReadCount(fip) == TIFF_VARIABLE2) { - value_count = 1; - } else if (TIFFFieldReadCount(fip) == TIFF_SPP) { - uint16 spp; - TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); - value_count = spp; - } else { - value_count = TIFFFieldReadCount(fip); - } - - // access fields as pointers to data - // (### determining this is NOT robust... and hardly can be. It is implemented looking the _TIFFVGetField code) - - if(TIFFFieldTag(fip) == TIFFTAG_TRANSFERFUNCTION) { - // reading this tag cause a bug probably located somewhere inside libtiff - return TRUE; - } - - if ((TIFFFieldDataType(fip) == TIFF_ASCII - || TIFFFieldReadCount(fip) == TIFF_VARIABLE - || TIFFFieldReadCount(fip) == TIFF_VARIABLE2 - || TIFFFieldReadCount(fip) == TIFF_SPP - || value_count > 1) - - && TIFFFieldTag(fip) != TIFFTAG_PAGENUMBER - && TIFFFieldTag(fip) != TIFFTAG_HALFTONEHINTS - && TIFFFieldTag(fip) != TIFFTAG_YCBCRSUBSAMPLING - && TIFFFieldTag(fip) != TIFFTAG_DOTRANGE - - && TIFFFieldTag(fip) != TIFFTAG_BITSPERSAMPLE //<- these two are tricky - - && TIFFFieldTag(fip) != TIFFTAG_COMPRESSION //<- they are defined as TIFF_VARIABLE but in reality return a single value - ) { - if(TIFFGetField(tif, tag_id, &raw_data) != 1) { - // stop, ignore error - return TRUE; - } - } else { - int value_size = 0; - - // access fields as values - - // Note: - // For TIFF_RATIONAL values, TIFFDataWidth() returns 8, but LibTIFF use internaly 4-byte float to represent rationals. - { - TIFFDataType tag_type = TIFFFieldDataType(fip); - switch(tag_type) { - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - value_size = 4; - break; - default: - value_size = TIFFDataWidth(tag_type); - break; - } - } - - raw_data = _TIFFmalloc(value_size * value_count); - mem_alloc = 1; - int ok = FALSE; - - // ### if value_count > 1, tag is PAGENUMBER or HALFTONEHINTS or YCBCRSUBSAMPLING or DOTRANGE, - // all off which are value_count == 2 (see tif_dirinfo.c) - switch(value_count) - { - case 1: - ok = TIFFGetField(tif, tag_id, raw_data); - break; - case 2: - ok = TIFFGetField(tif, tag_id, raw_data, (BYTE*)(raw_data) + value_size*1); - break; -/* # we might need more in the future: - case 3: - ok = TIFFGetField(tif, tag_id, raw_data, (BYTE*)(raw_data) + value_size*1, (BYTE*)(raw_data) + value_size*2); - break; -*/ - default: - FreeImage_OutputMessageProc(FIF_TIFF, "Unimplemented variable number of parameters for Tiff Tag %s", TIFFFieldName(fip)); - break; - } - if(ok != 1) { - _TIFFfree(raw_data); - return TRUE; - } - } - } - - // build FreeImage tag from Tiff Tag data we collected - - FITAG *fitag = FreeImage_CreateTag(); - if(!fitag) { - if(mem_alloc) { - _TIFFfree(raw_data); - } - return FALSE; - } - - FreeImage_SetTagID(fitag, (WORD)tag_id); - FreeImage_SetTagKey(fitag, key); - - switch(TIFFFieldDataType(fip)) { - case TIFF_BYTE: - FreeImage_SetTagType(fitag, FIDT_BYTE); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_UNDEFINED: - FreeImage_SetTagType(fitag, FIDT_UNDEFINED); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_SBYTE: - FreeImage_SetTagType(fitag, FIDT_SBYTE); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_SHORT: - FreeImage_SetTagType(fitag, FIDT_SHORT); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_SSHORT: - FreeImage_SetTagType(fitag, FIDT_SSHORT); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_LONG: - FreeImage_SetTagType(fitag, FIDT_LONG); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_IFD: - FreeImage_SetTagType(fitag, FIDT_IFD); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_SLONG: - FreeImage_SetTagType(fitag, FIDT_SLONG); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_RATIONAL: { - // LibTIFF converts rational to floats : reconvert floats to rationals - DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD)); - for(uint32 i = 0; i < value_count; i++) { - float *fv = (float*)raw_data; - FIRational rational(fv[i]); - rvalue[2*i] = rational.getNumerator(); - rvalue[2*i+1] = rational.getDenominator(); - } - FreeImage_SetTagType(fitag, FIDT_RATIONAL); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, rvalue); - free(rvalue); - } - break; - - case TIFF_SRATIONAL: { - // LibTIFF converts rational to floats : reconvert floats to rationals - LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG)); - for(uint32 i = 0; i < value_count; i++) { - float *fv = (float*)raw_data; - FIRational rational(fv[i]); - rvalue[2*i] = rational.getNumerator(); - rvalue[2*i+1] = rational.getDenominator(); - } - FreeImage_SetTagType(fitag, FIDT_RATIONAL); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, rvalue); - free(rvalue); - } - break; - - case TIFF_FLOAT: - FreeImage_SetTagType(fitag, FIDT_FLOAT); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_DOUBLE: - FreeImage_SetTagType(fitag, FIDT_DOUBLE); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_LONG8: // BigTIFF 64-bit unsigned integer - FreeImage_SetTagType(fitag, FIDT_LONG8); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_IFD8: // BigTIFF 64-bit unsigned integer (offset) - FreeImage_SetTagType(fitag, FIDT_IFD8); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_SLONG8: // BigTIFF 64-bit signed integer - FreeImage_SetTagType(fitag, FIDT_SLONG8); - FreeImage_SetTagLength(fitag, TIFFDataWidth( TIFFFieldDataType(fip) ) * value_count); - FreeImage_SetTagCount(fitag, value_count); - FreeImage_SetTagValue(fitag, raw_data); - break; - - case TIFF_ASCII: - default: { - size_t length = 0; - if(!mem_alloc && (TIFFFieldDataType(fip) == TIFF_ASCII) && (TIFFFieldReadCount(fip) == TIFF_VARIABLE)) { - // when metadata tag is of type ASCII and it's value is of variable size (TIFF_VARIABLE), - // tiff_read_exif_tag function gives length of 1 so all strings are truncated ... - // ... try to avoid this by using an explicit calculation for 'length' - length = strlen((char*)raw_data) + 1; - } - else { - // remember that raw_data = _TIFFmalloc(value_size * value_count); - const int value_size = TIFFDataWidth( TIFFFieldDataType(fip) ); - length = value_size * value_count; - } - FreeImage_SetTagType(fitag, FIDT_ASCII); - FreeImage_SetTagLength(fitag, (DWORD)length); - FreeImage_SetTagCount(fitag, (DWORD)length); - FreeImage_SetTagValue(fitag, raw_data); - } - break; - } - - const char *description = tagLib.getTagDescription(md_model, (WORD)tag_id); - if(description) { - FreeImage_SetTagDescription(fitag, description); - } - // store the tag - FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag); - - // destroy the tag - FreeImage_DeleteTag(fitag); - - if(mem_alloc) { - _TIFFfree(raw_data); - } - return TRUE; -} - -/** -Read all known exif tags - -@param tif TIFF handle -@param md_model Metadata model where to store the tags -@param dib Image being read -@return Returns TRUE if successful, returns FALSE otherwise -*/ -BOOL -tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) { - - TagLib& tagLib = TagLib::instance(); - - const int count = TIFFGetTagListCount(tif); - for(int i = 0; i < count; i++) { - uint32 tag_id = TIFFGetTagListEntry(tif, i); - // read the tag - if (!tiff_read_exif_tag(tif, tag_id, dib, md_model)) - return FALSE; - } - - // we want to know values of standard tags too!! - - // loop over all Core Directory Tags - // ### uses private data, but there is no other way - if(md_model == TagLib::EXIF_MAIN) { - const TIFFDirectory *td = &tif->tif_dir; - - uint32 lastTag = 0; //<- used to prevent reading some tags twice (as stored in tif_fieldinfo) - - for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) { - const TIFFField *fld = tif->tif_fields[fi]; - - const uint32 tag_id = TIFFFieldTag(fld); - - if(tag_id == lastTag) { - continue; - } - - // test if tag value is set - // (lifted directly from LibTiff _TIFFWriteDirectory) - - if( fld->field_bit == FIELD_CUSTOM ) { - int is_set = FALSE; - - for(int ci = 0; ci < td->td_customValueCount; ci++ ) { - is_set |= (td->td_customValues[ci].info == fld); - } - - if( !is_set ) { - continue; - } - - } else if(!TIFFFieldSet(tif, fld->field_bit)) { - continue; - } - - // process *all* other tags (some will be ignored) - - tiff_read_exif_tag(tif, tag_id, dib, md_model); - - lastTag = tag_id; - } - - } - - return TRUE; -} - - -/** -Skip tags that are already handled by the LibTIFF writing process -*/ -static BOOL -skip_write_field(TIFF* tif, uint32 tag) { - switch (tag) { - case TIFFTAG_SUBFILETYPE: - case TIFFTAG_OSUBFILETYPE: - case TIFFTAG_IMAGEWIDTH: - case TIFFTAG_IMAGELENGTH: - case TIFFTAG_BITSPERSAMPLE: - case TIFFTAG_COMPRESSION: - case TIFFTAG_PHOTOMETRIC: - case TIFFTAG_THRESHHOLDING: - case TIFFTAG_CELLWIDTH: - case TIFFTAG_CELLLENGTH: - case TIFFTAG_FILLORDER: - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_ORIENTATION: - case TIFFTAG_SAMPLESPERPIXEL: - case TIFFTAG_ROWSPERSTRIP: - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_MINSAMPLEVALUE: - case TIFFTAG_MAXSAMPLEVALUE: - case TIFFTAG_XRESOLUTION: - case TIFFTAG_YRESOLUTION: - case TIFFTAG_PLANARCONFIG: - case TIFFTAG_FREEOFFSETS: - case TIFFTAG_FREEBYTECOUNTS: - case TIFFTAG_GRAYRESPONSEUNIT: - case TIFFTAG_GRAYRESPONSECURVE: - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - case TIFFTAG_RESOLUTIONUNIT: - case TIFFTAG_PAGENUMBER: - case TIFFTAG_COLORRESPONSEUNIT: - case TIFFTAG_PREDICTOR: - case TIFFTAG_COLORMAP: - case TIFFTAG_HALFTONEHINTS: - case TIFFTAG_TILEWIDTH: - case TIFFTAG_TILELENGTH: - case TIFFTAG_TILEOFFSETS: - case TIFFTAG_TILEBYTECOUNTS: - case TIFFTAG_EXTRASAMPLES: - case TIFFTAG_SAMPLEFORMAT: - case TIFFTAG_SMINSAMPLEVALUE: - case TIFFTAG_SMAXSAMPLEVALUE: - // skip always, values have been set in SaveOneTIFF() - return TRUE; - break; - - case TIFFTAG_RICHTIFFIPTC: - // skip always, IPTC metadata model is set in tiff_write_iptc_profile() - return TRUE; - break; - - case TIFFTAG_YCBCRCOEFFICIENTS: - case TIFFTAG_REFERENCEBLACKWHITE: - case TIFFTAG_YCBCRSUBSAMPLING: - // skip as they cannot be filled yet - return TRUE; - break; - - case TIFFTAG_PAGENAME: - { - char *value = NULL; - TIFFGetField(tif, TIFFTAG_PAGENAME, &value); - // only skip if no value has been set - if(value == NULL) { - return FALSE; - } else { - return TRUE; - } - } - default: - return FALSE; - break; - } -} - -/** -Write all known exif tags - -@param tif TIFF handle -@param md_model Metadata model from where to load the tags -@param dib Image being written -@return Returns TRUE if successful, returns FALSE otherwise -*/ -BOOL -tiff_write_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) { - char defaultKey[16]; - - // only EXIF_MAIN so far - if(md_model != TagLib::EXIF_MAIN) { - return FALSE; - } - - if(FreeImage_GetMetadataCount(FIMD_EXIF_MAIN, dib) == 0) { - return FALSE; - } - - TagLib& tag_lib = TagLib::instance(); - - for (int fi = 0, nfi = (int)tif->tif_nfields; nfi > 0; nfi--, fi++) { - const TIFFField *fld = tif->tif_fields[fi]; - - const uint32 tag_id = TIFFFieldTag(fld); - - if(skip_write_field(tif, tag_id)) { - // skip tags that are already handled by the LibTIFF writing process - continue; - } - - FITAG *tag = NULL; - // get the tag key - const char *key = tag_lib.getTagFieldName(TagLib::EXIF_MAIN, (WORD)tag_id, defaultKey); - - if(FreeImage_GetMetadata(FIMD_EXIF_MAIN, dib, key, &tag)) { - FREE_IMAGE_MDTYPE tag_type = FreeImage_GetTagType(tag); - TIFFDataType tif_tag_type = TIFFFieldDataType(fld); - - // check for identical formats - - // (enum value are the sames between FREE_IMAGE_MDTYPE and TIFFDataType types) - if((int)tif_tag_type != (int)tag_type) { - // skip tag or _TIFFmemcpy will fail - continue; - } - // type of storage may differ (e.g. rationnal array vs float array type) - if((unsigned)_TIFFDataSize(tif_tag_type) != FreeImage_TagDataWidth(tag_type)) { - // skip tag or _TIFFmemcpy will fail - continue; - } - - if(tag_type == FIDT_ASCII) { - TIFFSetField(tif, tag_id, FreeImage_GetTagValue(tag)); - } else { - TIFFSetField(tif, tag_id, FreeImage_GetTagCount(tag), FreeImage_GetTagValue(tag)); - } - } - } - - return TRUE; -} -- cgit v1.2.3