bool MP3_CheckFormat ( XMP_FileFormat format,
                       XMP_StringPtr  filePath,
                       XMP_IO*    file,
                       XMPFiles *     parent )
{
    IgnoreParam(filePath);
    IgnoreParam(parent);	//supress warnings
    XMP_Assert ( format == kXMP_MP3File );		//standard assert

    if ( file->Length() < 10 ) return false;
    file ->Rewind();

    XMP_Uns8 header[3];
    file->ReadAll ( header, 3 );
    if ( ! CheckBytes( &header[0], "ID3", 3 ) ) return (parent->format == kXMP_MP3File);

    XMP_Uns8 major = XIO::ReadUns8( file );
    XMP_Uns8 minor = XIO::ReadUns8( file );

    if ( (major < 2) || (major > 4) || (minor == 0xFF) ) return false;

    XMP_Uns8 flags = XIO::ReadUns8 ( file );

    //TODO
    if ( flags & 0x10 ) XMP_Throw ( "no support for MP3 with footer", kXMPErr_Unimplemented );
    if ( flags & 0x80 ) return false; //no support for unsynchronized MP3 (as before, also see [1219125])
    if ( flags & 0x0F ) XMP_Throw ( "illegal header lower bits", kXMPErr_Unimplemented );

    XMP_Uns32 size = XIO::ReadUns32_BE ( file );
    if ( (size & 0x80808080) != 0 ) return false; //if any bit survives -> not a valid synchsafe 32 bit integer

    return true;

}	// MP3_CheckFormat
Esempio n. 2
0
// =================================================================================================
// MP3_CheckFormat
// ===============
// For MP3 we check parts .... See the MP3 spec for offset info.
bool MP3_CheckFormat ( XMP_FileFormat format,
					  XMP_StringPtr  filePath,
					  LFA_FileRef    file,
					  XMPFiles *     parent )
{
	IgnoreParam(filePath); IgnoreParam(parent);	//supress warnings
	XMP_Assert ( format == kXMP_MP3File );		//standard assert
	LFA_Rewind( file );

	XMP_Uns8 header[3];
	LFA_Read( file, header, 3, true );
	if ( !CheckBytes( &header[0], "ID3", 3 ))
		return (parent->format == kXMP_MP3File);	// No ID3 signature -> depend on first call hint.	

	XMP_Uns8 major = LFA_ReadUns8( file );
	XMP_Uns8 minor = LFA_ReadUns8( file );

	if ( (major<3 || major>4) || (minor == 0xFF) )
		return false;	// only support IDv2.3 and ID3v2.4, minor must not be 0xFF

	XMP_Uns8 flags = LFA_ReadUns8( file );

	//TODO
	if ( flags & 0x10 ) 
		XMP_Throw("no support for MP3 with footer",kXMPErr_Unimplemented); //no support for MP3 with footer
	if ( flags & 0x80 )
		return false; //no support for unsynchronized MP3 (as before, also see [1219125])
	if ( flags & 0x0F ) 
		XMP_Throw("illegal header lower bits",kXMPErr_Unimplemented);

	XMP_Uns32 size = LFA_ReadUns32_BE( file );
	if ( size & 0x80808080 ) return false; //if any bit survives -> not a valid synchsafe 32 bit integer

	return true;
}	// MP3_CheckFormat
Esempio n. 3
0
static void
RDF_ParseTypeOtherPropertyElement ( XMP_Node * xmpParent, const XML_Node & xmlNode, bool isTopLevel )
{
    IgnoreParam(xmpParent); IgnoreParam(xmlNode); IgnoreParam(isTopLevel);

    XMP_Throw ( "ParseTypeOther property element not allowed", kXMPErr_BadXMP );

}	// RDF_ParseTypeOtherPropertyElement
Esempio n. 4
0
static void StartNamespaceDeclHandler ( void * userData, XMP_StringPtr prefix, XMP_StringPtr uri )
{
    IgnoreParam(userData);

    // As a bug fix hack, change a URI of "http://purl.org/dc/1.1/" to ""http://purl.org/dc/elements/1.1/.
    // Early versions of Flash that put XMP in SWF used a bad URI for the dc: namespace.

    #if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
        ExpatAdapter * thiz = (ExpatAdapter*)userData;
    #endif

    if ( prefix == 0 ) prefix = "_dflt_";	// Have default namespace.
    if ( uri == 0 ) return;	// Ignore, have xmlns:pre="", no URI to register.

    #if XMP_DebugBuild & DumpXMLParseEvents
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "StartNamespace: %s - \"%s\"\n", prefix, uri );
        }
    #endif

    if ( XMP_LitMatch ( uri, "http://purl.org/dc/1.1/" ) ) uri = "http://purl.org/dc/elements/1.1/";
    (void) XMPMeta::RegisterNamespace ( uri, prefix, &voidStringPtr, &voidStringLen );

}	// StartNamespaceDeclHandler
Esempio n. 5
0
void ProcessRDF ( XMP_Node * xmpTree, const XML_Node & rdfNode, XMP_OptionBits options )
{
    IgnoreParam(options);

    RDF_RDF ( xmpTree, rdfNode );

}	// ProcessRDF
Esempio n. 6
0
void GIF_MetaHandler::UpdateFile ( bool doSafeUpdate )
{
	IgnoreParam(doSafeUpdate);
	XMP_Assert( !doSafeUpdate );	// This should only be called for "unsafe" updates.

	if ( ! this->needsUpdate ) return;

	XMP_IO * fileRef = this->parent->ioRef;

	/*XMP_StringPtr packetStr = xmpPacket.c_str();*/
	XMP_StringLen newPacketLength = (XMP_StringLen)xmpPacket.size();

	if ( newPacketLength == XMPPacketLength )
	{
		this->SeekFile( fileRef, this->packetInfo.offset, kXMP_SeekFromStart );
		fileRef->Write( this->xmpPacket.c_str(), newPacketLength );
	}
	else
	{
		XMP_IO* tempFile = fileRef->DeriveTemp();
		if ( tempFile == 0 ) XMP_Throw( "Failure creating GIF temp file", kXMPErr_InternalFailure );

		this->WriteTempFile( tempFile );
		fileRef->AbsorbTemp();
	}

	this->needsUpdate = false;

}	// GIF_MetaHandler::UpdateFile
Esempio n. 7
0
bool GIF_CheckFormat ( XMP_FileFormat format,
					   XMP_StringPtr  filePath,
                       XMP_IO*        fileRef,
                       XMPFiles *     parent )
{
	IgnoreParam(format); IgnoreParam(filePath); IgnoreParam(parent);
	XMP_Assert ( format == kXMP_GIFFile );

	if ( fileRef->Length() < GIF_89_Header_LEN ) return false;
	XMP_Uns8 buffer[ GIF_89_Header_LEN ];

	fileRef->Rewind();
	fileRef->Read( buffer, GIF_89_Header_LEN );
	if ( !CheckBytes( buffer, GIF_89_Header_DATA, GIF_89_Header_LEN ) ) return false;

	return true;

}	// GIF_CheckFormat
Esempio n. 8
0
bool ASF_CheckFormat ( XMP_FileFormat format,
					   XMP_StringPtr  filePath,
                       XMP_IO*    fileRef,
                       XMPFiles *     parent )
{

	IgnoreParam(format); IgnoreParam(fileRef); IgnoreParam(parent);
	XMP_Assert ( format == kXMP_WMAVFile );

	if ( fileRef->Length() < guidLen ) return false;
	GUID guid;

	fileRef->Rewind();
	fileRef->Read ( &guid, guidLen );
	if ( ! IsEqualGUID ( ASF_Header_Object, guid ) ) return false;

	return true;

}	// ASF_CheckFormat
bool ASF_CheckFormat ( XMP_FileFormat format,
					   XMP_StringPtr  filePath,
                       XMP_IO*    fileRef,
                       XMPFiles *     parent )
{

	IgnoreParam(format); IgnoreParam(fileRef); IgnoreParam(parent);
	XMP_Assert ( format == kXMP_WMAVFile );

	IOBuffer ioBuf;

	fileRef->Rewind();
	if ( ! CheckFileSpace ( fileRef, &ioBuf, guidLen ) ) return false;

	GUID guid;
	memcpy ( &guid, ioBuf.ptr, guidLen );

	if ( ! IsEqualGUID ( ASF_Header_Object, guid ) ) return false;

	return true;

}	// ASF_CheckFormat
Esempio n. 10
0
static void EndCdataSectionHandler ( void * userData )
{
    IgnoreParam(userData);

    #if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
        ExpatAdapter * thiz = (ExpatAdapter*)userData;
    #endif

    #if XMP_DebugBuild & DumpXMLParseEvents
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "EndCDATA\n" );
        }
    #endif

}	// EndCdataSectionHandler
Esempio n. 11
0
static void StartCdataSectionHandler ( void * userData )
{
    IgnoreParam(userData);

    #if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
        ExpatAdapter * thiz = (ExpatAdapter*)userData;
    #endif

    #if XMP_DebugBuild & DumpXMLParseEvents
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "StartCDATA\n" );
        }
    #endif

    // *** Since markup isn't recognized inside CDATA, this affects XMP's double escaping.

}	// StartCdataSectionHandler
Esempio n. 12
0
static void StartDoctypeDeclHandler ( void * userData, XMP_StringPtr doctypeName,
                                      XMP_StringPtr sysid, XMP_StringPtr pubid, int has_internal_subset )
{
    IgnoreParam(userData);

    ExpatAdapter * thiz = (ExpatAdapter*)userData;

    #if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "DocType: \"%s\"\n", doctypeName );
        }
    #endif

    thiz->isAborted = true;	// ! Can't throw an exception across the plain C Expat frames.
    (void) XML_StopParser ( thiz->parser, XML_FALSE /* not resumable */ );

}	// StartDoctypeDeclHandler
Esempio n. 13
0
static void EndElementHandler ( void * userData, XMP_StringPtr name )
{
    IgnoreParam(name);

    ExpatAdapter * thiz = (ExpatAdapter*)userData;

    #if XMP_DebugBuild
        --thiz->elemNesting;
    #endif
    (void) thiz->parseStack.pop_back();

    #if XMP_DebugBuild & DumpXMLParseEvents
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "EndElement: %s\n", name );
        }
    #endif

}	// EndElementHandler
Esempio n. 14
0
static void EndNamespaceDeclHandler ( void * userData, XMP_StringPtr prefix )
{
    IgnoreParam(userData);

    #if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
        ExpatAdapter * thiz = (ExpatAdapter*)userData;
    #endif

    if ( prefix == 0 ) prefix = "_dflt_";	// Have default namespace.

    #if XMP_DebugBuild & DumpXMLParseEvents
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "EndNamespace: %s\n", prefix );
        }
    #endif

    // ! Nothing to do, Expat has done all of the XML processing.

}	// EndNamespaceDeclHandler
Esempio n. 15
0
static void CommentHandler ( void * userData, XMP_StringPtr comment )
{
    IgnoreParam(userData);

    #if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
        ExpatAdapter * thiz = (ExpatAdapter*)userData;
    #endif

    if ( comment == 0 ) comment = "";

    #if XMP_DebugBuild & DumpXMLParseEvents
        if ( thiz->parseLog != 0 ) {
            PrintIndent ( thiz->parseLog, thiz->elemNesting );
            fprintf ( thiz->parseLog, "Comment: \"%s\"\n", comment );
        }
    #endif

    // ! Comments are ignored.

}	// CommentHandler
Esempio n. 16
0
XMP_Uns32 PSIR_FileWriter::UpdateFileResources ( LFA_FileRef sourceRef, LFA_FileRef destRef,
												 IOBuffer * ioBuf, XMP_AbortProc abortProc, void * abortArg )
{
	IgnoreParam(ioBuf);
	const XMP_Uns32 zero32 = 0;

	const bool checkAbort = (abortProc != 0);

	struct RsrcHeader {
		XMP_Uns32 type;
		XMP_Uns16 id;
	};
	XMP_Assert ( (offsetof(RsrcHeader,type) == 0) && (offsetof(RsrcHeader,id) == 4) );

	if ( this->memParsed ) XMP_Throw ( "Not file based", kXMPErr_EnforceFailure );

	XMP_Int64 destLenOffset = LFA_Seek ( destRef, 0, SEEK_CUR );
	XMP_Uns32 destLength = 0;

	LFA_Write ( destRef, &destLength, 4 );	// Write a placeholder for the new PSIR section length.

	#if 0
	{
		printf ( "\nPSIR_FileWriter::UpdateFileResources, count = %d\n", this->imgRsrcs.size() );
		InternalRsrcMap::iterator irPos = this->imgRsrcs.begin();
		InternalRsrcMap::iterator irEnd = this->imgRsrcs.end();
		for ( ; irPos != irEnd; ++irPos ) {
			InternalRsrcInfo& thisRsrc = irPos->second;
			printf ( "  #%d, dataLen %d, origOffset %d (0x%X)%s\n",
					 thisRsrc.id, thisRsrc.dataLen, thisRsrc.origOffset, thisRsrc.origOffset,
					 (thisRsrc.changed ? ", changed" : "") );
		}
	}
	#endif

	// First write all of the '8BIM' resources from the map. Use the internal data if present, else
	// copy the data from the file.

	RsrcHeader outHeader;
	outHeader.type  = MakeUns32BE ( k8BIM );

	InternalRsrcMap::iterator rsrcPos = this->imgRsrcs.begin();
	InternalRsrcMap::iterator rsrcEnd = this->imgRsrcs.end();

	// printf ( "\nPSIR_FileWriter::UpdateFileResources - 8BIM resources\n" );
	for ( ; rsrcPos != rsrcEnd; ++rsrcPos ) {

		InternalRsrcInfo& currRsrc = rsrcPos->second;

		outHeader.id = MakeUns16BE ( currRsrc.id );
		LFA_Write ( destRef, &outHeader, 6 );
		destLength += 6;

		if ( currRsrc.rsrcName == 0 ) {
			LFA_Write ( destRef, &zero32, 2 );
			destLength += 2;
		} else {
			XMP_Assert ( currRsrc.rsrcName[0] != 0 );
			XMP_Uns16 nameLen = currRsrc.rsrcName[0];	// ! Include room for +1.
			XMP_Uns16 paddedLen = (nameLen + 2) & 0xFFFE;	// ! Round up to an even total. Yes, +2!
			LFA_Write ( destRef, currRsrc.rsrcName, paddedLen );
			destLength += paddedLen;
		}

		XMP_Uns32 dataLen = MakeUns32BE ( currRsrc.dataLen );
		LFA_Write ( destRef, &dataLen, 4 );
		// printf ( "  #%d, offset %d (0x%X), dataLen %d\n", currRsrc.id, destLength, destLength, currRsrc.dataLen );

		if ( currRsrc.dataPtr != 0 ) {
			LFA_Write ( destRef, currRsrc.dataPtr, currRsrc.dataLen );
		} else {
			LFA_Seek ( sourceRef, currRsrc.origOffset, SEEK_SET );
			LFA_Copy ( sourceRef, destRef, currRsrc.dataLen );
		}

		destLength += 4 + currRsrc.dataLen;

		if ( (currRsrc.dataLen & 1) != 0 ) {
			LFA_Write ( destRef, &zero32, 1 );	// ! Pad the data to an even length.
			++destLength;
		}

	}

	// Now write all of the non-8BIM resources. Copy the entire resource chunk from the source file.

	// printf ( "\nPSIR_FileWriter::UpdateFileResources - other resources\n" );
	for ( size_t i = 0; i < this->otherRsrcs.size(); ++i ) {
		// printf ( "  offset %d (0x%X), length %d",
		//		 this->otherRsrcs[i].rsrcOffset, this->otherRsrcs[i].rsrcOffset, this->otherRsrcs[i].rsrcLength );
		LFA_Seek ( sourceRef, this->otherRsrcs[i].rsrcOffset, SEEK_SET );
		LFA_Copy ( sourceRef, destRef, this->otherRsrcs[i].rsrcLength );
		destLength += this->otherRsrcs[i].rsrcLength;	// Alignment padding is already included.
	}

	// Write the final PSIR section length, seek back to the end of the file, return the length.

	// printf ( "\nPSIR_FileWriter::UpdateFileResources - final length %d (0x%X)\n", destLength, destLength );
	LFA_Seek ( destRef, destLenOffset, SEEK_SET );
	XMP_Uns32 outLen = MakeUns32BE ( destLength );
	LFA_Write ( destRef, &outLen, 4 );
	LFA_Seek ( destRef, 0, SEEK_END );

	// *** Not rebuilding the internal map - turns out we never want it, why pay for the I/O.
	// *** Should probably add an option for all of these cases, memory and file based.

	return destLength;

}	// PSIR_FileWriter::UpdateFileResources
Esempio n. 17
0
void MP3_MetaHandler::WriteFile ( LFA_FileRef         sourceRef,
								 const std::string & sourcePath )
{
	IgnoreParam(sourceRef); IgnoreParam(sourcePath);
	XMP_Throw ( "MP3_MetaHandler::WriteFile: Not supported", kXMPErr_Unimplemented );
}	// MP3_MetaHandler::WriteFile
void MP3_MetaHandler::WriteTempFile ( XMP_IO* tempRef )
{
    IgnoreParam(tempRef);
    XMP_Throw ( "MP3_MetaHandler::WriteTempFile: Not supported", kXMPErr_Unimplemented );
}	// MP3_MetaHandler::WriteTempFile