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

📄 wav_handler.cpp

📁 flash xmp sdk,flash官方SDK
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// =================================================================================================// 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.// =================================================================================================#if WIN_ENV	#pragma warning ( disable : 4996 )	// '...' was declared deprecated#endif#include "WAV_Handler.hpp"#include "RIFF_Support.hpp"#include "Reconcile_Impl.hpp"#include "XMP_Const.h"using namespace std;#define kXMPUserDataType MakeFourCC ( '_', 'P', 'M', 'X' )	/* Yes, backwards! */#define	formtypeWAVE	MakeFourCC('W', 'A', 'V', 'E')// -------------------------------------------------------------------------------------------------// Premiere Pro specific info for reconciliation// ! MakeFourCC warning: The MakeFourCC macro creates a 32 bit int with the letters "reversed". This// ! is a leftover of the original Win-only code. It happens to work OK on little endian machines,// ! when stored in memory the letters are in the expected order. To be safe, always use the XMP// ! endian control macros when storing to memory or loading from memory.// FourCC codes for the RIFF chunks#define	wavWaveTitleChunk		MakeFourCC('D','I','S','P')#define	wavInfoCreateDateChunk	MakeFourCC('I','C','R','D')#define	wavInfoArtistChunk		MakeFourCC('I','A','R','T')#define	wavInfoAlbumChunk		MakeFourCC('I','N','A','M')#define	wavInfoGenreChunk		MakeFourCC('I','G','N','R')#define	wavInfoCommentChunk		MakeFourCC('I','C','M','T')#define wavInfoEngineerChunk	MakeFourCC('I','E','N','G')#define wavInfoCopyrightChunk	MakeFourCC('I','C','O','P')#define wavInfoSoftwareChunk	MakeFourCC('I','S','F','T')#define	wavInfoTag		MakeFourCC('I','N','F','O')#define	wavWaveTag		MakeFourCC('W','A','V','E')// DC#define kTitle		"title"#define kCopyright	"rights"// XMP#define kCreateDate	"CreateDate"// DM#define kArtist		"artist"#define kAlbum		"album"#define kGenre		"genre"#define kLogComment "logComment"#define kEngineer	"engineer"#define kSoftware	"CreatorTool"// -------------------------------------------------------------------------------------------------// Legacy digest info// ------------------//// The original WAV handler code didn't keep a legacy digest, it imported the legacy on every open.// Because local encoding is used for the legacy, this can cause loss in the XMP. (The use of local// encoding itself is an issue, the AVI handler is using UTF-8.)//// The legacy digest for WAV is a list of chunk IDs and a 128-bit MD5 digest, formatted like://   DISP,IART,ICMT,ICOP,ICRD,IENG,IGNR,INAM,ISFT;012345678ABCDEF012345678ABCDEF//// The list of IDs are the recognized legacy chunks, in alphabetical order. This the full list that// could be recognized, not restricted to those actually present in the specific file. When opening// a file the new software's list is used to create the comparison digest, not the list from the// file. So that changes to the recognized list will trigger an import.//// The MD5 digest is computed from the full legacy chunk, including the ID and length portions, not// including any pad byte for odd data length. The length must be in file (little endian) order,// not native machine order. The legacy chunks are added to the digest in list (alphabetical by ID)// order.//// Legacy can be imported in 3 circumstances://// 1. If the file does not yet have XMP, all of the legacy is imported.//// 2. If the file has XMP and a digest, and the recomputed digest differs from the saved digest, the//    legacy is imported. The digest comparison is the full string, including the list of IDs. A//    check is made for each legacy item://    2a. If the legacy item is missing or has an empty value, the corresponding XMP is deleted.//    2b. If the corresponding XMP is missing, the legacy value is imported.//    2c. If the new legacy value differs from a local encoding of the XMP value, the legacy value//        is imported.//// 3. If the file has XMP but no digest, legacy is imported for items that have no corresponding XMP.//    Any existing XMP is left alone. This is protection for tools that might be XMP aware but do//    not provide a digest or any legacy reconciliation.#define TAG_MAX_SIZE 5024// =================================================================================================static inline int GetStringRiffSize ( const std::string & str ){	int l = strlen ( const_cast<char *> (str.data()) );	if ( l & 1 ) ++l;	return l;}// =================================================================================================/// \file WAV_Handler.cpp/// \brief File format handler for WAV.////// This header ...///// =================================================================================================// =================================================================================================// WAV_MetaHandlerCTor// ===================XMPFileHandler * WAV_MetaHandlerCTor ( XMPFiles * parent ){	return new WAV_MetaHandler ( parent );}	// WAV_MetaHandlerCTor// =================================================================================================// WAV_CheckFormat// ===============//// A WAVE file must begin with "RIFF", a 4 byte little endian length, then "WAVE". The length should// be fileSize-8, but we don't bother checking this here.bool WAV_CheckFormat ( XMP_FileFormat format,					   XMP_StringPtr  filePath,			           LFA_FileRef    fileRef,			           XMPFiles *     parent ){	IgnoreParam(format); IgnoreParam(parent);	XMP_Assert ( format == kXMP_WAVFile );	if ( fileRef == 0 ) return false;		enum { kBufferSize = 12 };	XMP_Uns8 buffer [kBufferSize];		LFA_Seek ( fileRef, 0, SEEK_SET );	LFA_Read ( fileRef, buffer, kBufferSize );		// "RIFF" is 52 49 46 46, "WAVE" is 57 41 56 45	if ( (! CheckBytes ( &buffer[0], "\x52\x49\x46\x46", 4 )) ||		 (! CheckBytes ( &buffer[8], "\x57\x41\x56\x45", 4 )) ) return false;	return true;	}	// WAV_CheckFormat// =================================================================================================// WAV_MetaHandler::WAV_MetaHandler// ================================WAV_MetaHandler::WAV_MetaHandler ( XMPFiles * _parent ){	this->parent = _parent;	this->handlerFlags = kWAV_HandlerFlags;	this->stdCharForm  = kXMP_Char8Bit;	}	// WAV_MetaHandler::WAV_MetaHandler// =================================================================================================// WAV_MetaHandler::~WAV_MetaHandler// =================================WAV_MetaHandler::~WAV_MetaHandler(){	// Nothing to do.}	// WAV_MetaHandler::~WAV_MetaHandler// =================================================================================================// WAV_MetaHandler::UpdateFile// ===========================void WAV_MetaHandler::UpdateFile ( bool doSafeUpdate ){	if ( ! this->needsUpdate ) return;	if ( doSafeUpdate ) XMP_Throw ( "WAV_MetaHandler::UpdateFile: Safe update not supported", kXMPErr_Unavailable );	bool fReconciliate = ! (this->parent->openFlags & kXMPFiles_OpenOnlyXMP);	bool ok;	std::string strTitle, strArtist, strComment, strCopyright, strCreateDate,				strEngineer, strGenre, strAlbum, strSoftware;		if ( fReconciliate ) {			// Get the legacy item values, create the new digest, and add the digest to the XMP. The		// legacy chunks in alphabetical ID order are:		//   DISP - title		//   IART - artist		//   ICMT - log comment		//   ICOP - copyright		//   ICRD - create date		//   IENG - engineer		//   IGNR - genre		//   INAM - album		//   ISFT - software		MD5_CTX md5Ctx;		std::string digestStr;		XMP_Uns8 md5Val[16];		static char* hexDigits = "0123456789ABCDEF";				MD5Init ( &md5Ctx );		// Prepare the legacy values and compute the new digest.				PrepareLegacyExport ( kXMP_NS_DC, kTitle, wavWaveTitleChunk, &strTitle, &digestStr, &md5Ctx, true /* LangAlt */ );		PrepareLegacyExport ( kXMP_NS_DM, kArtist, wavInfoArtistChunk, &strArtist, &digestStr, &md5Ctx );		PrepareLegacyExport ( kXMP_NS_DM, kLogComment, wavInfoCommentChunk, &strComment, &digestStr, &md5Ctx );		PrepareLegacyExport ( kXMP_NS_DC, kCopyright, wavInfoCopyrightChunk, &strCopyright, &digestStr, &md5Ctx, true /* LangAlt */ );		PrepareLegacyExport ( kXMP_NS_XMP, kCreateDate, wavInfoCreateDateChunk, &strCreateDate, &digestStr, &md5Ctx );		PrepareLegacyExport ( kXMP_NS_DM, kEngineer, wavInfoEngineerChunk, &strEngineer, &digestStr, &md5Ctx );		PrepareLegacyExport ( kXMP_NS_DM, kGenre, wavInfoGenreChunk, &strGenre, &digestStr, &md5Ctx );		PrepareLegacyExport ( kXMP_NS_DM, kAlbum, wavInfoAlbumChunk, &strAlbum, &digestStr, &md5Ctx );		PrepareLegacyExport ( kXMP_NS_XMP, kSoftware, wavInfoSoftwareChunk, &strSoftware, &digestStr, &md5Ctx );				// Finish the digest and add it to the XMP.				MD5Final ( md5Val, &md5Ctx );				digestStr[digestStr.size()-1] = ';';		for ( size_t i = 0; i < 16; ++i ) {			XMP_Uns8 byte = md5Val[i];			digestStr += hexDigits [byte >> 4];			digestStr += hexDigits [byte & 0xF];		}		XMP_StringLen oldLen = this->xmpPacket.size();		this->xmpObj.SetProperty ( kXMP_NS_WAV, "NativeDigest", digestStr.c_str() );		try {			this->xmpObj.SerializeToBuffer ( &this->xmpPacket, kXMP_ExactPacketLength, oldLen );		} catch ( ... ) {			this->xmpObj.SerializeToBuffer ( &this->xmpPacket, kXMP_UseCompactFormat );		}		}		XMP_StringPtr packetStr = this->xmpPacket.c_str();	XMP_StringLen packetLen = this->xmpPacket.size();	if ( packetLen == 0 ) return;	// Make sure we're writing an even number of bytes as required by the RIFF specification	if ( (this->xmpPacket.size() & 1) == 1 ) this->xmpPacket.push_back (' ');	XMP_Assert ( (this->xmpPacket.size() & 1) == 0 );	packetStr = this->xmpPacket.c_str();	// ! Make sure they are current.	packetLen = this->xmpPacket.size();		LFA_FileRef fileRef ( this->parent->fileRef );	if ( fileRef == 0 ) return;	RIFF_Support::RiffState riffState;	long numTags = RIFF_Support::OpenRIFF(fileRef, riffState);	if ( numTags == 0 ) return;	ok = RIFF_Support::PutChunk ( fileRef, riffState, formtypeWAVE, kXMPUserDataType, (char*)packetStr, packetLen );	if ( ! ok ) return;	// If needed, reconciliate the XMP data back into the native metadata.	if ( fReconciliate ) {		PutChunk ( fileRef, riffState, wavWaveTag, wavWaveTitleChunk, strTitle.c_str(), strTitle.size() );		// Pad the old tags		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoCreateDateChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoArtistChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoAlbumChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoGenreChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoCommentChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoEngineerChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoCopyrightChunk, 0 );		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, 0, wavInfoSoftwareChunk, 0 );		// Get the old INFO list		std::string strOldInfo;		unsigned long lOldSize = 0;		bool ok = RIFF_Support::GetRIFFChunk ( fileRef, riffState, FOURCC_LIST, wavWaveTag, wavInfoTag, 0, &lOldSize );		if ( ok ) {			// We have to get rid of the "INFO" first.			strOldInfo.reserve ( lOldSize );			strOldInfo.assign ( lOldSize, ' ' );			RIFF_Support::GetRIFFChunk ( fileRef, riffState, FOURCC_LIST, wavWaveTag, wavInfoTag, (char*)strOldInfo.c_str(), &lOldSize );			// lOldSize -= 4;		}		// TODO: Cleaning up the OldInfo from the padding		// Pad the old INFO list		RIFF_Support::MarkChunkAsPadding ( fileRef, riffState, wavWaveTag, FOURCC_LIST, wavInfoTag );				// Calculating the new INFO list size		XMP_Int32 dwListSize = 4 + 8 * 8 +						   GetStringRiffSize ( strCreateDate )  +						   GetStringRiffSize ( strArtist ) +						   GetStringRiffSize ( strAlbum ) +						   GetStringRiffSize ( strGenre ) +						   GetStringRiffSize ( strComment ) +						   GetStringRiffSize ( strEngineer ) +						   GetStringRiffSize ( strCopyright ) +						   GetStringRiffSize ( strSoftware ) +						   lOldSize;  // list id (4 bytes) + 8 tags hdrs (8 each)		ok = MakeChunk ( fileRef, riffState, formtypeWAVE, dwListSize + 8 );		if ( ! ok ) return; // If there's an error making a chunk, bail		// Building the INFO list header		RIFF_Support::ltag listtag;		listtag.id = MakeUns32LE ( FOURCC_LIST );		listtag.len = MakeUns32LE ( dwListSize );		listtag.subid = MakeUns32LE ( wavInfoTag );		LFA_Write ( fileRef, &listtag, 12 );

⌨️ 快捷键说明

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