diff options
Diffstat (limited to 'samples/source/DumpScannedXMP.cpp')
-rw-r--r-- | samples/source/DumpScannedXMP.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/samples/source/DumpScannedXMP.cpp b/samples/source/DumpScannedXMP.cpp new file mode 100644 index 0000000..c8c5f94 --- /dev/null +++ b/samples/source/DumpScannedXMP.cpp @@ -0,0 +1,188 @@ +// ================================================================================================= +// Copyright 2002-2005 Adobe Systems Incorporated +// 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. +// ================================================================================================= + +#include <string> +#include <time.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdexcept> +#include <errno.h> + +#if WIN_ENV + #pragma warning ( disable : 4127 ) // conditional expression is constant + #pragma warning ( disable : 4996 ) // '...' was declared deprecated +#endif + +#define TXMP_STRING_TYPE std::string + +#include "XMP.hpp" +#include "XMP.incl_cpp" + +#include "XMPScanner.hpp" + +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, offset, SEEK_SET ); + fread ( (void*)xmlString.data(), 1, length, inFile ); + + char title [1000]; + + sprintf ( title, "// Dumping raw input for \"%s\" (%d..%d)", 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, length, xmlString.c_str() ); + fflush ( stdout ); + + SXMPMeta xmpObj; + try { + xmpObj.ParseFromBuffer ( xmlString.c_str(), length ); + } catch ( ... ) { + printf ( "## Parse failed\n\n" ); + return; + } + + xmpObj.DumpObject ( DumpCallback, stdout ); + fflush ( stdout ); + + string xmpString; + xmpObj.SerializeToBuffer ( &xmpString, kXMP_OmitPacketWrapper ); + printf ( "\nPretty serialization, %d bytes :\n\n%s\n", xmpString.size(), xmpString.c_str() ); + fflush ( stdout ); + + xmpObj.SerializeToBuffer ( &xmpString, (kXMP_OmitPacketWrapper | kXMP_UseCompactFormat) ); + printf ( "Compact serialization, %d 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 > 1 ) { + + printf ( "\n" ); + for ( int i = 1; i < argc; i++ ) ProcessFile ( argv[i] ); + + } else { + + char fileNameBuffer[1025]; + + while ( true ) { + + printf ( "\nFile: " ); + fgets( fileNameBuffer, sizeof(fileNameBuffer), stdin ); + string fileName ( fileNameBuffer ); + + if ( fileName.empty() ) break; + + if ( (fileName[fileName.size()-1] == '\n') || (fileName[fileName.size()-1] == '\r') ) { + fileName.erase ( fileName.size()-1, 1 ); // Remove eol, allowing for CRLF. + if ( (fileName[fileName.size()-1] == '\n') || (fileName[fileName.size()-1] == '\r') ) { + fileName.erase ( fileName.size()-1, 1 ); + } + } + + if ( fileName == "." ) break; + + // Dragging an icon on Windows pastes a quoted path. + if ( fileName[fileName.size()-1] == '"' ) fileName.erase ( fileName.size()-1, 1 ); + if ( fileName[0] == '"' ) fileName.erase ( 0, 1 ); + + if ( ! fileName.empty() ) { + printf ( "\n" ); + ProcessFile ( fileName.c_str() ); + } + + } + + } + + SXMPMeta::Terminate(); + return 0; + +} |