diff options
Diffstat (limited to 'plugins/AdvaImg/src/Metadata/IPTC.cpp')
-rw-r--r-- | plugins/AdvaImg/src/Metadata/IPTC.cpp | 342 |
1 files changed, 0 insertions, 342 deletions
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<std::string> 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; -} |