⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 riff_support.cpp

📁 flash xmp sdk,flash官方SDK
💻 CPP
字号:
// =================================================================================================// ADOBE SYSTEMS INCORPORATED// Copyright 2002-2007 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 "RIFF_Support.hpp"namespace RIFF_Support {	#define	ckidPremierePadding	MakeFourCC ('J','U','N','Q')	#define	formtypeAVIX		MakeFourCC ('A', 'V', 'I', 'X')	#ifndef	AVIMAXCHUNKSIZE		#define	AVIMAXCHUNKSIZE	((UInt32) 0x80000000)		/* 2 GB */	#endif	typedef struct	{		long	id;		UInt32	len;	} atag;	// Local function declarations	static bool ReadTag ( LFA_FileRef inFileRef, long * outTag, UInt32 * outLength, long * subtype, UInt64 & inOutPosition );	static void AddTag ( RiffState & inOutRiffState, long tag, UInt32 len, UInt64 & inOutPosition, long parentID, long parentnum, long subtypeID );	static long SubRead ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long parentid, UInt32 parentlen, UInt64 & inOutPosition );	static bool ReadChunk ( LFA_FileRef inFileRef, UInt64 & pos, UInt32 len, char * outBuffer );	#define GetFilePosition(file)	LFA_Seek ( file, 0, SEEK_CUR )		// =============================================================================================	bool GetMetaData ( LFA_FileRef inFileRef, long tagID, char * outBuffer, unsigned long * outBufferSize )	{		RiffState riffState;			long numTags = OpenRIFF ( inFileRef, riffState );		if ( numTags == 0 ) return false;			return GetRIFFChunk ( inFileRef, riffState, tagID, 0, 0, outBuffer, outBufferSize );		}	// =============================================================================================	bool SetMetaData ( LFA_FileRef inFileRef, long riffType, long tagID, const char * inBuffer, unsigned long inBufferSize )	{		RiffState riffState;			long numTags = OpenRIFF ( inFileRef, riffState );		if ( numTags == 0 ) return false;			return PutChunk ( inFileRef, riffState, riffType, tagID, inBuffer, inBufferSize );		}	// =============================================================================================	bool MarkChunkAsPadding ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, long tagID, long subtypeID )	{		UInt32 len;		UInt64 pos;		atag tag;			try {				bool found = FindChunk ( inOutRiffState, tagID, riffType, subtypeID, NULL, &len, &pos );			if ( ! found ) return false;				if ( subtypeID != 0 ) {				pos -= 12;			} else {				pos -= 8;			}			tag.id = MakeUns32LE ( ckidPremierePadding );			LFA_Seek ( inFileRef, pos, SEEK_SET );			LFA_Write ( inFileRef, &tag, 4 );				pos += 8;			AddTag ( inOutRiffState, ckidPremierePadding, len, pos, 0, 0, 0 );			} catch(...) {				return false;	// If a write fails, it throws, so we return false.			}			return true;	}	// =============================================================================================	bool PutChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, long tagID, const char * inBuffer, UInt32 inBufferSize )	{		UInt32 len;		UInt64 pos;		atag tag;			// Make sure we're writting an even number of bytes. Required by the RIFF specification.		XMP_Assert ( (inBufferSize & 1) == 0 );			try {			bool found = FindChunk ( inOutRiffState, tagID, 0, 0, NULL, &len, &pos );			if ( found ) {				if ( len == inBufferSize ) {					LFA_Seek ( inFileRef, pos, SEEK_SET );					LFA_Write ( inFileRef, inBuffer, inBufferSize );					return true;				}					pos -= 8;				tag.id = MakeUns32LE ( ckidPremierePadding );				LFA_Seek ( inFileRef, pos, SEEK_SET );				LFA_Write ( inFileRef, &tag, 4 );					if ( len > inBufferSize ) {					pos += 8;					AddTag ( inOutRiffState, ckidPremierePadding, len, pos, 0, 0, 0 );				}			}		} catch ( ... ) {			// If a write fails, it throws, so we return false			return false;		}			bool ok = MakeChunk ( inFileRef, inOutRiffState, riffType, (inBufferSize + 8) );		if ( ! ok ) return false;			return WriteChunk ( inFileRef, tagID, inBuffer, inBufferSize );		}	// =============================================================================================	bool RewriteChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long tagID, long parentID, const char * inData )	{		UInt32 len;		UInt64 pos;			try {			if ( FindChunk ( inOutRiffState, tagID, parentID, 0, NULL, &len, &pos ) ) {				LFA_Seek ( inFileRef, pos, SEEK_SET );				LFA_Write ( inFileRef, inData, len );			}		} catch ( ... ) {			return false;		}			return true;		}	// =============================================================================================	bool MakeChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, UInt32 len )	{		long starttag, taglen;		UInt32 rifflen, avail;		UInt64 pos;			/* look for top level Premiere padding chunk */		starttag = 0;		while ( FindChunk ( inOutRiffState, ckidPremierePadding, riffType, 0, &starttag, reinterpret_cast<unsigned long*>(&taglen), &pos ) ) {				pos -= 8;			taglen += 8;			long extra = taglen - len;			if ( extra < 0 ) continue;				RiffIterator iter = inOutRiffState.tags.begin();			iter += (starttag - 1);				if ( extra == 0 ) {				iter->len = 0;			} else {				atag pad;				UInt64 padpos;					/*  need 8 bytes extra to be able to split it */				extra -= 8;				if ( extra < 0 ) continue;					try{					padpos = pos + len;					LFA_Seek ( inFileRef, padpos, SEEK_SET );					pad.id = MakeUns32LE ( ckidPremierePadding );					pad.len = MakeUns32LE ( extra );					LFA_Write ( inFileRef, &pad, sizeof(pad) );				} catch ( ... ) {					return false;				}				iter->pos = padpos + 8;				iter->len = extra;			}				/* seek back to start of original padding chunk */			LFA_Seek ( inFileRef, pos, SEEK_SET );				return true;		}			/* can't take padding chunk, so append new chunk to end of file */			rifflen = inOutRiffState.rifflen + 8;		avail = AVIMAXCHUNKSIZE - rifflen;			LFA_Seek ( inFileRef, 0, SEEK_END );		pos = GetFilePosition ( inFileRef );			if ( avail < len ) {			/* if needed, create new AVIX chunk */			ltag avix;				avix.id = MakeUns32LE ( FOURCC_RIFF );			avix.len = MakeUns32LE ( 4 + len );			avix.subid = MakeUns32LE ( formtypeAVIX );			LFA_Write(inFileRef, &avix, sizeof(avix));				pos += 12;			AddTag ( inOutRiffState, avix.id, len, pos, 0, 0, 0 );		} else {			/* otherwise, rewrite length of last RIFF chunk in file */			pos = inOutRiffState.riffpos + 4;			rifflen = inOutRiffState.rifflen + len;			XMP_Uns32 fileLen = MakeUns32LE ( rifflen );			LFA_Seek ( inFileRef, pos, SEEK_SET );			LFA_Write ( inFileRef, &fileLen, 4 );			inOutRiffState.rifflen = rifflen;				/* prepare to write data */			LFA_Seek ( inFileRef, 0, SEEK_END );		}			return true;	}	// =============================================================================================	bool WriteChunk ( LFA_FileRef inFileRef, long tagID, const char * data, UInt32 len )	{		atag ck;		ck.id = MakeUns32LE ( tagID );		ck.len = MakeUns32LE ( len );			try {			LFA_Write ( inFileRef, &ck, 8 );			LFA_Write ( inFileRef, data, len );		} catch ( ... ) {			return false;		}			return true;	}	// =============================================================================================	long OpenRIFF ( LFA_FileRef inFileRef, RiffState & inOutRiffState )	{		UInt64 pos = 0;		long tag, subtype;		UInt32 len;			LFA_Seek ( inFileRef, 0, SEEK_SET );			// read first tag (always RIFFtype)		while ( ReadTag ( inFileRef, &tag, &len, &subtype, pos) ) {			if ( tag != FOURCC_RIFF ) break;			AddTag ( inOutRiffState, tag, len, pos, 0, 0, subtype );			if ( subtype != 0 ) SubRead ( inFileRef, inOutRiffState, subtype, len, pos );		}			return inOutRiffState.tags.size();	}	// =============================================================================================	static bool  ReadTag ( LFA_FileRef inFileRef, long * outTag, UInt32 * outLength, long * subtype, UInt64 & inOutPosition )	{		UInt32	realLength;			try {			long bytesRead;			bytesRead = LFA_Read ( inFileRef, outTag, 4 );			if ( bytesRead == 0 ) return false;			*outTag = GetUns32LE ( outTag );						bytesRead = LFA_Read ( inFileRef, outLength, 4 );			if ( bytesRead == 0 ) return false;			*outLength = GetUns32LE ( outLength );				realLength = *outLength;			realLength += (realLength & 1);		// round up to words				*subtype = 0;				if ( (*outTag != FOURCC_LIST) && (*outTag != FOURCC_RIFF) ) {				inOutPosition = GetFilePosition ( inFileRef );				UInt64 tempPos = inOutPosition + realLength;				LFA_Seek ( inFileRef, tempPos, SEEK_SET );			} else  {				bytesRead = LFA_Read ( inFileRef, subtype, 4 );				if ( bytesRead == 0 ) return false;				*subtype = GetUns32LE ( subtype );				*outLength -= 4;				realLength -= 4;					// Special case:				// Since the 'movi' chunk can contain billions of subchunks, skip over the 'movi' subchunk.				//				// The 'movi' subtype is added to the list as the TAG.				// The subtype is returned empty so nobody will try to parse the subchunks.				if ( *subtype == listtypeAVIMOVIE ) {					inOutPosition = GetFilePosition ( inFileRef );					UInt64 tempPos = inOutPosition + realLength;					LFA_Seek ( inFileRef, tempPos, SEEK_SET );					*outLength += 4;					*outTag = *subtype;					*subtype = 0;				}				inOutPosition = GetFilePosition ( inFileRef );			}		} catch ( ... ) {			return false;		}			return true;	}	// =============================================================================================	static void  AddTag ( RiffState & inOutRiffState, long tag, UInt32 len, UInt64 & inOutPosition, long parentID, long parentnum, long subtypeID )	{		RiffTag	newTag;			newTag.pos = inOutPosition;		newTag.tagID = tag;		newTag.len = len;		newTag.parent = parentnum;		newTag.parentID = parentID;		newTag.subtypeID = subtypeID;			inOutRiffState.tags.push_back ( newTag );			if ( tag == FOURCC_RIFF ) {			inOutRiffState.riffpos = inOutPosition - 12;			inOutRiffState.rifflen = len + 4;		}	}	// =============================================================================================	static long SubRead ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long parentid, UInt32 parentlen, UInt64 & inOutPosition )	{		long tag;		long subtype = 0;		long parentnum;		UInt32 len, total, childlen;		UInt64 oldpos;			total = 0;		parentnum = inOutRiffState.tags.size() - 1;			while ( parentlen > 0 ) {			oldpos = inOutPosition;			ReadTag ( inFileRef, &tag, &len, &subtype, inOutPosition );			AddTag ( inOutRiffState, tag, len, inOutPosition, parentid, parentnum, subtype );			len += (len & 1);			if ( subtype == 0 ) {				childlen = 8 + len;			} else {				childlen = 12 + SubRead ( inFileRef, inOutRiffState, subtype, len, inOutPosition );			}			if ( parentlen < childlen ) parentlen = childlen;			parentlen -= childlen;			total += childlen;		}			return total;		}	// =============================================================================================	bool GetRIFFChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long tagID,						long parentID, long subtypeID, char * outBuffer, unsigned long * outBufferSize )	{		UInt32 len;		UInt64 pos;				bool found = FindChunk ( inOutRiffState, tagID, parentID, subtypeID, 0, &len, &pos );		if ( ! found ) return false;			if ( outBuffer == 0 ) {			*outBufferSize = (unsigned long)len;			return true;	// Found, but not wanted.		}			if ( len > *outBufferSize ) len = *outBufferSize;			found = ReadChunk ( inFileRef, pos, len, outBuffer );		return found;		}	// =============================================================================================	bool FindChunk ( RiffState & inOutRiffState, long tagID, long parentID, long subtypeID,					 long * startTagIndex, UInt32 * len, UInt64 * pos)	{		std::vector<RiffTag>::iterator iter = inOutRiffState.tags.begin();		std::vector<RiffTag>::iterator endIter = inOutRiffState.tags.end();				// If we're using the next index, skip the iterator.		if ( startTagIndex != 0 ) iter += *startTagIndex;			for ( ; iter != endIter ; ++iter ) {			if ( startTagIndex != 0 ) *startTagIndex += 1;				if ( (parentID!= 0) && (iter->parentID != parentID) ) continue;			if ( (tagID != 0) && (iter->tagID != tagID) ) continue;			if ( (subtypeID != 0) && (iter->subtypeID != subtypeID) ) continue;				if ( len != 0 ) *len = iter->len;			if ( pos != 0 ) *pos = iter->pos;						return true;		}			return false;	}	// =============================================================================================	static bool ReadChunk ( LFA_FileRef inFileRef, UInt64 & pos, UInt32 len, char * outBuffer )	{			if ( (inFileRef == 0) || (outBuffer == 0) ) return false;			LFA_Seek (inFileRef, pos, SEEK_SET );		UInt32 bytesRead = LFA_Read ( inFileRef, outBuffer, len );		if ( bytesRead != len ) return false;			return true;		}} // namespace RIFF_Support

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -