diff options
Diffstat (limited to 'samples/source/DumpScannedXMP.cpp')
-rw-r--r-- | samples/source/DumpScannedXMP.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/samples/source/DumpScannedXMP.cpp b/samples/source/DumpScannedXMP.cpp new file mode 100644 index 0000000..9d7e65e --- /dev/null +++ b/samples/source/DumpScannedXMP.cpp @@ -0,0 +1,171 @@ +// ================================================================================================= +// Copyright 2002 Adobe +// All Rights Reserved. +// +// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms +// of the Adobe license agreement accompanying it. If you have received this file from a source other +// than Adobe, then your use, modification, or distribution of it requires the prior written permission +// of Adobe. +// ================================================================================================= + +/** +* Scans a data file to find all embedded XMP Packets, without using the smart handlers. If a packet is found, +* serializes the XMP and writes it to log file. +*/ + +#include <cstdio> +#include <vector> +#include <string> +#include <cstring> +#include <ctime> + +#include <cstdlib> +#include <stdexcept> +#include <cerrno> + +//#define ENABLE_XMP_CPP_INTERFACE 1; + +#if XMP_WinBuild + #pragma warning ( disable : 4127 ) // conditional expression is constant + #pragma warning ( disable : 4996 ) // '...' was declared deprecated +#endif + +#define TXMP_STRING_TYPE std::string + +#include "public/include/XMP.hpp" +#include "public/include/XMP.incl_cpp" + + +#include "XMPFiles/source/FormatSupport/XMPScanner.hpp" +#include "XMPFiles/source/FormatSupport/XMPScanner.cpp" + + +using namespace std; + +// ================================================================================================= + +static XMP_Status DumpCallback ( void * refCon, XMP_StringPtr outStr, XMP_StringLen outLen ) +{ + XMP_Status status = 0; + size_t count; + FILE * outFile = static_cast < FILE * > ( refCon ); + + count = fwrite ( outStr, 1, outLen, outFile ); + if ( count != outLen ) status = errno; + return status; + +} // DumpCallback + +// ================================================================================================= + +static void +ProcessPacket ( const char * fileName, + FILE * inFile, + size_t offset, + size_t length ) +{ + std::string xmlString; + xmlString.append ( length, ' ' ); + fseek ( inFile, (long)offset, SEEK_SET ); + fread ( (void*)xmlString.data(), 1, length, inFile ); + + char title [1000]; + + sprintf ( title, "// Dumping raw input for \"%s\" (%zu..%zu)", fileName, offset, (offset + length - 1) ); + printf ( "// " ); + for ( size_t i = 3; i < strlen(title); ++i ) printf ( "=" ); + printf ( "\n\n%s\n\n%.*s\n\n", title, (int)length, xmlString.c_str() ); + fflush ( stdout ); + + SXMPMeta xmpObj; + try { + xmpObj.ParseFromBuffer ( xmlString.c_str(), (XMP_StringLen)length ); + } catch ( ... ) { + printf ( "## Parse failed\n\n" ); + return; + } + + xmpObj.DumpObject ( DumpCallback, stdout ); + fflush ( stdout ); + + string xmpString; + xmpObj.SerializeToBuffer ( &xmpString, kXMP_OmitPacketWrapper ); + printf ( "\nPretty serialization, %zu bytes :\n\n%s\n", xmpString.size(), xmpString.c_str() ); + fflush ( stdout ); + + xmpObj.SerializeToBuffer ( &xmpString, (kXMP_OmitPacketWrapper | kXMP_UseCompactFormat) ); + printf ( "Compact serialization, %zu bytes :\n\n%s\n", xmpString.size(), xmpString.c_str() ); + fflush ( stdout ); + +} // ProcessPacket + +// ================================================================================================= + +static void +ProcessFile ( const char * fileName ) +{ + FILE * inFile; + size_t fileLen, readCount; + size_t snipCount; + char buffer [64*1024]; + + // --------------------------------------------------------------------- + // Use the scanner to find all of the packets then process each of them. + + inFile = fopen ( fileName, "rb" ); + if ( inFile == 0 ) { + printf ( "Can't open \"%s\"\n", fileName ); + return; + } + + fseek ( inFile, 0, SEEK_END ); + fileLen = ftell ( inFile ); // ! Only handles up to 2GB files. + fseek ( inFile, 0, SEEK_SET ); + + XMPScanner scanner ( fileLen ); + + for ( size_t filePos = 0; true; filePos += readCount ) { + readCount = fread ( buffer, 1, sizeof(buffer), inFile ); + if ( readCount == 0 ) break; + scanner.Scan ( buffer, filePos, readCount ); + } + + snipCount = scanner.GetSnipCount(); + + XMPScanner::SnipInfoVector snips (snipCount); + scanner.Report ( snips ); + + size_t packetCount = 0; + for ( size_t s = 0; s < snipCount; ++s ) { + if ( snips[s].fState == XMPScanner::eValidPacketSnip ) { + ++packetCount; + ProcessPacket ( fileName, inFile, (size_t)snips[s].fOffset, (size_t)snips[s].fLength ); + } + } + if ( packetCount == 0 ) printf ( " No packets found\n" ); + +} // ProcessFile + +// ================================================================================================= + +extern "C" int +main ( int argc, const char * argv [] ) +{ + + if ( ! SXMPMeta::Initialize() ) { + printf ( "## SXMPMeta::Initialize failed!\n" ); + return -1; + } + + if ( argc != 2 ) // 2 := command and 1 parameter + { + printf ("usage: DumpScannedXMP (filename)\n"); + return 0; + } + + for ( int i = 1; i < argc; ++i ) ProcessFile ( argv[i] ); + + SXMPMeta::Terminate(); + return 0; + +} |