/** Read JPEG_APPD marker (IPTC or Adobe Photoshop profile) */ BOOL jpeg_read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) { return read_iptc_profile(dib, dataptr, datalen); }
/** Read JPEG_APPD marker (IPTC or Adobe Photoshop profile) */ BOOL jpeg_read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) { #ifndef MINIMAL_FREEIMAGE_CODEC return read_iptc_profile(dib, dataptr, datalen); #endif }
/** Read ICC, XMP, Exif, Exif-GPS, IPTC, descriptive (i.e. Exif-TIFF) metadata @see ReadProfile, ReadDescriptiveMetadata */ static ERR ReadMetadata(PKImageDecode *pID, FIBITMAP *dib) { ERR error_code = 0; // error code as returned by the interface size_t currentPos = 0; // current stream position WMPStream *pStream = pID->pStream; WmpDEMisc *wmiDEMisc = &pID->WMP.wmiDEMisc; BYTE *pbProfile = NULL; try { // save current position error_code = pStream->GetPos(pStream, ¤tPos); JXR_CHECK(error_code); // ICC profile if(0 != wmiDEMisc->uColorProfileByteCount) { unsigned cbByteCount = wmiDEMisc->uColorProfileByteCount; unsigned uOffset = wmiDEMisc->uColorProfileOffset; error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile); JXR_CHECK(error_code); FreeImage_CreateICCProfile(dib, pbProfile, cbByteCount); } // XMP metadata if(0 != wmiDEMisc->uXMPMetadataByteCount) { unsigned cbByteCount = wmiDEMisc->uXMPMetadataByteCount; unsigned uOffset = wmiDEMisc->uXMPMetadataOffset; error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile); JXR_CHECK(error_code); // store the tag as XMP FITAG *tag = FreeImage_CreateTag(); if(tag) { FreeImage_SetTagLength(tag, cbByteCount); FreeImage_SetTagCount(tag, cbByteCount); FreeImage_SetTagType(tag, FIDT_ASCII); FreeImage_SetTagValue(tag, pbProfile); FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName); FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag); FreeImage_DeleteTag(tag); } } // IPTC metadata if(0 != wmiDEMisc->uIPTCNAAMetadataByteCount) { unsigned cbByteCount = wmiDEMisc->uIPTCNAAMetadataByteCount; unsigned uOffset = wmiDEMisc->uIPTCNAAMetadataOffset; error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile); JXR_CHECK(error_code); // decode the IPTC profile read_iptc_profile(dib, pbProfile, cbByteCount); } // Exif metadata if(0 != wmiDEMisc->uEXIFMetadataByteCount) { unsigned cbByteCount = wmiDEMisc->uEXIFMetadataByteCount; unsigned uOffset = wmiDEMisc->uEXIFMetadataOffset; error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile); JXR_CHECK(error_code); // decode the Exif profile jpegxr_read_exif_profile(dib, pbProfile, cbByteCount, uOffset); } // Exif-GPS metadata if(0 != wmiDEMisc->uGPSInfoMetadataByteCount) { unsigned cbByteCount = wmiDEMisc->uGPSInfoMetadataByteCount; unsigned uOffset = wmiDEMisc->uGPSInfoMetadataOffset; error_code = ReadProfile(pStream, cbByteCount, uOffset, &pbProfile); JXR_CHECK(error_code); // decode the Exif-GPS profile jpegxr_read_exif_gps_profile(dib, pbProfile, cbByteCount, uOffset); } // free profile buffer free(pbProfile); // restore initial position error_code = pID->pStream->SetPos(pID->pStream, currentPos); JXR_CHECK(error_code); // as a LAST STEP, read descriptive metadata // these metadata overwrite possible identical Exif-TIFF metadata // that could have been read inside the Exif IFD return ReadDescriptiveMetadata(pID, dib); } catch(...) { // free profile buffer free(pbProfile); if(currentPos) { // restore initial position pStream->SetPos(pStream, currentPos); } return error_code; } }