summaryrefslogtreecommitdiff
path: root/XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.cpp')
-rw-r--r--XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.cpp b/XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.cpp
new file mode 100644
index 0000000..c5dc42e
--- /dev/null
+++ b/XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.cpp
@@ -0,0 +1,231 @@
+// =================================================================================================
+// ADOBE SYSTEMS INCORPORATED
+// Copyright 2010 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.h>
+
+#include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header.
+#include "public/include/XMP_Const.h"
+
+#include "XMPFiles/source/FormatSupport/WAVE/PrmLMetadata.h"
+#include "source/Endian.h"
+
+using namespace IFF_RIFF;
+
+static const XMP_Uns32 kPrmlSizeFix = 282; // always 282 bytes
+
+static const XMP_Uns32 kSizeFilePath = 260;
+
+// Needed to be able to memcpy directly to this struct.
+#pragma pack ( push, 1 )
+ struct PrmlBoxContent
+ {
+ XMP_Uns32 mMagic;
+ XMP_Uns32 mSize;
+ XMP_Uns16 mVerAPI;
+ XMP_Uns16 mVerCode;
+ XMP_Uns32 mExportType;
+ XMP_Uns16 mMacVRefNum;
+ XMP_Uns32 mMacParID;
+ char mFilePath[kSizeFilePath];
+ };
+#pragma pack ( pop )
+
+//-----------------------------------------------------------------------------
+//
+// PrmLMetadata::PrmLMetadata(...)
+//
+// Purpose: ctor/dtor
+//
+//-----------------------------------------------------------------------------
+
+PrmLMetadata::PrmLMetadata()
+{
+}
+
+PrmLMetadata::~PrmLMetadata()
+{
+}
+
+//-----------------------------------------------------------------------------
+//
+// PrmLMetadata::parse(...)
+//
+// Purpose: Parses the given memory block and creates a data model representation
+// The implementation expects that the memory block is the data area of
+// the BEXT chunk and its size is at least as big as the minimum size
+// of a BEXT data block.
+// Throws exceptions if parsing is not possible
+//
+//-----------------------------------------------------------------------------
+
+void PrmLMetadata::parse( const XMP_Uns8* chunkData, XMP_Uns64 size )
+{
+ if( size >= kPrmlSizeFix )
+ {
+ const LittleEndian& LE = LittleEndian::getInstance();
+
+ PrmlBoxContent prml;
+ memset( &prml, 0, kPrmlSizeFix );
+
+ //
+ // copy input data into Prml block
+ // Safe as fixed size matches size of struct that is #pragma packed(1)
+ //
+ memcpy( &prml, chunkData, kPrmlSizeFix );
+
+ //
+ // copy values to map
+ //
+ this->setValue<XMP_Uns32>( kMagic, prml.mMagic );
+ this->setValue<XMP_Uns32>( kSize, prml.mSize );
+ this->setValue<XMP_Uns16>( kVerAPI, prml.mVerAPI );
+ this->setValue<XMP_Uns16>( kVerCode, prml.mVerCode );
+ this->setValue<XMP_Uns32>( kExportType, prml.mExportType );
+ this->setValue<XMP_Uns16>( kMacVRefNum, prml.mMacVRefNum );
+ this->setValue<XMP_Uns32>( kMacParID, prml.mMacParID );
+ this->setValue<std::string>( kFilePath, std::string( prml.mFilePath, kSizeFilePath ) );
+
+ this->resetChanges();
+ }
+ else
+ {
+ XMP_Throw ( "Not a valid Prml chunk", kXMPErr_BadFileFormat );
+ }
+}
+
+//-----------------------------------------------------------------------------
+//
+// PrmLMetadata::serialize(...)
+//
+// Purpose: Serializes the data model to a memory block.
+// The memory block will be the data area of a BEXT chunk.
+// Throws exceptions if serializing is not possible
+//
+//-----------------------------------------------------------------------------
+
+XMP_Uns64 PrmLMetadata::serialize( XMP_Uns8** outBuffer )
+{
+ XMP_Uns64 size = 0;
+
+ if( outBuffer != NULL )
+ {
+ const LittleEndian& LE = LittleEndian::getInstance();
+
+ size = kPrmlSizeFix;
+
+ //
+ // setup buffer
+ //
+ XMP_Uns8* buffer = new XMP_Uns8[static_cast<size_t>(size)];
+
+ //
+ // copy values and strings back to BEXT block
+ //
+ // ! Safe use of strncpy as the fixed size is consistent with the size of the destination buffer
+ // But it is intentional here that the string might not be null terminated if
+ // the size of the source is equal to the fixed size of the destination
+ //
+ PrmlBoxContent prml;
+ memset( &prml, 0, kPrmlSizeFix );
+
+ if( this->valueExists( kMagic ) )
+ {
+ LE.putUns32( this->getValue<XMP_Uns32>( kMagic ), &prml.mMagic );
+ }
+ if( this->valueExists( kSize ) )
+ {
+ LE.putUns32( this->getValue<XMP_Uns32>( kSize ), &prml.mSize );
+ }
+ if( this->valueExists( kVerAPI ) )
+ {
+ LE.putUns16( this->getValue<XMP_Uns16>( kVerAPI ), &prml.mVerAPI );
+ }
+ if( this->valueExists( kVerCode ) )
+ {
+ LE.putUns16( this->getValue<XMP_Uns16>( kVerCode ), &prml.mVerCode );
+ }
+ if( this->valueExists( kExportType ) )
+ {
+ LE.putUns32( this->getValue<XMP_Uns32>( kExportType ), &prml.mExportType );
+ }
+ if( this->valueExists( kMacVRefNum ) )
+ {
+ LE.putUns16( this->getValue<XMP_Uns16>( kMacVRefNum ), &prml.mMacVRefNum );
+ }
+ if( this->valueExists( kMacParID ) )
+ {
+ LE.putUns32( this->getValue<XMP_Uns32>( kMacParID ), &prml.mMacParID );
+ }
+ if( this->valueExists( kFilePath ) )
+ {
+ strncpy( prml.mFilePath, this->getValue<std::string>( kFilePath ).c_str(), kSizeFilePath );
+ }
+
+ //
+ // set input buffer to zero
+ //
+ memset( buffer, 0, static_cast<size_t>(size) );
+
+ //
+ // copy Prml block into buffer
+ //
+ memcpy( buffer, &prml, kPrmlSizeFix );
+
+ *outBuffer = buffer;
+ }
+ else
+ {
+ XMP_Throw ( "Invalid buffer", kXMPErr_BadParam );
+ }
+
+ return size;
+}
+
+//-----------------------------------------------------------------------------
+//
+// PrmLMetadata::isEmptyValue(...)
+//
+// Purpose: Is the value of the passed ValueObject and its id "empty"?
+//
+//-----------------------------------------------------------------------------
+
+bool PrmLMetadata::isEmptyValue( XMP_Uns32 id, ValueObject& valueObj )
+{
+ bool ret = true;
+
+ switch( id )
+ {
+ case kFilePath:
+ {
+ TValueObject<std::string>* strObj = dynamic_cast<TValueObject<std::string>*>(&valueObj);
+
+ ret = ( strObj == NULL || ( strObj != NULL && strObj->getValue().empty() ) );
+ }
+ break;
+
+ case kMagic:
+ case kSize:
+ case kVerAPI:
+ case kVerCode:
+ case kExportType:
+ case kMacVRefNum:
+ case kMacParID:
+ {
+ ret = false;
+ }
+ break;
+
+ default:
+ {
+ ret = true;
+ }
+ }
+
+ return ret;
+}