您的位置:首页 > 其它

WMA格式文件中的TAG信息格式及解析类

2010-05-15 01:33 411 查看
需要WMA格式的TAG信息,整理了一下,在这里与大家分享一下。

首先介绍下WMA文件头的结构,如下图

/*************************************************************************
// 分为文件头和各个帧数据(文件头前16个字节WMA格式是固定的,8个字节的大小是高位存在后面,以后遇到大小都是高位存在后面)
+--------------------------------------------------------------+
| Header (30 bytes) HeadFlag:16; HeadSize:8; Unknow:6 |
+--------------------------------------------------------------+
| Frames (1....n) |
+--------------------------------------------------------------+
// 所有的TAG信息存放在标准帧和扩展帧中,其他帧可以不予考虑,标准帧以及扩展帧的16个字节标识头都是固定的
// 所有的信息都是UNICODE编码
// 标准帧结构
+--------------------------------------------------------------+
| Header (24 bytes) HeadFlag:16; HeadSize:8; |
+--------------------------------------------------------------+
| 标题信息大小(2 bytes) |
+--------------------------------------------------------------+
| 艺术家信息大小(2 bytes) |
+--------------------------------------------------------------+
| 版权信息大小(2 bytes) |
+--------------------------------------------------------------+
| 备注信息大小(2 bytes) |
+--------------------------------------------------------------+
| 未知信息大小(2 bytes) |
+--------------------------------------------------------------+
| 标题信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 艺术家信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 版权信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 备注信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
| 未知信息内容(0x00 0x00结束) |
+--------------------------------------------------------------+
// 扩展帧结构
+--------------------------------------------------------------+
| Header (24 bytes) HeadFlag:16; HeadSize:8; |
+--------------------------------------------------------------+
| 扩展信息个数EXNO(2 bytes) |
+--------------------------------------------------------------+
| EXINFO (1....EXNO) |
+--------------------------------------------------------------+
// 每个扩展信息EXINFO结构
+--------------------------------------------------------------+
| EXINFO NAME Size (2 bytes) 扩展信息名字大小 |
+--------------------------------------------------------------+
| 扩展信息名称 |
+--------------------------------------------------------------+
| 标志FLAG (2 bytes) |
+--------------------------------------------------------------+
| 值的大小 (2 bytes) |
+--------------------------------------------------------------+
| 实际的值 (若是图片格式参考ID3V2.3) |
+--------------------------------------------------------------+
当扩展信息名字为WMFSDKVersion时,这个值表示的是这个WMA文件的版本;
当扩展信息名字为WM/AlbumTitle时,这个值代表的就是专辑名;
当扩展信息名字为WM/Genre时,这个值代表的就是流派;
下面再来看看那个标志Flag,这个基本上是为没什么用的(通常值为0),
对WM/TrackNumber和WM/Track这两个扩展信息名字有用,
当Flag为3的时候后面的值(也就是曲目信息)是以4个字节的整数的形式表示,
当Flag为0的时候,曲目信息是以普通的字符串形式表示的。
// 查看http://msdn.microsoft.com/en-us/library/ms867702.aspx



=================================================================

贴出实现类头文件:

/********************************************************************
	created:	2010/05/14
	created:	14:5:2010   9:12
	filename: 	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyWMATag.h
	file path:	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG
	file base:	CMyWMATag
	file ext:	h
	author:		zhangwf
	
	purpose:	解析WMA格式信息类,提取其中的TAG信息
*********************************************************************/
#ifndef _CMY_WMA_TAG_H_
#define _CMY_WMA_TAG_H_
//////////////////////////////////////////////////////////////////////////
#include "CMyPicInfo.h"
#include <string>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////////////////////////
/*************************************************************************
// 分为文件头和各个帧数据
+--------------------------------------------------------------+
|      Header (30 bytes)   HeadFlag:16; HeadSize:8; Unknow:6   |
+--------------------------------------------------------------+
|      Frames (1....n)                                         |
+--------------------------------------------------------------+
// 所有的TAG信息存放在标准帧和扩展帧中,其他帧可以不予考虑
// 所有的信息都是UNICODE编码
// 标准帧结构
+--------------------------------------------------------------+
|      Header (24 bytes)   HeadFlag:16; HeadSize:8;            |
+--------------------------------------------------------------+
|      标题信息大小(2 bytes)                                  |
+--------------------------------------------------------------+
|      艺术家信息大小(2 bytes)                                |
+--------------------------------------------------------------+
|      版权信息大小(2 bytes)                                  |
+--------------------------------------------------------------+
|      备注信息大小(2 bytes)                                  |
+--------------------------------------------------------------+
|      未知信息大小(2 bytes)                                  |
+--------------------------------------------------------------+
|      标题信息内容(0x00 0x00结束)                              |
+--------------------------------------------------------------+
|      艺术家信息内容(0x00 0x00结束)                            |
+--------------------------------------------------------------+
|      版权信息内容(0x00 0x00结束)                              |
+--------------------------------------------------------------+
|      备注信息内容(0x00 0x00结束)                              |
+--------------------------------------------------------------+
|      未知信息内容(0x00 0x00结束)                              |
+--------------------------------------------------------------+
// 扩展帧结构
+--------------------------------------------------------------+
|      Header (24 bytes)   HeadFlag:16; HeadSize:8;            |
+--------------------------------------------------------------+
|      扩展信息个数EXNO(2 bytes)                              |
+--------------------------------------------------------------+
|      EXINFO (1....EXNO)                                      |
+--------------------------------------------------------------+
// 每个扩展信息EXINFO结构
+--------------------------------------------------------------+
|      EXINFO NAME Size (2 bytes)   扩展信息名字大小            |
+--------------------------------------------------------------+
|      扩展信息名称                                             |
+--------------------------------------------------------------+
|      标志FLAG   (2 bytes)                                    |
+--------------------------------------------------------------+
|      值的大小   (2 bytes)                                     |
+--------------------------------------------------------------+
|      实际的值   (图片格式参考ID3V2.3)                         |
+--------------------------------------------------------------+
当扩展信息名字为WMFSDKVersion时,这个值表示的是这个WMA文件的版本;
当扩展信息名字为WM/AlbumTitle时,这个值代表的就是专辑名;
当扩展信息名字为WM/Genre时,这个值代表的就是流派;
下面再来看看那个标志Flag,这个基本上是为没什么用的(通常值为0),
对WM/TrackNumber和WM/Track这两个扩展信息名字有用,
当Flag为3的时候后面的值(也就是曲目信息)是以4个字节的整数的形式表示,
当Flag为0的时候,曲目信息是以普通的字符串形式表示的。
// 查看http://msdn.microsoft.com/en-us/library/ms867702.aspx
Author
Copyright
Description
Rating
Title
WM/AlbumArtist
WM/AlbumCoverURL
WM/AlbumTitle
WM/AudioFileURL
WM/AudioSourceURL
WM/AuthorURL
WM/BeatsPerMinute
WM/Category
WM/Composer
WM/Conductor
WM/ContentDistributor
WM/ContentGroupDescription
WM/Director
WM/DVDID
WM/EncodedBy
WM/EncodingSettings
WM/EncodingTime
WM/Genre
WM/GenreID
WM/InitialKey
WM/ISRC
WM/Language
WM/Lyrics
WM/Lyrics_Synchronised
WM/MCDI
WM/MediaClassPrimaryID
WM/MediaClassSecondaryID
WM/MediaCredits
WM/MediaIsDelay
WM/MediaIsFinale
WM/MediaIsLive
WM/MediaIsPremiere
WM/MediaIsRepeat
WM/MediaIsSAP
WM/MediaIsSubtitled
WM/MediaIsStereo
WM/MediaNetworkAffiliation
WM/MediaOriginalBroadcastDateTime
WM/MediaOriginalChannel
WM/MediaStationCallSign
WM/MediaStationName
WM/ModifiedBy
WM/Mood
WM/OriginalAlbumTitle
WM/OriginalArtist
WM/OriginalFilename
WM/OriginalLyricist
WM/OriginalReleaseTime
WM/OriginalReleaseYear
WM/ParentalRating
WM/ParentalRatingReason
WM/PartOfSet
WM/Period
WM/Picture
WM/Producer
WM/PromotionURL
WM/Provider
WM/ProviderCopyright
WM/ProviderRating
WM/ProviderStyle
WM/Publisher
WM/RadioStationName
WM/RadioStationOwner
WM/SharedUserRating
WM/SubTitle
WM/SubTitleDescription
WM/Text
WM/ToolName
WM/ToolVersion
WM/Track
WM/TrackNumber
WM/UniqueFileIdentifier
WM/UserWebURL
WM/WMCollectionGroupID
WM/WMCollectionID
WM/WMContentID
WM/Writer
WM/Year

WMFSDKVersion
WMFSDKNeeded
IsVBR
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// 定义帧类型
enum WMA_FRAMESTYLE_T
{
	WMA_FRAMESTYLE_STANDARD,   // 标准帧
	WMA_FRAMESTYLE_EXTEND,     // 扩展帧
	WMA_FRAMESTYLE_UNKNOWN,    // 未知帧
};

// 定义帧标识类型ID
enum WMA_FRAMEID_T
{
	// 基础类型标准帧中的内容
	WMA_FRAMEID_AUTHOR = 0,
	WMA_FRAMEID_COPYRIGHT,	
	WMA_FRAMEID_DESCRIPTION,	
	WMA_FRAMEID_RATING,
	WMA_FRAMEID_TITLE,

	// 其他类型按字母排序
	WMA_FRAMEID_ALBUMARTIST,
	WMA_FRAMEID_ALBUMCOVERURL,
	WMA_FRAMEID_ALBUMTITLE,
	WMA_FRAMEID_AUDIOFILEURL,
	WMA_FRAMEID_AUDIOSOURCEURL,
	WMA_FRAMEID_AUTHORURL,
	WMA_FRAMEID_BPMT,       // WM/BeatsPerMinute
	WMA_FRAMEID_CATEGORY,
	WMA_FRAMEID_COMPOSER,
	WMA_FRAMEID_CONDUCTOR,
	WMA_FRAMEID_CONTENTDISTRIBUTOR,
	WMA_FRAMEID_CGDPN, // WM/ContentGroupDescription
	WMA_FRAMEID_DIRECTOR, 
	WMA_FRAMEID_DVDID,
	WMA_FRAMEID_ENCODEDBY,
	WMA_FRAMEID_ENCODINGSETTINGS,
	WMA_FRAMEID_ENCODINGTIME,
	WMA_FRAMEID_GENRE,
	WMA_FRAMEID_GENREID,
	WMA_FRAMEID_INITIALKEY,
	WMA_FRAMEID_ISRC,
	WMA_FRAMEID_LANGUAGE,
	WMA_FRAMEID_LYRICS,
	WMA_FRAMEID_LYRICSSYNC, // WM/Lyrics_Synchronised
	WMA_FRAMEID_MCDI,
	WMA_FRAMEID_MCPID, // WM/MediaClassPrimaryID
	WMA_FRAMEID_MCSID, // WM/MediaClassSecondaryID
	WMA_FRAMEID_MDACREDITS, // WM/MediaCredits
	WMA_FRAMEID_MDAISDELAY,   // WM/MediaIsDelay
	WMA_FRAMEID_MDAISFINALE,  // WM/MediaIsFinale
	WMA_FRAMEID_MDAISLIVE,    // WM/MediaIsLive
	WMA_FRAMEID_MDAISPREMIERE,  // WM/MediaIsPremiere
	WMA_FRAMEID_MDAISREPEAT,    // WM/MediaIsRepeat
	WMA_FRAMEID_MDAISSAP,       // WM/MediaIsSAP
	WMA_FRAMEID_MDAISSUBTITLED,  // WM/MediaIsSubtitled
	WMA_FRAMEID_MDAISSTEREO,     // WM/MediaIsStereo
	WMA_FRAMEID_MDANETWORKAFFILIATION,  // WM/MediaNetworkAffiliation
	WMA_FRAMEID_MDAORIGINALBDT,         // WM/MediaOriginalBroadcastDateTime
	WMA_FRAMEID_MDAORIGINALCHANNEL,     // WM/MediaOriginalChannel
	WMA_FRAMEID_MDASTATIONCALLSIGN,     // WM/MediaStationCallSign
	WMA_FRAMEID_MDASTATIONNAME,         // WM/MediaStationName
	WMA_FRAMEID_MODIFIEDBY,
	WMA_FRAMEID_MOOD,
	WMA_FRAMEID_ORIGALBUMTITLE,     // WM/OriginalAlbumTitle
	WMA_FRAMEID_ORIGARTIST,         // WM/OriginalArtist
	WMA_FRAMEID_ORIGFILENAME,       // WM/OriginalFilename
	WMA_FRAMEID_ORIGLYRICIST,       // WM/OriginalLyricist
	WMA_FRAMEID_ORIGRELEASETIME,    // WM/OriginalReleaseTime
	WMA_FRAMEID_ORIGRELEASEYEAR,    // WM/OriginalReleaseYear
	WMA_FRAMEID_PARENTALRATING,
	WMA_FRAMEID_PARENTALRATINGREASON,    // WM/ParentalRatingReason
	WMA_FRAMEID_PARTOFSET,
	WMA_FRAMEID_PERIOD,	
	WMA_FRAMEID_PICTURE,
	WMA_FRAMEID_PRODUCER,
	WMA_FRAMEID_PROMOTIONURL,
	WMA_FRAMEID_PROVIDER,
	WMA_FRAMEID_PROVIDERCPYRIGHT,
	WMA_FRAMEID_PROVIDERRATING,
	WMA_FRAMEID_PROVIDERSTYLE,
	WMA_FRAMEID_PUBLISHER,
	WMA_FRAMEID_RADIOSTATIONNAME,
	WMA_FRAMEID_RADIOSTATIONOWNER,
	WMA_FRAMEID_SHAREUSERRATING,
	WMA_FRAMEID_SUBTITLE,
	WMA_FRAMEID_SUBTITLEDESCRIPTION,
	WMA_FRAMEID_TEXT,
	WMA_FRAMEID_TOOLNAME,
	WMA_FRAMEID_TOOLVERSION,
	WMA_FRAMEID_TRACK,
	WMA_FRAMEID_TRACKNUMBER,	
	WMA_FRAMEID_UNIQUEFILEIDENTIFIER,
	WMA_FRAMEID_USERWEBURL,
	WMA_FRAMEID_WMCOLLECTIONGROUPID,
	WMA_FRAMEID_WMCOLLECTIONID,
	WMA_FRAMEID_CONTENTID,
	WMA_FRAMEID_WRITER,	
	WMA_FRAMEID_YEAR,

	WMA_FRAMEID_SDKVERSION, // WMFSDKVersion
	WMA_FRAMEID_SDKNEEDED,  // WMFSDKNeeded
	WMA_FRAMEID_ISVBR,      // IsVBR
	

	////////////////////////////////////////////////////////////////////
	WMA_FRAMEID_UNKNOWN, // 未知

};
//////////////////////////////////////////////////////////////////////////
// 定义WMA文件头标识
typedef struct _WMA_HEADFLAG_INFO_
{
	unsigned char WmaFlag[16];          // 固定的16个字节内容表示是否WMA文件
}WMAHEADFLAG;

// 定义WMA文件头常量标识
const WMAHEADFLAG WMA_HEAD_FLAGCONST = {0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C};

// 定义WMA文件头大小
typedef struct _WMA_HEADSIZE_INFO_
{
	unsigned char Size[8];     // 8个字节表示大小(由后向前存储数据)
}WMAHEADSIZE;

// 定义WMA文件头结构
typedef struct _WMA_HEADINFO_
{
	WMAHEADFLAG HeadFlag;      // WMA文件标识
	WMAHEADSIZE HeadSize;	   // WMA文件头大小
	unsigned char Unknown[6];  // 6个字节具体代表什么不清楚(有的说是帧的数量)
}WMAHEADINFO;

// 定义帧头标识
typedef struct _WMA_FRAMEHEADFLAG_INFO_
{
	unsigned char Flag[16];   // 固定的16个字节表示帧类型
}WMAFRAMEHEADFLAG;

// 定义WMA标准帧及扩展帧常量标识
const WMAFRAMEHEADFLAG WMA_FRAMEHEAD_STANDARD = {0x33, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C};
const WMAFRAMEHEADFLAG WMA_FRAMEHEAD_EXTEND   = {0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50};

// 定义帧大小
typedef struct _WMA_FRAMEHEADSIZE_INFO_
{
	unsigned char Size[8];     // 8个字节表示帧大小(由后向前存储数据)
}WMAFRAMEHEADSIZE;

// 定义帧头结构
typedef struct _WMA_FRAMEHEAD_INFO_
{
	WMAFRAMEHEADFLAG FrameFlag;
	WMAFRAMEHEADSIZE FrameSize;
}WMAFRAMEHEADINFO;

// 定义解析值的类型
enum WMA_ATTRSTYLE_T
{
	WMA_ATTRSTYLE_TXT = 0, // 字符串属性
	WMA_ATTRSTYLE_VAL,     // 值属性
};

// 定义属性解析内容结构
typedef struct _WMA_ATTR_INFO_
{
	WMA_FRAMEID_T ID;           // ID表示解析的类型
	WMA_ATTRSTYLE_T AttrStyle;  // 值的类型
	wstring StrContent;         // 解析的TXT内容
	unsigned long ValContent;   // 解析的值内容
}WMAATTRINFO;

// 定义属性解析内容动态数组存放解析的内容
typedef vector<WMAATTRINFO> CWMAAttrArray;

// 定义图片解析内容结构
typedef struct _WMA_PICITEMINFO_
{
	wstring MimeType;         // "image/png" or "image/jpeg" 
	char PicType;             // 说明如下
	wstring Description;      // 图片描述
	CMYPICINFO PicData;       // 图片数据
}WMAPICITEMINFO;

// 定义PIC属性解析内容动态数组存放解析的内容(可能含有多张图片)
typedef vector<WMAPICITEMINFO> CWMAPicArray;

//////////////////////////////////////////////////////////////////////////
class CMyWMATag
{
public:
	// 构造函数
	CMyWMATag();

	// 析构函数
	~CMyWMATag();

public:
	// 接口函数
	// 解析WMA文件,成功后调用下面接口获取信息
	bool AnalyzeWMAFile(const char *filePathName);
	bool AnalyzeWMAFile(const wchar_t *filePathName);
	bool AnalyzeWMAFile(const wstring &filePathName);

	// 是否解析成功
	bool BeSuccess();

	// 取得头大小
	unsigned long GetHeadSize();

	//////////////////////////////////////////////////////////////////////////
	// 取得Txt属性内容接口
	bool GetTxtItemContent(WMA_FRAMEID_T frameID, wstring &itemContent);
	bool GetTxtItemContent(WMA_FRAMEID_T frameID, string &itemContent);

	//////////////////////////////////////////////////////////////////////////
	// 取得图片属性内容接口
	// 取得第一张图片
	bool GetFirstPic(CMYPICINFO &picInfo);

	// 保存第一张图片
	bool SaveFirstPicToFile(const char *filePathName);
	bool SaveFirstPicToFile(const wchar_t *filePathName);

	// 取得第一张图片的地址及大小
	const unsigned char* GetFirstPicAddr(unsigned long *pPicSize=NULL);

	// 取得第一行图片的大小
	unsigned long GetFirstPicSize();

	// 取得图片数量
	unsigned long GetPicCounts();

	// 取得第n张图片
	bool GetPic(unsigned long picIndex, CMYPICINFO &picInfo);

	// 取得第n张图片的地址
	const unsigned char* GetPicAddr(unsigned long picIndex, unsigned long *pPicSize=NULL);

	// 保存第n张图片
	bool SavePicToFile(unsigned long picIndex, const char *filePathName);
	bool SavePicToFile(unsigned long picIndex, const wchar_t *filePathName);

private:
	// 私有函数
	// 根据文件头结构判断是否WMA文件
	bool BeWMAFile(const WMAHEADFLAG &headFlag);

	// 清除信息
	void ClearDataInfo();

	// 计算头大小
	unsigned long GetHeadSize(const WMAHEADSIZE &headSize);

	// 得到帧类型
	WMA_FRAMESTYLE_T GetFrameStyle(const WMAFRAMEHEADFLAG &frameFlag);

	// 判断两个帧头标识是否相等
	bool BeSameFrameFlag(const WMAFRAMEHEADFLAG &firstFlag, const WMAFRAMEHEADFLAG &secondFlag);

	// 得到帧的大小
	unsigned long GetFrameSize(const WMAFRAMEHEADSIZE &frameSize);

	// 计算由2个字节拼接成的整数大小
	unsigned long CalUInt16Val(const unsigned char *pByteBuf, int bufSize);

	// 计算由4个字节拼接成的整数大小
	unsigned long CalUInt32Val(const unsigned char *pByteBuf, int bufSize);

	// 解析得到的帧数据
	unsigned long ParseFrameData(const unsigned char *pFrameData, unsigned long bufLength);

	// 得到帧头信息
	bool GetFrameHeadInfo(const unsigned char *pFrameData, unsigned long bufLength, WMAFRAMEHEADINFO &frameHead);

	// 解析标准帧数据
	bool ParseStandardFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray);

	// 解析扩展帧数据
	bool ParseExtendFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray, CWMAPicArray &WMAPicArray);

	// 得到string
	wstring GetWString(const unsigned char* pUCharBuf, unsigned long charsNums);

	// wstring转换为string
	string TransFromWString(const wstring &wstrVal);	

	// 取得扩展帧属性ID
	WMA_FRAMEID_T GetExFrameID(const wstring &exName);

	// 取得字符串根据0x00,0x00
	unsigned long GetWstringByWChars(const unsigned char* pPicDataBuf, unsigned long bufSize, wstring &strVal);

private:
	// 成员变量
	WMAHEADINFO m_HeadInfo;     // 存放头信息
	bool m_bAnalyzeSuccess;     // 保存解析是否成功
	CWMAAttrArray m_WMAAttrArray; // 存放解析到的TAG信息
	CWMAPicArray m_WMAPicArray;   // 存放解析的图片信息
};
//////////////////////////////////////////////////////////////////////////
#endif




贴出实现文件:

/********************************************************************
	created:	2010/05/14
	created:	14:5:2010   9:12
	filename: 	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyWMATag.cpp
	file path:	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG
	file base:	CMyWMATag
	file ext:	cpp
	author:		zhangwf
	
	purpose:	解析WMA格式信息类,提取其中的TAG信息
*********************************************************************/
//////////////////////////////////////////////////////////////////////////
#include <Windows.h>
#include "CMyWMATag.h"
//////////////////////////////////////////////////////////////////////////
// 构造函数
CMyWMATag::CMyWMATag()
{
	// 初始化成员变量
	ClearDataInfo();

}

// 析构函数
CMyWMATag::~CMyWMATag()
{

}

//////////////////////////////////////////////////////////////////////////
// 接口函数
// 解析WMA文件,成功后调用下面接口获取信息
bool CMyWMATag::AnalyzeWMAFile(const char *filePathName)
{
	// 清除上次信息
	ClearDataInfo();

	// 参数有效性
	if (filePathName == NULL)
	{		
		return false;
	}

	// 打开文件
	FILE *pWMAFile = fopen(filePathName, "rb");
	if (pWMAFile == NULL)
	{	
		return false;
	}

	// 读取WMA头结构
	memset(&m_HeadInfo, 0, sizeof(m_HeadInfo));
	if (fread(&m_HeadInfo, sizeof(m_HeadInfo), 1, pWMAFile) != 1)
	{		
		fclose(pWMAFile);
		return false;
	}

	// 判断是否WMA文件
	m_bAnalyzeSuccess = BeWMAFile(m_HeadInfo.HeadFlag);
	if (!m_bAnalyzeSuccess)
	{	
		memset(&m_HeadInfo, 0, sizeof(m_HeadInfo));
		fclose(pWMAFile);		
		return false;		
	}		

	// 计算要读取帧数据的字节数
	unsigned long lFrameDataSize = GetHeadSize(m_HeadInfo.HeadSize) - sizeof(WMAHEADINFO);

	// 为帧数据分配空间
	unsigned char *pFrameData = new unsigned char[lFrameDataSize];
	if (pFrameData == NULL)
	{
		fclose(pWMAFile);
		m_bAnalyzeSuccess = false;
		return false;
	}

	// 读取帧数据
	memset(pFrameData, 0, lFrameDataSize);
	if (fread(pFrameData, lFrameDataSize, 1, pWMAFile) != 1)
	{
		// 释放帧数据
		if (pFrameData != NULL)
		{
			delete[] pFrameData;
			pFrameData = NULL;
		}

		fclose(pWMAFile);
		m_bAnalyzeSuccess = false;
		return false;
	}

	// 读取成功关闭文件
	fclose(pWMAFile);

	// 解析帧数据
	ParseFrameData(pFrameData, lFrameDataSize);

	// 释放帧数据
	if (pFrameData != NULL)
	{
		delete[] pFrameData;
		pFrameData = NULL;
	}

	// 返回分析结果
	return m_bAnalyzeSuccess;
}

// 解析WMA文件
bool CMyWMATag::AnalyzeWMAFile(const wchar_t *filePathName)
{
	// 参数有效性
	if (filePathName == NULL)
	{
		return false;
	}

	// 计算转换为多字节字节数
	int nChars = WideCharToMultiByte(CP_ACP, 0, filePathName, -1, NULL, 0, NULL, NULL);

	// 申请空间
	char *pFileName = new char[nChars+1];
	if (pFileName == NULL)
	{
		return false;
	}

	// 转换为多字节
	memset(pFileName, 0, nChars+1);
	WideCharToMultiByte(CP_ACP, 0, filePathName, -1, pFileName, nChars, NULL, NULL);

	// 解析
	bool bResult = AnalyzeWMAFile(pFileName);

	// 释放
	if (pFileName != NULL)
	{
		delete[] pFileName;
		pFileName = NULL;
	}

	// 返回结果
	return bResult;	
}

// 解析WMA文件
bool CMyWMATag::AnalyzeWMAFile(const wstring &filePathName)
{
	return AnalyzeWMAFile(filePathName.c_str());
}

// 是否解析成功
bool CMyWMATag::BeSuccess()
{
	return m_bAnalyzeSuccess;
}

// 取得头大小
unsigned long CMyWMATag::GetHeadSize()
{
	return GetHeadSize(m_HeadInfo.HeadSize);
}

//////////////////////////////////////////////////////////////////////////
// 取得Txt属性内容接口
bool CMyWMATag::GetTxtItemContent(WMA_FRAMEID_T frameID, wstring &itemContent)
{
	// 解析失败
	if (!BeSuccess())
	{	
		return false;
	}

	// 查找
	for (unsigned long i=0; i<m_WMAAttrArray.size(); i++)
	{
		if (frameID == m_WMAAttrArray[i].ID)
		{
			if (m_WMAAttrArray[i].AttrStyle == WMA_ATTRSTYLE_TXT)
			{
				itemContent = m_WMAAttrArray[i].StrContent;
				return true;
			}
			else
			{
				return false;
			}			
		}
	}

	// 没有找到
	return false;
}

// 取得Txt属性内容接口
bool CMyWMATag::GetTxtItemContent(WMA_FRAMEID_T frameID, string &itemContent)
{
	wstring wContent;
	bool bOK = GetTxtItemContent(frameID, wContent);
	itemContent = TransFromWString(wContent);
	return bOK;
}

//////////////////////////////////////////////////////////////////////////
// 取得图片属性内容接口
// 取得第一张图片
bool CMyWMATag::GetFirstPic(CMYPICINFO &picInfo)
{
	// 解析失败
	if (!BeSuccess())
	{	
		return false;
	}

	// 查找是否有图片
	if (m_WMAPicArray.size() == 0)
	{
		return false;
	}

	// 得到第一张图片
	picInfo = m_WMAPicArray[0].PicData;
	return true;
}

// 保存第一张图片
bool CMyWMATag::SaveFirstPicToFile(const char *filePathName)
{
	if (BeSuccess() && m_WMAPicArray.size()>0)
	{
		return m_WMAPicArray[0].PicData.SavePicToFile(filePathName);
	}

	return false;
}
bool CMyWMATag::SaveFirstPicToFile(const wchar_t *filePathName)
{
	if (BeSuccess() && m_WMAPicArray.size()>0)
	{
		return m_WMAPicArray[0].PicData.SavePicToFile(filePathName);
	}

	return false;
}

// 取得第一张图片的地址及大小
const unsigned char* CMyWMATag::GetFirstPicAddr(unsigned long *pPicSize)
{
	if (BeSuccess() && m_WMAPicArray.size()>0)
	{
		if (pPicSize != NULL)
		{
			*pPicSize = m_WMAPicArray[0].PicData.GetPicBufSize();
		}

		return m_WMAPicArray[0].PicData.GetPicBufAddr();
	}

	return NULL;
}

// 取得第一行图片的大小
unsigned long CMyWMATag::GetFirstPicSize()
{
	if (BeSuccess() && m_WMAPicArray.size()>0)
	{
		return m_WMAPicArray[0].PicData.GetPicBufSize();
	}

	return 0;
}

// 取得图片数量
unsigned long CMyWMATag::GetPicCounts()
{
	return (unsigned long)m_WMAPicArray.size();
}

// 取得第n张图片
bool CMyWMATag::GetPic(unsigned long picIndex, CMYPICINFO &picInfo)
{
	// 解析失败
	if (!BeSuccess())
	{	
		return false;
	}

	// 得到图片数量
	unsigned long picCounts = GetPicCounts();

	// 查找是否有图片
	if (picCounts == 0)
	{
		return false;
	}

	// 索引是否有效
	if (picIndex >= picCounts)
	{
		return false;
	}

	// 得到第picIndex张图片
	picInfo = m_WMAPicArray[picIndex].PicData;
	return true;
}

// 取得第n张图片的地址
const unsigned char* CMyWMATag::GetPicAddr(unsigned long picIndex, unsigned long *pPicSize)
{
	// 解析失败
	if (!BeSuccess())
	{	
		return NULL;
	}

	// 得到图片数量
	unsigned long picCounts = GetPicCounts();

	// 查找是否有图片
	if (picCounts == 0)
	{
		return NULL;
	}

	// 索引是否有效
	if (picIndex >= picCounts)
	{
		return NULL;
	}

	// 取得图片大小
	if (pPicSize != NULL)
	{
		*pPicSize = m_WMAPicArray[picIndex].PicData.GetPicBufSize();
	}

	// 得到第picIndex张图片地址
	return m_WMAPicArray[picIndex].PicData.GetPicBufAddr();
}

// 保存第n张图片
bool CMyWMATag::SavePicToFile(unsigned long picIndex, const char *filePathName)
{
	// 参数有效性
	if (filePathName == NULL)
	{
		return false;
	}

	// 解析失败
	if (!BeSuccess())
	{	
		return false;
	}

	// 得到图片数量
	unsigned long picCounts = GetPicCounts();

	// 查找是否有图片
	if (picCounts == 0)
	{
		return false;
	}

	// 索引是否有效
	if (picIndex >= picCounts)
	{
		return false;
	}

	return m_WMAPicArray[picIndex].PicData.SavePicToFile(filePathName);
}

// 保存第n张图片
bool CMyWMATag::SavePicToFile(unsigned long picIndex, const wchar_t *filePathName)
{
	// 参数有效性
	if (filePathName == NULL)
	{
		return false;
	}

	// 解析失败
	if (!BeSuccess())
	{	
		return false;
	}

	// 得到图片数量
	unsigned long picCounts = GetPicCounts();

	// 查找是否有图片
	if (picCounts == 0)
	{
		return false;
	}

	// 索引是否有效
	if (picIndex >= picCounts)
	{
		return false;
	}

	return m_WMAPicArray[picIndex].PicData.SavePicToFile(filePathName);
}
//////////////////////////////////////////////////////////////////////////
// 私有函数
// 根据文件头结构判断是否WMA文件
bool CMyWMATag::BeWMAFile(const WMAHEADFLAG &headFlag)
{
	for (int i=0; i<sizeof(WMA_HEAD_FLAGCONST.WmaFlag); i++)
	{
		if (headFlag.WmaFlag[i] != WMA_HEAD_FLAGCONST.WmaFlag[i])
		{
			return false;
		}
	}

	return true;
}

// 清除信息
void CMyWMATag::ClearDataInfo()
{
	memset(&m_HeadInfo, 0, sizeof(m_HeadInfo));
	m_bAnalyzeSuccess = false;
	m_WMAAttrArray.clear();
	m_WMAPicArray.clear();
}

// 计算头大小
unsigned long CMyWMATag::GetHeadSize(const WMAHEADSIZE &headSize)
{
	return (unsigned long)((headSize.Size[3]<<24) | (headSize.Size[2]<<16) | (headSize.Size[1]<<8) | headSize.Size[0]);
}

// 得到帧类型
WMA_FRAMESTYLE_T CMyWMATag::GetFrameStyle(const WMAFRAMEHEADFLAG &frameFlag)
{
	// 判断是否标准帧
	if (BeSameFrameFlag(frameFlag, WMA_FRAMEHEAD_STANDARD))
	{
		return WMA_FRAMESTYLE_STANDARD;
	}

	// 判断是否扩展帧
	if (BeSameFrameFlag(frameFlag, WMA_FRAMEHEAD_EXTEND))
	{
		return WMA_FRAMESTYLE_EXTEND;
	}
	
	// 返回位置帧
	return WMA_FRAMESTYLE_UNKNOWN;
}

// 判断两个帧头标识是否相等
bool CMyWMATag::BeSameFrameFlag(const WMAFRAMEHEADFLAG &firstFlag, const WMAFRAMEHEADFLAG &secondFlag)
{
	for (int i=0; i<16; i++)
	{
		if (firstFlag.Flag[i] != secondFlag.Flag[i])
		{
			return false;
		}
	}

	return true;
}

// 得到帧的大小
unsigned long CMyWMATag::GetFrameSize(const WMAFRAMEHEADSIZE &frameSize)
{
	return (unsigned long)((frameSize.Size[3]<<24) | (frameSize.Size[2]<<16) | (frameSize.Size[1]<<8) | frameSize.Size[0]);
}

// 计算由2个字节拼接成的整数大小
unsigned long CMyWMATag::CalUInt16Val(const unsigned char *pByteBuf, int bufSize)
{
	// 参数有效性
	if (pByteBuf==NULL || bufSize<2)
	{
		return 0;
	}

	// 返回值
	return ((pByteBuf[1]<<8) | pByteBuf[0]);
}

// 计算由4个字节拼接成的整数大小
unsigned long CMyWMATag::CalUInt32Val(const unsigned char *pByteBuf, int bufSize)
{
	// 参数有效性
	if (pByteBuf==NULL || bufSize<4)
	{
		return 0;
	}

	// 返回值
	return ((pByteBuf[3]<<24) | (pByteBuf[2]<<16) | (pByteBuf[1]<<8) | pByteBuf[0]);
}

// 解析得到的帧数据
unsigned long CMyWMATag::ParseFrameData(const unsigned char *pFrameData, unsigned long bufLength)
{
	// 清除上次数据
	m_WMAAttrArray.clear();
	m_WMAPicArray.clear();

	// 参数有效性
	if (pFrameData==NULL || bufLength==0)
	{
		return 0;
	}

	// 存放临时变量
	WMAFRAMEHEADINFO frameHead;
	WMA_FRAMESTYLE_T frameStyle = WMA_FRAMESTYLE_UNKNOWN;
	unsigned long frameSize = 0;
	WMAATTRINFO attrItemInfo;

	// 遍历解析内容
	unsigned long pos = 0;
	while (pos+24 < bufLength)
	{
		// 得到帧头失败
		if (!GetFrameHeadInfo(pFrameData+pos, bufLength-pos, frameHead))
		{
			break;
		}
	
		// 得到帧风格类型
		frameStyle = GetFrameStyle(frameHead.FrameFlag);		

		// 是正确风格,取得帧大小
		frameSize = GetFrameSize(frameHead.FrameSize);		

		// 取得帧体内容	
		if (frameSize>=24 && pos+23+frameSize<bufLength)
		{
			// 是标准帧,解析标准帧
			if (frameStyle == WMA_FRAMESTYLE_STANDARD)
			{
				ParseStandardFrame(pFrameData+pos+24, frameSize-24, m_WMAAttrArray);
			}
			// 是扩展帧
			else if (frameStyle == WMA_FRAMESTYLE_EXTEND)
			{		
				ParseExtendFrame(pFrameData+pos+24, frameSize-24, m_WMAAttrArray, m_WMAPicArray);
			}			

			// 改变索引
			pos += frameSize;
		}
		else
		{
			pos++;
		}
	}

	for (unsigned int i=0; i<m_WMAAttrArray.size(); i++)
	{
		printf("ID:%d Content:%s/n", m_WMAAttrArray[i].ID, TransFromWString(m_WMAAttrArray[i].StrContent).c_str());
	}

	// 返回解析的属性数量
	return (unsigned long)m_WMAAttrArray.size() + (unsigned long)m_WMAPicArray.size();
}

// 得到帧头信息
bool CMyWMATag::GetFrameHeadInfo(const unsigned char *pFrameData, unsigned long bufLength, WMAFRAMEHEADINFO &frameHead)
{
	// 参数有效性
	if (pFrameData==NULL || bufLength<24)
	{
		return false;
	}

	// 得到帧标识
	int i = 0;
	for (i=0; i<16; i++)
	{
		frameHead.FrameFlag.Flag[i] = pFrameData[i];
	}

	// 得到帧大小
	for (i=0; i<8; i++)
	{
		frameHead.FrameSize.Size[i] = pFrameData[i+16];
	}

	return true;
}

// 解析标准帧数据
bool CMyWMATag::ParseStandardFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray)
{
	// 参数有效性
	if (pItemFrameData==NULL || frameSize==0)
	{
		return false;
	}

	// 计算标题信息大小
	unsigned long titleSize = CalUInt16Val(pItemFrameData, 2);

	// 计算艺术家信息大小
	unsigned long artistSize = CalUInt16Val(pItemFrameData+2, 2);

	// 计算版权信息大小
	unsigned long copyRightSize = CalUInt16Val(pItemFrameData+4, 2);

	// 计算备注信息大小
	unsigned long commentSize = CalUInt16Val(pItemFrameData+6, 2);

	// 计算未知信息大小
	unsigned long unknownSize = CalUInt16Val(pItemFrameData+8, 2);

	// 偏移量
	unsigned long offset = 10;

	// 临时存放信息
	WMAATTRINFO attrInfo;
	memset(&attrInfo, 0, sizeof(attrInfo));
	attrInfo.AttrStyle = WMA_ATTRSTYLE_TXT;

	// 取得标题信息
	attrInfo.ID = WMA_FRAMEID_TITLE;
	attrInfo.StrContent = GetWString(pItemFrameData+offset, titleSize);
	WMAAttrArray.push_back(attrInfo);
	offset += titleSize;

	// 取得艺术家信息
	attrInfo.ID = WMA_FRAMEID_AUTHOR;
	attrInfo.StrContent = GetWString(pItemFrameData+offset, artistSize);
	WMAAttrArray.push_back(attrInfo);
	offset += artistSize;

	// 取得版权信息
	attrInfo.ID = WMA_FRAMEID_COPYRIGHT;
	attrInfo.StrContent = GetWString(pItemFrameData+offset, copyRightSize);
	WMAAttrArray.push_back(attrInfo);
	offset += copyRightSize;

	// 取得备注信息
	attrInfo.ID = WMA_FRAMEID_DESCRIPTION;
	attrInfo.StrContent = GetWString(pItemFrameData+offset, commentSize);
	WMAAttrArray.push_back(attrInfo);
	offset += commentSize;

	// 取得未知信息
	attrInfo.ID = WMA_FRAMEID_RATING;
	attrInfo.StrContent = GetWString(pItemFrameData+offset, unknownSize);
	WMAAttrArray.push_back(attrInfo);
	offset += unknownSize;	

	// 返回成功
	return true;
}

// 得到string
wstring CMyWMATag::GetWString(const unsigned char* pUCharBuf, unsigned long charsNums)
{
	// 返回值
	wstring strRet = L"";

	// 参数有效性
	if (pUCharBuf==NULL || charsNums==0)
	{
		return strRet;
	}

	// 得到字符串
	strRet.append((const wchar_t*)pUCharBuf, charsNums/2);	
	return strRet;
}

// wstring转换为string
string CMyWMATag::TransFromWString(const wstring &wstrVal)
{
	// 计算字符数
	int nCharNums = (int)wstrVal.length();
	int mulBufSize = 2*nCharNums+10;

	// 申请空间
	char *pCharBuf = new char[mulBufSize];
	if (pCharBuf == NULL)
	{
		return "";
	}
	memset(pCharBuf, 0, mulBufSize);

	// 转换
	WideCharToMultiByte(CP_ACP, 0, wstrVal.c_str(), -1, pCharBuf, mulBufSize, NULL, NULL);

	// 得到结果
	string strVal(pCharBuf);

	// 释放空间
	if (pCharBuf != NULL)
	{
		delete[] pCharBuf;
		pCharBuf = NULL;
	}

	return strVal;
}

// 解析扩展帧数据
bool CMyWMATag::ParseExtendFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray, CWMAPicArray &WMAPicArray)
{
	// 参数有效性
	if (pItemFrameData==NULL || frameSize==0)
	{
		return false;
	}

	// 计算扩展信息数量
	unsigned long exInfoCounts = CalUInt16Val(pItemFrameData, 2);

	// 地址偏移量
	unsigned long offset = 2;

	// 临时存放扩展信息
	unsigned long exNameSize = 0;
	wstring exName = L"";
	unsigned long exFlagVal = 0;
	unsigned long valSize = 0;
	WMA_FRAMEID_T frameID = WMA_FRAMEID_UNKNOWN;
	WMAATTRINFO attrInfo;	
	WMAPICITEMINFO picItem;
	unsigned lenTmp = 0;

	// 取扩展信息
	for (unsigned exIndex=0; exIndex<exInfoCounts; exIndex++)
	{
		// 清除上次内容
		memset(&attrInfo, 0, sizeof(attrInfo));

		// 计算扩展名大小
		exNameSize = CalUInt16Val(pItemFrameData+offset, 2);
		offset += 2;		

		// 取得扩展名称
		exName = GetWString(pItemFrameData+offset, exNameSize);
		offset += exNameSize;

		// 取得扩展标识FLAG值
		exFlagVal = CalUInt16Val(pItemFrameData+offset, 2);
		offset += 2;

		// 取得实际值的大小
		valSize = CalUInt16Val(pItemFrameData+offset, 2);
		offset += 2;

		// 计算扩展属性ID
		frameID = GetExFrameID(exName);

		// 是否有效ID
		if (frameID != WMA_FRAMEID_UNKNOWN)
		{
			// 得到属性ID
			attrInfo.ID = frameID;

			// 图片得到图片信息
			if (frameID == WMA_FRAMEID_PICTURE)
			{			
				lenTmp = GetWstringByWChars(pItemFrameData+offset, frameSize-offset, picItem.MimeType);				
				picItem.PicType = (char)((pItemFrameData+offset+lenTmp)[0]);
				lenTmp += 1;
				lenTmp += GetWstringByWChars(pItemFrameData+offset+lenTmp, frameSize-offset-lenTmp, picItem.Description);
				picItem.PicData.SetPicBufData((const char*)(pItemFrameData+offset+lenTmp), valSize-lenTmp);
				m_WMAPicArray.push_back(picItem);
			}			
			else
			{
				// 扩展FLAG标识是字符串类型还是值类型
				// 表示值类型
				if (exFlagVal == 3)
				{
					attrInfo.AttrStyle = WMA_ATTRSTYLE_VAL;
					if (valSize >= 4)
					{
						attrInfo.ValContent = CalUInt32Val(pItemFrameData+offset, 4);
					}
					WMAAttrArray.push_back(attrInfo);
				}
				else
				{
					attrInfo.AttrStyle = WMA_ATTRSTYLE_TXT;
					attrInfo.StrContent = GetWString(pItemFrameData+offset, valSize);
					WMAAttrArray.push_back(attrInfo);
				}
			}		
		}

		// 改变地址偏移量
		offset += valSize;
	}	

	// 返回成功
	return true;
}

// 取得字符串根据0x00,0x00
unsigned long CMyWMATag::GetWstringByWChars(const unsigned char* pPicDataBuf, unsigned long bufSize, wstring &strVal)
{
	// 返回数量
	unsigned long lResult = 0;

	// 参数有效性
	if (pPicDataBuf==NULL || bufSize==0)
	{
		return lResult;
	}

	// 遍历
	const wchar_t *pWBuf = (const wchar_t*)pPicDataBuf;
	unsigned long wBufSize = bufSize/2;
	unsigned long wPos = 0;
	while (wPos < wBufSize)
	{
		if (pWBuf[wPos] == 0x00)
		{
			lResult = 2*(wPos+1);
			break;
		}
		else
		{
			wPos++;
		}
	}

	// 得到字符串
	strVal = L"";
	strVal.append(pWBuf, wPos+1);

	// 返回
	return lResult;	
}

// 取得扩展帧属性ID
WMA_FRAMEID_T CMyWMATag::GetExFrameID(const wstring &exName)
{
	// 用于返回值
	WMA_FRAMEID_T rtExFrameID = WMA_FRAMEID_UNKNOWN;

	// 与标识比较
	if (wcscmp(exName.c_str(), L"WM/AlbumArtist") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ALBUMARTIST;
	}
	else if (wcscmp(exName.c_str(), L"WM/AlbumCoverURL") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ALBUMCOVERURL;
	}	
	else if (wcscmp(exName.c_str(), L"WM/AlbumTitle") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ALBUMTITLE;
	}	
	else if (wcscmp(exName.c_str(), L"WM/AudioFileURL") == 0)
	{
		rtExFrameID = WMA_FRAMEID_AUDIOFILEURL;
	}	
	else if (wcscmp(exName.c_str(), L"WM/AudioSourceURL") == 0)
	{
		rtExFrameID = WMA_FRAMEID_AUDIOSOURCEURL;
	}	
	else if (wcscmp(exName.c_str(), L"WM/AuthorURL") == 0)
	{
		rtExFrameID = WMA_FRAMEID_AUTHORURL;
	}	
	else if (wcscmp(exName.c_str(), L"WM/BeatsPerMinute") == 0)
	{
		rtExFrameID = WMA_FRAMEID_BPMT;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Category") == 0)
	{
		rtExFrameID = WMA_FRAMEID_CATEGORY;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Composer") == 0)
	{
		rtExFrameID = WMA_FRAMEID_COMPOSER;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Conductor") == 0)
	{
		rtExFrameID = WMA_FRAMEID_CONDUCTOR;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ContentDistributor") == 0)
	{
		rtExFrameID = WMA_FRAMEID_CONTENTDISTRIBUTOR;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ContentGroupDescription") == 0)
	{
		rtExFrameID = WMA_FRAMEID_CGDPN;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Director") == 0)
	{
		rtExFrameID = WMA_FRAMEID_DIRECTOR;
	}	
	else if (wcscmp(exName.c_str(), L"WM/DVDID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_DVDID;
	}	
	else if (wcscmp(exName.c_str(), L"WM/EncodedBy") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ENCODEDBY;
	}	
	else if (wcscmp(exName.c_str(), L"WM/EncodingSettings") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ENCODINGSETTINGS;
	}	
	else if (wcscmp(exName.c_str(), L"WM/EncodingTime") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ENCODINGTIME;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Genre") == 0)
	{
		rtExFrameID = WMA_FRAMEID_GENRE;
	}	
	else if (wcscmp(exName.c_str(), L"WM/GenreID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_GENREID;
	}
	else if (wcscmp(exName.c_str(), L"WM/InitialKey") == 0)
	{
		rtExFrameID = WMA_FRAMEID_INITIALKEY;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ISRC") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ISRC;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Language") == 0)
	{
		rtExFrameID = WMA_FRAMEID_LANGUAGE;
	}
	else if (wcscmp(exName.c_str(), L"WM/Lyrics") == 0)
	{
		rtExFrameID = WMA_FRAMEID_LYRICS;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Lyrics_Synchronised") == 0)
	{
		rtExFrameID = WMA_FRAMEID_LYRICSSYNC;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MCDI") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MCDI;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaClassPrimaryID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MCPID;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaClassSecondaryID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MCSID;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaCredits") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDACREDITS;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaIsDelay") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISDELAY;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaIsFinale") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISFINALE;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaIsLive") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISLIVE;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaIsPremiere") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISPREMIERE;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaIsRepeat") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISREPEAT;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaIsSAP") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISSAP;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaIsSubtitled") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISSUBTITLED;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaIsStereo") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAISSTEREO;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaNetworkAffiliation") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDANETWORKAFFILIATION;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaOriginalBroadcastDateTime") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAORIGINALBDT;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaOriginalChannel") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDAORIGINALCHANNEL;
	}	
	else if (wcscmp(exName.c_str(), L"WM/MediaStationCallSign") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDASTATIONCALLSIGN;
	}
	else if (wcscmp(exName.c_str(), L"WM/MediaStationName") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MDASTATIONNAME;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ModifiedBy") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MODIFIEDBY;
	}
	else if (wcscmp(exName.c_str(), L"WM/Mood") == 0)
	{
		rtExFrameID = WMA_FRAMEID_MOOD;
	}	
	else if (wcscmp(exName.c_str(), L"WM/OriginalAlbumTitle") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ORIGALBUMTITLE;
	}
	else if (wcscmp(exName.c_str(), L"WM/OriginalArtist") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ORIGARTIST;
	}	
	else if (wcscmp(exName.c_str(), L"WM/OriginalFilename") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ORIGFILENAME;
	}
	else if (wcscmp(exName.c_str(), L"WM/OriginalLyricist") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ORIGLYRICIST;
	}	
	else if (wcscmp(exName.c_str(), L"WM/OriginalReleaseTime") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ORIGRELEASETIME;
	}
	else if (wcscmp(exName.c_str(), L"WM/OriginalReleaseYear") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ORIGRELEASEYEAR;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ParentalRating") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PARENTALRATING;
	}
	else if (wcscmp(exName.c_str(), L"WM/ParentalRatingReason") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PARENTALRATINGREASON;
	}	
	else if (wcscmp(exName.c_str(), L"WM/PartOfSet") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PARTOFSET;
	}
	else if (wcscmp(exName.c_str(), L"WM/Period") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PERIOD;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Picture") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PICTURE;
	}
	else if (wcscmp(exName.c_str(), L"WM/Producer") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PRODUCER;
	}	
	else if (wcscmp(exName.c_str(), L"WM/PromotionURL") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PROMOTIONURL;
	}
	else if (wcscmp(exName.c_str(), L"WM/Provider") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PROVIDER;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ProviderCopyright") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PROVIDERCPYRIGHT;
	}
	else if (wcscmp(exName.c_str(), L"WM/ProviderRating") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PROVIDERRATING;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ProviderStyle") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PROVIDERSTYLE;
	}
	else if (wcscmp(exName.c_str(), L"WM/Publisher") == 0)
	{
		rtExFrameID = WMA_FRAMEID_PUBLISHER;
	}	
	else if (wcscmp(exName.c_str(), L"WM/RadioStationName") == 0)
	{
		rtExFrameID = WMA_FRAMEID_RADIOSTATIONNAME;
	}
	else if (wcscmp(exName.c_str(), L"WM/RadioStationOwner") == 0)
	{
		rtExFrameID = WMA_FRAMEID_RADIOSTATIONOWNER;
	}	
	else if (wcscmp(exName.c_str(), L"WM/SharedUserRating") == 0)
	{
		rtExFrameID = WMA_FRAMEID_SHAREUSERRATING;
	}
	else if (wcscmp(exName.c_str(), L"WM/SubTitle") == 0)
	{
		rtExFrameID = WMA_FRAMEID_SUBTITLE;
	}	
	else if (wcscmp(exName.c_str(), L"WM/SubTitleDescription") == 0)
	{
		rtExFrameID = WMA_FRAMEID_SUBTITLEDESCRIPTION;
	}
	else if (wcscmp(exName.c_str(), L"WM/Text") == 0)
	{
		rtExFrameID = WMA_FRAMEID_TEXT;
	}	
	else if (wcscmp(exName.c_str(), L"WM/ToolName") == 0)
	{
		rtExFrameID = WMA_FRAMEID_TOOLNAME;
	}
	else if (wcscmp(exName.c_str(), L"WM/ToolVersion") == 0)
	{
		rtExFrameID = WMA_FRAMEID_TOOLVERSION;
	}	
	else if (wcscmp(exName.c_str(), L"WM/Track") == 0)
	{
		rtExFrameID = WMA_FRAMEID_TRACK;
	}
	else if (wcscmp(exName.c_str(), L"WM/TrackNumber") == 0)
	{
		rtExFrameID = WMA_FRAMEID_TRACKNUMBER;
	}
	else if (wcscmp(exName.c_str(), L"WM/UniqueFileIdentifier") == 0)
	{
		rtExFrameID = WMA_FRAMEID_UNIQUEFILEIDENTIFIER;
	}
	else if (wcscmp(exName.c_str(), L"WM/UserWebURL") == 0)
	{
		rtExFrameID = WMA_FRAMEID_USERWEBURL;
	}
	else if (wcscmp(exName.c_str(), L"WM/WMCollectionGroupID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_WMCOLLECTIONGROUPID;
	}
	else if (wcscmp(exName.c_str(), L"WM/WMCollectionID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_WMCOLLECTIONID;
	}
	else if (wcscmp(exName.c_str(), L"WM/WMContentID") == 0)
	{
		rtExFrameID = WMA_FRAMEID_CONTENTID;
	}
	else if (wcscmp(exName.c_str(), L"WM/Writer") == 0)
	{
		rtExFrameID = WMA_FRAMEID_WRITER;
	}
	else if (wcscmp(exName.c_str(), L"WM/Year") == 0)
	{
		rtExFrameID = WMA_FRAMEID_YEAR;
	}
	else if (wcscmp(exName.c_str(), L"WMFSDKVersion") == 0)
	{
		rtExFrameID = WMA_FRAMEID_SDKVERSION;
	}
	else if (wcscmp(exName.c_str(), L"WMFSDKNeeded") == 0)
	{
		rtExFrameID = WMA_FRAMEID_SDKNEEDED;
	}
	else if (wcscmp(exName.c_str(), L"IsVBR") == 0)
	{
		rtExFrameID = WMA_FRAMEID_ISVBR;
	}
	else
	{
		rtExFrameID = WMA_FRAMEID_UNKNOWN;
	}		
	
	return rtExFrameID;
}




贴出上面实现中用到存储图片的类头文件:

/********************************************************************
	created:	2010/05/14
	created:	14:5:2010   9:03
	filename: 	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyPicInfo.h
	file path:	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG
	file base:	CMyPicInfo
	file ext:	h
	author:		zhangwf
	
	purpose:	用于存储读取出的图片信息类
*********************************************************************/
#ifndef _CMY_PIC_INFO_H
#define _CMY_PIC_INFO_H
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 定义存放解析图片数据类
class CMYPICINFO
{
public:
	// 构造函数
	CMYPICINFO();

	// 析构函数
	~CMYPICINFO();

	// 拷贝构造函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的拷贝构造函数)
	CMYPICINFO(const CMYPICINFO &otherPicInfo);

	// 赋值函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的赋值函数)
	CMYPICINFO& operator =(const CMYPICINFO &otherPicInfo);

public:
	// 接口函数
	// 得到图片缓冲区地址(注意判断为NULL的情况)
	const unsigned char* GetPicBufAddr();

	// 得到缓冲区大小
	unsigned long GetPicBufSize();

	// 设置图片数据
	bool SetPicBufData(const char *pPicData, unsigned long picDataLength);

	// 释放图片数据
	void ReleaseData();

	// 保存数据到文件
	bool SavePicToFile(const char *filePathName);
	bool SavePicToFile(const wchar_t *filePathName);

private:
	// 私有成员函数
	// 申请空间
	bool NewPicBuf(unsigned long bufSize);

	// 释放空间
	void DeletePicBuf();

private:
	// 成员变量
	unsigned char *m_pPicBuf;
	unsigned long m_lBufSize;
};
//////////////////////////////////////////////////////////////////////////
#endif




贴出图片存储类实现文件:

/********************************************************************
	created:	2010/05/14
	created:	14:5:2010   9:03
	filename: 	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyPicInfo.cpp
	file path:	f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG
	file base:	CMyPicInfo
	file ext:	cpp
	author:		zhangwf
	
	purpose:	用于存储读取出的图片信息类
*********************************************************************/
//////////////////////////////////////////////////////////////////////////
#include "CMyPicInfo.h"
#include <Windows.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////

// 存放解析到的图片数据类
// 构造函数
CMYPICINFO::CMYPICINFO()
{
	// 初始化成员变量
	m_pPicBuf = NULL;
	m_lBufSize = 0;
}

// 析构函数
CMYPICINFO::~CMYPICINFO()
{
	// 释放空间
	DeletePicBuf();
}

// 拷贝构造函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的拷贝构造函数)
CMYPICINFO::CMYPICINFO(const CMYPICINFO &otherPicInfo)
{
	// 获得大小
	m_lBufSize = otherPicInfo.m_lBufSize;

	// 拷贝图片数据	
	m_pPicBuf = NULL;
	if (otherPicInfo.m_pPicBuf != NULL)
	{
		m_pPicBuf = new unsigned char[otherPicInfo.m_lBufSize];
		if (m_pPicBuf != NULL)
		{
			memcpy(m_pPicBuf, otherPicInfo.m_pPicBuf, otherPicInfo.m_lBufSize);	
		}
	}	
}

// 赋值函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的赋值函数)
CMYPICINFO& CMYPICINFO::operator =(const CMYPICINFO &otherPicInfo)
{
	// 检查自赋值
	if (this == &otherPicInfo)
	{
		return *this;
	}

	// 释放图片数据
	DeletePicBuf();

	// 获得图片大小
	m_lBufSize = otherPicInfo.m_lBufSize;

	// 拷贝图片数据
	if (otherPicInfo.m_pPicBuf != NULL)
	{
		m_pPicBuf = new unsigned char[otherPicInfo.m_lBufSize];
		if (m_pPicBuf != NULL)
		{
			memcpy(m_pPicBuf, otherPicInfo.m_pPicBuf, otherPicInfo.m_lBufSize);	
		}
	}	

	// 返回本对象的引用
	return *this;
}

//////////////////////////////////////////////////////////////////////////
// 接口函数
// 得到图片缓冲区地址(注意判断为NULL的情况)
const unsigned char* CMYPICINFO::GetPicBufAddr()
{
	return m_pPicBuf;
}

// 得到缓冲区大小
unsigned long CMYPICINFO::GetPicBufSize()
{
	return m_lBufSize;
}

// 设置图片数据
bool CMYPICINFO::SetPicBufData(const char *pPicData, unsigned long picDataLength)
{
	// 参数有效性
	if (pPicData==NULL || picDataLength==0)
	{
		return false;
	}

	// 重新申请空间
	if (!NewPicBuf(picDataLength))
	{
		return false;
	}

	// 拷贝数据
	memcpy(m_pPicBuf, pPicData, picDataLength);

	// 返回成功
	return true;
}

// 释放图片数据
void CMYPICINFO::ReleaseData()
{
	DeletePicBuf();
}

// 保存数据到文件
bool CMYPICINFO::SavePicToFile(const char *filePathName)
{
	// 判断是否有数据
	if (m_pPicBuf == NULL)
	{
		return false;
	}

	// 打开文件
	FILE *pFile = fopen(filePathName, "wb");
	if (pFile == NULL)
	{
		return false;
	}

	// 写入文件
	fwrite(m_pPicBuf, m_lBufSize, 1, pFile);
	fclose(pFile);
	return true;
}

// 保存数据到文件
bool CMYPICINFO::SavePicToFile(const wchar_t *filePathName)
{
	// 判断是否有数据
	if (m_pPicBuf == NULL)
	{
		return false;
	}

	// 打开文件
	FILE *pFile = _wfopen(filePathName, L"wb");
	if (pFile == NULL)
	{
		return false;
	}

	// 写入文件
	fwrite(m_pPicBuf, m_lBufSize, 1, pFile);
	fclose(pFile);
	return true;
}

//////////////////////////////////////////////////////////////////////////
// 私有函数
// 申请空间
bool CMYPICINFO::NewPicBuf(unsigned long bufSize)
{
	// 释放上次
	DeletePicBuf();

	// 参数是否有效
	if (bufSize == 0)
	{
		return false;
	}

	// 申请新的空间	
	m_pPicBuf = new unsigned char[bufSize];
	if (m_pPicBuf == NULL)
	{
		return false;
	}

	// 得到缓冲区大小
	m_lBufSize = bufSize;

	// 初始化内存空间
	memset(m_pPicBuf, 0, m_lBufSize);

	// 返回成功
	return true;
}

// 释放空间
void CMYPICINFO::DeletePicBuf()
{
	if (m_pPicBuf != NULL)
	{
		delete[] m_pPicBuf;
		m_pPicBuf = NULL;
		m_lBufSize = 0;
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: