0
 需要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

 

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

贴出实现类头文件:

  1. /******************************************************************** 
  2.     created:    2010/05/14 
  3.     created:    14:5:2010   9:12 
  4.     filename:   f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyWMATag.h 
  5.     file path:  f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG 
  6.     file base:  CMyWMATag 
  7.     file ext:   h 
  8.     author:     zhangwf 
  9.      
  10.     purpose:    解析WMA格式信息类,提取其中的TAG信息 
  11. *********************************************************************/  
  12. #ifndef _CMY_WMA_TAG_H_   
  13. #define _CMY_WMA_TAG_H_   
  14. //////////////////////////////////////////////////////////////////////////   
  15. #include "CMyPicInfo.h"   
  16. #include <string>   
  17. #include <vector>   
  18. using namespace std;  
  19. //////////////////////////////////////////////////////////////////////////   
  20. /************************************************************************* 
  21. // 分为文件头和各个帧数据 
  22. +--------------------------------------------------------------+ 
  23. |      Header (30 bytes)   HeadFlag:16; HeadSize:8; Unknow:6   | 
  24. +--------------------------------------------------------------+ 
  25. |      Frames (1....n)                                         | 
  26. +--------------------------------------------------------------+ 
  27. // 所有的TAG信息存放在标准帧和扩展帧中,其他帧可以不予考虑 
  28. // 所有的信息都是UNICODE编码 
  29. // 标准帧结构 
  30. +--------------------------------------------------------------+ 
  31. |      Header (24 bytes)   HeadFlag:16; HeadSize:8;            | 
  32. +--------------------------------------------------------------+ 
  33. |      标题信息大小(2 bytes)                                  | 
  34. +--------------------------------------------------------------+ 
  35. |      艺术家信息大小(2 bytes)                                | 
  36. +--------------------------------------------------------------+ 
  37. |      版权信息大小(2 bytes)                                  | 
  38. +--------------------------------------------------------------+ 
  39. |      备注信息大小(2 bytes)                                  | 
  40. +--------------------------------------------------------------+ 
  41. |      未知信息大小(2 bytes)                                  | 
  42. +--------------------------------------------------------------+ 
  43. |      标题信息内容(0x00 0x00结束)                              | 
  44. +--------------------------------------------------------------+ 
  45. |      艺术家信息内容(0x00 0x00结束)                            | 
  46. +--------------------------------------------------------------+ 
  47. |      版权信息内容(0x00 0x00结束)                              | 
  48. +--------------------------------------------------------------+ 
  49. |      备注信息内容(0x00 0x00结束)                              | 
  50. +--------------------------------------------------------------+ 
  51. |      未知信息内容(0x00 0x00结束)                              | 
  52. +--------------------------------------------------------------+ 
  53. // 扩展帧结构 
  54. +--------------------------------------------------------------+ 
  55. |      Header (24 bytes)   HeadFlag:16; HeadSize:8;            | 
  56. +--------------------------------------------------------------+ 
  57. |      扩展信息个数EXNO(2 bytes)                              | 
  58. +--------------------------------------------------------------+ 
  59. |      EXINFO (1....EXNO)                                      | 
  60. +--------------------------------------------------------------+ 
  61. // 每个扩展信息EXINFO结构 
  62. +--------------------------------------------------------------+ 
  63. |      EXINFO NAME Size (2 bytes)   扩展信息名字大小            | 
  64. +--------------------------------------------------------------+ 
  65. |      扩展信息名称                                             | 
  66. +--------------------------------------------------------------+ 
  67. |      标志FLAG   (2 bytes)                                    | 
  68. +--------------------------------------------------------------+ 
  69. |      值的大小   (2 bytes)                                     | 
  70. +--------------------------------------------------------------+ 
  71. |      实际的值   (图片格式参考ID3V2.3)                         | 
  72. +--------------------------------------------------------------+ 
  73. 当扩展信息名字为WMFSDKVersion时,这个值表示的是这个WMA文件的版本; 
  74. 当扩展信息名字为WM/AlbumTitle时,这个值代表的就是专辑名; 
  75. 当扩展信息名字为WM/Genre时,这个值代表的就是流派; 
  76. 下面再来看看那个标志Flag,这个基本上是为没什么用的(通常值为0), 
  77. 对WM/TrackNumber和WM/Track这两个扩展信息名字有用, 
  78. 当Flag为3的时候后面的值(也就是曲目信息)是以4个字节的整数的形式表示, 
  79. 当Flag为0的时候,曲目信息是以普通的字符串形式表示的。 
  80. // 查看http://msdn.microsoft.com/en-us/library/ms867702.aspx 
  81. Author 
  82. Copyright 
  83. Description 
  84. Rating 
  85. Title 
  86. WM/AlbumArtist 
  87. WM/AlbumCoverURL 
  88. WM/AlbumTitle 
  89. WM/AudioFileURL 
  90. WM/AudioSourceURL 
  91. WM/AuthorURL 
  92. WM/BeatsPerMinute 
  93. WM/Category 
  94. WM/Composer 
  95. WM/Conductor 
  96. WM/ContentDistributor 
  97. WM/ContentGroupDescription 
  98. WM/Director 
  99. WM/DVDID 
  100. WM/EncodedBy 
  101. WM/EncodingSettings 
  102. WM/EncodingTime 
  103. WM/Genre 
  104. WM/GenreID 
  105. WM/InitialKey 
  106. WM/ISRC 
  107. WM/Language 
  108. WM/Lyrics 
  109. WM/Lyrics_Synchronised 
  110. WM/MCDI 
  111. WM/MediaClassPrimaryID 
  112. WM/MediaClassSecondaryID 
  113. WM/MediaCredits 
  114. WM/MediaIsDelay 
  115. WM/MediaIsFinale 
  116. WM/MediaIsLive 
  117. WM/MediaIsPremiere 
  118. WM/MediaIsRepeat 
  119. WM/MediaIsSAP 
  120. WM/MediaIsSubtitled 
  121. WM/MediaIsStereo 
  122. WM/MediaNetworkAffiliation 
  123. WM/MediaOriginalBroadcastDateTime 
  124. WM/MediaOriginalChannel 
  125. WM/MediaStationCallSign 
  126. WM/MediaStationName 
  127. WM/ModifiedBy 
  128. WM/Mood 
  129. WM/OriginalAlbumTitle 
  130. WM/OriginalArtist 
  131. WM/OriginalFilename 
  132. WM/OriginalLyricist 
  133. WM/OriginalReleaseTime 
  134. WM/OriginalReleaseYear 
  135. WM/ParentalRating 
  136. WM/ParentalRatingReason 
  137. WM/PartOfSet 
  138. WM/Period 
  139. WM/Picture 
  140. WM/Producer 
  141. WM/PromotionURL 
  142. WM/Provider 
  143. WM/ProviderCopyright 
  144. WM/ProviderRating 
  145. WM/ProviderStyle 
  146. WM/Publisher 
  147. WM/RadioStationName 
  148. WM/RadioStationOwner 
  149. WM/SharedUserRating 
  150. WM/SubTitle 
  151. WM/SubTitleDescription 
  152. WM/Text 
  153. WM/ToolName 
  154. WM/ToolVersion 
  155. WM/Track 
  156. WM/TrackNumber 
  157. WM/UniqueFileIdentifier 
  158. WM/UserWebURL 
  159. WM/WMCollectionGroupID 
  160. WM/WMCollectionID 
  161. WM/WMContentID 
  162. WM/Writer 
  163. WM/Year 
  164.  
  165. WMFSDKVersion 
  166. WMFSDKNeeded 
  167. IsVBR 
  168. *************************************************************************/  
  169. //////////////////////////////////////////////////////////////////////////   
  170. // 定义帧类型   
  171. enum WMA_FRAMESTYLE_T  
  172. {  
  173.     WMA_FRAMESTYLE_STANDARD,   // 标准帧   
  174.     WMA_FRAMESTYLE_EXTEND,     // 扩展帧   
  175.     WMA_FRAMESTYLE_UNKNOWN,    // 未知帧   
  176. };  
  177.   
  178. // 定义帧标识类型ID   
  179. enum WMA_FRAMEID_T  
  180. {  
  181.     // 基础类型标准帧中的内容   
  182.     WMA_FRAMEID_AUTHOR = 0,  
  183.     WMA_FRAMEID_COPYRIGHT,    
  184.     WMA_FRAMEID_DESCRIPTION,      
  185.     WMA_FRAMEID_RATING,  
  186.     WMA_FRAMEID_TITLE,  
  187.   
  188.     // 其他类型按字母排序   
  189.     WMA_FRAMEID_ALBUMARTIST,  
  190.     WMA_FRAMEID_ALBUMCOVERURL,  
  191.     WMA_FRAMEID_ALBUMTITLE,  
  192.     WMA_FRAMEID_AUDIOFILEURL,  
  193.     WMA_FRAMEID_AUDIOSOURCEURL,  
  194.     WMA_FRAMEID_AUTHORURL,  
  195.     WMA_FRAMEID_BPMT,       // WM/BeatsPerMinute   
  196.     WMA_FRAMEID_CATEGORY,  
  197.     WMA_FRAMEID_COMPOSER,  
  198.     WMA_FRAMEID_CONDUCTOR,  
  199.     WMA_FRAMEID_CONTENTDISTRIBUTOR,  
  200.     WMA_FRAMEID_CGDPN, // WM/ContentGroupDescription   
  201.     WMA_FRAMEID_DIRECTOR,   
  202.     WMA_FRAMEID_DVDID,  
  203.     WMA_FRAMEID_ENCODEDBY,  
  204.     WMA_FRAMEID_ENCODINGSETTINGS,  
  205.     WMA_FRAMEID_ENCODINGTIME,  
  206.     WMA_FRAMEID_GENRE,  
  207.     WMA_FRAMEID_GENREID,  
  208.     WMA_FRAMEID_INITIALKEY,  
  209.     WMA_FRAMEID_ISRC,  
  210.     WMA_FRAMEID_LANGUAGE,  
  211.     WMA_FRAMEID_LYRICS,  
  212.     WMA_FRAMEID_LYRICSSYNC, // WM/Lyrics_Synchronised   
  213.     WMA_FRAMEID_MCDI,  
  214.     WMA_FRAMEID_MCPID, // WM/MediaClassPrimaryID   
  215.     WMA_FRAMEID_MCSID, // WM/MediaClassSecondaryID   
  216.     WMA_FRAMEID_MDACREDITS, // WM/MediaCredits   
  217.     WMA_FRAMEID_MDAISDELAY,   // WM/MediaIsDelay   
  218.     WMA_FRAMEID_MDAISFINALE,  // WM/MediaIsFinale   
  219.     WMA_FRAMEID_MDAISLIVE,    // WM/MediaIsLive   
  220.     WMA_FRAMEID_MDAISPREMIERE,  // WM/MediaIsPremiere   
  221.     WMA_FRAMEID_MDAISREPEAT,    // WM/MediaIsRepeat   
  222.     WMA_FRAMEID_MDAISSAP,       // WM/MediaIsSAP   
  223.     WMA_FRAMEID_MDAISSUBTITLED,  // WM/MediaIsSubtitled   
  224.     WMA_FRAMEID_MDAISSTEREO,     // WM/MediaIsStereo   
  225.     WMA_FRAMEID_MDANETWORKAFFILIATION,  // WM/MediaNetworkAffiliation   
  226.     WMA_FRAMEID_MDAORIGINALBDT,         // WM/MediaOriginalBroadcastDateTime   
  227.     WMA_FRAMEID_MDAORIGINALCHANNEL,     // WM/MediaOriginalChannel   
  228.     WMA_FRAMEID_MDASTATIONCALLSIGN,     // WM/MediaStationCallSign   
  229.     WMA_FRAMEID_MDASTATIONNAME,         // WM/MediaStationName   
  230.     WMA_FRAMEID_MODIFIEDBY,  
  231.     WMA_FRAMEID_MOOD,  
  232.     WMA_FRAMEID_ORIGALBUMTITLE,     // WM/OriginalAlbumTitle   
  233.     WMA_FRAMEID_ORIGARTIST,         // WM/OriginalArtist   
  234.     WMA_FRAMEID_ORIGFILENAME,       // WM/OriginalFilename   
  235.     WMA_FRAMEID_ORIGLYRICIST,       // WM/OriginalLyricist   
  236.     WMA_FRAMEID_ORIGRELEASETIME,    // WM/OriginalReleaseTime   
  237.     WMA_FRAMEID_ORIGRELEASEYEAR,    // WM/OriginalReleaseYear   
  238.     WMA_FRAMEID_PARENTALRATING,  
  239.     WMA_FRAMEID_PARENTALRATINGREASON,    // WM/ParentalRatingReason   
  240.     WMA_FRAMEID_PARTOFSET,  
  241.     WMA_FRAMEID_PERIOD,   
  242.     WMA_FRAMEID_PICTURE,  
  243.     WMA_FRAMEID_PRODUCER,  
  244.     WMA_FRAMEID_PROMOTIONURL,  
  245.     WMA_FRAMEID_PROVIDER,  
  246.     WMA_FRAMEID_PROVIDERCPYRIGHT,  
  247.     WMA_FRAMEID_PROVIDERRATING,  
  248.     WMA_FRAMEID_PROVIDERSTYLE,  
  249.     WMA_FRAMEID_PUBLISHER,  
  250.     WMA_FRAMEID_RADIOSTATIONNAME,  
  251.     WMA_FRAMEID_RADIOSTATIONOWNER,  
  252.     WMA_FRAMEID_SHAREUSERRATING,  
  253.     WMA_FRAMEID_SUBTITLE,  
  254.     WMA_FRAMEID_SUBTITLEDESCRIPTION,  
  255.     WMA_FRAMEID_TEXT,  
  256.     WMA_FRAMEID_TOOLNAME,  
  257.     WMA_FRAMEID_TOOLVERSION,  
  258.     WMA_FRAMEID_TRACK,  
  259.     WMA_FRAMEID_TRACKNUMBER,      
  260.     WMA_FRAMEID_UNIQUEFILEIDENTIFIER,  
  261.     WMA_FRAMEID_USERWEBURL,  
  262.     WMA_FRAMEID_WMCOLLECTIONGROUPID,  
  263.     WMA_FRAMEID_WMCOLLECTIONID,  
  264.     WMA_FRAMEID_CONTENTID,  
  265.     WMA_FRAMEID_WRITER,   
  266.     WMA_FRAMEID_YEAR,  
  267.   
  268.     WMA_FRAMEID_SDKVERSION, // WMFSDKVersion   
  269.     WMA_FRAMEID_SDKNEEDED,  // WMFSDKNeeded   
  270.     WMA_FRAMEID_ISVBR,      // IsVBR   
  271.       
  272.   
  273.     ////////////////////////////////////////////////////////////////////   
  274.     WMA_FRAMEID_UNKNOWN, // 未知   
  275.   
  276. };  
  277. //////////////////////////////////////////////////////////////////////////   
  278. // 定义WMA文件头标识   
  279. typedef struct _WMA_HEADFLAG_INFO_  
  280. {  
  281.     unsigned char WmaFlag[16];          // 固定的16个字节内容表示是否WMA文件   
  282. }WMAHEADFLAG;  
  283.   
  284. // 定义WMA文件头常量标识   
  285. const WMAHEADFLAG WMA_HEAD_FLAGCONST = {0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C};  
  286.   
  287. // 定义WMA文件头大小   
  288. typedef struct _WMA_HEADSIZE_INFO_  
  289. {  
  290.     unsigned char Size[8];     // 8个字节表示大小(由后向前存储数据)   
  291. }WMAHEADSIZE;  
  292.   
  293. // 定义WMA文件头结构   
  294. typedef struct _WMA_HEADINFO_  
  295. {  
  296.     WMAHEADFLAG HeadFlag;      // WMA文件标识   
  297.     WMAHEADSIZE HeadSize;      // WMA文件头大小   
  298.     unsigned char Unknown[6];  // 6个字节具体代表什么不清楚(有的说是帧的数量)   
  299. }WMAHEADINFO;  
  300.   
  301. // 定义帧头标识   
  302. typedef struct _WMA_FRAMEHEADFLAG_INFO_  
  303. {  
  304.     unsigned char Flag[16];   // 固定的16个字节表示帧类型   
  305. }WMAFRAMEHEADFLAG;  
  306.   
  307. // 定义WMA标准帧及扩展帧常量标识   
  308. const WMAFRAMEHEADFLAG WMA_FRAMEHEAD_STANDARD = {0x33, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C};  
  309. const WMAFRAMEHEADFLAG WMA_FRAMEHEAD_EXTEND   = {0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50};  
  310.   
  311. // 定义帧大小   
  312. typedef struct _WMA_FRAMEHEADSIZE_INFO_  
  313. {  
  314.     unsigned char Size[8];     // 8个字节表示帧大小(由后向前存储数据)   
  315. }WMAFRAMEHEADSIZE;  
  316.   
  317. // 定义帧头结构   
  318. typedef struct _WMA_FRAMEHEAD_INFO_  
  319. {  
  320.     WMAFRAMEHEADFLAG FrameFlag;  
  321.     WMAFRAMEHEADSIZE FrameSize;  
  322. }WMAFRAMEHEADINFO;  
  323.   
  324. // 定义解析值的类型   
  325. enum WMA_ATTRSTYLE_T  
  326. {  
  327.     WMA_ATTRSTYLE_TXT = 0, // 字符串属性   
  328.     WMA_ATTRSTYLE_VAL,     // 值属性   
  329. };  
  330.   
  331. // 定义属性解析内容结构   
  332. typedef struct _WMA_ATTR_INFO_  
  333. {  
  334.     WMA_FRAMEID_T ID;           // ID表示解析的类型   
  335.     WMA_ATTRSTYLE_T AttrStyle;  // 值的类型   
  336.     wstring StrContent;         // 解析的TXT内容   
  337.     unsigned long ValContent;   // 解析的值内容   
  338. }WMAATTRINFO;  
  339.   
  340. // 定义属性解析内容动态数组存放解析的内容   
  341. typedef vector<WMAATTRINFO> CWMAAttrArray;  
  342.   
  343. // 定义图片解析内容结构   
  344. typedef struct _WMA_PICITEMINFO_  
  345. {  
  346.     wstring MimeType;         // "image/png" or "image/jpeg"    
  347.     char PicType;             // 说明如下   
  348.     wstring Description;      // 图片描述   
  349.     CMYPICINFO PicData;       // 图片数据   
  350. }WMAPICITEMINFO;  
  351.   
  352. // 定义PIC属性解析内容动态数组存放解析的内容(可能含有多张图片)   
  353. typedef vector<WMAPICITEMINFO> CWMAPicArray;  
  354.   
  355.   
  356. //////////////////////////////////////////////////////////////////////////   
  357. class CMyWMATag  
  358. {  
  359. public:  
  360.     // 构造函数   
  361.     CMyWMATag();  
  362.   
  363.     // 析构函数   
  364.     ~CMyWMATag();  
  365.   
  366. public:  
  367.     // 接口函数   
  368.     // 解析WMA文件,成功后调用下面接口获取信息   
  369.     bool AnalyzeWMAFile(const char *filePathName);  
  370.     bool AnalyzeWMAFile(const wchar_t *filePathName);  
  371.     bool AnalyzeWMAFile(const wstring &filePathName);  
  372.   
  373.     // 是否解析成功   
  374.     bool BeSuccess();  
  375.   
  376.     // 取得头大小   
  377.     unsigned long GetHeadSize();  
  378.   
  379.     //////////////////////////////////////////////////////////////////////////   
  380.     // 取得Txt属性内容接口   
  381.     bool GetTxtItemContent(WMA_FRAMEID_T frameID, wstring &itemContent);  
  382.     bool GetTxtItemContent(WMA_FRAMEID_T frameID, string &itemContent);  
  383.   
  384.     //////////////////////////////////////////////////////////////////////////   
  385.     // 取得图片属性内容接口   
  386.     // 取得第一张图片   
  387.     bool GetFirstPic(CMYPICINFO &picInfo);  
  388.   
  389.     // 保存第一张图片   
  390.     bool SaveFirstPicToFile(const char *filePathName);  
  391.     bool SaveFirstPicToFile(const wchar_t *filePathName);  
  392.   
  393.     // 取得第一张图片的地址及大小   
  394.     const unsigned char* GetFirstPicAddr(unsigned long *pPicSize=NULL);  
  395.   
  396.     // 取得第一行图片的大小   
  397.     unsigned long GetFirstPicSize();  
  398.   
  399.     // 取得图片数量   
  400.     unsigned long GetPicCounts();  
  401.   
  402.     // 取得第n张图片   
  403.     bool GetPic(unsigned long picIndex, CMYPICINFO &picInfo);  
  404.   
  405.     // 取得第n张图片的地址   
  406.     const unsigned char* GetPicAddr(unsigned long picIndex, unsigned long *pPicSize=NULL);  
  407.   
  408.     // 保存第n张图片   
  409.     bool SavePicToFile(unsigned long picIndex, const char *filePathName);  
  410.     bool SavePicToFile(unsigned long picIndex, const wchar_t *filePathName);  
  411.   
  412. private:  
  413.     // 私有函数   
  414.     // 根据文件头结构判断是否WMA文件   
  415.     bool BeWMAFile(const WMAHEADFLAG &headFlag);  
  416.   
  417.     // 清除信息   
  418.     void ClearDataInfo();  
  419.   
  420.     // 计算头大小   
  421.     unsigned long GetHeadSize(const WMAHEADSIZE &headSize);  
  422.   
  423.     // 得到帧类型   
  424.     WMA_FRAMESTYLE_T GetFrameStyle(const WMAFRAMEHEADFLAG &frameFlag);  
  425.   
  426.     // 判断两个帧头标识是否相等   
  427.     bool BeSameFrameFlag(const WMAFRAMEHEADFLAG &firstFlag, const WMAFRAMEHEADFLAG &secondFlag);  
  428.   
  429.     // 得到帧的大小   
  430.     unsigned long GetFrameSize(const WMAFRAMEHEADSIZE &frameSize);  
  431.   
  432.     // 计算由2个字节拼接成的整数大小   
  433.     unsigned long CalUInt16Val(const unsigned char *pByteBuf, int bufSize);  
  434.   
  435.     // 计算由4个字节拼接成的整数大小   
  436.     unsigned long CalUInt32Val(const unsigned char *pByteBuf, int bufSize);  
  437.   
  438.     // 解析得到的帧数据   
  439.     unsigned long ParseFrameData(const unsigned char *pFrameData, unsigned long bufLength);  
  440.   
  441.     // 得到帧头信息   
  442.     bool GetFrameHeadInfo(const unsigned char *pFrameData, unsigned long bufLength, WMAFRAMEHEADINFO &frameHead);  
  443.   
  444.     // 解析标准帧数据   
  445.     bool ParseStandardFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray);  
  446.   
  447.     // 解析扩展帧数据   
  448.     bool ParseExtendFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray, CWMAPicArray &WMAPicArray);  
  449.   
  450.     // 得到string   
  451.     wstring GetWString(const unsigned char* pUCharBuf, unsigned long charsNums);  
  452.   
  453.     // wstring转换为string   
  454.     string TransFromWString(const wstring &wstrVal);      
  455.   
  456.     // 取得扩展帧属性ID   
  457.     WMA_FRAMEID_T GetExFrameID(const wstring &exName);  
  458.   
  459.     // 取得字符串根据0x00,0x00   
  460.     unsigned long GetWstringByWChars(const unsigned char* pPicDataBuf, unsigned long bufSize, wstring &strVal);  
  461.   
  462. private:  
  463.     // 成员变量   
  464.     WMAHEADINFO m_HeadInfo;     // 存放头信息   
  465.     bool m_bAnalyzeSuccess;     // 保存解析是否成功   
  466.     CWMAAttrArray m_WMAAttrArray; // 存放解析到的TAG信息   
  467.     CWMAPicArray m_WMAPicArray;   // 存放解析的图片信息   
  468. };  
  469. //////////////////////////////////////////////////////////////////////////   
  470. #endif  

 

贴出实现文件:

  1. /******************************************************************** 
  2.     created:    2010/05/14 
  3.     created:    14:5:2010   9:12 
  4.     filename:   f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyWMATag.cpp 
  5.     file path:  f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG 
  6.     file base:  CMyWMATag 
  7.     file ext:   cpp 
  8.     author:     zhangwf 
  9.      
  10.     purpose:    解析WMA格式信息类,提取其中的TAG信息 
  11. *********************************************************************/  
  12. //////////////////////////////////////////////////////////////////////////   
  13. #include <Windows.h>   
  14. #include "CMyWMATag.h"   
  15. //////////////////////////////////////////////////////////////////////////   
  16. // 构造函数   
  17. CMyWMATag::CMyWMATag()  
  18. {  
  19.     // 初始化成员变量   
  20.     ClearDataInfo();  
  21.   
  22. }  
  23.   
  24. // 析构函数   
  25. CMyWMATag::~CMyWMATag()  
  26. {  
  27.   
  28. }  
  29.   
  30. //////////////////////////////////////////////////////////////////////////   
  31. // 接口函数   
  32. // 解析WMA文件,成功后调用下面接口获取信息   
  33. bool CMyWMATag::AnalyzeWMAFile(const char *filePathName)  
  34. {  
  35.     // 清除上次信息   
  36.     ClearDataInfo();  
  37.   
  38.     // 参数有效性   
  39.     if (filePathName == NULL)  
  40.     {         
  41.         return false;  
  42.     }  
  43.   
  44.     // 打开文件   
  45.     FILE *pWMAFile = fopen(filePathName, "rb");  
  46.     if (pWMAFile == NULL)  
  47.     {     
  48.         return false;  
  49.     }  
  50.   
  51.     // 读取WMA头结构   
  52.     memset(&m_HeadInfo, 0, sizeof(m_HeadInfo));  
  53.     if (fread(&m_HeadInfo, sizeof(m_HeadInfo), 1, pWMAFile) != 1)  
  54.     {         
  55.         fclose(pWMAFile);  
  56.         return false;  
  57.     }  
  58.   
  59.     // 判断是否WMA文件   
  60.     m_bAnalyzeSuccess = BeWMAFile(m_HeadInfo.HeadFlag);  
  61.     if (!m_bAnalyzeSuccess)  
  62.     {     
  63.         memset(&m_HeadInfo, 0, sizeof(m_HeadInfo));  
  64.         fclose(pWMAFile);         
  65.         return false;         
  66.     }         
  67.   
  68.     // 计算要读取帧数据的字节数   
  69.     unsigned long lFrameDataSize = GetHeadSize(m_HeadInfo.HeadSize) - sizeof(WMAHEADINFO);  
  70.   
  71.     // 为帧数据分配空间   
  72.     unsigned char *pFrameData = new unsigned char[lFrameDataSize];  
  73.     if (pFrameData == NULL)  
  74.     {  
  75.         fclose(pWMAFile);  
  76.         m_bAnalyzeSuccess = false;  
  77.         return false;  
  78.     }  
  79.   
  80.     // 读取帧数据   
  81.     memset(pFrameData, 0, lFrameDataSize);  
  82.     if (fread(pFrameData, lFrameDataSize, 1, pWMAFile) != 1)  
  83.     {  
  84.         // 释放帧数据   
  85.         if (pFrameData != NULL)  
  86.         {  
  87.             delete[] pFrameData;  
  88.             pFrameData = NULL;  
  89.         }  
  90.   
  91.         fclose(pWMAFile);  
  92.         m_bAnalyzeSuccess = false;  
  93.         return false;  
  94.     }  
  95.   
  96.     // 读取成功关闭文件   
  97.     fclose(pWMAFile);  
  98.   
  99.     // 解析帧数据   
  100.     ParseFrameData(pFrameData, lFrameDataSize);  
  101.   
  102.     // 释放帧数据   
  103.     if (pFrameData != NULL)  
  104.     {  
  105.         delete[] pFrameData;  
  106.         pFrameData = NULL;  
  107.     }  
  108.   
  109.     // 返回分析结果   
  110.     return m_bAnalyzeSuccess;  
  111. }  
  112.   
  113. // 解析WMA文件   
  114. bool CMyWMATag::AnalyzeWMAFile(const wchar_t *filePathName)  
  115. {  
  116.     // 参数有效性   
  117.     if (filePathName == NULL)  
  118.     {  
  119.         return false;  
  120.     }  
  121.   
  122.     // 计算转换为多字节字节数   
  123.     int nChars = WideCharToMultiByte(CP_ACP, 0, filePathName, -1, NULL, 0, NULL, NULL);  
  124.   
  125.     // 申请空间   
  126.     char *pFileName = new char[nChars+1];  
  127.     if (pFileName == NULL)  
  128.     {  
  129.         return false;  
  130.     }  
  131.   
  132.     // 转换为多字节   
  133.     memset(pFileName, 0, nChars+1);  
  134.     WideCharToMultiByte(CP_ACP, 0, filePathName, -1, pFileName, nChars, NULL, NULL);  
  135.   
  136.     // 解析   
  137.     bool bResult = AnalyzeWMAFile(pFileName);  
  138.   
  139.     // 释放   
  140.     if (pFileName != NULL)  
  141.     {  
  142.         delete[] pFileName;  
  143.         pFileName = NULL;  
  144.     }  
  145.   
  146.     // 返回结果   
  147.     return bResult;   
  148. }  
  149.   
  150. // 解析WMA文件   
  151. bool CMyWMATag::AnalyzeWMAFile(const wstring &filePathName)  
  152. {  
  153.     return AnalyzeWMAFile(filePathName.c_str());  
  154. }  
  155.   
  156. // 是否解析成功   
  157. bool CMyWMATag::BeSuccess()  
  158. {  
  159.     return m_bAnalyzeSuccess;  
  160. }  
  161.   
  162. // 取得头大小   
  163. unsigned long CMyWMATag::GetHeadSize()  
  164. {  
  165.     return GetHeadSize(m_HeadInfo.HeadSize);  
  166. }  
  167.   
  168. //////////////////////////////////////////////////////////////////////////   
  169. // 取得Txt属性内容接口   
  170. bool CMyWMATag::GetTxtItemContent(WMA_FRAMEID_T frameID, wstring &itemContent)  
  171. {  
  172.     // 解析失败   
  173.     if (!BeSuccess())  
  174.     {     
  175.         return false;  
  176.     }  
  177.   
  178.     // 查找   
  179.     for (unsigned long i=0; i<m_WMAAttrArray.size(); i++)  
  180.     {  
  181.         if (frameID == m_WMAAttrArray[i].ID)  
  182.         {  
  183.             if (m_WMAAttrArray[i].AttrStyle == WMA_ATTRSTYLE_TXT)  
  184.             {  
  185.                 itemContent = m_WMAAttrArray[i].StrContent;  
  186.                 return true;  
  187.             }  
  188.             else  
  189.             {  
  190.                 return false;  
  191.             }             
  192.         }  
  193.     }  
  194.   
  195.     // 没有找到   
  196.     return false;  
  197. }  
  198.   
  199. // 取得Txt属性内容接口   
  200. bool CMyWMATag::GetTxtItemContent(WMA_FRAMEID_T frameID, string &itemContent)  
  201. {  
  202.     wstring wContent;  
  203.     bool bOK = GetTxtItemContent(frameID, wContent);  
  204.     itemContent = TransFromWString(wContent);  
  205.     return bOK;  
  206. }  
  207.   
  208. //////////////////////////////////////////////////////////////////////////   
  209. // 取得图片属性内容接口   
  210. // 取得第一张图片   
  211. bool CMyWMATag::GetFirstPic(CMYPICINFO &picInfo)  
  212. {  
  213.     // 解析失败   
  214.     if (!BeSuccess())  
  215.     {     
  216.         return false;  
  217.     }  
  218.   
  219.     // 查找是否有图片   
  220.     if (m_WMAPicArray.size() == 0)  
  221.     {  
  222.         return false;  
  223.     }  
  224.   
  225.     // 得到第一张图片   
  226.     picInfo = m_WMAPicArray[0].PicData;  
  227.     return true;  
  228. }  
  229.   
  230. // 保存第一张图片   
  231. bool CMyWMATag::SaveFirstPicToFile(const char *filePathName)  
  232. {  
  233.     if (BeSuccess() && m_WMAPicArray.size()>0)  
  234.     {  
  235.         return m_WMAPicArray[0].PicData.SavePicToFile(filePathName);  
  236.     }  
  237.   
  238.     return false;  
  239. }  
  240. bool CMyWMATag::SaveFirstPicToFile(const wchar_t *filePathName)  
  241. {  
  242.     if (BeSuccess() && m_WMAPicArray.size()>0)  
  243.     {  
  244.         return m_WMAPicArray[0].PicData.SavePicToFile(filePathName);  
  245.     }  
  246.   
  247.     return false;  
  248. }  
  249.   
  250. // 取得第一张图片的地址及大小   
  251. const unsigned char* CMyWMATag::GetFirstPicAddr(unsigned long *pPicSize)  
  252. {  
  253.     if (BeSuccess() && m_WMAPicArray.size()>0)  
  254.     {  
  255.         if (pPicSize != NULL)  
  256.         {  
  257.             *pPicSize = m_WMAPicArray[0].PicData.GetPicBufSize();  
  258.         }  
  259.   
  260.         return m_WMAPicArray[0].PicData.GetPicBufAddr();  
  261.     }  
  262.   
  263.     return NULL;  
  264. }  
  265.   
  266. // 取得第一行图片的大小   
  267. unsigned long CMyWMATag::GetFirstPicSize()  
  268. {  
  269.     if (BeSuccess() && m_WMAPicArray.size()>0)  
  270.     {  
  271.         return m_WMAPicArray[0].PicData.GetPicBufSize();  
  272.     }  
  273.   
  274.     return 0;  
  275. }  
  276.   
  277. // 取得图片数量   
  278. unsigned long CMyWMATag::GetPicCounts()  
  279. {  
  280.     return (unsigned long)m_WMAPicArray.size();  
  281. }  
  282.   
  283. // 取得第n张图片   
  284. bool CMyWMATag::GetPic(unsigned long picIndex, CMYPICINFO &picInfo)  
  285. {  
  286.     // 解析失败   
  287.     if (!BeSuccess())  
  288.     {     
  289.         return false;  
  290.     }  
  291.   
  292.     // 得到图片数量   
  293.     unsigned long picCounts = GetPicCounts();  
  294.   
  295.     // 查找是否有图片   
  296.     if (picCounts == 0)  
  297.     {  
  298.         return false;  
  299.     }  
  300.   
  301.     // 索引是否有效   
  302.     if (picIndex >= picCounts)  
  303.     {  
  304.         return false;  
  305.     }  
  306.   
  307.     // 得到第picIndex张图片   
  308.     picInfo = m_WMAPicArray[picIndex].PicData;  
  309.     return true;  
  310. }  
  311.   
  312. // 取得第n张图片的地址   
  313. const unsigned char* CMyWMATag::GetPicAddr(unsigned long picIndex, unsigned long *pPicSize)  
  314. {  
  315.     // 解析失败   
  316.     if (!BeSuccess())  
  317.     {     
  318.         return NULL;  
  319.     }  
  320.   
  321.     // 得到图片数量   
  322.     unsigned long picCounts = GetPicCounts();  
  323.   
  324.     // 查找是否有图片   
  325.     if (picCounts == 0)  
  326.     {  
  327.         return NULL;  
  328.     }  
  329.   
  330.     // 索引是否有效   
  331.     if (picIndex >= picCounts)  
  332.     {  
  333.         return NULL;  
  334.     }  
  335.   
  336.     // 取得图片大小   
  337.     if (pPicSize != NULL)  
  338.     {  
  339.         *pPicSize = m_WMAPicArray[picIndex].PicData.GetPicBufSize();  
  340.     }  
  341.   
  342.     // 得到第picIndex张图片地址   
  343.     return m_WMAPicArray[picIndex].PicData.GetPicBufAddr();  
  344. }  
  345.   
  346. // 保存第n张图片   
  347. bool CMyWMATag::SavePicToFile(unsigned long picIndex, const char *filePathName)  
  348. {  
  349.     // 参数有效性   
  350.     if (filePathName == NULL)  
  351.     {  
  352.         return false;  
  353.     }  
  354.   
  355.     // 解析失败   
  356.     if (!BeSuccess())  
  357.     {     
  358.         return false;  
  359.     }  
  360.   
  361.     // 得到图片数量   
  362.     unsigned long picCounts = GetPicCounts();  
  363.   
  364.     // 查找是否有图片   
  365.     if (picCounts == 0)  
  366.     {  
  367.         return false;  
  368.     }  
  369.   
  370.     // 索引是否有效   
  371.     if (picIndex >= picCounts)  
  372.     {  
  373.         return false;  
  374.     }  
  375.   
  376.     return m_WMAPicArray[picIndex].PicData.SavePicToFile(filePathName);  
  377. }  
  378.   
  379. // 保存第n张图片   
  380. bool CMyWMATag::SavePicToFile(unsigned long picIndex, const wchar_t *filePathName)  
  381. {  
  382.     // 参数有效性   
  383.     if (filePathName == NULL)  
  384.     {  
  385.         return false;  
  386.     }  
  387.   
  388.     // 解析失败   
  389.     if (!BeSuccess())  
  390.     {     
  391.         return false;  
  392.     }  
  393.   
  394.     // 得到图片数量   
  395.     unsigned long picCounts = GetPicCounts();  
  396.   
  397.     // 查找是否有图片   
  398.     if (picCounts == 0)  
  399.     {  
  400.         return false;  
  401.     }  
  402.   
  403.     // 索引是否有效   
  404.     if (picIndex >= picCounts)  
  405.     {  
  406.         return false;  
  407.     }  
  408.   
  409.     return m_WMAPicArray[picIndex].PicData.SavePicToFile(filePathName);  
  410. }  
  411. //////////////////////////////////////////////////////////////////////////   
  412. // 私有函数   
  413. // 根据文件头结构判断是否WMA文件   
  414. bool CMyWMATag::BeWMAFile(const WMAHEADFLAG &headFlag)  
  415. {  
  416.     for (int i=0; i<sizeof(WMA_HEAD_FLAGCONST.WmaFlag); i++)  
  417.     {  
  418.         if (headFlag.WmaFlag[i] != WMA_HEAD_FLAGCONST.WmaFlag[i])  
  419.         {  
  420.             return false;  
  421.         }  
  422.     }  
  423.   
  424.     return true;  
  425. }  
  426.   
  427. // 清除信息   
  428. void CMyWMATag::ClearDataInfo()  
  429. {  
  430.     memset(&m_HeadInfo, 0, sizeof(m_HeadInfo));  
  431.     m_bAnalyzeSuccess = false;  
  432.     m_WMAAttrArray.clear();  
  433.     m_WMAPicArray.clear();  
  434. }  
  435.   
  436. // 计算头大小   
  437. unsigned long CMyWMATag::GetHeadSize(const WMAHEADSIZE &headSize)  
  438. {  
  439.     return (unsigned long)((headSize.Size[3]<<24) | (headSize.Size[2]<<16) | (headSize.Size[1]<<8) | headSize.Size[0]);  
  440. }  
  441.   
  442. // 得到帧类型   
  443. WMA_FRAMESTYLE_T CMyWMATag::GetFrameStyle(const WMAFRAMEHEADFLAG &frameFlag)  
  444. {  
  445.     // 判断是否标准帧   
  446.     if (BeSameFrameFlag(frameFlag, WMA_FRAMEHEAD_STANDARD))  
  447.     {  
  448.         return WMA_FRAMESTYLE_STANDARD;  
  449.     }  
  450.   
  451.     // 判断是否扩展帧   
  452.     if (BeSameFrameFlag(frameFlag, WMA_FRAMEHEAD_EXTEND))  
  453.     {  
  454.         return WMA_FRAMESTYLE_EXTEND;  
  455.     }  
  456.       
  457.     // 返回位置帧   
  458.     return WMA_FRAMESTYLE_UNKNOWN;  
  459. }  
  460.   
  461. // 判断两个帧头标识是否相等   
  462. bool CMyWMATag::BeSameFrameFlag(const WMAFRAMEHEADFLAG &firstFlag, const WMAFRAMEHEADFLAG &secondFlag)  
  463. {  
  464.     for (int i=0; i<16; i++)  
  465.     {  
  466.         if (firstFlag.Flag[i] != secondFlag.Flag[i])  
  467.         {  
  468.             return false;  
  469.         }  
  470.     }  
  471.   
  472.     return true;  
  473. }  
  474.   
  475. // 得到帧的大小   
  476. unsigned long CMyWMATag::GetFrameSize(const WMAFRAMEHEADSIZE &frameSize)  
  477. {  
  478.     return (unsigned long)((frameSize.Size[3]<<24) | (frameSize.Size[2]<<16) | (frameSize.Size[1]<<8) | frameSize.Size[0]);  
  479. }  
  480.   
  481. // 计算由2个字节拼接成的整数大小   
  482. unsigned long CMyWMATag::CalUInt16Val(const unsigned char *pByteBuf, int bufSize)  
  483. {  
  484.     // 参数有效性   
  485.     if (pByteBuf==NULL || bufSize<2)  
  486.     {  
  487.         return 0;  
  488.     }  
  489.   
  490.     // 返回值   
  491.     return ((pByteBuf[1]<<8) | pByteBuf[0]);  
  492. }  
  493.   
  494. // 计算由4个字节拼接成的整数大小   
  495. unsigned long CMyWMATag::CalUInt32Val(const unsigned char *pByteBuf, int bufSize)  
  496. {  
  497.     // 参数有效性   
  498.     if (pByteBuf==NULL || bufSize<4)  
  499.     {  
  500.         return 0;  
  501.     }  
  502.   
  503.     // 返回值   
  504.     return ((pByteBuf[3]<<24) | (pByteBuf[2]<<16) | (pByteBuf[1]<<8) | pByteBuf[0]);  
  505. }  
  506.   
  507. // 解析得到的帧数据   
  508. unsigned long CMyWMATag::ParseFrameData(const unsigned char *pFrameData, unsigned long bufLength)  
  509. {  
  510.     // 清除上次数据   
  511.     m_WMAAttrArray.clear();  
  512.     m_WMAPicArray.clear();  
  513.   
  514.     // 参数有效性   
  515.     if (pFrameData==NULL || bufLength==0)  
  516.     {  
  517.         return 0;  
  518.     }  
  519.   
  520.     // 存放临时变量   
  521.     WMAFRAMEHEADINFO frameHead;  
  522.     WMA_FRAMESTYLE_T frameStyle = WMA_FRAMESTYLE_UNKNOWN;  
  523.     unsigned long frameSize = 0;  
  524.     WMAATTRINFO attrItemInfo;  
  525.   
  526.   
  527.     // 遍历解析内容   
  528.     unsigned long pos = 0;  
  529.     while (pos+24 < bufLength)  
  530.     {  
  531.         // 得到帧头失败   
  532.         if (!GetFrameHeadInfo(pFrameData+pos, bufLength-pos, frameHead))  
  533.         {  
  534.             break;  
  535.         }  
  536.       
  537.         // 得到帧风格类型   
  538.         frameStyle = GetFrameStyle(frameHead.FrameFlag);          
  539.   
  540.         // 是正确风格,取得帧大小   
  541.         frameSize = GetFrameSize(frameHead.FrameSize);        
  542.   
  543.         // 取得帧体内容      
  544.         if (frameSize>=24 && pos+23+frameSize<bufLength)  
  545.         {  
  546.             // 是标准帧,解析标准帧   
  547.             if (frameStyle == WMA_FRAMESTYLE_STANDARD)  
  548.             {  
  549.                 ParseStandardFrame(pFrameData+pos+24, frameSize-24, m_WMAAttrArray);  
  550.             }  
  551.             // 是扩展帧   
  552.             else if (frameStyle == WMA_FRAMESTYLE_EXTEND)  
  553.             {         
  554.                 ParseExtendFrame(pFrameData+pos+24, frameSize-24, m_WMAAttrArray, m_WMAPicArray);  
  555.             }             
  556.   
  557.             // 改变索引   
  558.             pos += frameSize;  
  559.         }  
  560.         else  
  561.         {  
  562.             pos++;  
  563.         }  
  564.     }  
  565.   
  566.     for (unsigned int i=0; i<m_WMAAttrArray.size(); i++)  
  567.     {  
  568.         printf("ID:%d Content:%s/n", m_WMAAttrArray[i].ID, TransFromWString(m_WMAAttrArray[i].StrContent).c_str());  
  569.     }  
  570.   
  571.     // 返回解析的属性数量   
  572.     return (unsigned long)m_WMAAttrArray.size() + (unsigned long)m_WMAPicArray.size();  
  573. }  
  574.   
  575. // 得到帧头信息   
  576. bool CMyWMATag::GetFrameHeadInfo(const unsigned char *pFrameData, unsigned long bufLength, WMAFRAMEHEADINFO &frameHead)  
  577. {  
  578.     // 参数有效性   
  579.     if (pFrameData==NULL || bufLength<24)  
  580.     {  
  581.         return false;  
  582.     }  
  583.   
  584.     // 得到帧标识   
  585.     int i = 0;  
  586.     for (i=0; i<16; i++)  
  587.     {  
  588.         frameHead.FrameFlag.Flag[i] = pFrameData[i];  
  589.     }  
  590.   
  591.     // 得到帧大小   
  592.     for (i=0; i<8; i++)  
  593.     {  
  594.         frameHead.FrameSize.Size[i] = pFrameData[i+16];  
  595.     }  
  596.   
  597.     return true;  
  598. }  
  599.   
  600. // 解析标准帧数据   
  601. bool CMyWMATag::ParseStandardFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray)  
  602. {  
  603.     // 参数有效性   
  604.     if (pItemFrameData==NULL || frameSize==0)  
  605.     {  
  606.         return false;  
  607.     }  
  608.   
  609.     // 计算标题信息大小   
  610.     unsigned long titleSize = CalUInt16Val(pItemFrameData, 2);  
  611.   
  612.     // 计算艺术家信息大小   
  613.     unsigned long artistSize = CalUInt16Val(pItemFrameData+2, 2);  
  614.   
  615.     // 计算版权信息大小   
  616.     unsigned long copyRightSize = CalUInt16Val(pItemFrameData+4, 2);  
  617.   
  618.     // 计算备注信息大小   
  619.     unsigned long commentSize = CalUInt16Val(pItemFrameData+6, 2);  
  620.   
  621.     // 计算未知信息大小   
  622.     unsigned long unknownSize = CalUInt16Val(pItemFrameData+8, 2);  
  623.   
  624.     // 偏移量   
  625.     unsigned long offset = 10;  
  626.   
  627.     // 临时存放信息   
  628.     WMAATTRINFO attrInfo;  
  629.     memset(&attrInfo, 0, sizeof(attrInfo));  
  630.     attrInfo.AttrStyle = WMA_ATTRSTYLE_TXT;  
  631.   
  632.     // 取得标题信息   
  633.     attrInfo.ID = WMA_FRAMEID_TITLE;  
  634.     attrInfo.StrContent = GetWString(pItemFrameData+offset, titleSize);  
  635.     WMAAttrArray.push_back(attrInfo);  
  636.     offset += titleSize;  
  637.   
  638.     // 取得艺术家信息   
  639.     attrInfo.ID = WMA_FRAMEID_AUTHOR;  
  640.     attrInfo.StrContent = GetWString(pItemFrameData+offset, artistSize);  
  641.     WMAAttrArray.push_back(attrInfo);  
  642.     offset += artistSize;  
  643.   
  644.     // 取得版权信息   
  645.     attrInfo.ID = WMA_FRAMEID_COPYRIGHT;  
  646.     attrInfo.StrContent = GetWString(pItemFrameData+offset, copyRightSize);  
  647.     WMAAttrArray.push_back(attrInfo);  
  648.     offset += copyRightSize;  
  649.   
  650.     // 取得备注信息   
  651.     attrInfo.ID = WMA_FRAMEID_DESCRIPTION;  
  652.     attrInfo.StrContent = GetWString(pItemFrameData+offset, commentSize);  
  653.     WMAAttrArray.push_back(attrInfo);  
  654.     offset += commentSize;  
  655.   
  656.     // 取得未知信息   
  657.     attrInfo.ID = WMA_FRAMEID_RATING;  
  658.     attrInfo.StrContent = GetWString(pItemFrameData+offset, unknownSize);  
  659.     WMAAttrArray.push_back(attrInfo);  
  660.     offset += unknownSize;    
  661.   
  662.     // 返回成功   
  663.     return true;  
  664. }  
  665.   
  666. // 得到string   
  667. wstring CMyWMATag::GetWString(const unsigned char* pUCharBuf, unsigned long charsNums)  
  668. {  
  669.     // 返回值   
  670.     wstring strRet = L"";  
  671.   
  672.     // 参数有效性   
  673.     if (pUCharBuf==NULL || charsNums==0)  
  674.     {  
  675.         return strRet;  
  676.     }  
  677.   
  678.     // 得到字符串   
  679.     strRet.append((const wchar_t*)pUCharBuf, charsNums/2);    
  680.     return strRet;  
  681. }  
  682.   
  683. // wstring转换为string   
  684. string CMyWMATag::TransFromWString(const wstring &wstrVal)  
  685. {  
  686.     // 计算字符数   
  687.     int nCharNums = (int)wstrVal.length();  
  688.     int mulBufSize = 2*nCharNums+10;  
  689.   
  690.     // 申请空间   
  691.     char *pCharBuf = new char[mulBufSize];  
  692.     if (pCharBuf == NULL)  
  693.     {  
  694.         return "";  
  695.     }  
  696.     memset(pCharBuf, 0, mulBufSize);  
  697.   
  698.     // 转换   
  699.     WideCharToMultiByte(CP_ACP, 0, wstrVal.c_str(), -1, pCharBuf, mulBufSize, NULL, NULL);  
  700.   
  701.     // 得到结果   
  702.     string strVal(pCharBuf);  
  703.   
  704.     // 释放空间   
  705.     if (pCharBuf != NULL)  
  706.     {  
  707.         delete[] pCharBuf;  
  708.         pCharBuf = NULL;  
  709.     }  
  710.   
  711.     return strVal;  
  712. }  
  713.   
  714. // 解析扩展帧数据   
  715. bool CMyWMATag::ParseExtendFrame(const unsigned char *pItemFrameData, unsigned long frameSize, CWMAAttrArray &WMAAttrArray, CWMAPicArray &WMAPicArray)  
  716. {  
  717.     // 参数有效性   
  718.     if (pItemFrameData==NULL || frameSize==0)  
  719.     {  
  720.         return false;  
  721.     }  
  722.   
  723.     // 计算扩展信息数量   
  724.     unsigned long exInfoCounts = CalUInt16Val(pItemFrameData, 2);  
  725.   
  726.     // 地址偏移量   
  727.     unsigned long offset = 2;  
  728.   
  729.     // 临时存放扩展信息   
  730.     unsigned long exNameSize = 0;  
  731.     wstring exName = L"";  
  732.     unsigned long exFlagVal = 0;  
  733.     unsigned long valSize = 0;  
  734.     WMA_FRAMEID_T frameID = WMA_FRAMEID_UNKNOWN;  
  735.     WMAATTRINFO attrInfo;     
  736.     WMAPICITEMINFO picItem;  
  737.     unsigned lenTmp = 0;  
  738.   
  739.     // 取扩展信息   
  740.     for (unsigned exIndex=0; exIndex<exInfoCounts; exIndex++)  
  741.     {  
  742.         // 清除上次内容   
  743.         memset(&attrInfo, 0, sizeof(attrInfo));  
  744.   
  745.         // 计算扩展名大小   
  746.         exNameSize = CalUInt16Val(pItemFrameData+offset, 2);  
  747.         offset += 2;          
  748.   
  749.         // 取得扩展名称   
  750.         exName = GetWString(pItemFrameData+offset, exNameSize);  
  751.         offset += exNameSize;  
  752.   
  753.         // 取得扩展标识FLAG值   
  754.         exFlagVal = CalUInt16Val(pItemFrameData+offset, 2);  
  755.         offset += 2;  
  756.   
  757.         // 取得实际值的大小   
  758.         valSize = CalUInt16Val(pItemFrameData+offset, 2);  
  759.         offset += 2;  
  760.   
  761.         // 计算扩展属性ID   
  762.         frameID = GetExFrameID(exName);  
  763.   
  764.         // 是否有效ID   
  765.         if (frameID != WMA_FRAMEID_UNKNOWN)  
  766.         {  
  767.             // 得到属性ID   
  768.             attrInfo.ID = frameID;  
  769.   
  770.             // 图片得到图片信息   
  771.             if (frameID == WMA_FRAMEID_PICTURE)  
  772.             {             
  773.                 lenTmp = GetWstringByWChars(pItemFrameData+offset, frameSize-offset, picItem.MimeType);               
  774.                 picItem.PicType = (char)((pItemFrameData+offset+lenTmp)[0]);  
  775.                 lenTmp += 1;  
  776.                 lenTmp += GetWstringByWChars(pItemFrameData+offset+lenTmp, frameSize-offset-lenTmp, picItem.Description);  
  777.                 picItem.PicData.SetPicBufData((const char*)(pItemFrameData+offset+lenTmp), valSize-lenTmp);  
  778.                 m_WMAPicArray.push_back(picItem);  
  779.             }             
  780.             else  
  781.             {  
  782.                 // 扩展FLAG标识是字符串类型还是值类型   
  783.                 // 表示值类型   
  784.                 if (exFlagVal == 3)  
  785.                 {  
  786.                     attrInfo.AttrStyle = WMA_ATTRSTYLE_VAL;  
  787.                     if (valSize >= 4)  
  788.                     {  
  789.                         attrInfo.ValContent = CalUInt32Val(pItemFrameData+offset, 4);  
  790.                     }  
  791.                     WMAAttrArray.push_back(attrInfo);  
  792.                 }  
  793.                 else  
  794.                 {  
  795.                     attrInfo.AttrStyle = WMA_ATTRSTYLE_TXT;  
  796.                     attrInfo.StrContent = GetWString(pItemFrameData+offset, valSize);  
  797.                     WMAAttrArray.push_back(attrInfo);  
  798.                 }  
  799.             }         
  800.         }  
  801.   
  802.         // 改变地址偏移量   
  803.         offset += valSize;  
  804.     }     
  805.   
  806.     // 返回成功   
  807.     return true;  
  808. }  
  809.   
  810. // 取得字符串根据0x00,0x00   
  811. unsigned long CMyWMATag::GetWstringByWChars(const unsigned char* pPicDataBuf, unsigned long bufSize, wstring &strVal)  
  812. {  
  813.     // 返回数量   
  814.     unsigned long lResult = 0;  
  815.   
  816.     // 参数有效性   
  817.     if (pPicDataBuf==NULL || bufSize==0)  
  818.     {  
  819.         return lResult;  
  820.     }  
  821.   
  822.     // 遍历   
  823.     const wchar_t *pWBuf = (const wchar_t*)pPicDataBuf;  
  824.     unsigned long wBufSize = bufSize/2;  
  825.     unsigned long wPos = 0;  
  826.     while (wPos < wBufSize)  
  827.     {  
  828.         if (pWBuf[wPos] == 0x00)  
  829.         {  
  830.             lResult = 2*(wPos+1);  
  831.             break;  
  832.         }  
  833.         else  
  834.         {  
  835.             wPos++;  
  836.         }  
  837.     }  
  838.   
  839.     // 得到字符串   
  840.     strVal = L"";  
  841.     strVal.append(pWBuf, wPos+1);  
  842.   
  843.     // 返回   
  844.     return lResult;   
  845. }  
  846.   
  847. // 取得扩展帧属性ID   
  848. WMA_FRAMEID_T CMyWMATag::GetExFrameID(const wstring &exName)  
  849. {  
  850.     // 用于返回值   
  851.     WMA_FRAMEID_T rtExFrameID = WMA_FRAMEID_UNKNOWN;  
  852.   
  853.     // 与标识比较   
  854.     if (wcscmp(exName.c_str(), L"WM/AlbumArtist") == 0)  
  855.     {  
  856.         rtExFrameID = WMA_FRAMEID_ALBUMARTIST;  
  857.     }  
  858.     else if (wcscmp(exName.c_str(), L"WM/AlbumCoverURL") == 0)  
  859.     {  
  860.         rtExFrameID = WMA_FRAMEID_ALBUMCOVERURL;  
  861.     }     
  862.     else if (wcscmp(exName.c_str(), L"WM/AlbumTitle") == 0)  
  863.     {  
  864.         rtExFrameID = WMA_FRAMEID_ALBUMTITLE;  
  865.     }     
  866.     else if (wcscmp(exName.c_str(), L"WM/AudioFileURL") == 0)  
  867.     {  
  868.         rtExFrameID = WMA_FRAMEID_AUDIOFILEURL;  
  869.     }     
  870.     else if (wcscmp(exName.c_str(), L"WM/AudioSourceURL") == 0)  
  871.     {  
  872.         rtExFrameID = WMA_FRAMEID_AUDIOSOURCEURL;  
  873.     }     
  874.     else if (wcscmp(exName.c_str(), L"WM/AuthorURL") == 0)  
  875.     {  
  876.         rtExFrameID = WMA_FRAMEID_AUTHORURL;  
  877.     }     
  878.     else if (wcscmp(exName.c_str(), L"WM/BeatsPerMinute") == 0)  
  879.     {  
  880.         rtExFrameID = WMA_FRAMEID_BPMT;  
  881.     }     
  882.     else if (wcscmp(exName.c_str(), L"WM/Category") == 0)  
  883.     {  
  884.         rtExFrameID = WMA_FRAMEID_CATEGORY;  
  885.     }     
  886.     else if (wcscmp(exName.c_str(), L"WM/Composer") == 0)  
  887.     {  
  888.         rtExFrameID = WMA_FRAMEID_COMPOSER;  
  889.     }     
  890.     else if (wcscmp(exName.c_str(), L"WM/Conductor") == 0)  
  891.     {  
  892.         rtExFrameID = WMA_FRAMEID_CONDUCTOR;  
  893.     }     
  894.     else if (wcscmp(exName.c_str(), L"WM/ContentDistributor") == 0)  
  895.     {  
  896.         rtExFrameID = WMA_FRAMEID_CONTENTDISTRIBUTOR;  
  897.     }     
  898.     else if (wcscmp(exName.c_str(), L"WM/ContentGroupDescription") == 0)  
  899.     {  
  900.         rtExFrameID = WMA_FRAMEID_CGDPN;  
  901.     }     
  902.     else if (wcscmp(exName.c_str(), L"WM/Director") == 0)  
  903.     {  
  904.         rtExFrameID = WMA_FRAMEID_DIRECTOR;  
  905.     }     
  906.     else if (wcscmp(exName.c_str(), L"WM/DVDID") == 0)  
  907.     {  
  908.         rtExFrameID = WMA_FRAMEID_DVDID;  
  909.     }     
  910.     else if (wcscmp(exName.c_str(), L"WM/EncodedBy") == 0)  
  911.     {  
  912.         rtExFrameID = WMA_FRAMEID_ENCODEDBY;  
  913.     }     
  914.     else if (wcscmp(exName.c_str(), L"WM/EncodingSettings") == 0)  
  915.     {  
  916.         rtExFrameID = WMA_FRAMEID_ENCODINGSETTINGS;  
  917.     }     
  918.     else if (wcscmp(exName.c_str(), L"WM/EncodingTime") == 0)  
  919.     {  
  920.         rtExFrameID = WMA_FRAMEID_ENCODINGTIME;  
  921.     }     
  922.     else if (wcscmp(exName.c_str(), L"WM/Genre") == 0)  
  923.     {  
  924.         rtExFrameID = WMA_FRAMEID_GENRE;  
  925.     }     
  926.     else if (wcscmp(exName.c_str(), L"WM/GenreID") == 0)  
  927.     {  
  928.         rtExFrameID = WMA_FRAMEID_GENREID;  
  929.     }  
  930.     else if (wcscmp(exName.c_str(), L"WM/InitialKey") == 0)  
  931.     {  
  932.         rtExFrameID = WMA_FRAMEID_INITIALKEY;  
  933.     }     
  934.     else if (wcscmp(exName.c_str(), L"WM/ISRC") == 0)  
  935.     {  
  936.         rtExFrameID = WMA_FRAMEID_ISRC;  
  937.     }     
  938.     else if (wcscmp(exName.c_str(), L"WM/Language") == 0)  
  939.     {  
  940.         rtExFrameID = WMA_FRAMEID_LANGUAGE;  
  941.     }  
  942.     else if (wcscmp(exName.c_str(), L"WM/Lyrics") == 0)  
  943.     {  
  944.         rtExFrameID = WMA_FRAMEID_LYRICS;  
  945.     }     
  946.     else if (wcscmp(exName.c_str(), L"WM/Lyrics_Synchronised") == 0)  
  947.     {  
  948.         rtExFrameID = WMA_FRAMEID_LYRICSSYNC;  
  949.     }     
  950.     else if (wcscmp(exName.c_str(), L"WM/MCDI") == 0)  
  951.     {  
  952.         rtExFrameID = WMA_FRAMEID_MCDI;  
  953.     }  
  954.     else if (wcscmp(exName.c_str(), L"WM/MediaClassPrimaryID") == 0)  
  955.     {  
  956.         rtExFrameID = WMA_FRAMEID_MCPID;  
  957.     }     
  958.     else if (wcscmp(exName.c_str(), L"WM/MediaClassSecondaryID") == 0)  
  959.     {  
  960.         rtExFrameID = WMA_FRAMEID_MCSID;  
  961.     }     
  962.     else if (wcscmp(exName.c_str(), L"WM/MediaCredits") == 0)  
  963.     {  
  964.         rtExFrameID = WMA_FRAMEID_MDACREDITS;  
  965.     }  
  966.     else if (wcscmp(exName.c_str(), L"WM/MediaIsDelay") == 0)  
  967.     {  
  968.         rtExFrameID = WMA_FRAMEID_MDAISDELAY;  
  969.     }     
  970.     else if (wcscmp(exName.c_str(), L"WM/MediaIsFinale") == 0)  
  971.     {  
  972.         rtExFrameID = WMA_FRAMEID_MDAISFINALE;  
  973.     }     
  974.     else if (wcscmp(exName.c_str(), L"WM/MediaIsLive") == 0)  
  975.     {  
  976.         rtExFrameID = WMA_FRAMEID_MDAISLIVE;  
  977.     }  
  978.     else if (wcscmp(exName.c_str(), L"WM/MediaIsPremiere") == 0)  
  979.     {  
  980.         rtExFrameID = WMA_FRAMEID_MDAISPREMIERE;  
  981.     }     
  982.     else if (wcscmp(exName.c_str(), L"WM/MediaIsRepeat") == 0)  
  983.     {  
  984.         rtExFrameID = WMA_FRAMEID_MDAISREPEAT;  
  985.     }     
  986.     else if (wcscmp(exName.c_str(), L"WM/MediaIsSAP") == 0)  
  987.     {  
  988.         rtExFrameID = WMA_FRAMEID_MDAISSAP;  
  989.     }  
  990.     else if (wcscmp(exName.c_str(), L"WM/MediaIsSubtitled") == 0)  
  991.     {  
  992.         rtExFrameID = WMA_FRAMEID_MDAISSUBTITLED;  
  993.     }     
  994.     else if (wcscmp(exName.c_str(), L"WM/MediaIsStereo") == 0)  
  995.     {  
  996.         rtExFrameID = WMA_FRAMEID_MDAISSTEREO;  
  997.     }  
  998.     else if (wcscmp(exName.c_str(), L"WM/MediaNetworkAffiliation") == 0)  
  999.     {  
  1000.         rtExFrameID = WMA_FRAMEID_MDANETWORKAFFILIATION;  
  1001.     }     
  1002.     else if (wcscmp(exName.c_str(), L"WM/MediaOriginalBroadcastDateTime") == 0)  
  1003.     {  
  1004.         rtExFrameID = WMA_FRAMEID_MDAORIGINALBDT;  
  1005.     }  
  1006.     else if (wcscmp(exName.c_str(), L"WM/MediaOriginalChannel") == 0)  
  1007.     {  
  1008.         rtExFrameID = WMA_FRAMEID_MDAORIGINALCHANNEL;  
  1009.     }     
  1010.     else if (wcscmp(exName.c_str(), L"WM/MediaStationCallSign") == 0)  
  1011.     {  
  1012.         rtExFrameID = WMA_FRAMEID_MDASTATIONCALLSIGN;  
  1013.     }  
  1014.     else if (wcscmp(exName.c_str(), L"WM/MediaStationName") == 0)  
  1015.     {  
  1016.         rtExFrameID = WMA_FRAMEID_MDASTATIONNAME;  
  1017.     }     
  1018.     else if (wcscmp(exName.c_str(), L"WM/ModifiedBy") == 0)  
  1019.     {  
  1020.         rtExFrameID = WMA_FRAMEID_MODIFIEDBY;  
  1021.     }  
  1022.     else if (wcscmp(exName.c_str(), L"WM/Mood") == 0)  
  1023.     {  
  1024.         rtExFrameID = WMA_FRAMEID_MOOD;  
  1025.     }     
  1026.     else if (wcscmp(exName.c_str(), L"WM/OriginalAlbumTitle") == 0)  
  1027.     {  
  1028.         rtExFrameID = WMA_FRAMEID_ORIGALBUMTITLE;  
  1029.     }  
  1030.     else if (wcscmp(exName.c_str(), L"WM/OriginalArtist") == 0)  
  1031.     {  
  1032.         rtExFrameID = WMA_FRAMEID_ORIGARTIST;  
  1033.     }     
  1034.     else if (wcscmp(exName.c_str(), L"WM/OriginalFilename") == 0)  
  1035.     {  
  1036.         rtExFrameID = WMA_FRAMEID_ORIGFILENAME;  
  1037.     }  
  1038.     else if (wcscmp(exName.c_str(), L"WM/OriginalLyricist") == 0)  
  1039.     {  
  1040.         rtExFrameID = WMA_FRAMEID_ORIGLYRICIST;  
  1041.     }     
  1042.     else if (wcscmp(exName.c_str(), L"WM/OriginalReleaseTime") == 0)  
  1043.     {  
  1044.         rtExFrameID = WMA_FRAMEID_ORIGRELEASETIME;  
  1045.     }  
  1046.     else if (wcscmp(exName.c_str(), L"WM/OriginalReleaseYear") == 0)  
  1047.     {  
  1048.         rtExFrameID = WMA_FRAMEID_ORIGRELEASEYEAR;  
  1049.     }     
  1050.     else if (wcscmp(exName.c_str(), L"WM/ParentalRating") == 0)  
  1051.     {  
  1052.         rtExFrameID = WMA_FRAMEID_PARENTALRATING;  
  1053.     }  
  1054.     else if (wcscmp(exName.c_str(), L"WM/ParentalRatingReason") == 0)  
  1055.     {  
  1056.         rtExFrameID = WMA_FRAMEID_PARENTALRATINGREASON;  
  1057.     }     
  1058.     else if (wcscmp(exName.c_str(), L"WM/PartOfSet") == 0)  
  1059.     {  
  1060.         rtExFrameID = WMA_FRAMEID_PARTOFSET;  
  1061.     }  
  1062.     else if (wcscmp(exName.c_str(), L"WM/Period") == 0)  
  1063.     {  
  1064.         rtExFrameID = WMA_FRAMEID_PERIOD;  
  1065.     }     
  1066.     else if (wcscmp(exName.c_str(), L"WM/Picture") == 0)  
  1067.     {  
  1068.         rtExFrameID = WMA_FRAMEID_PICTURE;  
  1069.     }  
  1070.     else if (wcscmp(exName.c_str(), L"WM/Producer") == 0)  
  1071.     {  
  1072.         rtExFrameID = WMA_FRAMEID_PRODUCER;  
  1073.     }     
  1074.     else if (wcscmp(exName.c_str(), L"WM/PromotionURL") == 0)  
  1075.     {  
  1076.         rtExFrameID = WMA_FRAMEID_PROMOTIONURL;  
  1077.     }  
  1078.     else if (wcscmp(exName.c_str(), L"WM/Provider") == 0)  
  1079.     {  
  1080.         rtExFrameID = WMA_FRAMEID_PROVIDER;  
  1081.     }     
  1082.     else if (wcscmp(exName.c_str(), L"WM/ProviderCopyright") == 0)  
  1083.     {  
  1084.         rtExFrameID = WMA_FRAMEID_PROVIDERCPYRIGHT;  
  1085.     }  
  1086.     else if (wcscmp(exName.c_str(), L"WM/ProviderRating") == 0)  
  1087.     {  
  1088.         rtExFrameID = WMA_FRAMEID_PROVIDERRATING;  
  1089.     }     
  1090.     else if (wcscmp(exName.c_str(), L"WM/ProviderStyle") == 0)  
  1091.     {  
  1092.         rtExFrameID = WMA_FRAMEID_PROVIDERSTYLE;  
  1093.     }  
  1094.     else if (wcscmp(exName.c_str(), L"WM/Publisher") == 0)  
  1095.     {  
  1096.         rtExFrameID = WMA_FRAMEID_PUBLISHER;  
  1097.     }     
  1098.     else if (wcscmp(exName.c_str(), L"WM/RadioStationName") == 0)  
  1099.     {  
  1100.         rtExFrameID = WMA_FRAMEID_RADIOSTATIONNAME;  
  1101.     }  
  1102.     else if (wcscmp(exName.c_str(), L"WM/RadioStationOwner") == 0)  
  1103.     {  
  1104.         rtExFrameID = WMA_FRAMEID_RADIOSTATIONOWNER;  
  1105.     }     
  1106.     else if (wcscmp(exName.c_str(), L"WM/SharedUserRating") == 0)  
  1107.     {  
  1108.         rtExFrameID = WMA_FRAMEID_SHAREUSERRATING;  
  1109.     }  
  1110.     else if (wcscmp(exName.c_str(), L"WM/SubTitle") == 0)  
  1111.     {  
  1112.         rtExFrameID = WMA_FRAMEID_SUBTITLE;  
  1113.     }     
  1114.     else if (wcscmp(exName.c_str(), L"WM/SubTitleDescription") == 0)  
  1115.     {  
  1116.         rtExFrameID = WMA_FRAMEID_SUBTITLEDESCRIPTION;  
  1117.     }  
  1118.     else if (wcscmp(exName.c_str(), L"WM/Text") == 0)  
  1119.     {  
  1120.         rtExFrameID = WMA_FRAMEID_TEXT;  
  1121.     }     
  1122.     else if (wcscmp(exName.c_str(), L"WM/ToolName") == 0)  
  1123.     {  
  1124.         rtExFrameID = WMA_FRAMEID_TOOLNAME;  
  1125.     }  
  1126.     else if (wcscmp(exName.c_str(), L"WM/ToolVersion") == 0)  
  1127.     {  
  1128.         rtExFrameID = WMA_FRAMEID_TOOLVERSION;  
  1129.     }     
  1130.     else if (wcscmp(exName.c_str(), L"WM/Track") == 0)  
  1131.     {  
  1132.         rtExFrameID = WMA_FRAMEID_TRACK;  
  1133.     }  
  1134.     else if (wcscmp(exName.c_str(), L"WM/TrackNumber") == 0)  
  1135.     {  
  1136.         rtExFrameID = WMA_FRAMEID_TRACKNUMBER;  
  1137.     }  
  1138.     else if (wcscmp(exName.c_str(), L"WM/UniqueFileIdentifier") == 0)  
  1139.     {  
  1140.         rtExFrameID = WMA_FRAMEID_UNIQUEFILEIDENTIFIER;  
  1141.     }  
  1142.     else if (wcscmp(exName.c_str(), L"WM/UserWebURL") == 0)  
  1143.     {  
  1144.         rtExFrameID = WMA_FRAMEID_USERWEBURL;  
  1145.     }  
  1146.     else if (wcscmp(exName.c_str(), L"WM/WMCollectionGroupID") == 0)  
  1147.     {  
  1148.         rtExFrameID = WMA_FRAMEID_WMCOLLECTIONGROUPID;  
  1149.     }  
  1150.     else if (wcscmp(exName.c_str(), L"WM/WMCollectionID") == 0)  
  1151.     {  
  1152.         rtExFrameID = WMA_FRAMEID_WMCOLLECTIONID;  
  1153.     }  
  1154.     else if (wcscmp(exName.c_str(), L"WM/WMContentID") == 0)  
  1155.     {  
  1156.         rtExFrameID = WMA_FRAMEID_CONTENTID;  
  1157.     }  
  1158.     else if (wcscmp(exName.c_str(), L"WM/Writer") == 0)  
  1159.     {  
  1160.         rtExFrameID = WMA_FRAMEID_WRITER;  
  1161.     }  
  1162.     else if (wcscmp(exName.c_str(), L"WM/Year") == 0)  
  1163.     {  
  1164.         rtExFrameID = WMA_FRAMEID_YEAR;  
  1165.     }  
  1166.     else if (wcscmp(exName.c_str(), L"WMFSDKVersion") == 0)  
  1167.     {  
  1168.         rtExFrameID = WMA_FRAMEID_SDKVERSION;  
  1169.     }  
  1170.     else if (wcscmp(exName.c_str(), L"WMFSDKNeeded") == 0)  
  1171.     {  
  1172.         rtExFrameID = WMA_FRAMEID_SDKNEEDED;  
  1173.     }  
  1174.     else if (wcscmp(exName.c_str(), L"IsVBR") == 0)  
  1175.     {  
  1176.         rtExFrameID = WMA_FRAMEID_ISVBR;  
  1177.     }  
  1178.     else  
  1179.     {  
  1180.         rtExFrameID = WMA_FRAMEID_UNKNOWN;  
  1181.     }         
  1182.       
  1183.     return rtExFrameID;  
  1184. }  

 

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

  1. /******************************************************************** 
  2.     created:    2010/05/14 
  3.     created:    14:5:2010   9:03 
  4.     filename:   f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyPicInfo.h 
  5.     file path:  f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG 
  6.     file base:  CMyPicInfo 
  7.     file ext:   h 
  8.     author:     zhangwf 
  9.      
  10.     purpose:    用于存储读取出的图片信息类 
  11. *********************************************************************/  
  12. #ifndef _CMY_PIC_INFO_H   
  13. #define _CMY_PIC_INFO_H   
  14. //////////////////////////////////////////////////////////////////////////   
  15. //////////////////////////////////////////////////////////////////////////   
  16. // 定义存放解析图片数据类   
  17. class CMYPICINFO  
  18. {  
  19. public:  
  20.     // 构造函数   
  21.     CMYPICINFO();  
  22.   
  23.     // 析构函数   
  24.     ~CMYPICINFO();  
  25.   
  26.     // 拷贝构造函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的拷贝构造函数)   
  27.     CMYPICINFO(const CMYPICINFO &otherPicInfo);  
  28.   
  29.     // 赋值函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的赋值函数)   
  30.     CMYPICINFO& operator =(const CMYPICINFO &otherPicInfo);  
  31.   
  32. public:  
  33.     // 接口函数   
  34.     // 得到图片缓冲区地址(注意判断为NULL的情况)   
  35.     const unsigned char* GetPicBufAddr();  
  36.   
  37.     // 得到缓冲区大小   
  38.     unsigned long GetPicBufSize();  
  39.   
  40.     // 设置图片数据   
  41.     bool SetPicBufData(const char *pPicData, unsigned long picDataLength);  
  42.   
  43.     // 释放图片数据   
  44.     void ReleaseData();  
  45.   
  46.     // 保存数据到文件   
  47.     bool SavePicToFile(const char *filePathName);  
  48.     bool SavePicToFile(const wchar_t *filePathName);  
  49.   
  50. private:  
  51.     // 私有成员函数   
  52.     // 申请空间   
  53.     bool NewPicBuf(unsigned long bufSize);  
  54.   
  55.     // 释放空间   
  56.     void DeletePicBuf();  
  57.   
  58. private:  
  59.     // 成员变量   
  60.     unsigned char *m_pPicBuf;  
  61.     unsigned long m_lBufSize;  
  62. };  
  63. //////////////////////////////////////////////////////////////////////////   
  64. #endif  

 

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

  1. /******************************************************************** 
  2.     created:    2010/05/14 
  3.     created:    14:5:2010   9:03 
  4.     filename:   f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG/CMyPicInfo.cpp 
  5.     file path:  f:/个人资料_ZWF/自己的源代码/TestID3TAG/TestID3TAG 
  6.     file base:  CMyPicInfo 
  7.     file ext:   cpp 
  8.     author:     zhangwf 
  9.      
  10.     purpose:    用于存储读取出的图片信息类 
  11. *********************************************************************/  
  12. //////////////////////////////////////////////////////////////////////////   
  13. #include "CMyPicInfo.h"   
  14. #include <Windows.h>   
  15. #include <stdio.h>   
  16. //////////////////////////////////////////////////////////////////////////   
  17.   
  18. // 存放解析到的图片数据类   
  19. // 构造函数   
  20. CMYPICINFO::CMYPICINFO()  
  21. {  
  22.     // 初始化成员变量   
  23.     m_pPicBuf = NULL;  
  24.     m_lBufSize = 0;  
  25. }  
  26.   
  27. // 析构函数   
  28. CMYPICINFO::~CMYPICINFO()  
  29. {  
  30.     // 释放空间   
  31.     DeletePicBuf();  
  32. }  
  33.   
  34. // 拷贝构造函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的拷贝构造函数)   
  35. CMYPICINFO::CMYPICINFO(const CMYPICINFO &otherPicInfo)  
  36. {  
  37.     // 获得大小   
  38.     m_lBufSize = otherPicInfo.m_lBufSize;  
  39.   
  40.     // 拷贝图片数据      
  41.     m_pPicBuf = NULL;  
  42.     if (otherPicInfo.m_pPicBuf != NULL)  
  43.     {  
  44.         m_pPicBuf = new unsigned char[otherPicInfo.m_lBufSize];  
  45.         if (m_pPicBuf != NULL)  
  46.         {  
  47.             memcpy(m_pPicBuf, otherPicInfo.m_pPicBuf, otherPicInfo.m_lBufSize);   
  48.         }  
  49.     }     
  50. }  
  51.   
  52. // 赋值函数(使用Vector存放此类型时必须支持拷贝,由于含有指针分配的字符数组这里不能够用默认的赋值函数)   
  53. CMYPICINFO& CMYPICINFO::operator =(const CMYPICINFO &otherPicInfo)  
  54. {  
  55.     // 检查自赋值   
  56.     if (this == &otherPicInfo)  
  57.     {  
  58.         return *this;  
  59.     }  
  60.   
  61.     // 释放图片数据   
  62.     DeletePicBuf();  
  63.   
  64.     // 获得图片大小   
  65.     m_lBufSize = otherPicInfo.m_lBufSize;  
  66.   
  67.     // 拷贝图片数据   
  68.     if (otherPicInfo.m_pPicBuf != NULL)  
  69.     {  
  70.         m_pPicBuf = new unsigned char[otherPicInfo.m_lBufSize];  
  71.         if (m_pPicBuf != NULL)  
  72.         {  
  73.             memcpy(m_pPicBuf, otherPicInfo.m_pPicBuf, otherPicInfo.m_lBufSize);   
  74.         }  
  75.     }     
  76.   
  77.     // 返回本对象的引用   
  78.     return *this;  
  79. }  
  80.   
  81. //////////////////////////////////////////////////////////////////////////   
  82. // 接口函数   
  83. // 得到图片缓冲区地址(注意判断为NULL的情况)   
  84. const unsigned char* CMYPICINFO::GetPicBufAddr()  
  85. {  
  86.     return m_pPicBuf;  
  87. }  
  88.   
  89. // 得到缓冲区大小   
  90. unsigned long CMYPICINFO::GetPicBufSize()  
  91. {  
  92.     return m_lBufSize;  
  93. }  
  94.   
  95. // 设置图片数据   
  96. bool CMYPICINFO::SetPicBufData(const char *pPicData, unsigned long picDataLength)  
  97. {  
  98.     // 参数有效性   
  99.     if (pPicData==NULL || picDataLength==0)  
  100.     {  
  101.         return false;  
  102.     }  
  103.   
  104.     // 重新申请空间   
  105.     if (!NewPicBuf(picDataLength))  
  106.     {  
  107.         return false;  
  108.     }  
  109.   
  110.     // 拷贝数据   
  111.     memcpy(m_pPicBuf, pPicData, picDataLength);  
  112.   
  113.     // 返回成功   
  114.     return true;  
  115. }  
  116.   
  117. // 释放图片数据   
  118. void CMYPICINFO::ReleaseData()  
  119. {  
  120.     DeletePicBuf();  
  121. }  
  122.   
  123. // 保存数据到文件   
  124. bool CMYPICINFO::SavePicToFile(const char *filePathName)  
  125. {  
  126.     // 判断是否有数据   
  127.     if (m_pPicBuf == NULL)  
  128.     {  
  129.         return false;  
  130.     }  
  131.   
  132.     // 打开文件   
  133.     FILE *pFile = fopen(filePathName, "wb");  
  134.     if (pFile == NULL)  
  135.     {  
  136.         return false;  
  137.     }  
  138.   
  139.     // 写入文件   
  140.     fwrite(m_pPicBuf, m_lBufSize, 1, pFile);  
  141.     fclose(pFile);  
  142.     return true;  
  143. }  
  144.   
  145. // 保存数据到文件   
  146. bool CMYPICINFO::SavePicToFile(const wchar_t *filePathName)  
  147. {  
  148.     // 判断是否有数据   
  149.     if (m_pPicBuf == NULL)  
  150.     {  
  151.         return false;  
  152.     }  
  153.   
  154.     // 打开文件   
  155.     FILE *pFile = _wfopen(filePathName, L"wb");  
  156.     if (pFile == NULL)  
  157.     {  
  158.         return false;  
  159.     }  
  160.   
  161.     // 写入文件   
  162.     fwrite(m_pPicBuf, m_lBufSize, 1, pFile);  
  163.     fclose(pFile);  
  164.     return true;  
  165. }  
  166.   
  167. //////////////////////////////////////////////////////////////////////////   
  168. // 私有函数   
  169. // 申请空间   
  170. bool CMYPICINFO::NewPicBuf(unsigned long bufSize)  
  171. {  
  172.     // 释放上次   
  173.     DeletePicBuf();  
  174.   
  175.     // 参数是否有效   
  176.     if (bufSize == 0)  
  177.     {  
  178.         return false;  
  179.     }  
  180.   
  181.     // 申请新的空间      
  182.     m_pPicBuf = new unsigned char[bufSize];  
  183.     if (m_pPicBuf == NULL)  
  184.     {  
  185.         return false;  
  186.     }  
  187.   
  188.     // 得到缓冲区大小   
  189.     m_lBufSize = bufSize;  
  190.   
  191.     // 初始化内存空间   
  192.     memset(m_pPicBuf, 0, m_lBufSize);  
  193.   
  194.     // 返回成功   
  195.     return true;  
  196. }  
  197.   
  198. // 释放空间   
  199. void CMYPICINFO::DeletePicBuf()  
  200. {  
  201.     if (m_pPicBuf != NULL)  
  202.     {  
  203.         delete[] m_pPicBuf;  
  204.         m_pPicBuf = NULL;  
  205.         m_lBufSize = 0;  
  206.     }  
  207. }  

 

关闭 返回顶部
联系我们
Copyright © 2011. 聚财吧. All rights reserved.