summaryrefslogtreecommitdiff
path: root/samples/source/common
diff options
context:
space:
mode:
authorHubert Figuière <hub@figuiere.net>2015-03-06 11:11:01 +0100
committerHubert Figuière <hub@figuiere.net>2015-03-06 11:11:01 +0100
commit606a7df73750084a36fe69651e7b672333a76412 (patch)
treee337e53680715d69be570ccfcf8757ca898ea124 /samples/source/common
parent4652015fe779e12fb06ff8fa56bf70e373cd3894 (diff)
Update to XMP SDK CC 2014.12
Diffstat (limited to 'samples/source/common')
-rw-r--r--samples/source/common/DumpFile.cpp247
-rw-r--r--samples/source/common/TagTree.cpp16
-rw-r--r--samples/source/common/globals.h2
3 files changed, 224 insertions, 41 deletions
diff --git a/samples/source/common/DumpFile.cpp b/samples/source/common/DumpFile.cpp
index c651aca..32dd253 100644
--- a/samples/source/common/DumpFile.cpp
+++ b/samples/source/common/DumpFile.cpp
@@ -291,9 +291,17 @@ static XMP_Uns64 GetUns64LE ( const void * addr );
// =================================================================================================
// ahead declarations
+struct JpegMarker {
+ XMP_Uns8 * jpegMarkerPtr;
+ XMP_Uns16 jpegMarkerLen;
+};
+typedef std::vector<JpegMarker> JpegMarkers;
+
static void DumpTIFF ( XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const char * label, std::string path );
+static void DumpTIFF ( const JpegMarkers& psirMarkers, XMP_Uns8 * dataStart, const char * label, std::string path );
static void DumpIPTC ( XMP_Uns8 * iptcOrigin, XMP_Uns32 iptcLen, XMP_Uns32 fileOffset, const char * label );
static void DumpImageResources ( XMP_Uns8 * psirOrigin, XMP_Uns32 psirLen, XMP_Uns32 fileOffset, const char * label );
+static void DumpImageResources ( const JpegMarkers& psirMarkers, XMP_Uns8 * dataStart, const char * label );
static void DumpIFDChain ( XMP_Uns8 * startPtr, XMP_Uns8 * endPtr, XMP_Uns8 * tiffContent, XMP_Uns32 fileOffset, const char * label, std::string path );
// =================================================================================================
@@ -1208,6 +1216,136 @@ DumpIPTC (XMP_Uns8 * iptcOrigin, XMP_Uns32 iptcLen, XMP_Uns32 fileOffset, const
} // DumpIPTC
// =================================================================================================
+
+static void
+DumpImageResources ( const JpegMarkers& psirMarkers, XMP_Uns8 * dataStart, const char * label )
+{
+
+ XMP_Uns32 i = 0, size = psirMarkers.size();
+ std::string combinedPSIRData;
+ for ( i = 0; i < size; i++ ) {
+ combinedPSIRData.append( (const char *) psirMarkers[i].jpegMarkerPtr, psirMarkers[i].jpegMarkerLen );
+ }
+
+
+ XMP_Uns8 * psirPtr = (XMP_Uns8 *) combinedPSIRData.data();
+ XMP_Uns8 * psirEnd = psirPtr + combinedPSIRData.size();
+
+ XMP_Uns8 * irPtr;
+ XMP_Uns32 irLen, irOffset; //irType replaced by irTypeStr below
+
+ XMP_Uns8 * iptcPtr = 0;
+ XMP_Uns8 * xmpPtr = 0;
+ XMP_Uns8 * exif1Ptr = 0;
+ XMP_Uns8 * exif3Ptr = 0;
+ XMP_Uns32 iptcLen, xmpLen, exif1Len, exif3Len;
+ XMP_Int32 lastIndexUsed = -1;
+ while (psirPtr < psirEnd) {
+ // calculate fileOffset and psirOrigin
+ size_t currentOffset = (const char *) psirPtr - combinedPSIRData.data();
+ XMP_Uns32 length = 0;
+ for (i = 0; i < size; i++ ) {
+ length += psirMarkers[i].jpegMarkerLen;
+ if ( currentOffset <= length )
+ break;
+ }
+ if ( lastIndexUsed != i ) {
+ if ( lastIndexUsed != -1 )
+ tree->popNode();
+ // time to push a new node
+ tree->pushNode("Photoshop Image Resources %d", i + 1 );
+ XMP_Uns32 fileOffset = psirMarkers[i].jpegMarkerPtr - dataStart;
+ tree->addComment("from %s, offset %d (0x%X), size %d",
+ label, fileOffset, fileOffset, psirMarkers[i].jpegMarkerLen);
+ lastIndexUsed = i;
+ }
+ XMP_Uns32 fileOffset = psirMarkers[i].jpegMarkerPtr - dataStart;
+ XMP_Uns8 * psirOrigin = psirMarkers[i].jpegMarkerPtr;
+
+ std::string irTypeStr = convert8Bit(psirPtr,false,4); //get in an endian neutral way
+ XMP_Uns16 irID = GetUns16BE ( psirPtr+4 ); // The image resource ID.
+
+ const char* irName = (XMP_StringPtr)psirPtr+6; // A Pascal string.
+ irOffset = 6 + ((*irName + 2) & 0xFFFFFFFE); // Offset to the image resource data length.
+ irLen = GetUns32BE (psirPtr+irOffset);
+ irPtr = psirPtr + irOffset + 4;
+
+ irOffset = fileOffset + ((psirPtr - (XMP_Uns8 *) combinedPSIRData.data()) - ( length - psirMarkers[i].jpegMarkerLen ) );
+
+ if ( irTypeStr != "8BIM" ) {
+ tree->setKeyValue( fromArgs("PSIR:%s:#%u",irTypeStr.c_str(),irID),"" );
+ tree->comment("(non-8BIM encountered and tolerated, see bug 1454756)");
+ } else if ( irID == kPSIR_IPTC ) { //****************
+ tree->setKeyValue("PSIR:IPTC","");
+ iptcPtr = irPtr;
+ iptcLen = irLen;
+ if (iptcPtr != 0) {
+ XMP_Uns32 offset = fileOffset + ((iptcPtr - (XMP_Uns8 *) combinedPSIRData.data()) - ( length - psirMarkers[i].jpegMarkerLen ) );
+ DumpIPTC (iptcPtr, iptcLen, offset, "PSIR #1028");
+ }
+ } else if (irID == kPSIR_XMP) { //****************
+ tree->setKeyValue("PSIR:XMP","");
+ xmpPtr = irPtr;
+ xmpLen = irLen;
+ if (xmpPtr != 0) {
+ XMP_Uns32 offset = fileOffset + ((xmpPtr - (XMP_Uns8 *) combinedPSIRData.data()) - ( length - psirMarkers[i].jpegMarkerLen ) );
+ DumpXMP (xmpPtr, xmpLen, offset, "PSIR #1060");
+ }
+ } else if (irID == kPSIR_Exif_1) { //****************
+ tree->setKeyValue("PSIR:Exif-1","");
+ exif1Ptr = irPtr;
+ exif1Len = irLen;
+ XMP_Uns32 offset = fileOffset + ((exif1Ptr - (XMP_Uns8 *) combinedPSIRData.data()) - ( length - psirMarkers[i].jpegMarkerLen ) );
+ DumpTIFF (exif1Ptr, exif1Len, offset, "PSIR #1058 (Exif 1)", "PSIR:Exif-1");
+ } else if (irID == kPSIR_Exif_3) { //****************
+ tree->setKeyValue("PSIR:Exif-3","");
+ exif3Ptr = irPtr;
+ exif3Len = irLen;
+ XMP_Uns32 offset = fileOffset + ((exif3Ptr - (XMP_Uns8 *) combinedPSIRData.data()) - ( length - psirMarkers[i].jpegMarkerLen ) );
+ if (exif3Ptr != 0) DumpTIFF (exif3Ptr, exif3Len, offset, "PSIR #1059 (Exif 3)", "PSIR:Exif-3");
+ } else if (irID == kPSIR_IPTC_Digest) {
+ tree->setKeyValue("PSIR:IPTC digest",
+ fromArgs("%.8X-%.8X-%.8X-%.8X",
+ GetUns32BE(irPtr),
+ GetUns32BE(irPtr+4),
+ GetUns32BE(irPtr+8),
+ GetUns32BE(irPtr+12) )
+ );
+ } else if (irID == kPSIR_CopyrightFlag) {
+ bool copyrighted = (*irPtr != 0);
+ tree->setKeyValue("PSIR:copyrighted",(copyrighted ? "yes" : "no"));
+ } else if (irID == kPSIR_CopyrightURL) {
+ tree->setKeyValue("PSIR:copyright URL",convert8Bit(irPtr,true,irLen));
+ } else if (irID == kPSIR_OldCaption) {
+ tree->setKeyValue("PSIR:old caption",convert8Bit(irPtr,true,irLen));
+ } else if (irID == kPSIR_PrintCaption) {
+ tree->comment("** obsolete print caption **");
+ } else {
+ tree->setKeyValue(
+ fromArgs("PSIR:%s:#%d",irTypeStr.c_str(),irID),
+ ""
+ );
+ }
+ if ( irOffset + irLen > (psirMarkers[i].jpegMarkerPtr - dataStart) + psirMarkers[i].jpegMarkerLen ) {
+ //merged from two markers
+ tree->addComment("offset %d (0x%X), size %d - split in multiple markers", irOffset, irOffset, irLen);
+ } else {
+ tree->addComment("offset %d (0x%X), size %d", irOffset, irOffset, irLen);
+ }
+ if (*irName != 0) tree->addComment("\"%.*s\"", (int)(*irName), (irName+1));
+ psirPtr = irPtr + ((irLen + 1) & 0xFFFFFFFE); // Round the length to be even.
+ } //while-loop
+
+ if (psirPtr != psirEnd) {
+ tree->addComment("** Unexpected end of image resources, delta %d", (long)(psirPtr - psirEnd));
+ }
+
+ //NB: dump routines moved up into if-else's
+ tree->popNode();
+} // DumpImageResources
+
+// =================================================================================================
+
static void
DumpImageResources (XMP_Uns8 * psirOrigin, XMP_Uns32 psirLen, XMP_Uns32 fileOffset, const char * label)
{
@@ -1621,6 +1759,7 @@ DumpIFDChain (XMP_Uns8 * startPtr, XMP_Uns8 * endPtr,
static void
DumpTIFF (XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const char * label, std::string path)
{
+ tree->pushNode("TIFF content from %s", label);
// ! TIFF can be nested because of the Photoshop 6 weiredness. Save and restore the procs.
GetUns16_Proc save_GetUns16 = TIFF_GetUns16;
GetUns32_Proc save_GetUns32 = TIFF_GetUns32;
@@ -1652,6 +1791,28 @@ DumpTIFF (XMP_Uns8 * tiffContent, XMP_Uns32 tiffLen, XMP_Uns32 fileOffset, const
TIFF_GetUns32 = save_GetUns32;
TIFF_GetUns64 = save_GetUns64;
+ tree->popNode();
+} // DumpTIFF
+
+
+// =================================================================================================
+
+static void DumpTIFF ( const JpegMarkers& exifMarkers, XMP_Uns8 * dataStart, const char * label, std::string path )
+{
+ XMP_Uns32 i = 0, size = exifMarkers.size();
+ std::string combinedExifData;
+ tree->pushNode( "Combined EXIF Markers from %s", path.c_str() );
+ for ( i = 0; i < size; i++ ) {
+ tree->pushNode( "EXIF Marker %d", i + 1 );
+ tree->addComment("offset %d (0x%X), size %d", exifMarkers[i].jpegMarkerPtr - dataStart,
+ exifMarkers[i].jpegMarkerPtr - dataStart, exifMarkers[i].jpegMarkerLen );
+ combinedExifData.append( (const char *) exifMarkers[i].jpegMarkerPtr, exifMarkers[i].jpegMarkerLen );
+ tree->popNode();
+ }
+
+ DumpTIFF( (XMP_Uns8 *) combinedExifData.data(), combinedExifData.length(), exifMarkers[0].jpegMarkerPtr - dataStart, label, path );
+
+ tree->popNode();
} // DumpTIFF
// =================================================================================================
@@ -1680,11 +1841,9 @@ DumpJPEG (XMP_Uns8 * jpegContent, XMP_Uns32 jpegLen)
XMP_Uns32 segOffset;
XMP_Uns8 * xmpPtr = 0;
- XMP_Uns8 * psirPtr = 0;
- XMP_Uns8 * exifPtr = 0;
XMP_Uns16 xmpLen = 0;
- XMP_Uns16 psirLen = 0;
- XMP_Uns16 exifLen = 0;
+
+ JpegMarkers psirMarkers, exifMarkers;
while (segPtr < endPtr) { // ----------------------------------------------------------------
@@ -1740,13 +1899,17 @@ DumpJPEG (XMP_Uns8 * jpegContent, XMP_Uns32 jpegLen)
((memcmp(segName,"Exif\0\0",6) == 0) || (memcmp(segName,"Exif\0\xFF",6) == 0))) {
tree->addComment("EXIF");
tree->changeValue("EXIF");
- exifPtr = segPtr + 4 + 6;
- exifLen = segLen - 2 - 6;
+ JpegMarker exifMarker;
+ exifMarker.jpegMarkerPtr = segPtr + 4 + 6;
+ exifMarker.jpegMarkerLen = segLen - 2 - 6;
+ exifMarkers.push_back(exifMarker);
} else if ((minorKind == 13) && (strcmp(segName,"Photoshop 3.0") == 0)) {
tree->addComment("PSIR");
tree->changeValue("PSIR");
- psirPtr = segPtr + 4 + strlen(segName) + 1;
- psirLen = (XMP_Uns16)(segLen - 2 - strlen(segName) - 1);
+ JpegMarker psirMarker;
+ psirMarker.jpegMarkerPtr = segPtr + 4 + strlen(segName) + 1;
+ psirMarker.jpegMarkerLen = (XMP_Uns16)(segLen - 2 - strlen(segName) - 1);
+ psirMarkers.push_back(psirMarker);
} else if ((minorKind == 1) && (strcmp(segName,"http://ns.adobe.com/xap/1.0/") == 0)) {
tree->addComment("XMP");
tree->changeValue("XMP");
@@ -1834,16 +1997,20 @@ DumpJPEG (XMP_Uns8 * jpegContent, XMP_Uns32 jpegLen)
));
}
- if (exifPtr != 0) DumpTIFF (exifPtr, exifLen, (exifPtr - jpegContent), "JPEG Exif APP1", "JPEG:APP1");
- if (psirPtr != 0) DumpImageResources (psirPtr, psirLen, (psirPtr - jpegContent), "JPEG Photoshop APP13");
+ if (exifMarkers.size() > 0) DumpTIFF (exifMarkers, jpegContent, "JPEG Exif APP1", "JPEG:APP1");
+ if (psirMarkers.size() > 0) DumpImageResources (psirMarkers, jpegContent, "JPEG Photoshop APP13");
if (xmpPtr != 0) DumpXMP (xmpPtr, xmpLen, (xmpPtr - jpegContent), "JPEG XMP APP1");
} // DumpJPEG
// =================================================================================================
-
+//#if !IOS_ENV
static const XMP_Uns8 kUUID_XMP[16] =
{ 0xBE, 0x7A, 0xCF, 0xCB, 0x97, 0xA9, 0x42, 0xE8, 0x9C, 0x71, 0x99, 0x94, 0x91, 0xE3, 0xAF, 0xAC };
+/*#else
+static const XMP_Uns8 kUUID_XMP[16] =
+{ 0xFFFFFFBE, 0x0000007A, 0xFFFFFFCF, 0xFFFFFFCB, 0xFFFFFF97, 0xFFFFFFA9, 0x00000042, 0xFFFFFFE8, 0xFFFFFF9C, 0x00000071, 0xFFFFFF99, 0xFFFFFF94, 0xFFFFFF91, 0xFFFFFFE3, 0xFFFFFFAF, 0xFFFFFFAC };
+#endif */
static const XMP_Uns8 kUUID_Exif[16] =
{ 0x05, 0x37, 0xCD, 0xAB, 0x9D, 0x0C, 0x44, 0x31, 0xA7, 0x2A, 0xFA, 0x56, 0x1F, 0x2A, 0x11, 0x3E };
static const XMP_Uns8 kUUID_IPTC[16] =
@@ -1877,13 +2044,8 @@ digestInternationalTextSequence ( LFA_FileRef file, std::string isoPath, XMP_Int
tree->digest16u(file,isoPath+"language code",true,true);
(*remainingSize) -= 4;
if ( (*remainingSize) != miniBoxStringSize )
- {
tree->addComment("WARNING: boxSize and miniBoxSize differ!");
- }
- else
- {
- tree->digestString( file, isoPath+"value", miniBoxStringSize, false );
- }
+ tree->digestString( file, isoPath+"value", miniBoxStringSize, false );
}
/**
@@ -1948,13 +2110,17 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath )
std::string boxString( fromArgs( "%.4s" , &tempBoxType) );
// substitute mac-copyright signs with an easier-to-handle "(c)"
- if ( boxString.at(0) == 0xA9 )
- boxString = std::string("(c)") + boxString.substr(1);
+#if !IOS_ENV
+ if ( boxString.at(0) == 0xa9 )
+#else
+ if ( boxString.at(0) == 0xffffffa9 )
+#endif
+ boxString = std::string("(c)") + boxString.substr(1);
isoPath = origIsoPath + boxString + "/";
// TEMP
// Log::info("pushing %s, endOfThisLevel: 0x%X", isoPath.c_str(), endOfThisLevel );
-
+ // printf ("%s \n", isoPath.c_str());
tree->pushNode( isoPath );
tree->addComment("offset 0x%I64X, size 0x%I64X", boxPos , boxSize);
@@ -2255,23 +2421,7 @@ DumpISOBoxes ( LFA_FileRef file, XMP_Uns32 maxBoxLen, std::string _isoPath )
// (c)-style quicktime boxes and boxes of no interest:
default:
- if ( 0 == isoPath.compare( 0 , 20, "moov/udta/meta/ilst/"))
- { // => iTunes metadata (hunt for data childs)
- // a container box, hunt for 'data' atom by recursion:
- bool ok;
- XMP_Int64 keep = LFA_Tell( file );
- DumpISOBoxes( file, remainingSize, isoPath );
- LFA_Seek( file, keep, SEEK_SET, &ok );
- assertMsg( "seek failed", ok );
- }
- else if ( 0 == isoPath.compare( 0 , 10, "moov/udta/" ))
- { // => Quicktime metadata "international text sequence" ( size, language code, value )
- digestInternationalTextSequence( file, isoPath, &remainingSize );
- } else
- {
- tree->addComment("WARNING: unknown flavor of (c)*** boxes, neither QT nor iTunes");
- }
- break;
+ break;
}
bool ok;
@@ -3223,6 +3373,10 @@ DumpRIFFChunk ( LFA_FileRef file, XMP_Int64 parentEnd, std::string origChunkPath
( ( origChunkPath == "RIFF:WAVE" || origChunkPath == "RIFF:AVI ")
&& idString == "bext" );
+ bool isIXMLChunk =
+ ( ( origChunkPath == "RIFF:WAVE" )
+ && idString == "iXML" );
+
bool isXMPchunk = false; //assume beforehand
if ( idString == "_PMX" )
{ // detour first, to detect xmp in wrong places
@@ -3333,6 +3487,25 @@ DumpRIFFChunk ( LFA_FileRef file, XMP_Int64 parentEnd, std::string origChunkPath
tree->addComment("packet end: 0x%llX", LFA_Tell( file ) );
tree->popNode();
+ } else if ( isIXMLChunk ) {
+ tree->pushNode("iXML packet");
+
+ tree->addOffset( file );
+ tree->addComment("packet size: 0x%llX", chunkSize - 8 );
+ //Skip( file, chunkSize - 8 );
+
+ size_t sizeofIXMLValue = chunkSize-8;
+ char* descriptionBuffer = new char[ sizeofIXMLValue + 2 ];
+ LFA_Read( file, descriptionBuffer, sizeofIXMLValue, true );
+ descriptionBuffer[sizeofIXMLValue]='\0'; // tack on, in case not contained
+ // parse till first \0
+ std::string description( descriptionBuffer );
+
+ delete[] descriptionBuffer;
+ tree->addComment("packet end: 0x%llX", LFA_Tell( file ) );
+
+ tree->popNode();
+
}
else
{
diff --git a/samples/source/common/TagTree.cpp b/samples/source/common/TagTree.cpp
index 713998a..aa8ca12 100644
--- a/samples/source/common/TagTree.cpp
+++ b/samples/source/common/TagTree.cpp
@@ -139,9 +139,8 @@ void TagTree::digest(LFA_FileRef file,const std::string key /*=NULL*/,
// require all == false => leave the throwing to this routine
if (numOfBytes != LFA_Read ( file, value, numOfBytes, false)) // saying 1,4 guarantes read as ordered (4,1 would not)
Log::error("could not read %d number of files (End of File reached?)",numOfBytes);
-
+#if !IOS_ENV
char* out=new char[2 + numOfBytes*3 + 5]; //'0x12 34 45 78 ' length formula: 2 ("0x") + numOfBytes x 3 + 5 (padding)
-
if (!key.empty()) {
snprintf(out,3,"0x");
XMP_Int64 i; // *)
@@ -150,8 +149,19 @@ void TagTree::digest(LFA_FileRef file,const std::string key /*=NULL*/,
snprintf(&out[2+i*3],1,"%c",'\0'); // *) using i one more time (needed while bug 1613297 regarding snprintf not fixed)
setKeyValue(key,out);
}
+#else
+ char* out=new char[2 + numOfBytes*9 + 5]; //'0x12 34 45 78 ' length formula: 2 ("0x") + numOfBytes x 3 + 5 (padding)
+ if (!key.empty()) {
+ snprintf(out,3,"0x");
+ XMP_Int64 i; // *)
+ for (i=0; i < numOfBytes; i++)
+ snprintf(&out[2+i*9],10,"%.8X ",value[i]); //always must allow that extra 0-byte on mac (overwritten again and again)
+ snprintf(&out[2+i*9],1,"%c",'\0'); // *) using i one more time (needed while bug 1613297 regarding snprintf not fixed)
+ setKeyValue(key,out);
+ }
- delete out;
+#endif
+ delete out;
if (!returnValue) delete value; //if we own it, we delete it
}
diff --git a/samples/source/common/globals.h b/samples/source/common/globals.h
index 164b519..8b0d09c 100644
--- a/samples/source/common/globals.h
+++ b/samples/source/common/globals.h
@@ -77,7 +77,7 @@
const std::string AEOEUE_MAC_MOJIBAKE_BUGINESE("<C6 92 C3 B7 E2 80 B9>");
const std::string AEOEUE_LATIN1_MOJIBAKE_BUGINESE("<C2 80 C2 85 C2 86>");
- #if MAC_ENV
+ #if MAC_ENV || IOS_ENV
const std::string AEOEUE_LOCAL = std::string(AEOEUE_MAC_LOCAL_CSTRING);
const std::string AEOEUE_WIN_LOCAL_TO_UTF8 = AEOEUE_MAC_MOJIBAKE_BUGINESE;
const std::string AEOEUE_MAC_LOCAL_TO_UTF8 = AEOEUE_UTF8_BUGINESE;