Merge "support album art." into tizen
[platform/core/multimedia/libmm-fileinfo.git] / utils / mm_file_util_tag.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "mm_debug.h"
26 #include "mm_file_utils.h"
27
28 //#define ENABLE_ITUNES_META            //All itunes metadata extracted by ffmpeg. see mov_read_udta_string()
29
30 typedef struct _mmfilemp4basicboxheader {
31         unsigned int size;
32         unsigned int type;
33         long long start_offset; /*huge file*/
34 } MMFILE_MP4_BASIC_BOX_HEADER;
35
36 typedef struct _mmfilemp4ftpybox {
37         unsigned int major_brand;
38         unsigned short major_version;
39         unsigned short minor_version;
40         unsigned int *compatiable_brands;
41 } MMFILE_MP4_FTYPBOX;
42
43 typedef enum {
44         eMMFILE_3GP_TAG_TITLE = 0x01,
45         eMMFILE_3GP_TAG_CAPTION = 0x02,
46         eMMFILE_3GP_TAG_COPYRIGHT = 0x03,
47         eMMFILE_3GP_TAG_PERFORMER = 0x04,
48         eMMFILE_3GP_TAG_AUTHOR = 0x05,
49         eMMFILE_3GP_TAG_GENRE = 0x06,
50 } eMMFILE_3GP_TEXT_TAG;
51
52 typedef struct _mmfile3gptagtextbox {
53         unsigned char version;
54         unsigned char flag[3];
55         unsigned char language[2];
56         unsigned char *text;
57 } MMFILE_3GP_TEXT_TAGBOX;
58
59 typedef struct _mmfile3gptagyearbox {
60         unsigned char version;
61         unsigned char flag[3];
62         unsigned short year;
63 } MMFILE_3GP_YEAR_TAGBOX;
64
65 typedef struct _mmfile3gptagalbumbox {
66         unsigned char version;
67         unsigned char flag[3];
68         unsigned char language[2];
69         unsigned char *albumtile;
70         unsigned char trackNumber;
71 } MMFILE_3GP_ALBUM_TAGBOX;
72
73 typedef struct _mmfile3gpratingbox {
74         unsigned char version;
75         unsigned char flag[3];
76         unsigned int  ratingEntity;
77         unsigned int  ratingCriteria;
78         unsigned char language[2];
79         unsigned char *ratingInfo;
80 } MMFILE_3GP_RATING_TAGBOX;
81
82 typedef struct _mmfile3gpclsfbox {
83         unsigned char version;
84         unsigned char flag[3];
85         unsigned int  classificationEntity;
86         unsigned int  classificationTable;
87         unsigned char language[2];
88         unsigned char *classificationInfo;
89 } MMFILE_3GP_CLASSIFICATION_TAGBOX;
90
91 typedef struct _mmfile3gphdlrbox {
92         unsigned int  version;
93         unsigned int  pre_defined;
94         unsigned int  handler_type;
95         unsigned int  reserved[3];
96         unsigned char *boxname;
97 } MMFILE_3GP_HANDLER_BOX;
98
99 typedef struct _mmfileidv2box {
100         unsigned char version;
101         unsigned char flag[3];
102         unsigned char language[2];
103         unsigned char *id3v2Data;
104 } MMFILE_3GP_ID3V2_BOX;
105
106 typedef struct _mmfilelocibox {
107         unsigned char version;
108         unsigned char flag[3];
109         unsigned char language[2];
110         unsigned char *name;
111         unsigned char role;
112         float         longitude;
113         float         latitude;
114         float         altitude;
115         unsigned char *astronomical_body;
116         unsigned char *additional_notes;
117 } MMFILE_3GP_LOCATION_TAGBOX;
118
119 #define MMFILE_MP4_BASIC_BOX_HEADER_LEN 8
120 #define MMFILE_MP4_MOVIE_HEADER_BOX_LEN 96
121 #define MMFILE_MP4_HDLR_BOX_LEN         24
122 #define MMFILE_MP4_STSZ_BOX_LEN         20
123 #define MMFILE_MP4_MP4VBOX_LEN          80
124 #define MMFILE_MP4_MP4ABOX_LEN          28
125 #define MMFILE_3GP_TEXT_TAGBOX_LEN      6
126 #define MMFILE_3GP_YEAR_TAGBOX_LEN      6
127 #define MMFILE_3GP_ALBUM_TAGBOX_LEN     6
128 #define MMFILE_3GP_RATING_TAGBOX_LEN    14
129 #define MMFILE_3GP_CLASS_TAGBOX_LEN     14
130 #define MMFILE_3GP_HANDLER_BOX_LEN      24
131 #define MMFILE_3GP_ID3V2_BOX_LEN        6
132 #define MMFILE_SYNC_LYRIC_INFO_MIN_LEN        5
133
134
135 #define FOURCC(a,b,c,d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24))
136
137 #define MIN(a,b) (((a)<(b))?(a):(b))
138
139 #define GENRE_COUNT     149
140
141 static char* MpegAudio_Genre[GENRE_COUNT] = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal",
142 "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial",
143 "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk",
144 "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise",
145 "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic",
146 "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta",
147 "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes",
148 "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock",
149 "Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass",
150 "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic",
151 "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove",
152 "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle",
153 "Duet", "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore",
154 "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian", "Heavy Metal", "Black Metal", "Crossover",
155 "Contemporary", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop", "Unknown" };
156
157
158 static int GetStringFromTextTagBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header, eMMFILE_3GP_TEXT_TAG eTag)
159 {
160         int ret = MMFILE_UTIL_FAIL;    /*fail*/
161         MMFILE_3GP_TEXT_TAGBOX texttag = {0,};
162         int readed = 0;
163         int textBytes = 0;
164         char *temp_text = NULL;
165
166         if (!formatContext || !fp || !basic_header) {
167                 debug_error ("invalid param\n");
168                 return MMFILE_UTIL_FAIL;
169         }
170
171         textBytes = basic_header->size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_TEXT_TAGBOX_LEN;
172
173         readed = mmfile_read (fp, (unsigned char *)&texttag, MMFILE_3GP_TEXT_TAGBOX_LEN);
174         if (readed != MMFILE_3GP_TEXT_TAGBOX_LEN) {
175                 debug_error ("read text tag header fail\n");
176                 ret = MMFILE_UTIL_FAIL;
177                 goto exception;
178         }
179
180         if (textBytes <= 1) /* there exist only 00 (null) */
181         {
182                 debug_error ("Text is NULL\n");
183                 goto exception;
184         }
185
186         texttag.text = mmfile_malloc (textBytes);
187         if (!texttag.text) {
188                 debug_error ("malloc fail for text box\n");
189                 ret = MMFILE_UTIL_FAIL;
190                 goto exception;
191         }
192
193         readed = mmfile_read (fp, (unsigned char *)texttag.text, textBytes);
194         if (readed != textBytes) {
195                 debug_error ("read text fail\n");
196                 ret = MMFILE_UTIL_FAIL;
197                 goto exception;
198         }
199
200         /* check BOM char */
201         if ( (texttag.text[0] == 0xFE) && (texttag.text[1] == 0xFF)) {
202                 /* this char is UTF-16 */
203                 unsigned int bytes_written = 0;
204                 temp_text = mmfile_string_convert ((const char *)&texttag.text[2], readed-2, "UTF-8", "UTF-16",NULL, (unsigned int*)&bytes_written);
205         } else {
206                 temp_text = mmfile_strdup ((const char *)texttag.text);
207         }
208
209         switch (eTag) {
210                 case eMMFILE_3GP_TAG_TITLE: {
211                         if (!formatContext->title) {
212                                 formatContext->title = temp_text;
213                         }
214                         break;
215                 }
216                 case eMMFILE_3GP_TAG_CAPTION: {
217                         if (!formatContext->description) {
218                                 formatContext->description = temp_text;
219                         }
220                         break;
221                 }
222                 case eMMFILE_3GP_TAG_COPYRIGHT: {
223                         if (!formatContext->copyright) {
224                                 formatContext->copyright = temp_text;
225                         }
226                         break;
227                 }
228                 case eMMFILE_3GP_TAG_PERFORMER: {
229                         if (!formatContext->artist) {
230                                 formatContext->artist = temp_text;
231                         }
232                         break;
233                 }
234                 case eMMFILE_3GP_TAG_AUTHOR: {
235                         if (!formatContext->author) {
236                                 formatContext->author = temp_text;
237                         }
238                         break;
239                 }
240                 case eMMFILE_3GP_TAG_GENRE: {
241                         if (!formatContext->genre) {
242                                 formatContext->genre = temp_text;
243                         }
244                         break;
245                 }
246                 default: {
247                         debug_warning("Not supported Text Tag type[%d]\n", eTag);
248                         break;
249                 }
250         }
251
252         mmfile_free (texttag.text);
253         texttag.text = NULL;
254         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
255
256         return MMFILE_UTIL_SUCCESS;
257
258 exception:
259         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
260         if (texttag.text) {
261                 mmfile_free(texttag.text);
262         }
263         return ret;
264 }
265
266 static int GetYearFromYearTagBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
267 {
268 #define MAX_YEAR_BUFFER 10
269         int readed = 0;
270         MMFILE_3GP_YEAR_TAGBOX yearbox = {0,};
271         char temp_year[MAX_YEAR_BUFFER] = {0,};
272
273         if (!formatContext || !fp || !basic_header) {
274                 debug_error ("invalid param\n");
275                 return MMFILE_UTIL_FAIL;
276         }
277
278         readed = mmfile_read (fp, (unsigned char *)&yearbox, MMFILE_3GP_YEAR_TAGBOX_LEN);
279         if (readed != MMFILE_3GP_YEAR_TAGBOX_LEN) {
280                 debug_error ("read yeartag header fail\n");
281                 goto exception;
282         }
283
284         if (!formatContext->year) {
285                 yearbox.year = mmfile_io_be_int16 (yearbox.year);
286                 snprintf (temp_year, MAX_YEAR_BUFFER, "%d", yearbox.year);
287                 temp_year[MAX_YEAR_BUFFER-1] = '\0';
288                 formatContext->year = mmfile_strdup ((const char*)temp_year);
289         }
290
291         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
292         return MMFILE_UTIL_SUCCESS;
293
294 exception:
295         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
296
297         return MMFILE_UTIL_FAIL;
298 }
299
300 static int GetAlbumFromAlbumTagBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
301 {
302         int albumTitleLen = 0;
303         char *temp_text = NULL;
304         int readed = 0;
305         int trackFlags = 0;
306         MMFILE_3GP_ALBUM_TAGBOX albumbox = {0,};
307
308         if (!formatContext || !fp || !basic_header) {
309                 debug_error ("invalid param\n");
310                 return MMFILE_UTIL_FAIL;
311         }
312
313         readed = mmfile_read (fp, (unsigned char *)&albumbox, MMFILE_3GP_ALBUM_TAGBOX_LEN);
314         if (readed != MMFILE_3GP_ALBUM_TAGBOX_LEN) {
315                 debug_error ("read albumtag header fail\n");
316                 goto exception;
317         }
318
319         albumTitleLen = basic_header->size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_ALBUM_TAGBOX_LEN - 1; /* 1: track number */
320         if (albumTitleLen > 1) /* there exist only 00 (null) */
321         {
322                 #ifdef __MMFILE_TEST_MODE__
323                 debug_msg ("albumTitleLen=%d\n", albumTitleLen);
324                 #endif
325
326                 albumbox.albumtile = mmfile_malloc (albumTitleLen + 1); /* 1: for null char */
327                 if (!albumbox.albumtile) {
328                         debug_error ("malloc fail for album title text\n");
329                         goto exception;
330                 }
331
332                 readed = mmfile_read (fp, (unsigned char *)albumbox.albumtile, albumTitleLen);
333                 if (readed != albumTitleLen) {
334                         debug_error ("read album title fail\n");
335                         goto exception;
336                 }
337
338                 if (albumbox.albumtile[albumTitleLen-1] == '\0') /* there exist track number */
339                 {
340                         trackFlags = 1;
341                 }
342                 else
343                 {
344                         trackFlags = 0;
345                         readed = mmfile_read (fp, (unsigned char *)&(albumbox.albumtile[albumTitleLen]), 1);
346                         if (readed != 1) {
347                                 debug_error ("read album title fail\n");
348                                 goto exception;
349                         }            
350                         albumbox.albumtile[albumTitleLen] = '\0';
351                 }
352
353                 /* check BOM char */
354                 if ( (albumbox.albumtile[0] == 0xFE) && (albumbox.albumtile[1] == 0xFF)) {
355                         /* this char is UTF-16 */
356                         unsigned int bytes_written = 0;
357                         temp_text = mmfile_string_convert ((const char*)&albumbox.albumtile[2], readed-2, "UTF-8", "UTF-16", NULL, (unsigned int*)&bytes_written);
358                 } else {
359                         temp_text = mmfile_strdup ((const char*)albumbox.albumtile);
360                 }
361
362                 if (!formatContext->album) {
363                         formatContext->album = temp_text;
364                 }
365
366                 #ifdef __MMFILE_TEST_MODE__
367                 debug_msg ("formatContext->album=%s, strlen=%d\n", formatContext->album, strlen(formatContext->album));
368                 #endif
369         }
370
371         if (trackFlags) {
372                 readed = mmfile_read (fp, (unsigned char *)&albumbox.trackNumber, 1);
373                 if (readed != 1) {
374                         debug_error ("read track number fail\n");
375                         goto exception;
376                 }
377
378                 if (formatContext->tagTrackNum == 0) {
379                         char tracknum[10] = {0,};
380                         snprintf (tracknum, 10, "%d", albumbox.trackNumber);
381                         tracknum[9] = '\0';
382                         formatContext->tagTrackNum = mmfile_strdup ((const char*)tracknum);
383                 }
384         }
385
386         mmfile_free (albumbox.albumtile);
387         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
388
389         return MMFILE_UTIL_SUCCESS;
390
391 exception:
392         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
393         mmfile_free (albumbox.albumtile);
394
395         return MMFILE_UTIL_FAIL;
396 }
397
398 static int GetRatingFromRatingTagBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
399 {
400         int readed = 0;
401         int  ratinginfoLen = 0;
402         char *temp_text = NULL;
403
404         MMFILE_3GP_RATING_TAGBOX ratingTag = {0,};
405
406         if (!formatContext || !fp || !basic_header) {
407                 debug_error ("invalid param\n");
408                 return MMFILE_UTIL_FAIL;
409         }
410
411         readed = mmfile_read (fp, (unsigned char *)&ratingTag, MMFILE_3GP_RATING_TAGBOX_LEN);
412         if (readed != MMFILE_3GP_RATING_TAGBOX_LEN) {
413                 debug_error ("read rating tag header fail\n");
414                 goto exception;
415         }
416
417         ratinginfoLen = basic_header->size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_RATING_TAGBOX_LEN;
418
419         if (ratinginfoLen == 1) {
420                 debug_error ("Rating Text is NULL\n");
421                 goto exception;
422         }
423
424         ratingTag.ratingInfo = mmfile_malloc (ratinginfoLen);
425         if (!ratingTag.ratingInfo) {
426                 debug_error ("rating info error\n");
427                 goto exception;
428         }
429
430         readed = mmfile_read (fp, (unsigned char *)ratingTag.ratingInfo, ratinginfoLen);
431         if (readed != ratinginfoLen) {
432                 debug_error ("read rating info string fail\n");
433                 goto exception;
434         }
435
436         /* check BOM char */
437         if ( (ratingTag.ratingInfo[0] == 0xFE) && (ratingTag.ratingInfo[1] == 0xFF)) {
438                 /* this char is UTF-16 */
439                 unsigned int bytes_written = 0;
440                 temp_text = mmfile_string_convert ((const char*)&ratingTag.ratingInfo[2], readed-2, "UTF-8", "UTF-16", NULL, (unsigned int*)&bytes_written);
441         } else {
442                 temp_text = mmfile_strdup ((const char*)ratingTag.ratingInfo);
443         }
444
445         if (!formatContext->rating) {
446                 formatContext->rating = temp_text;
447         } else {
448                 mmfile_free (temp_text);
449         }
450
451         mmfile_free (ratingTag.ratingInfo);
452         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
453
454         return MMFILE_UTIL_SUCCESS;
455
456 exception:
457         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
458         mmfile_free (ratingTag.ratingInfo);
459
460         return MMFILE_UTIL_FAIL;
461 }
462
463
464 static int GetClassficationFromClsfTagBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
465 {
466         int classinfoLen = 0;
467         int readed = 0;
468         char *temp_text = NULL;
469         MMFILE_3GP_CLASSIFICATION_TAGBOX classTag = {0,};
470
471         if (!formatContext || !fp || !basic_header) {
472                 debug_error ("invalid param\n");
473                 return MMFILE_UTIL_FAIL;
474         }
475
476         readed = mmfile_read (fp, (unsigned char *)&classTag, MMFILE_3GP_CLASS_TAGBOX_LEN);
477         if (readed != MMFILE_3GP_CLASS_TAGBOX_LEN) {
478                 debug_error ("read classification tag header fail\n");
479                 goto exception;
480         }
481
482
483         classinfoLen = basic_header->size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_CLASS_TAGBOX_LEN;
484         if (classinfoLen == 1) {
485                 debug_error ("Classification Text is NULL\n");
486                 goto exception;
487         }
488
489         classTag.classificationInfo = mmfile_malloc (classinfoLen);
490         if (!classTag.classificationInfo) {
491                 debug_error ("class info error\n");
492                 goto exception;
493         }
494
495         readed = mmfile_read (fp, (unsigned char *)classTag.classificationInfo, classinfoLen);
496         if (readed != classinfoLen) {
497                 debug_error ("read class info string fail\n");
498                 goto exception;
499         }
500
501         /* check BOM char */
502         if ( (classTag.classificationInfo[0] == 0xFE) && (classTag.classificationInfo[1] == 0xFF)) {
503                 /* this char is UTF-16 */
504                 unsigned int bytes_written = 0;
505                 temp_text = mmfile_string_convert ((const char*)&classTag.classificationInfo[2], readed-2, "UTF-8", "UTF-16", NULL, (unsigned int*)&bytes_written);
506         } else {
507                 temp_text = mmfile_strdup ((const char*)classTag.classificationInfo);
508         }
509
510         if (!formatContext->classification) {
511                 formatContext->classification = temp_text;
512         } else {
513                 mmfile_free (temp_text);
514         }
515
516         mmfile_free (classTag.classificationInfo);
517         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
518
519         return MMFILE_UTIL_SUCCESS;
520
521 exception:
522         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
523         mmfile_free (classTag.classificationInfo);
524
525         return MMFILE_UTIL_FAIL;
526 }
527
528 /**
529  * The Location Information box
530  * --------------------+-------------------+-----------------------------------+------
531  * Field                                Type                            Details                                                         Value
532  * --------------------+-------------------+-----------------------------------+------
533  * BoxHeader.Size               Unsigned int(32)
534  * BoxHeader.Type               Unsigned int(32)                                                                                'loci'
535  * BoxHeader.Version    Unsigned int(8)                                                                                 0
536  * BoxHeader.Flags              Bit(24)                                                                                                 0
537  * Pad                                  Bit(1)                                                                                                  0
538  * Language                             Unsigned int(5)[3]      Packed ISO-639-2/T language code
539  * Name                                 String                          Text of place name
540  * Role                                 Unsigned int(8)         Non-negative value indicating role
541  *                                                                                       of location
542  * Longitude                    Unsigned int(32)        Fixed-point value of the longitude
543  * Latitude                             Unsigned int(32)        Fixed-point value of the latitude
544  * Altitude                             Unsigned int(32)        Fixed-point value of the Altitude
545  * Astronomical_body    String                          Text of astronomical body
546  * Additional_notes             String                          Text of additional location-related
547  *                                                                                       information
548  * --------------------+-------------------+-----------------------------------+------
549  */
550 static int _get_char_position (unsigned char *src, char ch, int max)
551 {
552         int i;
553         for (i = 0; i < max; i++) {
554                 if ( *(src + i) == ch)
555                         return i;
556         }
557
558         return -1;
559
560  
561 static int GetLocationFromLociTagBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
562 {
563
564         MMFILE_3GP_LOCATION_TAGBOX lociTag = {0,};
565         int readed = 0;
566         int bufferLen = 0;
567         unsigned char *buffer = NULL;
568         unsigned char *p = NULL;
569         int pos = 0;
570         unsigned int bytes_written = 0;
571         unsigned int name_sz = 0;
572         unsigned int astro_sz = 0;
573
574         int ilong, ilati, ialti;
575         float flong, flati, falti;
576
577
578         if (!formatContext || !fp || !basic_header) {
579                 debug_error ("invalid param\n");
580                 return MMFILE_UTIL_FAIL;
581         }
582
583         readed = mmfile_read (fp, (unsigned char *)&lociTag, 6); /*6 = version + flag + pad + language */
584         if (readed != 6) {
585                 debug_error ("read location tag header fail\n");
586                 goto exception;
587         }
588
589         /*buffer len = name + role + ... + additional notes length */
590         bufferLen = basic_header->size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - 6;
591         if (bufferLen < 1) {
592                 debug_error ("too small buffer\n");
593                 goto exception;
594         }
595
596         buffer = mmfile_malloc (bufferLen);
597         if (!buffer) {
598                 debug_error ("buffer malloc error\n");
599                 goto exception;
600         }
601
602         readed = mmfile_read (fp, (unsigned char *)buffer, bufferLen);
603         if (readed != bufferLen) {
604                 debug_error ("read location tag fail\n");
605                 goto exception;
606         }
607         p = buffer;
608
609         /*name*/
610         pos = _get_char_position (p, '\0', readed - (1+4+4+4+2));
611         if (pos >= 0) {
612                 if (p[0] == 0xFE && p[1] == 0xFF) {
613                         lociTag.name = (unsigned char*)mmfile_string_convert ((const char*)(p + 2), pos - 2, "UTF-8", "UTF-16", NULL, (unsigned int*)&bytes_written);
614                 } else {
615                         lociTag.name = (unsigned char*)mmfile_strdup ((const char*)p);
616                 }
617         } else {
618                 goto exception;
619         }
620         name_sz = pos + 1;
621         p += (pos + 1);
622
623         /*role*/
624         lociTag.role = *p;
625         p++;
626
627         #ifdef __MMFILE_TEST_MODE__
628         debug_msg ("long: 0x%02X 0x%02X 0x%02X 0x%02X \n", *(p+0), *(p+1), *(p+2), *(p+3));
629         debug_msg ("lati: 0x%02X 0x%02X 0x%02X 0x%02X \n", *(p+4), *(p+5), *(p+6), *(p+7));
630         debug_msg ("alti: 0x%02X 0x%02X 0x%02X 0x%02X \n", *(p+8), *(p+9), *(p+10), *(p+11));
631         #endif
632
633         ilong = mmfile_io_be_uint32 (*(unsigned int*)p);
634         ilati = mmfile_io_be_uint32 (*(unsigned int*)(p+4));
635         ialti = mmfile_io_be_uint32 (*(unsigned int*)(p+8));
636
637         flong = (float)ilong / (1<<16);
638         flati = (float)ilati / (1<<16);
639         falti = (float)ialti / (1<<16);
640
641         /*longitude*/
642         lociTag.longitude = flong;
643         /*latitude*/
644         lociTag.latitude = flati;
645         /*altitude*/
646         lociTag.altitude = falti;
647         
648         p += 12;
649
650         /*astronomical body*/
651         pos = _get_char_position (p, '\0', readed - (name_sz+1+4+4+4+1));
652         if (pos >= 0) {
653                 if (p[0] == 0xFE && p[1] == 0xFF) {
654                         lociTag.astronomical_body = (unsigned char*)mmfile_string_convert ((const char*)(p + 2), pos - 2, "UTF-8", "UTF-16", NULL, (unsigned int*)&bytes_written);
655                 } else {
656                         lociTag.astronomical_body = (unsigned char*)mmfile_strdup ((const char*)p);
657                 }
658         } else {
659                 goto exception;
660         }
661         astro_sz = pos + 1;
662         p += (pos + 1);
663
664         /*additional notes*/
665         pos = _get_char_position (p, '\0', readed - (name_sz+1+4+4+4+astro_sz));
666         if (pos >= 0) {
667                 if (p[0] == 0xFE && p[1] == 0xFF) {
668                         lociTag.additional_notes = (unsigned char*)mmfile_string_convert ((const char*)(p + 2), pos - 2, "UTF-8", "UTF-16", NULL, (unsigned int*)&bytes_written);
669                 } else {
670                         lociTag.additional_notes = (unsigned char*)mmfile_strdup ((const char*)p);
671                 }
672         } else {
673                 goto exception;
674         }
675
676         #ifdef __MMFILE_TEST_MODE__
677         debug_msg ("** Location Information **\n");
678         debug_msg ("Name             : %s\n", lociTag.name);
679         debug_msg ("Role             : %d (0: shooting, 1: real, 2: fictional, other: reserved)\n", lociTag.role);
680         debug_msg ("Longitude        : %16.16f\n", lociTag.longitude);
681         debug_msg ("Latitude         : %16.16f\n", lociTag.latitude);
682         debug_msg ("Altitude         : %16.16f\n", lociTag.altitude);
683         debug_msg ("Astronomical body: %s\n", lociTag.astronomical_body);
684         debug_msg ("Additional notes : %s\n", lociTag.additional_notes);
685         #endif
686
687         formatContext->longitude = lociTag.longitude;
688         formatContext->latitude = lociTag.latitude;
689         formatContext->altitude = lociTag.altitude;
690
691         mmfile_free (buffer);
692         mmfile_free (lociTag.name);
693         mmfile_free (lociTag.astronomical_body);
694         mmfile_free (lociTag.additional_notes);
695
696         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
697         return MMFILE_UTIL_SUCCESS;
698         
699 exception:
700         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
701         mmfile_free (buffer);
702         mmfile_free (lociTag.name);
703         mmfile_free (lociTag.astronomical_body);
704         mmfile_free (lociTag.additional_notes);
705
706         return MMFILE_UTIL_FAIL;
707 }
708
709 static int GetTagFromMetaBox (MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header)
710 {
711         int readed = 0;
712         MMFILE_MP4_BASIC_BOX_HEADER hdlrBoxHeader = {0,};
713         MMFILE_MP4_BASIC_BOX_HEADER id3v2BoxHeader = {0,};
714         MMFILE_3GP_ID3V2_BOX id3v2Box = {0,};
715         AvFileContentInfo tagInfo = {0,};
716         unsigned char tagVersion = 0;
717         bool versionCheck = false;
718         int id3v2Len = 0;
719         unsigned int meta_version = 0;
720         MMFILE_3GP_HANDLER_BOX hdlrBox = {0,};
721         int encSize = 0;
722         int id3_meta = 0;
723 #ifdef ENABLE_ITUNES_META /* We don't support itunes meta now. so this is not defined yet */
724         int iTunes_meta = 0;
725 #endif
726
727         /* meta box */
728         readed = mmfile_read (fp, (unsigned char *)&meta_version, 4);
729         if (readed != 4) {
730                 debug_error ("read meta box version\n");
731                 goto exception;
732         }
733
734         /* hdlr box */
735         readed = mmfile_read (fp, (unsigned char *)&hdlrBoxHeader, MMFILE_MP4_BASIC_BOX_HEADER_LEN);
736         if (readed != MMFILE_MP4_BASIC_BOX_HEADER_LEN) {
737                 debug_error ("read hdlr box header\n");
738                 goto exception;
739         }
740
741         if (hdlrBoxHeader.type != FOURCC ('h', 'd', 'l', 'r')) {
742                 debug_warning ("meta type is not hdlr\n");
743                 goto exception;
744         }
745
746         hdlrBoxHeader.size = mmfile_io_be_uint32 (hdlrBoxHeader.size);
747         hdlrBoxHeader.type = mmfile_io_le_uint32 (hdlrBoxHeader.type);
748
749         readed = mmfile_read (fp, (unsigned char *)&hdlrBox, MMFILE_3GP_HANDLER_BOX_LEN);
750         if (readed != MMFILE_3GP_HANDLER_BOX_LEN) {
751                 debug_error ("read hdlr box\n");
752                 goto exception;
753         }
754
755         hdlrBox.handler_type = mmfile_io_le_uint32 (hdlrBox.handler_type);
756
757         /**
758          * check tag type (ID3v2 or iTunes)
759          */
760         if (hdlrBox.handler_type == FOURCC ('I', 'D', '3', '2')) {
761                 #ifdef __MMFILE_TEST_MODE__
762                 debug_msg ("ID3v2 tag detected.\n");
763                 #endif
764
765                 id3_meta = 1;
766 #ifdef ENABLE_ITUNES_META
767                 iTunes_meta = 0;
768 #endif
769         } else if (hdlrBox.handler_type == FOURCC ('m', 'd', 'i', 'r') &&
770                                 mmfile_io_le_uint32 (hdlrBox.reserved[0]) == FOURCC ('a', 'p', 'p', 'l')) {
771
772                 #ifdef __MMFILE_TEST_MODE__
773                 debug_msg ("Apple iTunes tag detected by mdir.\n");
774                 #endif
775
776 #ifdef ENABLE_ITUNES_META
777                 iTunes_meta = 1;
778 #endif
779         } else {
780                 debug_warning ("unknown meta type. 4CC:[%c%c%c%c]\n", ((char*)&hdlrBox.handler_type)[0],
781                                                                                                                                 ((char*)&hdlrBox.handler_type)[1],
782                                                                                                                                 ((char*)&hdlrBox.handler_type)[2],
783                                                                                                                                 ((char*)&hdlrBox.handler_type)[3]);
784                 //goto exception;
785         }
786
787 #ifdef ENABLE_ITUNES_META
788         if(!id3_meta && !iTunes_meta) {
789                 /*Check ilst.
790                 APPLE meta data for iTunes reader = 'mdir.' so if handler type is 'mdir', this content may has itunes meta.
791                 most of contents has 'mdir' + 'appl'. but some contents just has 'mdir'
792                 but 'ilst' is meta for iTunes. so find 'ilst' is more correct to check if this contents has iTunes meta or not.*/
793
794                 char *ilst_box = "ilst";
795                 int buf_size = strlen(ilst_box);
796
797                 unsigned char read_buf[buf_size+1];
798                 memset(read_buf, 0x00, buf_size+1);
799
800                 /* skip hdlr box */
801                 mmfile_seek (fp, hdlrBoxHeader.size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_HANDLER_BOX_LEN +4, SEEK_CUR);       //+4 is hdlr size field
802
803                 readed = mmfile_read (fp, read_buf, buf_size);  // to find 'ilst'
804                 if (readed != buf_size) {
805                         debug_error ("read fail [%d]\n", readed);
806                         goto exception;
807                 }
808
809                 if(read_buf[0] == 'i' && read_buf[1] == 'l' && read_buf[2] == 's' && read_buf[3] == 't') {
810                         #ifdef __MMFILE_TEST_MODE__
811                                 debug_msg ("Apple iTunes tag detected by ilst.\n");
812                         #endif
813
814                         iTunes_meta = 1;
815                 }
816         }
817 #endif
818
819 #ifdef ENABLE_ITUNES_META
820         if (iTunes_meta) {
821                 /**
822                  * iTunes (Cover[?ovr] & Track[trkn] only extract!) + Genre/Artist : Added 2010.10.27,28
823                  *
824                  *  4cc   : 4byte
825                  *        : 4byte       size
826                  * 'data' : 4byte
827                  *        : 4byte       type
828                  *        : 4byte       unknown
829                  */
830 #define _ITUNES_READ_BUF_SZ             20
831 #define _ITUNES_TRACK_NUM_SZ    4
832 #define _ITUNES_GENRE_NUM_SZ    4
833 #define _ITUNES_COVER_TYPE_JPEG 13
834 #define _ITUNES_COVER_TYPE_PNG          14
835
836                 unsigned char read_buf[_ITUNES_READ_BUF_SZ];
837                 int i = 0;
838                 int cover_sz = 0, cover_type = 0, cover_found = 0;
839                 int track_num = 0, track_found = 0;
840                 int genre_index = 0, genre_found = 0;
841                 int artist_sz = 0, artist_found = 0;
842                 int limit = basic_header->size - hdlrBoxHeader.size;
843                 long long cover_offset = 0, track_offset =0 , genre_offset = 0, artist_offset = 0;
844
845                 for (i = 0, cover_found = 0, track_found = 0, genre_found = 0, artist_found = 0; i < limit && (cover_found == 0 || track_found == 0 || genre_found == 0 || artist_found == 0) ; i++) {
846                         readed = mmfile_read (fp, read_buf, _ITUNES_READ_BUF_SZ);
847                         if (readed != _ITUNES_READ_BUF_SZ)
848                                 goto exception;
849
850 /*ffmpeg extract artist, tracknum, excep cover image. see mov_read_udta_string()*/
851 #if 0
852                         /**
853                          * Artist : Added 2010.10.28
854                          */
855                         if (artist_found == 0 &&
856                                 read_buf[0] == 0xa9 && read_buf[1] == 'A' && read_buf[2] == 'R' && read_buf[3] == 'T' &&
857                                 read_buf[8] == 'd' && read_buf[9] == 'a' && read_buf[10] == 't' && read_buf[11] == 'a') {
858
859                                 artist_found = 1;
860                                 artist_offset = mmfile_tell (fp);
861                                 artist_sz = mmfile_io_be_uint32 (*(int*)(read_buf + 4)) - 16; /* atom len(4)+data(4)+atom verion(1)+flag(3)+null(4) = 16 */
862
863                                 #ifdef __MMFILE_TEST_MODE__
864                                 debug_msg ("[%s][%d]----------------------------------- artist found, offset=[%lld], size=[%d]\n", __func__, __LINE__, artist_offset, artist_sz);
865                                 #endif
866                         }
867
868                         /**
869                          * Track number
870                          */
871                         if (track_found == 0 &&
872                                 read_buf[0] == 't' && read_buf[1] == 'r' && read_buf[2] == 'k' && read_buf[3] == 'n' &&
873                                 read_buf[8] == 'd' && read_buf[9] == 'a' && read_buf[10] == 't' && read_buf[11] == 'a') {
874
875                                 track_found = 1;
876                                 track_offset = mmfile_tell (fp);
877
878                                 #ifdef __MMFILE_TEST_MODE__
879                                 debug_msg ("[%s][%d]----------------------------------- Track found, offset=[%lld]\n", __func__, __LINE__, track_offset);
880                                 #endif
881                         }
882 #endif
883                         /**
884                          * Genre : Added 2010.10.27
885                          */
886                         /*ffmpeg extract genre but only (0xa9,'g','e','n'). see mov_read_udta_string()*/
887                         if (genre_found == 0 &&
888                                 read_buf[0] == 'g' && read_buf[1] == 'n' && read_buf[2] == 'r' && read_buf[3] == 'e' &&
889                                 read_buf[8] == 'd' && read_buf[9] == 'a' && read_buf[10] == 't' && read_buf[11] == 'a') {
890
891                                 genre_found = 1;
892                                 genre_offset = mmfile_tell (fp);
893
894                                 #ifdef __MMFILE_TEST_MODE__
895                                 debug_msg ("[%s][%d]----------------------------------- genre found, offset=[%lld]\n", __func__, __LINE__, genre_offset);
896                                 #endif
897                         }
898
899                         /**
900                          * Cover image
901                          */
902
903                         if (cover_found == 0 &&
904                                 read_buf[0] == 'c' && read_buf[1] == 'o' && read_buf[2] == 'v' && read_buf[3] == 'r' &&
905                                 read_buf[8] == 'd' && read_buf[9] == 'a' && read_buf[10] == 't' && read_buf[11] == 'a') {
906
907                                 cover_found = 1;
908                                 cover_sz = mmfile_io_be_uint32 (*(int*)(read_buf + 4)) - 12;
909                                 cover_type = mmfile_io_be_uint32 (*(int*)(read_buf + 12));
910
911                                 cover_offset = mmfile_tell (fp);
912
913                                 #ifdef __MMFILE_TEST_MODE__
914                                 debug_msg ("[%s][%d]----------------------------------- cover_found found,  offset=[%lld]\n", __func__, __LINE__, cover_offset);
915                                 #endif
916                         }
917
918                         mmfile_seek (fp, -(_ITUNES_READ_BUF_SZ - 1), SEEK_CUR); /*FIXME: poor search*/
919                 } /*loop*/
920
921 /*ffmpeg extract artist, tracknum, excep cover image. see mov_read_udta_string()*/
922 #if 0
923                 if (artist_found) {
924                         if (artist_sz > 0) {
925                                 mmfile_seek (fp, artist_offset, SEEK_SET);
926
927                                 if (formatContext->artist) {
928                                         #ifdef __MMFILE_TEST_MODE__
929                                         debug_msg ("[%s][%d]----------------------------------- previous artist was [%s] \n", __func__, __LINE__, formatContext->artist);
930                                         #endif
931                                         free (formatContext->artist);
932                                 }
933                                 #ifdef __MMFILE_TEST_MODE__
934                                 debug_msg ("[%s][%d]----------------------------------- new artist will be allocated with size (len+1) [%d] \n", __func__, __LINE__, artist_sz+1);
935                                 #endif
936                                 formatContext->artist = mmfile_malloc (artist_sz+1);
937
938                                 if (formatContext->artist) {
939                                         readed = mmfile_read (fp, (unsigned char*)formatContext->artist, artist_sz);
940                                         formatContext->artist[artist_sz] = '\0';
941
942                                         #ifdef __MMFILE_TEST_MODE__
943                                         debug_msg ("[%s][%d]----------------------------------- new artist is [%s] \n", __func__, __LINE__, formatContext->artist);
944                                         #endif
945
946                                         if (readed != artist_sz) {
947                                                 debug_error ("failed to read. ret = %d, in = %d\n", readed, artist_sz);
948                                                 mmfile_free (formatContext->artist);
949                                         }
950                                 }
951                         }
952                 }
953
954                 if (track_found) {
955                         mmfile_seek (fp, track_offset, SEEK_SET);
956                         readed = mmfile_read (fp, read_buf, _ITUNES_TRACK_NUM_SZ);
957                         if (readed != _ITUNES_TRACK_NUM_SZ) {
958                                 debug_error ("failed to read. ret = %d, in = %d\n", readed, _ITUNES_TRACK_NUM_SZ);
959                         } else {
960                                 track_num = mmfile_io_be_uint32 (*(int*)read_buf);
961                                 if (!formatContext->tagTrackNum) {
962                                         memset (read_buf, 0x00, _ITUNES_READ_BUF_SZ);
963                                         sprintf ((char*)read_buf, "%d", track_num);
964                                         formatContext->tagTrackNum = mmfile_strdup ((const char*)read_buf);
965                                 }
966                         }
967                 }
968 #endif
969                 if (genre_found) {
970                         mmfile_seek (fp, genre_offset, SEEK_SET);
971                         readed = mmfile_read (fp, read_buf, _ITUNES_GENRE_NUM_SZ);
972                         if (readed != _ITUNES_GENRE_NUM_SZ) {
973                                 debug_error ("failed to read. ret = %d, in = %d\n", readed, _ITUNES_GENRE_NUM_SZ);
974                         } else {
975                                 genre_index = mmfile_io_be_uint16 (*(int*)read_buf);
976                                 #ifdef __MMFILE_TEST_MODE__
977                                 debug_msg ("[%s][%d] genre index=[%d] \n", __func__, __LINE__, genre_index);
978                                 #endif
979                                 if (genre_index > 0 && genre_index < GENRE_COUNT)       {
980                                         if (!formatContext->genre) {
981                                                 memset (read_buf, 0x00, _ITUNES_READ_BUF_SZ);
982                                                 snprintf ((char*)read_buf, sizeof(read_buf),"%s", MpegAudio_Genre[genre_index-1]);
983                                                 #ifdef __MMFILE_TEST_MODE__
984                                                 debug_msg ("[%s][%d] genre string=[%s] \n", __func__, __LINE__, read_buf);
985                                                 #endif
986                                                 formatContext->genre = mmfile_strdup ((const char*)read_buf);
987                                         }
988                                 }
989                         }
990                 }
991 /*
992         1) below spec is in "iTunes Package Asset Specification 4.3" published by apple.
993         Music Cover Art Image Profile
994         - TIFF with ".tif" extension (32-bit uncompressed), JPEG with ".jpg" extension (quality unconstrained), or PNG with ".png" extension
995         - RGB (screen standard)
996         - Minimum size of 600 x 600 pixels
997         - Images must be at least 72 dpi
998
999         2)I found below info from google.
1000         cover image flag : JPEG (13, 0xd), PNG (14, 0xe)
1001
1002         3)So, FIXME when cover image format is tif!
1003 */
1004                 if (cover_found) {
1005                         if (cover_sz > 0) {
1006                                 mmfile_seek (fp, cover_offset, SEEK_SET);
1007
1008                                 formatContext->artwork = mmfile_malloc (cover_sz);
1009                                 formatContext->artworkSize = cover_sz;
1010                                 if(cover_type == _ITUNES_COVER_TYPE_JPEG) {
1011                                         formatContext->artworkMime = mmfile_strdup("image/jpeg");
1012                                 } else if(cover_type == _ITUNES_COVER_TYPE_PNG) {
1013                                         formatContext->artworkMime = mmfile_strdup("image/png");
1014                                 /*} else if(cover_type == _ITUNES_COVER_TYPE_TIF) {
1015                                         formatContext->artworkMime = mmfile_strdup("image/tif");*/
1016                                 } else {
1017                                         debug_error("Not proper cover image type, but set to jpeg. cover_type[%d]", cover_type);
1018                                         formatContext->artworkMime = mmfile_strdup("image/jpeg");
1019                                 }
1020
1021                                 if (formatContext->artwork) {
1022                                         readed = mmfile_read (fp, formatContext->artwork, cover_sz);
1023                                         if (readed != cover_sz) {
1024                                                 debug_error ("failed to read. ret = %d, in = %d\n", readed, cover_sz);
1025                                                 mmfile_free (formatContext->artwork);
1026                                                 formatContext->artworkSize = 0;
1027                                                 mmfile_free (formatContext->artworkMime);
1028                                         }
1029                                 }
1030                         }
1031                 }
1032
1033                 /*reset seek position*/
1034                 mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
1035
1036                 return MMFILE_UTIL_SUCCESS;
1037
1038         } else
1039 #endif
1040         if(id3_meta) {
1041                 /**
1042                  * ID3v2
1043                  */
1044                 /* skip hdlr box name */
1045                 mmfile_seek (fp, hdlrBoxHeader.size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_HANDLER_BOX_LEN, SEEK_CUR);
1046
1047                 /* id3 tag box */
1048                 readed = mmfile_read (fp, (unsigned char *)&id3v2BoxHeader, MMFILE_MP4_BASIC_BOX_HEADER_LEN);
1049                 if (readed != MMFILE_MP4_BASIC_BOX_HEADER_LEN)
1050                 {
1051                         debug_error ("read id3v2 box header\n");
1052                         goto exception;
1053                 }
1054
1055                 id3v2BoxHeader.size = mmfile_io_be_uint32 (id3v2BoxHeader.size);
1056                 id3v2BoxHeader.type = mmfile_io_le_uint32 (id3v2BoxHeader.type);
1057
1058                 if (id3v2BoxHeader.type != FOURCC ('I', 'D', '3', '2'))
1059                 {
1060                         debug_warning ("meta type is not id3v2\n");
1061                         goto exception;
1062                 }
1063
1064                 readed = mmfile_read (fp, (unsigned char *)&id3v2Box, MMFILE_3GP_ID3V2_BOX_LEN);
1065                 if (readed != MMFILE_3GP_ID3V2_BOX_LEN)
1066                 {
1067                         debug_error ("read id3v2 box\n");
1068                         goto exception;
1069                 }
1070
1071                 id3v2Len = id3v2BoxHeader.size - MMFILE_MP4_BASIC_BOX_HEADER_LEN - MMFILE_3GP_ID3V2_BOX_LEN;
1072
1073                 id3v2Box.id3v2Data = mmfile_malloc (id3v2Len);
1074                 if (!id3v2Box.id3v2Data)
1075                 {
1076                         debug_error ("malloc id3tag data error\n");
1077                         goto exception;
1078                 }
1079
1080                 readed = mmfile_read (fp, (unsigned char *)id3v2Box.id3v2Data, id3v2Len);
1081                 if (readed != id3v2Len)
1082                 {
1083                         debug_error ("read id3tag data error\n");
1084                         goto exception;
1085                 }
1086
1087                 /* check id3v2 */
1088                 if (!IS_ID3V2_TAG(id3v2Box.id3v2Data))
1089                 {
1090                         debug_error ("it is not id3tag\n");
1091                         goto exception;
1092                 }
1093
1094                 if (id3v2Box.id3v2Data[3] == 0xFF ||  id3v2Box.id3v2Data[4] == 0xFF ||
1095                         id3v2Box.id3v2Data[6] >= 0x80 ||  id3v2Box.id3v2Data[7] >= 0x80 ||
1096                    id3v2Box.id3v2Data[8] >= 0x80 ||  id3v2Box.id3v2Data[9] >= 0x80)
1097                 {
1098                         debug_error ("it is not valid id3tag\n");
1099                         goto exception;
1100                 }
1101
1102                 tagVersion = id3v2Box.id3v2Data[3];
1103                 if ( tagVersion > 4)
1104                 {
1105                         debug_error ("tag vesion is too high\n");
1106                         goto exception;
1107                 }
1108
1109                 encSize = mmfile_io_le_uint32(&id3v2Box.id3v2Data[6]);
1110                 tagInfo.tagV2Info.tagLen = MP3_TAGv2_HEADER_LEN;
1111                 tagInfo.tagV2Info.tagLen += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
1112                 tagInfo.tagV2Info.tagVersion = tagVersion;
1113                 tagInfo.fileLen = id3v2Len;
1114
1115                 /* set id3v2 data to formatContext */
1116                 switch (tagVersion)
1117                 {
1118                         case 2:
1119                         {
1120                                 versionCheck = mm_file_id3tag_parse_v222(&tagInfo, id3v2Box.id3v2Data);
1121                                 break;
1122                         }
1123                         case 3:
1124                         {
1125                                 versionCheck = mm_file_id3tag_parse_v223(&tagInfo, id3v2Box.id3v2Data);
1126                                 break;
1127                         }
1128                         case 4:
1129                         {
1130                                 versionCheck = mm_file_id3tag_parse_v224(&tagInfo, id3v2Box.id3v2Data);
1131                                 break;
1132                         }
1133                         case 1:
1134                         default:
1135                         {
1136                                 debug_error ("tag vesion is not support\n");
1137                                 versionCheck = false;
1138                                 break;
1139                         }
1140                 }
1141
1142                 if (versionCheck == false)
1143                 {
1144                         debug_error ("tag parsing is fail\n");
1145                         goto exception;
1146                 }
1147
1148                 if (!formatContext->title)          formatContext->title = mmfile_strdup((const char*)tagInfo.pTitle);
1149                 if (!formatContext->artist)         formatContext->artist = mmfile_strdup((const char*)tagInfo.pArtist);
1150                 if (!formatContext->author)         formatContext->author = mmfile_strdup((const char*)tagInfo.pAuthor);
1151                 if (!formatContext->copyright)      formatContext->copyright = mmfile_strdup((const char*)tagInfo.pCopyright);
1152                 if (!formatContext->comment)        formatContext->comment = mmfile_strdup((const char*)tagInfo.pComment);
1153                 if (!formatContext->album)          formatContext->album = mmfile_strdup((const char*)tagInfo.pAlbum);
1154                 if (!formatContext->album_artist)   formatContext->album_artist = mmfile_strdup((const char*)tagInfo.pAlbum_Artist);
1155                 if (!formatContext->year)           formatContext->year = mmfile_strdup((const char*)tagInfo.pYear);
1156                 if (!formatContext->genre)          formatContext->genre = mmfile_strdup((const char*)tagInfo.pGenre);
1157                 if (!formatContext->tagTrackNum)    formatContext->tagTrackNum = mmfile_strdup((const char*)tagInfo.pTrackNum);
1158                 if (!formatContext->composer)       formatContext->composer = mmfile_strdup((const char*)tagInfo.pComposer);
1159                 if (!formatContext->classification) formatContext->classification = mmfile_strdup((const char*)tagInfo.pContentGroup);
1160                 if (!formatContext->conductor)      formatContext->conductor = mmfile_strdup((const char*)tagInfo.pConductor);
1161
1162                 formatContext->artwork = mmfile_malloc (tagInfo.imageInfo.imageLen);
1163                 if ((tagInfo.imageInfo.imageLen > 0) && formatContext->artwork)
1164                 {
1165                         formatContext->artworkSize = tagInfo.imageInfo.imageLen;
1166                         memcpy (formatContext->artwork, tagInfo.imageInfo.pImageBuf, tagInfo.imageInfo.imageLen);
1167                 }
1168
1169                 mm_file_free_AvFileContentInfo (&tagInfo);
1170                 mmfile_free (id3v2Box.id3v2Data);
1171
1172                 /*reset seek position*/
1173                 mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
1174
1175                 return MMFILE_UTIL_SUCCESS;
1176
1177         }
1178
1179
1180 exception:
1181         mmfile_seek (fp, basic_header->start_offset + basic_header->size, SEEK_SET);
1182         mmfile_free (id3v2Box.id3v2Data);
1183
1184         return MMFILE_UTIL_FAIL;
1185 }
1186
1187
1188 EXPORT_API int MMFileUtilGetMetaDataFromMP4 (MMFileFormatContext * formatContext)
1189 {
1190         MMFileIOHandle *fp = NULL;
1191         int ret = 0;
1192         int readed;
1193
1194         ret = mmfile_open (&fp, formatContext->uriFileName, MMFILE_RDONLY);
1195         if(ret == MMFILE_UTIL_FAIL) {
1196                 debug_error ("error: mmfile_open\n");
1197                 goto exit;
1198         }
1199
1200         MMFILE_MP4_BASIC_BOX_HEADER basic_header = {0,};
1201         basic_header.start_offset = mmfile_tell (fp);
1202
1203         while ( (ret != MMFILE_UTIL_FAIL) && ((readed = mmfile_read (fp, (unsigned char *)&basic_header, MMFILE_MP4_BASIC_BOX_HEADER_LEN)) > 0 ) ) {
1204                 basic_header.size = mmfile_io_be_uint32 (basic_header.size);
1205                 basic_header.type = mmfile_io_le_uint32 (basic_header.type);
1206
1207                 if (basic_header.size == 0) {
1208                         debug_warning ("header is invalid.\n");
1209                         basic_header.size = readed;
1210                         basic_header.type = 0;
1211                 }
1212
1213                 #ifdef __MMFILE_TEST_MODE__
1214                 debug_msg ("START_OFFSET:[%lld] SIZE:[%d Byte] 4CC:[%c%c%c%c]\n",
1215                                         basic_header.start_offset, basic_header.size,
1216                                         ((char*)&basic_header.type)[0], ((char*)&basic_header.type)[1],
1217                                         ((char*)&basic_header.type)[2], ((char*)&basic_header.type)[3]);
1218                 #endif
1219
1220                 switch (basic_header.type) {
1221                         case FOURCC ('m', 'o', 'o', 'v'): {
1222                                 #ifdef __MMFILE_TEST_MODE__
1223                                 debug_msg ("MPEG4: [moov] SIZE: [%d]Byte\n", basic_header.size);
1224                                 #endif
1225                                 break;
1226                         }
1227                         case FOURCC ('u', 'd', 't', 'a'): {
1228                                 #ifdef __MMFILE_TEST_MODE__
1229                                 debug_msg ("MPEG4: [udat] SIZE: [%d]Byte\n", basic_header.size);
1230                                 #endif
1231                                 break;
1232                         }
1233                         /////////////////////////////////////////////////////////////////
1234                         //                  Extracting Tag Data                        //
1235                         /////////////////////////////////////////////////////////////////
1236                         case FOURCC ('t', 'i', 't', 'l'): {
1237                                 #ifdef __MMFILE_TEST_MODE__
1238                                 debug_msg ("MPEG4: [titl] SIZE: [%d]Byte\n", basic_header.size);
1239                                 #endif
1240                                 GetStringFromTextTagBox (formatContext, fp, &basic_header, eMMFILE_3GP_TAG_TITLE);
1241                                 break;
1242                         }
1243                         case FOURCC ('d', 's', 'c', 'p'): {
1244                                 #ifdef __MMFILE_TEST_MODE__
1245                                 debug_msg ("MPEG4: [dscp] SIZE: [%d]Byte\n", basic_header.size);
1246                                 #endif
1247                                 GetStringFromTextTagBox (formatContext, fp, &basic_header, eMMFILE_3GP_TAG_CAPTION);
1248                                 break;
1249                         }
1250                         case FOURCC ('c', 'p', 'r', 't'): {
1251                                 #ifdef __MMFILE_TEST_MODE__
1252                                 debug_msg ("MPEG4: [cprt] SIZE: [%d]Byte\n", basic_header.size);
1253                                 #endif
1254                                 GetStringFromTextTagBox (formatContext, fp, &basic_header, eMMFILE_3GP_TAG_COPYRIGHT);
1255                                 break;
1256                         }
1257                         case FOURCC ('p', 'e', 'r', 'f'): {
1258                                 #ifdef __MMFILE_TEST_MODE__
1259                                 debug_msg ("MPEG4: [perf] SIZE: [%d]Byte\n", basic_header.size);
1260                                 #endif
1261                                 GetStringFromTextTagBox (formatContext, fp, &basic_header, eMMFILE_3GP_TAG_PERFORMER );
1262                                 break;
1263                         }
1264                         case FOURCC ('a', 'u', 't', 'h'): {
1265                                 #ifdef __MMFILE_TEST_MODE__
1266                                 debug_msg ("MPEG4: [auth] SIZE: [%d]Byte\n", basic_header.size);
1267                                 #endif
1268                                 GetStringFromTextTagBox (formatContext, fp, &basic_header, eMMFILE_3GP_TAG_AUTHOR);
1269                                 break;
1270                         }
1271                         case FOURCC ('g', 'n', 'r', 'e'): {
1272                                 #ifdef __MMFILE_TEST_MODE__
1273                                 debug_msg ("MPEG4: [gnre] SIZE: [%d]Byte\n", basic_header.size);
1274                                 #endif
1275                                 GetStringFromTextTagBox (formatContext, fp, &basic_header, eMMFILE_3GP_TAG_GENRE);
1276                                 break;
1277                         }
1278                         case FOURCC ('a', 'l', 'b', 'm'): {
1279                                 #ifdef __MMFILE_TEST_MODE__
1280                                 debug_msg ("MPEG4: [albm] SIZE: [%d]Byte\n", basic_header.size);
1281                                 #endif
1282                                 GetAlbumFromAlbumTagBox (formatContext, fp, &basic_header);
1283                                 break;
1284                         }
1285                         case FOURCC ('y', 'r', 'r', 'c'): {
1286                                 #ifdef __MMFILE_TEST_MODE__
1287                                 debug_msg ("MPEG4: [yrrc] SIZE: [%d]Byte\n", basic_header.size);
1288                                 #endif
1289                                 GetYearFromYearTagBox (formatContext, fp, &basic_header);
1290                                 break;
1291                         }
1292                         case FOURCC ('r', 't', 'n', 'g'): {
1293                                 #ifdef __MMFILE_TEST_MODE__
1294                                 debug_msg ("MPEG4: [rtng] SIZE: [%d]Byte\n", basic_header.size);
1295                                 #endif
1296                                 GetRatingFromRatingTagBox (formatContext, fp, &basic_header); /* not use */
1297                                 break;
1298                         }
1299                         case FOURCC ('c', 'l', 's', 'f'): {
1300                                 #ifdef __MMFILE_TEST_MODE__
1301                                 debug_msg ("MPEG4: [clsf] SIZE: [%d]Byte\n", basic_header.size);
1302                                 #endif
1303                                 GetClassficationFromClsfTagBox (formatContext, fp, &basic_header);
1304                                 break;
1305                         }
1306                         case FOURCC ('k', 'y', 'w', 'd'): {
1307                                 #ifdef __MMFILE_TEST_MODE__
1308                                 debug_msg ("MPEG4: [kywd] SIZE: [%d]Byte\n", basic_header.size);
1309                                 #endif
1310                                 ret = mmfile_seek (fp, basic_header.start_offset + basic_header.size, SEEK_SET);
1311                                 break;
1312                         }
1313                         case FOURCC ('l', 'o', 'c', 'i'): {
1314                                 #ifdef __MMFILE_TEST_MODE__
1315                                 debug_msg ("MPEG4: [loci] SIZE: [%d]Byte\n", basic_header.size);
1316                                 #endif
1317                                 GetLocationFromLociTagBox (formatContext, fp, &basic_header);
1318                                 break;
1319                         }
1320                         /////////////////////////////////////////////////////////////////
1321                         //                  Extracting ID3 Tag Data                    //
1322                         /////////////////////////////////////////////////////////////////
1323                         case FOURCC ('m', 'e', 't', 'a'): {
1324                                 #ifdef __MMFILE_TEST_MODE__
1325                                 debug_msg ("MPEG4: [meta] SIZE: [%d]Byte\n", basic_header.size);
1326                                 #endif
1327                                 GetTagFromMetaBox (formatContext, fp, &basic_header);
1328                                 break;
1329                         }
1330                         default: {
1331                                 #ifdef __MMFILE_TEST_MODE__
1332                                 debug_msg ("4CC: Not Support.. so skip it\n");
1333                                 #endif
1334                                 ret = mmfile_seek (fp, basic_header.start_offset + basic_header.size, SEEK_SET);
1335                                 break;
1336                         }
1337                 }
1338
1339                 if (ret == MMFILE_UTIL_FAIL) {
1340                         debug_error("mmfile operation is error\n");
1341                         ret = -1;
1342                         goto exit;
1343                 }
1344
1345                 basic_header.start_offset = mmfile_tell (fp);
1346         }
1347
1348 exit:
1349         mmfile_close (fp);
1350         return ret;
1351 }
1352
1353 EXPORT_API
1354 bool mm_file_id3tag_parse_v110(AvFileContentInfo* pInfo,  unsigned char *buffer)
1355 {
1356         const char *locale = MMFileUtilGetLocale (NULL);
1357
1358 #ifdef __MMFILE_TEST_MODE__
1359         debug_msg ("ID3tag v110--------------------------------------------------------------\n");
1360 #endif
1361
1362         if(pInfo->tagV2Info.bTitleMarked == false) {
1363                 pInfo->pTitle = mmfile_string_convert ((const char*)&buffer[3], MP3_ID3_TITLE_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
1364                 #ifdef __MMFILE_TEST_MODE__
1365                 debug_msg ( "pInfo->pTitle returned =(%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
1366                 #endif
1367         }
1368
1369         if(pInfo->tagV2Info.bArtistMarked == false) {
1370                 pInfo->pArtist = mmfile_string_convert ((const char*)&buffer[33], MP3_ID3_ARTIST_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
1371                 #ifdef __MMFILE_TEST_MODE__
1372                 debug_msg ( "pInfo->pArtist returned =(%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
1373                 #endif
1374         }
1375         if(pInfo->tagV2Info.bAlbumMarked == false) {
1376                 pInfo->pAlbum = mmfile_string_convert ((const char*)&buffer[63], MP3_ID3_ALBUM_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
1377                 #ifdef __MMFILE_TEST_MODE__
1378                 debug_msg (  "pInfo->pAlbum returned =(%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
1379                 #endif
1380         }
1381         if(pInfo->tagV2Info.bYearMarked == false) {
1382                 pInfo->pYear = mmfile_string_convert ((const char*)&buffer[93], MP3_ID3_YEAR_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
1383                 #ifdef __MMFILE_TEST_MODE__
1384                 debug_msg (  "pInfo->pYear returned =(%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
1385                 #endif
1386         }
1387         if(pInfo->tagV2Info.bDescriptionMarked == false) {
1388                 pInfo->pComment = mmfile_string_convert ((const char*)&buffer[97], MP3_ID3_DESCRIPTION_LENGTH, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
1389                 #ifdef __MMFILE_TEST_MODE__
1390                 debug_msg (  "pInfo->pComment returned =(%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
1391                 #endif
1392         }
1393
1394         if(pInfo->tagV2Info.bTrackNumMarked== false) {
1395                 pInfo->pTrackNum = mmfile_malloc (5);
1396                 pInfo->pTrackNum[4] = 0;
1397                 snprintf(pInfo->pTrackNum, 4, "%04d", (int)buffer[126]);
1398                 pInfo->tracknumLen = strlen(pInfo->pTrackNum);
1399                 #ifdef __MMFILE_TEST_MODE__
1400                 debug_msg (  "pInfo->pTrackNum returned =(%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
1401                 #endif
1402         }
1403
1404         if(pInfo->tagV2Info.bGenreMarked == false) {
1405                 pInfo->genre = buffer[127];
1406                 #ifdef __MMFILE_TEST_MODE__
1407                 debug_msg (  "pInfo->genre returned genre number (%d)\n", pInfo->genre);
1408                 #endif
1409         }
1410
1411         return true;
1412 }
1413
1414 EXPORT_API
1415 bool mm_file_id3tag_parse_v222(AvFileContentInfo* pInfo, unsigned char *buffer)
1416 {
1417         unsigned long taglen = 0;
1418         unsigned long needToloopv2taglen;
1419         unsigned long oneFrameLen = 0;
1420         unsigned long v2numOfFrames = 0;
1421         unsigned long curPos = 0;
1422         char CompTmp[4];
1423         char *pExtContent = NULL;
1424         unsigned long purelyFramelen = 0;
1425         char *tmpConvert2Pcode = NULL;
1426         int inx=0, encodingOffSet=0, realCpyFrameNum=0,
1427                 checkImgMimeTypeMax=0, checkImgDescriptionMax=0, checkImgExtMax=0,
1428                 imgstartOffset=0, tmp = 0;
1429
1430         int textEncodingType = 0;
1431         const char *locale = NULL;
1432
1433         pInfo->tagV2Info.bTitleMarked = false;
1434         pInfo->tagV2Info.bAlbumMarked= false;
1435         pInfo->tagV2Info.bArtistMarked= false;
1436         pInfo->tagV2Info.bDescriptionMarked= false;
1437         pInfo->tagV2Info.bGenreMarked= false;
1438         pInfo->tagV2Info.bYearMarked= false;
1439         pInfo->tagV2Info.bTrackNumMarked= false;
1440         pInfo->tagV2Info.bEncByMarked= false;
1441         pInfo->tagV2Info.bURLMarked= false;
1442         pInfo->tagV2Info.bCopyRightMarked= false;
1443         pInfo->tagV2Info.bOriginArtistMarked= false;
1444         pInfo->tagV2Info.bComposerMarked= false;
1445         pInfo->tagV2Info.bImageMarked= false;
1446         pInfo->imageInfo.bURLInfo = false;
1447         pInfo->tagV2Info.bGenreUTF16 = false;
1448         pInfo->tagV2Info.bConductorMarked = false;
1449
1450         pInfo->imageInfo.pImageBuf = NULL;
1451         pInfo->imageInfo.imageLen = 0;
1452
1453         locale = MMFileUtilGetLocale (NULL);
1454
1455         taglen = pInfo->tagV2Info.tagLen;
1456         needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
1457         curPos = MP3_TAGv2_HEADER_LEN;
1458         
1459 #ifdef __MMFILE_TEST_MODE__
1460         debug_msg ("ID3tag v222--------------------------------------------------------------\n");
1461 #endif
1462         if(needToloopv2taglen -MP3_TAGv2_22_TXT_HEADER_LEN > MP3_TAGv2_22_TXT_HEADER_LEN) {
1463                 v2numOfFrames = 1;
1464                 while(needToloopv2taglen > MP3_TAGv2_22_TXT_HEADER_LEN)
1465                 {
1466                         if((buffer[curPos] < '0' || buffer[curPos] > 'Z') || (buffer[curPos+1] < '0' || buffer[curPos+1] > 'Z')
1467                                 || (buffer[curPos+2] < '0' || buffer[curPos+2] > 'Z'))
1468                                 break;
1469
1470                         memcpy(CompTmp, &buffer[curPos], 3);
1471
1472                         CompTmp[3] = 0;
1473                         oneFrameLen = MP3_TAGv2_22_TXT_HEADER_LEN;
1474                         oneFrameLen += (unsigned long)buffer[3+curPos] << 16 | (unsigned long)buffer[4+curPos] << 8
1475                                 | (unsigned long)buffer[5+curPos];
1476                         if(oneFrameLen > taglen-curPos)
1477                                 break;
1478                         purelyFramelen = oneFrameLen - MP3_TAGv2_22_TXT_HEADER_LEN;
1479                         curPos +=MP3_TAGv2_22_TXT_HEADER_LEN;
1480
1481                         if(oneFrameLen > MP3_TAGv2_22_TXT_HEADER_LEN && purelyFramelen <= taglen-curPos)
1482                         {
1483                                 curPos += purelyFramelen;
1484
1485                                 if(buffer[curPos-purelyFramelen] == 0x00)
1486                                 {
1487                                         encodingOffSet = 1;
1488                                         textEncodingType = AV_ID3V2_ISO_8859;
1489                                 }
1490                                 else if(buffer[curPos-purelyFramelen] == 0x01)
1491                                 {
1492                                         encodingOffSet = 1;
1493                                         textEncodingType = AV_ID3V2_UTF16;
1494                                 }
1495
1496                                 //in order to deliver valid string to MP
1497                                 while((buffer[curPos-purelyFramelen+encodingOffSet] < 0x20) && (encodingOffSet < purelyFramelen))
1498                                         encodingOffSet++;
1499
1500                                 if(encodingOffSet < purelyFramelen)
1501                                 {
1502                                         realCpyFrameNum = purelyFramelen - encodingOffSet;
1503                                         pExtContent = mmfile_malloc (realCpyFrameNum+3);
1504                                         memset(pExtContent, '\0', realCpyFrameNum+3);
1505                                         if(textEncodingType == AV_ID3V2_ISO_8859)
1506                                         {
1507                                                 if(strncmp((char *)CompTmp, "PIC", 3) != 0)
1508                                                 {
1509                                                         tmpConvert2Pcode = mmfile_malloc ((realCpyFrameNum)*2+2);
1510                                                         memset(tmpConvert2Pcode, 0, (realCpyFrameNum)*2+2);
1511                                                 }
1512                                         }
1513
1514                                         memcpy(pExtContent, &buffer[curPos-purelyFramelen+encodingOffSet], purelyFramelen-encodingOffSet);
1515
1516                                         if(realCpyFrameNum > 0)
1517                                         {
1518                                                 if(strncmp((char *)CompTmp, "TT2", 3) == 0 && pInfo->tagV2Info.bTitleMarked == false)
1519                                                 {
1520                                                         if(textEncodingType == AV_ID3V2_UTF16)
1521                                                         {
1522                                                                 pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->titleLen);
1523                                                         }
1524                                                         else
1525                                                         {
1526                                                                 pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
1527                                                         }
1528
1529                                                         #ifdef __MMFILE_TEST_MODE__
1530                                                         debug_msg ( "pInfo->pTitle returned = (%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
1531                                                         #endif
1532                                                         pInfo->tagV2Info.bTitleMarked = true;
1533                                                 }
1534                                                 else if(strncmp((char *)CompTmp, "TP1", 3) == 0 && pInfo->tagV2Info.bArtistMarked == false)
1535                                                 {
1536                                                         if(textEncodingType == AV_ID3V2_UTF16)
1537                                                         {
1538                                                                 pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->artistLen);
1539                                                         }
1540                                                         else
1541                                                         {
1542                                                                 pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
1543                                                         }
1544                                                         #ifdef __MMFILE_TEST_MODE__
1545                                                         debug_msg ( "pInfo->pArtist returned = (%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
1546                                                         #endif
1547                                                         pInfo->tagV2Info.bArtistMarked = true;
1548                                                 }
1549                                                 else if(strncmp((char *)CompTmp, "TP3", 3) == 0 && pInfo->tagV2Info.bConductorMarked == false)
1550                                                 {
1551                                                         if(textEncodingType == AV_ID3V2_UTF16)
1552                                                         {
1553                                                                 pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->conductorLen);
1554                                                         }
1555                                                         else
1556                                                         {
1557                                                                 pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->conductorLen);
1558                                                         }
1559                                                         #ifdef __MMFILE_TEST_MODE__
1560                                                         debug_msg ( "pInfo->pConductor returned = (%s), pInfo->conductorLen(%d)\n", pInfo->pConductor, pInfo->conductorLen);
1561                                                         #endif
1562                                                         pInfo->tagV2Info.bConductorMarked = true;
1563                                                 }
1564                                                 else if(strncmp((char *)CompTmp, "TAL", 3) == 0 && pInfo->tagV2Info.bAlbumMarked == false)
1565                                                 {
1566                                                         if(textEncodingType == AV_ID3V2_UTF16)
1567                                                         {
1568                                                                 pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->albumLen);
1569                                                         }
1570                                                         else
1571                                                         {
1572                                                                 pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
1573                                                         }
1574                                                         #ifdef __MMFILE_TEST_MODE__
1575                                                         debug_msg ( "pInfo->pAlbum returned = (%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
1576                                                         #endif
1577                                                         pInfo->tagV2Info.bAlbumMarked = true;
1578                                                 }
1579                                                 else if(strncmp((char *)CompTmp, "TYE", 3) == 0 && pInfo->tagV2Info.bYearMarked == false)
1580                                                 {
1581                                                         if(textEncodingType == AV_ID3V2_UTF16)
1582                                                         {
1583                                                                 pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->yearLen);
1584                                                         }
1585                                                         else
1586                                                         {
1587                                                                 pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
1588                                                         }
1589                                                         #ifdef __MMFILE_TEST_MODE__
1590                                                         debug_msg ( "pInfo->pYear returned = (%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
1591                                                         #endif
1592                                                         pInfo->tagV2Info.bYearMarked = true;
1593                                                 }
1594                                                 else if(strncmp((char *)CompTmp, "COM", 3) == 0 && pInfo->tagV2Info.bDescriptionMarked == false)
1595                                                 {
1596                                                         //skip language data!
1597                                                         if(realCpyFrameNum > 4)
1598                                                         {
1599                                                                 realCpyFrameNum -= 4;
1600                                                                 tmp = 4;
1601
1602                                                                 //pExtContent[tmp+1] value should't have encoding value
1603                                                                 if(pExtContent[tmp] > 0x20 && (pExtContent[tmp - 1] == 0x00 || pExtContent[tmp - 1] == 0x01))
1604                                                                 {
1605                                                                         if(pExtContent[tmp - 1] == 0x00)
1606                                                                                 textEncodingType = AV_ID3V2_ISO_8859;
1607                                                                         else
1608                                                                                 textEncodingType = AV_ID3V2_UTF16;
1609
1610                                                                         if(textEncodingType == AV_ID3V2_UTF16)
1611                                                                         {
1612                                                                                 pInfo->pComment = mmfile_string_convert ((char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->commentLen);
1613                                                                         }
1614                                                                         else
1615                                                                         {
1616                                                                                 pInfo->pComment = mmfile_string_convert ((char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
1617                                                                         }
1618
1619                                                                         #ifdef __MMFILE_TEST_MODE__
1620                                                                         debug_msg ( "pInfo->pComment returned = (%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
1621                                                                         #endif
1622                                                                         pInfo->tagV2Info.bDescriptionMarked = true;
1623                                                                 }
1624                                                                 else
1625                                                                 {
1626                                                                         #ifdef __MMFILE_TEST_MODE__
1627                                                                         debug_msg (  "mmf_file_id3tag_parse_v222: failed to get Comment Info tmp(%d), purelyFramelen - encodingOffSet(%d)\n", tmp, purelyFramelen - encodingOffSet );
1628                                                                         #endif
1629                                                                 }
1630                                                         }
1631                                                         else
1632                                                         {
1633                                                                 #ifdef __MMFILE_TEST_MODE__
1634                                                                 debug_msg (  "mmf_file_id3tag_parse_v222: Description info too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum );
1635                                                                 #endif
1636                                                         }
1637                                                         tmp = 0;
1638
1639                                                 }
1640                                                 else if(strncmp((char *)CompTmp, "TCO", 3) == 0 && pInfo->tagV2Info.bGenreMarked == false)
1641                                                 {
1642                                                         if(textEncodingType == AV_ID3V2_UTF16)
1643                                                         {
1644                                                                 pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->genreLen);
1645                                                         }
1646                                                         else
1647                                                         {
1648                                                                 pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->genreLen);
1649                                                         }
1650
1651                                                         #ifdef __MMFILE_TEST_MODE__
1652                                                         debug_msg ( "pInfo->pGenre returned = (%s), pInfo->genreLen(%d)\n", pInfo->pGenre, pInfo->genreLen);
1653                                                         #endif
1654
1655                                                         if((pInfo->pGenre != NULL) && (pInfo->genreLen > 0)) {
1656                                                                 int ret = 0;
1657                                                                 int int_genre = -1;
1658
1659                                                                 ret = sscanf( pInfo->pGenre, "%d", &int_genre);
1660
1661                                                                 if(ret == 1) {
1662                                                                         #ifdef __MMFILE_TEST_MODE__
1663                                                                         debug_msg("genre information is inteager [%d]\n", int_genre);
1664                                                                         #endif
1665
1666                                                                         //Change int to string
1667                                                                         if((0 <= int_genre) && (int_genre < GENRE_COUNT-1)) {
1668                                                                                 /*save genreinfo like "(123)". mm_file_id3tag_restore_content_info convert it to string*/
1669                                                                                 char tmp_genre[6] = {0,};       /*ex. "(123)+NULL"*/
1670                                                                                 int tmp_genre_len = 0;
1671
1672                                                                                 memset (tmp_genre, 0, 6);
1673                                                                                 snprintf(tmp_genre, sizeof(tmp_genre), "(%d)", int_genre);
1674
1675                                                                                 tmp_genre_len = strlen(tmp_genre);
1676                                                                                 if(tmp_genre_len > 0) {
1677                                                                                         if(pInfo->pGenre) _FREE_EX(pInfo->pGenre);
1678                                                                                         pInfo->pGenre = mmfile_malloc (sizeof(char) * (tmp_genre_len + 1) );
1679                                                                                         if (pInfo->pGenre)
1680                                                                                         {
1681                                                                                                 strncpy(pInfo->pGenre, tmp_genre, tmp_genre_len);
1682                                                                                                 pInfo->pGenre[tmp_genre_len] = 0;
1683                                                                                         }
1684                                                                                 }
1685                                                                         }
1686                                                                 }
1687                                                         }
1688
1689                                                         pInfo->tagV2Info.bGenreMarked = true;
1690                                                 }
1691                                                 else if(strncmp((char *)CompTmp, "TRK", 3) == 0 && pInfo->tagV2Info.bTrackNumMarked == false)
1692                                                 {
1693                                                         if(textEncodingType == AV_ID3V2_UTF16)
1694                                                         {
1695                                                                 pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->tracknumLen);
1696                                                         }
1697                                                         else
1698                                                         {
1699                                                                 pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->tracknumLen);
1700                                                         }
1701
1702                                                         #ifdef __MMFILE_TEST_MODE__
1703                                                         debug_msg ( "pInfo->pTrackNum returned = (%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
1704                                                         #endif
1705                                                         pInfo->tagV2Info.bTrackNumMarked = true;
1706                                                 }
1707                                                 else if(strncmp((char *)CompTmp, "TEN", 3) == 0 && pInfo->tagV2Info.bEncByMarked == false)
1708                                                 {
1709                                                         if(textEncodingType == AV_ID3V2_UTF16)
1710                                                         {
1711                                                                 pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->encbyLen);
1712                                                         }
1713                                                         else
1714                                                         {
1715                                                                 pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->encbyLen);
1716                                                         }
1717
1718                                                         #ifdef __MMFILE_TEST_MODE__
1719                                                         debug_msg ( "pInfo->pEncBy returned = (%s), pInfo->encbyLen(%d)\n", pInfo->pEncBy, pInfo->encbyLen);
1720                                                         #endif
1721                                                         pInfo->tagV2Info.bEncByMarked = true;
1722                                                 }
1723                                                 else if(strncmp((char *)CompTmp, "WXX", 3) == 0 && pInfo->tagV2Info.bURLMarked == false)
1724                                                 {
1725                                                         if(realCpyFrameNum > 4)
1726                                                         {
1727                                                                 //skip language data!
1728                                                                 realCpyFrameNum -= 4;
1729                                                                 tmp = 4;
1730
1731                                                                 //pExtContent[tmp+1] value should't have null value
1732                                                                 if(pExtContent[tmp] > 0x20 && (pExtContent[tmp - 1] == 0x00 || pExtContent[tmp - 1] == 0x01))
1733                                                                 {
1734                                                                         if(pExtContent[tmp - 1] == 0x00)
1735                                                                                 textEncodingType = AV_ID3V2_ISO_8859;
1736                                                                         else
1737                                                                                 textEncodingType = AV_ID3V2_UTF16;
1738
1739                                                                         if(textEncodingType == AV_ID3V2_UTF16)
1740                                                                         {
1741                                                                                 pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->urlLen);
1742                                                                         }
1743                                                                         else
1744                                                                         {
1745                                                                                 pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->urlLen);
1746                                                                         }
1747
1748                                                                         #ifdef __MMFILE_TEST_MODE__
1749                                                                         debug_msg ( "pInfo->pURL returned = (%s), pInfo->urlLen(%d)\n", pInfo->pURL, pInfo->urlLen);
1750                                                                         #endif
1751                                                                         pInfo->tagV2Info.bURLMarked = true;
1752                                                                 }
1753                                                                 else
1754                                                                 {
1755                                                                         #ifdef __MMFILE_TEST_MODE__
1756                                                                         debug_msg (  "mmf_file_id3tag_parse_v222: failed to get URL Info tmp(%d), purelyFramelen - encodingOffSet(%d)\n", tmp, purelyFramelen - encodingOffSet );
1757                                                                         #endif
1758                                                                 }
1759                                                         }
1760                                                         else
1761                                                         {
1762                                                                 #ifdef __MMFILE_TEST_MODE__
1763                                                                 debug_msg (  "mmf_file_id3tag_parse_v222: URL info too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum );
1764                                                                 #endif
1765                                                         }
1766                                                         tmp = 0;
1767                                                 }
1768                                                 else if(strncmp((char *)CompTmp, "TCR", 3) == 0 && pInfo->tagV2Info.bCopyRightMarked == false)
1769                                                 {
1770                                                         if(textEncodingType == AV_ID3V2_UTF16)
1771                                                         {
1772                                                                 pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->copyrightLen);
1773                                                         }
1774                                                         else
1775                                                         {
1776                                                                 pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->copyrightLen);
1777                                                         }
1778
1779                                                         #ifdef __MMFILE_TEST_MODE__
1780                                                         debug_msg ( "pInfo->pCopyright returned = (%s), pInfo->copyrightLen(%d)\n", pInfo->pCopyright, pInfo->copyrightLen);
1781                                                         #endif
1782                                                         pInfo->tagV2Info.bCopyRightMarked = true;
1783                                                 }
1784                                                 else if(strncmp((char *)CompTmp, "TOA", 3) == 0 && pInfo->tagV2Info.bOriginArtistMarked == false)
1785                                                 {
1786                                                         if(textEncodingType == AV_ID3V2_UTF16)
1787                                                         {
1788                                                                 pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->originartistLen);
1789                                                         }
1790                                                         else
1791                                                         {
1792                                                                 pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->originartistLen);
1793                                                         }
1794
1795                                                         #ifdef __MMFILE_TEST_MODE__
1796                                                         debug_msg ( "pInfo->pOriginArtist returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pOriginArtist, pInfo->originartistLen);
1797                                                         #endif
1798                                                         pInfo->tagV2Info.bOriginArtistMarked = true;
1799                                                 }
1800                                                 else if(strncmp((char *)CompTmp, "TCM", 3) == 0 && pInfo->tagV2Info.bComposerMarked == false)
1801                                                 {
1802                                                         if(textEncodingType == AV_ID3V2_UTF16)
1803                                                         {
1804                                                                 pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->composerLen);
1805                                                         }
1806                                                         else
1807                                                         {
1808                                                                 pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->composerLen);
1809                                                         }
1810                                                         #ifdef __MMFILE_TEST_MODE__
1811                                                         debug_msg ( "pInfo->pComposer returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pComposer, pInfo->composerLen);
1812                                                         #endif
1813                                                         pInfo->tagV2Info.bComposerMarked = true;
1814                                                 }
1815                                                 else if(strncmp((char *)CompTmp, "TRD", 3) == 0 && pInfo->tagV2Info.bRecDateMarked== false)
1816                                                 {
1817                                                         if(textEncodingType == AV_ID3V2_UTF16)
1818                                                         {
1819                                                                 pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->recdateLen);
1820                                                         }
1821                                                         else
1822                                                         {
1823                                                                 pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->recdateLen);
1824                                                         }
1825                                                         #ifdef __MMFILE_TEST_MODE__
1826                                                         debug_msg ( "pInfo->pRecDate returned = (%s), pInfo->recdateLen(%d)\n", pInfo->pRecDate, pInfo->recdateLen);
1827                                                         #endif
1828                                                         pInfo->tagV2Info.bRecDateMarked = true;
1829                                                 }
1830                                                 else if(strncmp((char *)CompTmp, "PIC", 3) == 0 && pInfo->tagV2Info.bImageMarked == false && realCpyFrameNum <= 2000000)
1831                                                 {
1832                                                         if(textEncodingType == AV_ID3V2_UTF16)
1833                                                         {
1834                                                                 #ifdef __MMFILE_TEST_MODE__
1835                                                                 debug_msg ("mmf_file_id3tag_parse_v222: this is abnormal case!!\n");
1836                                                                 #endif
1837                                                         }
1838                                                         else
1839                                                         {
1840                                                                 if(pExtContent[0] != 0)
1841                                                                 {
1842                                                                         for(inx = 0; inx < MP3_ID3_IMAGE_EXT_MAX_LENGTH; inx++)
1843                                                                                 pInfo->imageInfo.imageExt[inx] = '\0';//ini mimetype variable
1844
1845                                                                         while((checkImgExtMax < MP3_ID3_IMAGE_EXT_MAX_LENGTH-1) && pExtContent[checkImgExtMax] != '\0')
1846                                                                         {
1847                                                                                 pInfo->imageInfo.imageExt[checkImgExtMax] = pExtContent[checkImgExtMax];
1848                                                                                 checkImgExtMax++;
1849                                                                         }
1850                                                                 }
1851                                                                 else
1852                                                                 {
1853                                                                         #ifdef __MMFILE_TEST_MODE__
1854                                                                          debug_msg ( "mmf_file_id3tag_parse_v222: PIC image's not included to image Extention\n");
1855                                                                         #endif
1856                                                                 }
1857
1858                                                                 imgstartOffset += checkImgExtMax;
1859
1860                                                                 if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
1861                                                                 {
1862                                                                         pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
1863                                                                 }
1864                                                                 imgstartOffset++;//PictureType(1byte)
1865
1866                                                                 if(pExtContent[imgstartOffset] != 0x0)
1867                                                                 {
1868                                                                         for(inx = 0; inx < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1; inx++)
1869                                                                                 pInfo->imageInfo.imageDescription[inx] = '\0';//ini imgdescripiton variable
1870
1871                                                                         while((checkImgDescriptionMax < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1) && pExtContent[imgstartOffset+checkImgDescriptionMax] != '\0')
1872                                                                         {
1873                                                                                 pInfo->imageInfo.imageDescription[checkImgDescriptionMax] = pExtContent[imgstartOffset+checkImgDescriptionMax];
1874                                                                                 checkImgDescriptionMax++;
1875                                                                         }
1876                                                                         pInfo->imageInfo.imgDesLen= checkImgDescriptionMax;
1877                                                                 }
1878                                                                 else
1879                                                                 {
1880                                                                         pInfo->imageInfo.imgDesLen= 0;
1881                                                                 }
1882
1883                                                                 imgstartOffset += checkImgDescriptionMax;
1884
1885                                                                 if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
1886                                                                 {
1887                                                                         imgstartOffset ++; // endofDesceriptionType(1byte)
1888
1889                                                                         while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
1890                                                                         {
1891                                                                                 imgstartOffset ++;
1892                                                                         }
1893
1894                                                                         #ifdef __MMFILE_TEST_MODE__
1895                                                                         debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
1896                                                                         #endif
1897
1898                                                                         if(realCpyFrameNum - imgstartOffset > 0)
1899                                                                         {
1900                                                                                 pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
1901                                                                                 pInfo->imageInfo.pImageBuf= mmfile_malloc (pInfo->imageInfo.imageLen + 1);
1902                                                                                 memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
1903                                                                                 pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
1904
1905                                                                                 if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
1906                                                                                         pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
1907                                                                         }
1908                                                                         else
1909                                                                         {
1910                                                                                 #ifdef __MMFILE_TEST_MODE__
1911                                                                                 debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
1912                                                                                 #endif
1913                                                                         }
1914                                                                 }
1915
1916                                                         }
1917
1918                                                         checkImgMimeTypeMax = 0;
1919                                                         checkImgDescriptionMax = 0;
1920                                                         checkImgExtMax = 0;
1921                                                         inx = 0;
1922                                                         imgstartOffset = 0;
1923                                                         pInfo->tagV2Info.bImageMarked= true;
1924
1925                                                 }
1926                                         }
1927
1928                                 }
1929                         }
1930                         else
1931                         {
1932                                 curPos += purelyFramelen;
1933                                 if(purelyFramelen != 0)
1934                                         needToloopv2taglen = MP3_TAGv2_22_TXT_HEADER_LEN;
1935                         }
1936
1937                         if(pExtContent) _FREE_EX(pExtContent);
1938                         if(tmpConvert2Pcode)    _FREE_EX(tmpConvert2Pcode);
1939                         memset(CompTmp, 0, 4);
1940                         if(curPos < taglen)
1941                         {
1942                                 needToloopv2taglen -= oneFrameLen;
1943                                 v2numOfFrames++;
1944                         }
1945                         else
1946                                 needToloopv2taglen = MP3_TAGv2_22_TXT_HEADER_LEN;
1947                         oneFrameLen = 0;
1948                         encodingOffSet = 0;
1949                         realCpyFrameNum = 0;
1950                         textEncodingType = 0;
1951                         purelyFramelen = 0;
1952
1953                 }
1954         }
1955
1956
1957
1958         if(taglen) {
1959                 return true;
1960         } else {
1961                 return false;
1962         }
1963 }
1964
1965 EXPORT_API
1966 bool mm_file_id3tag_parse_v223(AvFileContentInfo* pInfo, unsigned char *buffer)
1967 {
1968         unsigned long taglen = 0;
1969         unsigned long needToloopv2taglen;
1970         unsigned long oneFrameLen = 0;
1971         unsigned long v2numOfFrames = 0;
1972         unsigned long curPos = 0;
1973         char CompTmp[5];
1974         unsigned char *pExtContent = NULL;
1975         unsigned long purelyFramelen = 0;
1976         char *tmpConvert2Pcode = NULL;
1977         int inx=0, encodingOffSet=0, realCpyFrameNum=0, checkImgMimeTypeMax=0, checkImgDescriptionMax=0, imgstartOffset=0,  tmp = 0;
1978         int textEncodingType = 0;
1979         const char *locale = NULL;
1980
1981         locale = MMFileUtilGetLocale (NULL);
1982
1983         pInfo->tagV2Info.bTitleMarked = false;
1984         pInfo->tagV2Info.bAlbumMarked= false;
1985         pInfo->tagV2Info.bArtistMarked= false;
1986         pInfo->tagV2Info.bDescriptionMarked= false;
1987         pInfo->tagV2Info.bGenreMarked= false;
1988         pInfo->tagV2Info.bYearMarked= false;
1989         pInfo->tagV2Info.bTrackNumMarked= false;
1990         pInfo->tagV2Info.bEncByMarked= false;
1991         pInfo->tagV2Info.bURLMarked= false;
1992         pInfo->tagV2Info.bCopyRightMarked= false;
1993         pInfo->tagV2Info.bOriginArtistMarked= false;
1994         pInfo->tagV2Info.bComposerMarked= false;
1995         pInfo->tagV2Info.bImageMarked= false;
1996         pInfo->imageInfo.bURLInfo = false;
1997         pInfo->tagV2Info.bConductorMarked = false;
1998         pInfo->tagV2Info.bUnsyncLyricsMarked = false;
1999         pInfo->tagV2Info.bSyncLyricsMarked = false;
2000
2001         pInfo->tagV2Info.bGenreUTF16 = false;
2002
2003         pInfo->imageInfo.pImageBuf = NULL;
2004         pInfo->imageInfo.imageLen = 0;
2005
2006         taglen = pInfo->tagV2Info.tagLen;
2007         needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
2008         curPos = MP3_TAGv2_HEADER_LEN;
2009
2010 #ifdef __MMFILE_TEST_MODE__
2011         debug_msg ("ID3tag v223--------------------------------------------------------------\n");
2012 #endif
2013
2014         if(needToloopv2taglen -MP3_TAGv2_23_TXT_HEADER_LEN > MP3_TAGv2_23_TXT_HEADER_LEN)
2015         {
2016                 v2numOfFrames = 1;
2017                 while(needToloopv2taglen > MP3_TAGv2_23_TXT_HEADER_LEN)
2018                 {
2019                         if((buffer[curPos] < '0' || buffer[curPos] > 'Z') || (buffer[curPos+1] < '0' || buffer[curPos+1] > 'Z')
2020                                 || (buffer[curPos+2] < '0' || buffer[curPos+2] > 'Z')|| (buffer[curPos+3] < '0' || buffer[curPos+3] > 'Z'))
2021                                 break;
2022
2023                         memcpy(CompTmp, &buffer[curPos], 4);
2024
2025                         CompTmp[4] = 0;
2026                         oneFrameLen = MP3_TAGv2_23_TXT_HEADER_LEN;
2027                         oneFrameLen += (unsigned long)buffer[4+curPos] << 24 | (unsigned long)buffer[5+curPos] << 16
2028                                 | (unsigned long)buffer[6+curPos] << 8 | (unsigned long)buffer[7+curPos];
2029                         
2030                         #ifdef __MMFILE_TEST_MODE__
2031                         debug_msg ("----------------------------------------------------------------------------------------------------\n");
2032                         #endif
2033
2034                         if(oneFrameLen > taglen-curPos)
2035                                 break;
2036
2037                         purelyFramelen = oneFrameLen - MP3_TAGv2_23_TXT_HEADER_LEN;
2038                         curPos +=MP3_TAGv2_23_TXT_HEADER_LEN;
2039
2040                         if(oneFrameLen > MP3_TAGv2_23_TXT_HEADER_LEN && purelyFramelen <= taglen-curPos)
2041                         {
2042                                 curPos += purelyFramelen;
2043
2044                                 if( IS_ENCODEDBY_UTF16(buffer+(curPos-purelyFramelen)) )
2045                                 {
2046                                         encodingOffSet = 2;
2047                                         #ifdef __MMFILE_TEST_MODE__
2048                                         debug_msg ( "this text string(%s) encoded by UTF16 encodingOffSet(%d)\n", CompTmp, encodingOffSet);
2049                                         #endif
2050                                         textEncodingType = AV_ID3V2_UTF16;
2051                                 }
2052                                 else if ( IS_ENCODEDBY_UTF16_R(buffer+(curPos-purelyFramelen)) )
2053                                 {
2054                                         encodingOffSet = 2;
2055                                         #ifdef __MMFILE_TEST_MODE__
2056                                         debug_msg ( "this text string(%s) encoded by UTF16 encodingOffSet(%d)\n", CompTmp, encodingOffSet);
2057                                         #endif
2058                                         textEncodingType = AV_ID3V2_UTF16_BE;
2059                                 }
2060                                 else if( IS_ENCODEDBY_UTF16(buffer+(curPos-purelyFramelen+1)) )
2061                                 {
2062                                         encodingOffSet = 3;
2063                                         #ifdef __MMFILE_TEST_MODE__
2064                                         debug_msg ( "this text string(%s) encoded by UTF16 encodingOffSet(%d)\n", CompTmp, encodingOffSet);
2065                                         #endif
2066                                         textEncodingType = AV_ID3V2_UTF16;
2067                                 }
2068                                 else if ( IS_ENCODEDBY_UTF16_R(buffer+(curPos-purelyFramelen+1)) )
2069                                 {
2070                                         encodingOffSet = 3;
2071                                         #ifdef __MMFILE_TEST_MODE__
2072                                         debug_msg ( "this text string(%s) encoded by UTF16 encodingOffSet(%d)\n", CompTmp, encodingOffSet);
2073                                         #endif
2074                                         textEncodingType = AV_ID3V2_UTF16_BE;
2075                                 }
2076                                 else
2077                                 {
2078                                         if (buffer[curPos-purelyFramelen+encodingOffSet] == 0x00)
2079                                         {
2080                                                 #ifdef __MMFILE_TEST_MODE__
2081                                                 debug_msg ("encodingOffset will be set to 1\n");
2082                                                 #endif
2083
2084                                                 encodingOffSet=1;
2085                                         }
2086                                         else
2087                                         {
2088                                                 #ifdef __MMFILE_TEST_MODE__
2089                                                 debug_msg ("Finding encodingOffset\n");
2090                                                 #endif
2091
2092                                                 while((buffer[curPos-purelyFramelen+encodingOffSet] < 0x20) && (encodingOffSet < purelyFramelen)) // text string encoded by ISO-8859-1
2093                                                         encodingOffSet++;
2094                                         }
2095                                         textEncodingType = AV_ID3V2_ISO_8859;
2096                                         #ifdef __MMFILE_TEST_MODE__
2097                                         debug_msg ( "this text string(%s) encoded by ISO-8859-1 encodingOffSet(%d)\n", CompTmp, encodingOffSet);
2098                                         #endif
2099                                 }
2100
2101                                 if(encodingOffSet < purelyFramelen)
2102                                 {
2103                                         realCpyFrameNum = purelyFramelen - encodingOffSet;
2104                                         pExtContent = mmfile_malloc (realCpyFrameNum+3);
2105                                         memset(pExtContent, '\0', realCpyFrameNum+3);
2106                                         if(textEncodingType == AV_ID3V2_ISO_8859)
2107                                         {
2108                                                 if(strncmp((char *)CompTmp, "APIC", 4) != 0)
2109                                                 {
2110                                                         tmpConvert2Pcode = mmfile_malloc ((realCpyFrameNum)*2+2);
2111                                                         memset(tmpConvert2Pcode, 0, (realCpyFrameNum)*2+2);
2112                                                 }
2113                                         }
2114
2115                                         memcpy(pExtContent, &buffer[curPos-purelyFramelen+encodingOffSet], purelyFramelen-encodingOffSet);
2116                                         if(realCpyFrameNum > 0)
2117                                         {
2118                                                 if(strncmp((char *)CompTmp, "TIT2", 4) == 0 && pInfo->tagV2Info.bTitleMarked == false)
2119                                                 {
2120                                                         if(textEncodingType == AV_ID3V2_UTF16)
2121                                                         {
2122                                                                 pInfo->pTitle = mmfile_string_convert ((char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->titleLen);
2123                                                         }
2124                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2125                                                         {
2126                                                                 debug_warning ("not implemented\n");
2127                                                         }
2128                                                         else
2129                                                         {
2130                                                                 pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
2131                                                         }
2132
2133                                                         #ifdef __MMFILE_TEST_MODE__
2134                                                         debug_msg ( "pInfo->pTitle returned = (%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
2135                                                         #endif
2136                                                         pInfo->tagV2Info.bTitleMarked = true;
2137
2138                                                 }
2139                                                 else if(strncmp((char *)CompTmp, "TPE1", 4) == 0 && pInfo->tagV2Info.bArtistMarked == false)
2140                                                 {
2141                                                         if(textEncodingType == AV_ID3V2_UTF16)
2142                                                         {
2143                                                                 pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->artistLen);
2144                                                         }
2145                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2146                                                         {
2147                                                                 debug_warning ("not implemented\n");
2148                                                         }
2149                                                         else
2150                                                         {
2151                                                                 pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
2152                                                         }
2153
2154                                                         #ifdef __MMFILE_TEST_MODE__
2155                                                         debug_msg ( "pInfo->pArtist returned = (%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
2156                                                         #endif
2157                                                         pInfo->tagV2Info.bArtistMarked = true;
2158                                                 }
2159                                                 else if(strncmp((char *)CompTmp, "TPE3", 4) == 0 && pInfo->tagV2Info.bConductorMarked == false)
2160                                                 {
2161                                                         if(textEncodingType == AV_ID3V2_UTF16)
2162                                                         {
2163                                                                 pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->conductorLen);
2164                                                         }
2165                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2166                                                         {
2167                                                                 debug_warning ("not implemented\n");
2168                                                         }
2169                                                         else
2170                                                         {
2171                                                                 pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->conductorLen);
2172                                                         }
2173
2174                                                         #ifdef __MMFILE_TEST_MODE__
2175                                                         debug_msg ( "pInfo->pConductor returned = (%s), pInfo->conductorLen(%d)\n", pInfo->pConductor, pInfo->conductorLen);
2176                                                         #endif
2177                                                         pInfo->tagV2Info.bConductorMarked = true;
2178                                                 }
2179                                                 else if(strncmp((char *)CompTmp, "TALB", 4) == 0 && pInfo->tagV2Info.bAlbumMarked == false)
2180                                                 {
2181                                                         if(textEncodingType == AV_ID3V2_UTF16)
2182                                                         {
2183                                                                 pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->albumLen);
2184                                                         }
2185                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2186                                                         {
2187                                                                 debug_warning ("not implemented\n");
2188                                                         }
2189                                                         else
2190                                                         {
2191                                                                 pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
2192                                                         }
2193                                                         #ifdef __MMFILE_TEST_MODE__
2194                                                         debug_msg ( "pInfo->pAlbum returned = (%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
2195                                                         #endif
2196                                                         pInfo->tagV2Info.bAlbumMarked = true;
2197                                                 }
2198                                                 else if(strncmp((char *)CompTmp, "TYER", 4) == 0 && pInfo->tagV2Info.bYearMarked == false)
2199                                                 {
2200                                                         if(textEncodingType == AV_ID3V2_UTF16)
2201                                                         {
2202                                                                 pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->yearLen);
2203                                                         }
2204                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2205                                                         {
2206                                                                 debug_warning ("not implemented\n");
2207                                                         }
2208                                                         else
2209                                                         {
2210                                                                 pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
2211                                                         }
2212
2213                                                         #ifdef __MMFILE_TEST_MODE__
2214                                                         debug_msg ( "pInfo->pYear returned = (%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
2215                                                         #endif
2216                                                         pInfo->tagV2Info.bYearMarked = true;
2217                                                 }
2218                                                 else if(strncmp((char *)CompTmp, "COMM", 4) == 0 && pInfo->tagV2Info.bDescriptionMarked == false)
2219                                                 {
2220                                                         if(realCpyFrameNum > 3)
2221                                                         {
2222                                                                 realCpyFrameNum -= 3;
2223                                                                 tmp = 3;
2224
2225                                                                 //pExtContent[tmp+1] value should't have encoding value
2226                                                                 if(pExtContent[tmp] == 0x00 || pExtContent[tmp] == 0xFF|| pExtContent[tmp] == 0xFE)
2227                                                                 {
2228                                                                         if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
2229                                                                         {
2230                                                                                 while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
2231                                                                                 {
2232                                                                                         realCpyFrameNum -= 4;
2233                                                                                         tmp += 4;
2234                                                                                 }
2235
2236                                                                                 if(IS_ENCODEDBY_UTF16(pExtContent+tmp) && (realCpyFrameNum > 2))
2237                                                                                 {
2238                                                                                         realCpyFrameNum -= 2;
2239                                                                                         tmp += 2;
2240                                                                                         textEncodingType = AV_ID3V2_UTF16;
2241                                                                                 }
2242                                                                                 else if (IS_ENCODEDBY_UTF16_R(pExtContent+tmp) && (realCpyFrameNum > 2))
2243                                                                                 {
2244                                                                                         realCpyFrameNum -= 2;
2245                                                                                         tmp += 2;
2246                                                                                         textEncodingType = AV_ID3V2_UTF16_BE;
2247                                                                                 }
2248                                                                                 else if(IS_ENCODEDBY_UTF16(pExtContent+tmp+1) && (realCpyFrameNum > 3))
2249                                                                                 {
2250                                                                                         realCpyFrameNum -= 3;
2251                                                                                         tmp += 3;
2252                                                                                         textEncodingType = AV_ID3V2_UTF16;
2253                                                                                 }
2254                                                                                 else if (IS_ENCODEDBY_UTF16_R(pExtContent+tmp+1)  && (realCpyFrameNum > 3))
2255                                                                                 {
2256                                                                                         realCpyFrameNum -= 3;
2257                                                                                         tmp += 3;
2258                                                                                         textEncodingType = AV_ID3V2_UTF16_BE;
2259                                                                                 }
2260                                                                                 else
2261                                                                                 {
2262                                                                                         #ifdef __MMFILE_TEST_MODE__
2263                                                                                         debug_msg ( "pInfo->pComment Never Get Here!!\n");
2264                                                                                         #endif
2265                                                                                 }
2266                                                                         }
2267                                                                         else
2268                                                                         {
2269                                                                                 while((pExtContent[tmp] < 0x20) && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
2270                                                                                 {
2271                                                                                         realCpyFrameNum --;
2272                                                                                         tmp++;
2273                                                                                 }
2274                                                                                 textEncodingType = AV_ID3V2_ISO_8859;
2275                                                                         }
2276
2277                                                                         #ifdef __MMFILE_TEST_MODE__
2278                                                                         debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
2279                                                                         #endif
2280
2281                                                                         if(textEncodingType == AV_ID3V2_UTF16)
2282                                                                         {
2283                                                                                 pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->commentLen);
2284                                                                         }
2285                                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2286                                                                         {
2287                                                                                 debug_warning ("not implemented\n");
2288                                                                         }
2289                                                                         else
2290                                                                         {
2291                                                                                 pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
2292                                                                         }
2293                                                                 }
2294                                                                 else
2295                                                                 {
2296                                                                         #ifdef __MMFILE_TEST_MODE__
2297                                                                         debug_msg ( "failed to get Comment Info tmp(%d), purelyFramelen - encodingOffSet(%d)\n", tmp, purelyFramelen - encodingOffSet);
2298                                                                         #endif
2299                                                                         pInfo->commentLen = 0;
2300                                                                 }
2301                                                         }
2302                                                         else
2303                                                         {
2304                                                                 #ifdef __MMFILE_TEST_MODE__
2305                                                                 debug_msg ( "Description info too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum);
2306                                                                 #endif
2307                                                                 pInfo->commentLen = 0;
2308                                                         }
2309                                                         tmp = 0;
2310
2311                                                         #ifdef __MMFILE_TEST_MODE__
2312                                                         debug_msg ( "pInfo->pComment returned = (%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
2313                                                         #endif
2314                                                         pInfo->tagV2Info.bDescriptionMarked = true;
2315                                                 }
2316                                                 else if(strncmp((char *)CompTmp, "SYLT", 4) == 0 && pInfo->tagV2Info.bSyncLyricsMarked == false)
2317                                                 {
2318                                                         int idx = 0;
2319                                                         int copy_len = 0;
2320                                                         int copy_start_pos = tmp;
2321                                                         AvSynclyricsInfo *synclyrics_info = NULL;
2322                                                         GList *synclyrics_info_list = NULL;
2323                                                                         
2324                                                         if(realCpyFrameNum > 5)
2325                                                         {
2326                                                                 realCpyFrameNum -= 5;
2327                                                                 tmp = 5;
2328
2329                                                                 //pExtContent[tmp+1] value should't have encoding value
2330                                                                 if(pExtContent[tmp] == 0x00 || pExtContent[tmp] == 0xFF|| pExtContent[tmp] == 0xFE)
2331                                                                 {
2332                                                                         if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
2333                                                                         {
2334                                                                                 while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
2335                                                                                 {
2336                                                                                         realCpyFrameNum -= 4;
2337                                                                                         tmp += 4;
2338                                                                                 }
2339
2340                                                                                 if(IS_ENCODEDBY_UTF16(pExtContent+tmp) && (realCpyFrameNum > 2))
2341                                                                                 {
2342                                                                                         realCpyFrameNum -= 2;
2343                                                                                         tmp += 2;
2344                                                                                         textEncodingType = AV_ID3V2_UTF16;
2345                                                                                 }
2346                                                                                 else if (IS_ENCODEDBY_UTF16_R(pExtContent+tmp) && (realCpyFrameNum > 2))
2347                                                                                 {
2348                                                                                         realCpyFrameNum -= 2;
2349                                                                                         tmp += 2;
2350                                                                                         textEncodingType = AV_ID3V2_UTF16_BE;
2351                                                                                 }
2352                                                                                 else if(IS_ENCODEDBY_UTF16(pExtContent+tmp+1) && (realCpyFrameNum > 3))
2353                                                                                 {
2354                                                                                         realCpyFrameNum -= 3;
2355                                                                                         tmp += 3;
2356                                                                                         textEncodingType = AV_ID3V2_UTF16;
2357                                                                                 }
2358                                                                                 else if (IS_ENCODEDBY_UTF16_R(pExtContent+tmp+1)  && (realCpyFrameNum > 3))
2359                                                                                 {
2360                                                                                         realCpyFrameNum -= 3;
2361                                                                                         tmp += 3;
2362                                                                                         textEncodingType = AV_ID3V2_UTF16_BE;
2363                                                                                 }
2364                                                                                 else
2365                                                                                 {
2366                                                                                         #ifdef __MMFILE_TEST_MODE__
2367                                                                                         debug_msg ( "pInfo->pSyncLyrics Never Get Here!!\n");
2368                                                                                         #endif
2369                                                                                 }
2370                                                                         }
2371                                                                         else
2372                                                                         {
2373                                                                                 while((pExtContent[tmp] < 0x20) && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
2374                                                                                 {
2375                                                                                         realCpyFrameNum --;
2376                                                                                         tmp++;
2377                                                                                 }
2378                                                                                 textEncodingType = AV_ID3V2_ISO_8859;
2379                                                                         }
2380
2381                                                                         #ifdef __MMFILE_TEST_MODE__
2382                                                                         debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
2383                                                                         #endif
2384
2385                                                                         if(realCpyFrameNum < MMFILE_SYNC_LYRIC_INFO_MIN_LEN)
2386                                                                         {
2387                                                                                 #ifdef __MMFILE_TEST_MODE__
2388                                                                                 debug_msg ( "failed to get Synchronised lyrics Info realCpyFramNum(%d)\n", realCpyFrameNum);
2389                                                                                 #endif
2390                                                                                 pInfo->syncLyricsNum = 0;
2391                                                                         }
2392                                                                         else
2393                                                                         {
2394                                                                                 if(textEncodingType == AV_ID3V2_UTF16)
2395                                                                                 {
2396                                                                                         debug_warning ("[AV_ID3V2_UTF16] not implemented\n");
2397                                                                                 }
2398                                                                                 else if (textEncodingType == AV_ID3V2_UTF16_BE)
2399                                                                                 {
2400                                                                                         debug_warning ("[AV_ID3V2_UTF16_BE] not implemented\n");
2401                                                                                 }
2402                                                                                 else
2403                                                                                 {
2404                                                                                         for(idx = 0; idx < realCpyFrameNum; idx++)
2405                                                                                         {
2406                                                                                                 if(pExtContent[tmp+idx] == 0x00)
2407                                                                                                 {
2408                                                                                                         synclyrics_info = (AvSynclyricsInfo *)malloc(sizeof(AvSynclyricsInfo));
2409
2410                                                                                                         if(textEncodingType == AV_ID3V2_UTF8) {
2411                                                                                                                 synclyrics_info->lyric_info= mmfile_malloc(copy_len+1);
2412                                                                                                                 memset(synclyrics_info->lyric_info, 0, copy_len+1);
2413                                                                                                                 memcpy(synclyrics_info->lyric_info, pExtContent+copy_start_pos, copy_len);
2414                                                                                                                 synclyrics_info->lyric_info[copy_len+1] = '\0';
2415                                                                                                         }
2416                                                                                                         else {
2417                                                                                                                 synclyrics_info->lyric_info = mmfile_string_convert ((const char*)&pExtContent[copy_start_pos], copy_len, "UTF-8", locale, NULL, NULL);
2418                                                                                                         }
2419
2420                                                                                                         synclyrics_info->time_info= (unsigned long)pExtContent[tmp+idx+1] << 24 | (unsigned long)pExtContent[tmp+idx+2] << 16 | (unsigned long)pExtContent[tmp+idx+3] << 8  | (unsigned long)pExtContent[tmp+idx+4];
2421                                                                                                         idx += 4;
2422                                                                                                         copy_start_pos = tmp + idx + 1;
2423                                                                                                         debug_msg("[%d][%s] idx[%d], copy_len[%d] copy_start_pos[%d]", synclyrics_info->time_info, synclyrics_info->lyric_info, idx, copy_len, copy_start_pos);
2424                                                                                                         copy_len = 0;
2425                                                                                                         synclyrics_info_list = g_list_append(synclyrics_info_list, synclyrics_info);
2426                                                                                                 }
2427                                                                                                 copy_len ++;
2428                                                                                         }
2429                                                                                         pInfo->pSyncLyrics = synclyrics_info_list;
2430                                                                                         pInfo->syncLyricsNum = g_list_length(pInfo->pSyncLyrics);
2431                                                                                 }
2432                                                                         }
2433                                                                 }
2434                                                                 else
2435                                                                 {
2436                                                                         #ifdef __MMFILE_TEST_MODE__
2437                                                                         debug_msg ( "failed to get Synchronised lyrics Info tmp(%d), purelyFramelen - encodingOffSet(%d)\n", tmp, purelyFramelen - encodingOffSet);
2438                                                                         #endif
2439                                                                         pInfo->syncLyricsNum = 0;
2440                                                                 }
2441                                                         }
2442                                                         else
2443                                                         {
2444                                                                 #ifdef __MMFILE_TEST_MODE__
2445                                                                 debug_msg ( "Synchronised lyrics too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum);
2446                                                                 #endif
2447                                                                 pInfo->syncLyricsNum = 0;
2448                                                         }
2449                                                         tmp = 0;
2450
2451                                                         #ifdef __MMFILE_TEST_MODE__
2452                                                         debug_msg ( "pInfo->pSyncLyrics returned = (%s), pInfo->syncLyricsNum(%d)\n", pInfo->pSyncLyrics, pInfo->syncLyricsNum);
2453                                                         #endif
2454                                                         pInfo->tagV2Info.bSyncLyricsMarked = true;
2455                                                 }
2456                                                 else if(strncmp((char *)CompTmp, "USLT", 4) == 0 && pInfo->tagV2Info.bUnsyncLyricsMarked == false)
2457                                                 {
2458                                                         if(realCpyFrameNum > 3)
2459                                                         {
2460                                                                 realCpyFrameNum -= 3;
2461                                                                 tmp = 3;
2462
2463                                                                 //pExtContent[tmp+1] value should't have encoding value
2464                                                                 if(pExtContent[tmp] == 0x00 || pExtContent[tmp] == 0xFF|| pExtContent[tmp] == 0xFE)
2465                                                                 {
2466                                                                         if (pExtContent[tmp] == 0x00) {
2467                                                                                 realCpyFrameNum -= 2;
2468                                                                                 tmp = 5;
2469                                                                         }
2470
2471                                                                         if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
2472                                                                         {
2473                                                                                 while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
2474                                                                                 {
2475                                                                                         realCpyFrameNum -= 4;
2476                                                                                         tmp += 4;
2477                                                                                 }
2478
2479                                                                                 if(IS_ENCODEDBY_UTF16(pExtContent+tmp) && (realCpyFrameNum > 2))
2480                                                                                 {
2481                                                                                         realCpyFrameNum -= 2;
2482                                                                                         tmp += 2;
2483                                                                                         textEncodingType = AV_ID3V2_UTF16;
2484                                                                                 }
2485                                                                                 else if (IS_ENCODEDBY_UTF16_R(pExtContent+tmp) && (realCpyFrameNum > 2))
2486                                                                                 {
2487                                                                                         realCpyFrameNum -= 2;
2488                                                                                         tmp += 2;
2489                                                                                         textEncodingType = AV_ID3V2_UTF16_BE;
2490                                                                                 }
2491                                                                                 else if(IS_ENCODEDBY_UTF16(pExtContent+tmp+1) && (realCpyFrameNum > 3))
2492                                                                                 {
2493                                                                                         realCpyFrameNum -= 3;
2494                                                                                         tmp += 3;
2495                                                                                         textEncodingType = AV_ID3V2_UTF16;
2496                                                                                 }
2497                                                                                 else if (IS_ENCODEDBY_UTF16_R(pExtContent+tmp+1)  && (realCpyFrameNum > 3))
2498                                                                                 {
2499                                                                                         realCpyFrameNum -= 3;
2500                                                                                         tmp += 3;
2501                                                                                         textEncodingType = AV_ID3V2_UTF16_BE;
2502                                                                                 }
2503                                                                                 else
2504                                                                                 {
2505                                                                                         #ifdef __MMFILE_TEST_MODE__
2506                                                                                         debug_msg ( "pInfo->pUnsyncLyrics Never Get Here!!\n");
2507                                                                                         #endif
2508                                                                                 }
2509                                                                         }
2510                                                                         else
2511                                                                         {
2512                                                                                 while((pExtContent[tmp] < 0x20) && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
2513                                                                                 {
2514                                                                                         realCpyFrameNum --;
2515                                                                                         tmp++;
2516                                                                                 }
2517                                                                                 textEncodingType = AV_ID3V2_ISO_8859;
2518                                                                         }
2519
2520                                                                         #ifdef __MMFILE_TEST_MODE__
2521                                                                         debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
2522                                                                         #endif
2523
2524                                                                         if(textEncodingType == AV_ID3V2_UTF16)
2525                                                                         {
2526                                                                                 pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->unsynclyricsLen);
2527                                                                         }
2528                                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2529                                                                         {
2530                                                                                 debug_warning ("not implemented\n");
2531                                                                         }
2532                                                                         else
2533                                                                         {
2534                                                                                 pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->unsynclyricsLen);
2535                                                                         }
2536                                                                 }
2537                                                                 else
2538                                                                 {
2539                                                                         #ifdef __MMFILE_TEST_MODE__
2540                                                                         debug_msg ( "failed to get Unsynchronised lyrics Info tmp(%d), purelyFramelen - encodingOffSet(%d)\n", tmp, purelyFramelen - encodingOffSet);
2541                                                                         #endif
2542                                                                         pInfo->unsynclyricsLen = 0;
2543                                                                 }
2544                                                         }
2545                                                         else
2546                                                         {
2547                                                                 #ifdef __MMFILE_TEST_MODE__
2548                                                                 debug_msg ( "Unsynchronised lyrics too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum);
2549                                                                 #endif
2550                                                                 pInfo->unsynclyricsLen = 0;
2551                                                         }
2552                                                         tmp = 0;
2553
2554                                                         #ifdef __MMFILE_TEST_MODE__
2555                                                         debug_msg ( "pInfo->pUnsyncLyrics returned = (%s), pInfo->unsynclyricsLen(%d)\n", pInfo->pUnsyncLyrics, pInfo->unsynclyricsLen);
2556                                                         #endif
2557                                                         pInfo->tagV2Info.bUnsyncLyricsMarked = true;
2558                                                 }
2559                                                 else if(strncmp((char *)CompTmp, "TCON", 4) == 0 && pInfo->tagV2Info.bGenreMarked == false)
2560                                                 {
2561                                                         if(textEncodingType == AV_ID3V2_UTF16)
2562                                                         {
2563                                                                 pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->genreLen);
2564                                                         }
2565                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2566                                                         {
2567                                                                 debug_warning ("not implemented\n");
2568                                                         }
2569                                                         else
2570                                                         {
2571                                                                 pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->genreLen);
2572                                                         }
2573
2574                                                                 #ifdef __MMFILE_TEST_MODE__
2575                                                                         debug_msg ( "pInfo->pGenre returned = (%s), pInfo->genreLen(%d)\n", pInfo->pGenre, pInfo->genreLen);
2576                                                                 #endif
2577
2578                                                         if((pInfo->pGenre != NULL) && (pInfo->genreLen > 0)) {
2579                                                                 int ret = 0;
2580                                                                 int int_genre = -1;
2581
2582                                                                 ret = sscanf( pInfo->pGenre, "%d", &int_genre);
2583
2584                                                                 if(ret == 1) {
2585                                                                         #ifdef __MMFILE_TEST_MODE__
2586                                                                         debug_msg("genre information is inteager [%d]\n", int_genre);
2587                                                                         #endif
2588
2589                                                                         //Change int to string
2590                                                                         if((0 <= int_genre) && (int_genre < GENRE_COUNT-1)) {
2591                                                                                 /*save genreinfo like "(123)". mm_file_id3tag_restore_content_info convert it to string*/
2592                                                                                 char tmp_genre[6] = {0,};       /*ex. "(123)+NULL"*/
2593                                                                                 int tmp_genre_len = 0;
2594
2595                                                                                 memset (tmp_genre, 0, 6);
2596                                                                                 snprintf(tmp_genre, sizeof(tmp_genre), "(%d)", int_genre);
2597
2598                                                                                 tmp_genre_len = strlen(tmp_genre);
2599                                                                                 if(tmp_genre_len > 0) {
2600                                                                                         if(pInfo->pGenre) _FREE_EX(pInfo->pGenre);
2601                                                                                         pInfo->pGenre = mmfile_malloc (sizeof(char) * (tmp_genre_len + 1) );
2602                                                                                         if (pInfo->pGenre)
2603                                                                                         {
2604                                                                                                 strncpy(pInfo->pGenre, tmp_genre, tmp_genre_len);
2605                                                                                                 pInfo->pGenre[tmp_genre_len] = 0;
2606                                                                                         }
2607                                                                                 }
2608                                                                         }
2609                                                                 }
2610                                                         }
2611
2612                                                         pInfo->tagV2Info.bGenreMarked = true;
2613                                                 }
2614                                                 else if(strncmp((char *)CompTmp, "TRCK", 4) == 0 && pInfo->tagV2Info.bTrackNumMarked == false)
2615                                                 {
2616                                                         if(textEncodingType == AV_ID3V2_UTF16)
2617                                                         {
2618                                                                 pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->tracknumLen);
2619                                                         }
2620                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2621                                                         {
2622                                                                 debug_warning ("not implemented\n");
2623                                                         }
2624                                                         else
2625                                                         {
2626                                                                 pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->tracknumLen);
2627                                                         }
2628
2629                                                         #ifdef __MMFILE_TEST_MODE__
2630                                                         debug_msg ( "pInfo->pTrackNum returned = (%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
2631                                                         #endif
2632                                                         pInfo->tagV2Info.bTrackNumMarked = true;
2633                                                 }
2634                                                 else if(strncmp((char *)CompTmp, "TENC", 4) == 0 && pInfo->tagV2Info.bEncByMarked == false)
2635                                                 {
2636                                                         if(textEncodingType == AV_ID3V2_UTF16)
2637                                                         {
2638                                                                 pInfo->pEncBy = mmfile_string_convert ((char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->encbyLen);
2639                                                         }
2640                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2641                                                         {
2642                                                                 debug_warning ("not implemented\n");
2643                                                         }
2644                                                         else
2645                                                         {
2646                                                                 pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->encbyLen);
2647                                                         }
2648                                                         #ifdef __MMFILE_TEST_MODE__
2649                                                         debug_msg ( "pInfo->pEncBy returned = (%s), pInfo->encbyLen(%d)\n", pInfo->pEncBy, pInfo->encbyLen);
2650                                                         #endif
2651                                                         pInfo->tagV2Info.bEncByMarked = true;
2652                                                 }
2653                                                 else if(strncmp((char *)CompTmp, "WXXX", 4) == 0 && pInfo->tagV2Info.bURLMarked == false)
2654                                                 {
2655                                                         if(textEncodingType == AV_ID3V2_UTF16)
2656                                                         {
2657                                                                 pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->urlLen);
2658                                                         }
2659                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2660                                                         {
2661                                                                 debug_warning ("not implemented\n");
2662                                                         }
2663                                                         else
2664                                                         {
2665                                                                 pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->urlLen);
2666                                                         }
2667
2668                                                         #ifdef __MMFILE_TEST_MODE__
2669                                                         debug_msg ( "pInfo->pURL returned = (%s), pInfo->urlLen(%d)\n", pInfo->pURL, pInfo->urlLen);
2670                                                         #endif
2671                                                         pInfo->tagV2Info.bURLMarked = true;
2672                                                 }
2673                                                 else if(strncmp((char *)CompTmp, "TCOP", 4) == 0 && pInfo->tagV2Info.bCopyRightMarked == false)
2674                                                 {
2675                                                         if(textEncodingType == AV_ID3V2_UTF16)
2676                                                         {
2677                                                                 pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->copyrightLen);
2678                                                         }
2679                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2680                                                         {
2681                                                                 debug_warning ("not implemented\n");
2682                                                         }
2683                                                         else
2684                                                         {
2685                                                                 pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->copyrightLen);
2686                                                         }
2687
2688                                                         #ifdef __MMFILE_TEST_MODE__
2689                                                         debug_msg ( "pInfo->pCopyright returned = (%s), pInfo->copyrightLen(%d)\n", pInfo->pCopyright, pInfo->copyrightLen);
2690                                                         #endif
2691                                                         pInfo->tagV2Info.bCopyRightMarked = true;
2692                                                 }
2693                                                 else if(strncmp((char *)CompTmp, "TOPE", 4) == 0 && pInfo->tagV2Info.bOriginArtistMarked == false)
2694                                                 {
2695                                                         if(textEncodingType == AV_ID3V2_UTF16)
2696                                                         {
2697                                                                 pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->originartistLen);
2698                                                         }
2699                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2700                                                         {
2701                                                                 debug_warning ("not implemented\n");
2702                                                         }
2703                                                         else
2704                                                         {
2705                                                                 pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->originartistLen);
2706                                                         }
2707                                                         #ifdef __MMFILE_TEST_MODE__
2708                                                         debug_msg ( "pInfo->pOriginArtist returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pOriginArtist, pInfo->originartistLen);
2709                                                         #endif
2710                                                         pInfo->tagV2Info.bOriginArtistMarked = true;
2711                                                 }
2712                                                 else if(strncmp((char *)CompTmp, "TCOM", 4) == 0 && pInfo->tagV2Info.bComposerMarked == false)
2713                                                 {
2714                                                         if(textEncodingType == AV_ID3V2_UTF16)
2715                                                         {
2716                                                                 pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->composerLen);
2717                                                         }
2718                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2719                                                         {
2720                                                                 debug_warning ("not implemented\n");
2721                                                         }
2722                                                         else
2723                                                         {
2724                                                                 pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->composerLen);
2725                                                         }
2726
2727                                                         #ifdef __MMFILE_TEST_MODE__
2728                                                         debug_msg ( "pInfo->pComposer returned = (%s), pInfo->composerLen(%d)\n", pInfo->pComposer, pInfo->composerLen);
2729                                                         #endif
2730                                                         pInfo->tagV2Info.bComposerMarked = true;
2731                                                 }
2732                                                 else if(strncmp((char *)CompTmp, "TRDA", 4) == 0 && pInfo->tagV2Info.bRecDateMarked== false)
2733                                                 {
2734                                                         if(textEncodingType == AV_ID3V2_UTF16)
2735                                                         {
2736                                                                 pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->recdateLen);
2737                                                         }
2738                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
2739                                                         {
2740                                                                 debug_warning ("not implemented\n");
2741                                                         }
2742                                                         else
2743                                                         {
2744                                                                 pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->recdateLen);
2745                                                         }
2746                                                         #ifdef __MMFILE_TEST_MODE__
2747                                                         debug_msg ( "pInfo->pRecDate returned = (%s), pInfo->recdateLen(%d)\n", pInfo->pRecDate, pInfo->recdateLen);
2748                                                         #endif
2749                                                         pInfo->tagV2Info.bRecDateMarked = true;
2750                                                 }
2751                                                 else if(strncmp((char *)CompTmp, "APIC", 4) == 0 && pInfo->tagV2Info.bImageMarked == false && realCpyFrameNum <= 2000000)
2752                                                 {
2753                                                         if(textEncodingType == AV_ID3V2_UTF16)
2754                                                         {
2755                                                                 #ifdef __MMFILE_TEST_MODE__
2756                                                                 debug_msg ( "mmf_file_id3tag_parse_v223: this is abnormal case!!\n");
2757                                                                 #endif
2758
2759                                                         }
2760                                                         else
2761                                                         {
2762                                                                 if(pExtContent[0] != '\0')
2763                                                                 {
2764                                                                         for(inx = 0; inx < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1; inx++)
2765                                                                                 pInfo->imageInfo.imageMIMEType[inx] = '\0';//ini mimetype variable
2766
2767                                                                         while((checkImgMimeTypeMax < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1) && pExtContent[checkImgMimeTypeMax] != '\0')
2768                                                                         {
2769                                                                                 pInfo->imageInfo.imageMIMEType[checkImgMimeTypeMax] = pExtContent[checkImgMimeTypeMax];
2770                                                                                 checkImgMimeTypeMax++;
2771                                                                         }
2772                                                                         pInfo->imageInfo.imgMimetypeLen = checkImgMimeTypeMax;
2773                                                                 }
2774                                                                 else
2775                                                                 {
2776                                                                         pInfo->imageInfo.imgMimetypeLen = 0;
2777                                                                         #ifdef __MMFILE_TEST_MODE__
2778                                                                         debug_msg ( "APIC image's not included to MIME type\n");
2779                                                                         #endif
2780                                                                 }
2781
2782                                                                 imgstartOffset += checkImgMimeTypeMax;
2783
2784                                                                 if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
2785                                                                 {
2786                                                                         imgstartOffset++;//endofMIME(1byte)
2787                                                                         #ifdef __MMFILE_TEST_MODE__
2788                                                                         debug_msg ( "after scaning Mime type imgstartOffset(%d) value!\n", imgstartOffset);
2789                                                                         #endif
2790
2791                                                                         if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
2792                                                                         {
2793                                                                                 pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
2794                                                                         }
2795                                                                         else
2796                                                                         {
2797                                                                                 #ifdef __MMFILE_TEST_MODE__
2798                                                                                 debug_msg ( "APIC image has invalid picture type(0x%x)\n", pExtContent[imgstartOffset]);
2799                                                                                 #endif
2800                                                                         }
2801                                                                         imgstartOffset++;//PictureType(1byte)
2802                                                                         #ifdef __MMFILE_TEST_MODE__
2803                                                                         debug_msg ( "after scaning PictureType imgstartOffset(%d) value!\n", imgstartOffset);
2804                                                                         #endif
2805
2806                                                                         if(pExtContent[imgstartOffset] != 0x0)
2807                                                                         {
2808                                                                                 for(inx = 0; inx < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1; inx++)
2809                                                                                         pInfo->imageInfo.imageDescription[inx] = '\0';//ini imgdescripiton variable
2810
2811                                                                                 while((checkImgDescriptionMax < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1) && pExtContent[imgstartOffset+checkImgDescriptionMax] != '\0')
2812                                                                                 {
2813                                                                                         pInfo->imageInfo.imageDescription[checkImgDescriptionMax] = pExtContent[imgstartOffset+checkImgDescriptionMax];
2814                                                                                         checkImgDescriptionMax++;
2815                                                                                 }
2816                                                                                 pInfo->imageInfo.imgDesLen= checkImgDescriptionMax;
2817                                                                         }
2818                                                                         else
2819                                                                         {
2820                                                                                 pInfo->imageInfo.imgDesLen= 0;
2821                                                                                 #ifdef __MMFILE_TEST_MODE__
2822                                                                                 debug_msg ( "APIC image's not included to Description!!!\n");
2823                                                                                 #endif
2824                                                                         }
2825
2826                                                                         imgstartOffset += checkImgDescriptionMax;
2827                                                                         if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
2828                                                                         {
2829                                                                                 imgstartOffset ++; // endofDesceriptionType(1byte)
2830
2831                                                                                 while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
2832                                                                                 {
2833                                                                                         imgstartOffset ++;
2834                                                                                 }
2835
2836                                                                                 #ifdef __MMFILE_TEST_MODE__
2837                                                                                 debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
2838                                                                                 #endif
2839
2840                                                                                 if(realCpyFrameNum - imgstartOffset > 0)
2841                                                                                 {
2842                                                                                         pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
2843                                                                                         pInfo->imageInfo.pImageBuf = mmfile_malloc (pInfo->imageInfo.imageLen + 1);
2844                                                                                         memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
2845                                                                                         pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
2846                                                                                         if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
2847                                                                                                 pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
2848                                                                                 }
2849                                                                                 else
2850                                                                                 {
2851                                                                                         #ifdef __MMFILE_TEST_MODE__
2852                                                                                         debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
2853                                                                                         #endif
2854                                                                                 }
2855                                                                                 #ifdef __MMFILE_TEST_MODE__
2856                                                                                 debug_msg ( "pInfo->imageInfo.imageLen(%d), imgstartOffset(%d)!\n", pInfo->imageInfo.imageLen, imgstartOffset);
2857                                                                                 #endif
2858                                                                         }
2859                                                                         else
2860                                                                         {
2861                                                                                 #ifdef __MMFILE_TEST_MODE__
2862                                                                                 debug_msg ( "pExtContent[imgstartOffset](%d) value should setted NULL value for end of description! realCpyFrameNum - imgstartOffset(%d)\n",
2863                                                                                                         pExtContent[imgstartOffset], realCpyFrameNum - imgstartOffset);
2864                                                                                 #endif
2865                                                                         }
2866                                                                 }
2867                                                                 else
2868                                                                 {
2869                                                                         #ifdef __MMFILE_TEST_MODE__
2870                                                                         debug_msg ( "pExtContent[imgstartOffset](%d) value should setted NULL value for end of mimetype! realCpyFrameNum - imgstartOffset(%d)\n",
2871                                                                                         pExtContent[imgstartOffset], realCpyFrameNum - imgstartOffset);
2872                                                                         #endif
2873                                                                 }
2874
2875                                                         }
2876
2877                                                         checkImgMimeTypeMax = 0;
2878                                                         checkImgDescriptionMax = 0;
2879                                                         inx = 0;
2880                                                         imgstartOffset = 0;
2881                                                         pInfo->tagV2Info.bImageMarked= true;
2882
2883                                                 }
2884                                                 else
2885                                                 {
2886                                                         #ifdef __MMFILE_TEST_MODE__
2887                                                         debug_msg ( "CompTmp(%s) This Frame ID currently not Supports!!\n", CompTmp);
2888                                                         #endif
2889                                                 }
2890                                         }
2891
2892                                 }
2893                                 else
2894                                 {
2895                                         #ifdef __MMFILE_TEST_MODE__
2896                                         debug_msg ( "All of the pExtContent Values are NULL\n");
2897                                         #endif
2898                                 }
2899                         }
2900                         else
2901                         {
2902                                 curPos += purelyFramelen;
2903                                 if(purelyFramelen != 0)
2904                                         needToloopv2taglen = MP3_TAGv2_23_TXT_HEADER_LEN;
2905                                 #ifdef __MMFILE_TEST_MODE__
2906                                 debug_msg ( "This Frame's size is Zero! purelyFramelen(%d)\n", purelyFramelen);
2907                                 #endif
2908                         }
2909
2910                         if(pExtContent) _FREE_EX(pExtContent);
2911                         if(tmpConvert2Pcode)    _FREE_EX(tmpConvert2Pcode);
2912                         memset(CompTmp, 0, 4);
2913
2914                         if(curPos < taglen)
2915                         {
2916                                 needToloopv2taglen -= oneFrameLen;
2917                                 v2numOfFrames++;
2918                         }
2919                         else
2920                                 needToloopv2taglen = MP3_TAGv2_23_TXT_HEADER_LEN;
2921                         oneFrameLen = 0;
2922                         encodingOffSet = 0;
2923                         realCpyFrameNum = 0;
2924                         textEncodingType = 0;
2925                         purelyFramelen = 0;
2926
2927                 }
2928         }
2929
2930         if(taglen)
2931                 return true;
2932         else
2933                 return false;
2934
2935 }
2936
2937 EXPORT_API
2938 bool mm_file_id3tag_parse_v224(AvFileContentInfo* pInfo, unsigned char *buffer)
2939 {
2940         unsigned long taglen = 0;
2941         unsigned long needToloopv2taglen;
2942         unsigned long oneFrameLen = 0;
2943         unsigned long v2numOfFrames = 0;
2944         unsigned long curPos = 0;
2945         char CompTmp[5];
2946         unsigned char *pExtContent = NULL;
2947         unsigned long purelyFramelen = 0;
2948         char *tmpConvert2Pcode = NULL;
2949         int inx=0, encodingOffSet=0, realCpyFrameNum=0, checkImgMimeTypeMax=0, checkImgDescriptionMax=0, imgstartOffset=0,  tmp = 0;
2950         int textEncodingType = 0;
2951         const char *locale = NULL;
2952
2953         locale = MMFileUtilGetLocale (NULL);
2954
2955         pInfo->tagV2Info.bTitleMarked = false;
2956         pInfo->tagV2Info.bAlbumMarked= false;
2957         pInfo->tagV2Info.bArtistMarked= false;
2958         pInfo->tagV2Info.bDescriptionMarked= false;
2959         pInfo->tagV2Info.bGenreMarked= false;
2960         pInfo->tagV2Info.bYearMarked= false;
2961         pInfo->tagV2Info.bTrackNumMarked= false;
2962         pInfo->tagV2Info.bEncByMarked= false;
2963         pInfo->tagV2Info.bURLMarked= false;
2964         pInfo->tagV2Info.bCopyRightMarked= false;
2965         pInfo->tagV2Info.bOriginArtistMarked= false;
2966         pInfo->tagV2Info.bComposerMarked= false;
2967         pInfo->tagV2Info.bImageMarked= false;
2968         pInfo->imageInfo.bURLInfo = false;
2969         pInfo->tagV2Info.bConductorMarked = false;
2970         pInfo->tagV2Info.bGenreUTF16 = false;
2971         pInfo->tagV2Info.bUnsyncLyricsMarked = false;
2972         pInfo->tagV2Info.bSyncLyricsMarked = false;
2973
2974         pInfo->imageInfo.pImageBuf = NULL;
2975         pInfo->imageInfo.imageLen = 0;
2976
2977         taglen = pInfo->tagV2Info.tagLen;
2978         needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
2979         curPos = MP3_TAGv2_HEADER_LEN;
2980
2981 #ifdef __MMFILE_TEST_MODE__
2982         debug_msg ("ID3tag v224--------------------------------------------------------------\n");
2983 #endif
2984
2985         /* check Extended Header */
2986         if (buffer[5] & 0x40)
2987         {
2988                 /* if extended header exists, skip it*/
2989                 int extendedHeaderLen = (unsigned long)buffer[10] << 21 | (unsigned long)buffer[11] << 14 | (unsigned long)buffer[12] << 7  | (unsigned long)buffer[13];
2990
2991                 #ifdef __MMFILE_TEST_MODE__
2992                 debug_msg ("[%s][%d]--------------- extendedHeaderLen = %d\n",__func__,__LINE__, extendedHeaderLen);
2993                 #endif 
2994
2995                 curPos += extendedHeaderLen;
2996         }
2997
2998         if(needToloopv2taglen -MP3_TAGv2_23_TXT_HEADER_LEN > MP3_TAGv2_23_TXT_HEADER_LEN)
2999         {
3000                 v2numOfFrames = 1;
3001                 while(needToloopv2taglen > MP3_TAGv2_23_TXT_HEADER_LEN)
3002                 {
3003                         if((buffer[curPos] < '0' || buffer[curPos] > 'Z') || (buffer[curPos+1] < '0' || buffer[curPos+1] > 'Z')
3004                                 || (buffer[curPos+2] < '0' || buffer[curPos+2] > 'Z')|| (buffer[curPos+3] < '0' || buffer[curPos+3] > 'Z'))
3005                                 break;
3006
3007                         memcpy(CompTmp, &buffer[curPos], 4);
3008
3009                         CompTmp[4] = 0;
3010                         oneFrameLen = MP3_TAGv2_23_TXT_HEADER_LEN;
3011                         oneFrameLen += (unsigned long)buffer[4+curPos] << 21 | (unsigned long)buffer[5+curPos] << 14
3012                                 | (unsigned long)buffer[6+curPos] << 7 | (unsigned long)buffer[7+curPos];
3013                         if(oneFrameLen > taglen-curPos)
3014                                 break;
3015
3016                         purelyFramelen = oneFrameLen - MP3_TAGv2_23_TXT_HEADER_LEN;
3017                         curPos +=MP3_TAGv2_23_TXT_HEADER_LEN;
3018
3019 #ifdef __MMFILE_TEST_MODE__
3020                         debug_msg ("-----------------------------------------------------------------------------------\n");
3021 #endif
3022
3023                         if(oneFrameLen > MP3_TAGv2_23_TXT_HEADER_LEN && purelyFramelen <= taglen-curPos)
3024                         {
3025                                 curPos += purelyFramelen;
3026
3027                                 //in case of UTF 16 encoding
3028                                 //buffer+(curPos-purelyFramelen) data should '0x01' but in order to expansion, we don't accurately check the value.
3029                                 if(IS_ENCODEDBY_UTF16(buffer+(curPos-purelyFramelen)))
3030                                 {
3031                                         encodingOffSet = 2;
3032                                         textEncodingType = AV_ID3V2_UTF16;
3033                                 }
3034                                 else if (IS_ENCODEDBY_UTF16_R(buffer+(curPos-purelyFramelen)))
3035                                 {
3036                                         encodingOffSet = 2;
3037                                         textEncodingType = AV_ID3V2_UTF16_BE;
3038                                 }
3039                                 else if(IS_ENCODEDBY_UTF16(buffer+(curPos-purelyFramelen+1)))
3040                                 {
3041                                         encodingOffSet = 3;
3042                                         textEncodingType = AV_ID3V2_UTF16;
3043                                 }
3044                                 else if(IS_ENCODEDBY_UTF16_R(buffer+(curPos-purelyFramelen+1)))
3045                                 {
3046                                         encodingOffSet = 3;
3047                                         textEncodingType = AV_ID3V2_UTF16_BE;
3048                                 }
3049                                 else
3050                                 {
3051                                         //in case of UTF-16 BE encoding
3052                                         if(buffer[curPos-purelyFramelen] == 0x02)
3053                                         {
3054                                                 encodingOffSet = 1;
3055                                                 while((buffer[curPos-purelyFramelen+encodingOffSet] == '\0') && (encodingOffSet < purelyFramelen))
3056                                                         encodingOffSet++;//null skip!
3057                                                 textEncodingType = AV_ID3V2_UTF16_BE;
3058                                         }
3059                                         //in case of UTF8 encoding
3060                                         else if (buffer[curPos-purelyFramelen] == 0x03)
3061                                         {
3062                                                 encodingOffSet = 1;
3063                                                 while((buffer[curPos-purelyFramelen+encodingOffSet] == '\0') && (encodingOffSet < purelyFramelen))
3064                                                         encodingOffSet++;//null skip!
3065                                                 textEncodingType = AV_ID3V2_UTF8;
3066                                         }
3067                                         //in case of ISO-8859-1 encoding
3068                                         else
3069                                         {
3070                                                 //buffer+(curPos-purelyFramelen) data should 0x00 but in order to expansion, we don't accurately check the value.
3071                                                 encodingOffSet = 1;
3072                                                 while((buffer[curPos-purelyFramelen+encodingOffSet] < 0x20) && (encodingOffSet < purelyFramelen))
3073                                                         encodingOffSet++;//less than 0x20 value skip!
3074                                                 textEncodingType = AV_ID3V2_ISO_8859;
3075                                         }
3076                                 }
3077
3078                                 if(encodingOffSet < purelyFramelen)
3079                                 {
3080                                         realCpyFrameNum = purelyFramelen - encodingOffSet;
3081                                         pExtContent = mmfile_malloc (realCpyFrameNum+3);
3082                                         memset(pExtContent, '\0', realCpyFrameNum+3);
3083                                         if(textEncodingType == AV_ID3V2_ISO_8859)
3084                                         {
3085                                                 if(strncmp((char *)CompTmp, "APIC", 4) != 0)
3086                                                 {
3087                                                         tmpConvert2Pcode = mmfile_malloc ((realCpyFrameNum)*2+2);
3088                                                         memset(tmpConvert2Pcode, 0, (realCpyFrameNum)*2+2);
3089                                                 }
3090                                         }
3091
3092                                         memcpy(pExtContent, &buffer[curPos-purelyFramelen+encodingOffSet], purelyFramelen-encodingOffSet);
3093
3094                                         if(realCpyFrameNum > 0)
3095                                         {
3096                                                 if(strncmp((char *)CompTmp, "TIT2", 4) == 0 && pInfo->tagV2Info.bTitleMarked == false)
3097                                                 {
3098                                                         if(textEncodingType == AV_ID3V2_UTF16)
3099                                                         {
3100                                                                 pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->titleLen);
3101                                                         }
3102                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3103                                                         {
3104                                                                 debug_warning ("not implemented\n");
3105                                                         }
3106                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3107                                                         {
3108                                                                 pInfo->pTitle= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3109                                                                 memcpy(pInfo->pTitle, pExtContent, realCpyFrameNum);
3110                                                                 pInfo->pTitle[realCpyFrameNum] = '\0';
3111                                                                 /*string copy with '\0'*/
3112                                                                 pInfo->titleLen = realCpyFrameNum;
3113                                                                 _STRNCPY_EX (pInfo->pTitle, pExtContent, pInfo->titleLen);
3114                                                         }
3115                                                         else
3116                                                         {
3117                                                                 pInfo->pTitle = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->titleLen);
3118                                                         }
3119
3120                                                         #ifdef __MMFILE_TEST_MODE__
3121                                                         debug_msg ( "pInfo->pTitle returned = (%s), pInfo->titleLen(%d)\n", pInfo->pTitle, pInfo->titleLen);
3122                                                         #endif
3123                                                         pInfo->tagV2Info.bTitleMarked = true;
3124
3125                                                 }
3126                                                 else if(strncmp((char *)CompTmp, "TPE1", 4) == 0 && pInfo->tagV2Info.bArtistMarked == false)
3127                                                 {
3128                                                         if(textEncodingType == AV_ID3V2_UTF16)
3129                                                         {
3130                                                                 pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->artistLen);
3131                                                         }
3132                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3133                                                         {
3134                                                                 debug_warning ("not implemented\n");
3135                                                         }
3136                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3137                                                         {
3138                                                                 pInfo->pArtist= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3139                                                                 memcpy(pInfo->pArtist, pExtContent, realCpyFrameNum);
3140                                                                 pInfo->pArtist[realCpyFrameNum] = '\0';
3141                                                                 /*string copy with '\0'*/
3142                                                                 pInfo->artistLen = realCpyFrameNum;
3143                                                                 _STRNCPY_EX (pInfo->pArtist, pExtContent, pInfo->artistLen);
3144                                                         }
3145                                                         else
3146                                                         {
3147                                                                 pInfo->pArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->artistLen);
3148                                                         }
3149
3150                                                         #ifdef __MMFILE_TEST_MODE__
3151                                                         debug_msg ( "pInfo->pArtist returned = (%s), pInfo->artistLen(%d)\n", pInfo->pArtist, pInfo->artistLen);
3152                                                         #endif
3153                                                         pInfo->tagV2Info.bArtistMarked = true;
3154                                                 }
3155                                                 else if(strncmp((char *)CompTmp, "TPE3", 4) == 0 && pInfo->tagV2Info.bConductorMarked == false)
3156                                                 {
3157                                                         if(textEncodingType == AV_ID3V2_UTF16)
3158                                                         {
3159                                                                 pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->conductorLen);
3160                                                         }
3161                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3162                                                         {
3163                                                                 debug_warning ("not implemented\n");
3164                                                         }
3165                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3166                                                         {
3167                                                                 pInfo->pConductor= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3168                                                                 memcpy(pInfo->pConductor, pExtContent, realCpyFrameNum);
3169                                                                 pInfo->pConductor[realCpyFrameNum] = '\0';
3170                                                                 /*string copy with '\0'*/
3171                                                                 pInfo->conductorLen = realCpyFrameNum;
3172                                                                 _STRNCPY_EX (pInfo->pConductor, pExtContent, pInfo->conductorLen);
3173                                                         }
3174                                                         else
3175                                                         {
3176                                                                 pInfo->pConductor = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->conductorLen);
3177                                                         }
3178
3179                                                         #ifdef __MMFILE_TEST_MODE__
3180                                                         debug_msg ( "pInfo->pConductor returned = (%s), pInfo->conductorLen(%d)\n", pInfo->pConductor, pInfo->conductorLen);
3181                                                         #endif
3182                                                         pInfo->tagV2Info.bConductorMarked = true;
3183                                                 }
3184                                                 else if(strncmp((char *)CompTmp, "TALB", 4) == 0 && pInfo->tagV2Info.bAlbumMarked == false)
3185                                                 {
3186                                                         if(textEncodingType == AV_ID3V2_UTF16)
3187                                                         {
3188                                                                 pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->albumLen);
3189                                                         }
3190                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3191                                                         {
3192                                                                 debug_warning ("not implemented\n");
3193                                                         }
3194                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3195                                                         {
3196                                                                 pInfo->pAlbum= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3197                                                                 memcpy(pInfo->pAlbum, pExtContent, realCpyFrameNum);
3198                                                                 pInfo->pAlbum[realCpyFrameNum] = '\0';
3199                                                                 /*string copy with '\0'*/
3200                                                                 pInfo->albumLen = realCpyFrameNum;
3201                                                                 _STRNCPY_EX (pInfo->pAlbum, pExtContent, pInfo->albumLen);
3202                                                         }
3203                                                         else
3204                                                         {
3205                                                                 pInfo->pAlbum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->albumLen);
3206                                                         }
3207
3208                                                         #ifdef __MMFILE_TEST_MODE__
3209                                                         debug_msg ( "pInfo->pAlbum returned = (%s), pInfo->albumLen(%d)\n", pInfo->pAlbum, pInfo->albumLen);
3210                                                         #endif
3211                                                         pInfo->tagV2Info.bAlbumMarked = true;
3212                                                 }
3213                                                 else if(strncmp((char *)CompTmp, "TYER", 4) == 0 && pInfo->tagV2Info.bYearMarked == false)      //TODO. TYER is replaced by the TDRC. but many files use TYER in v2.4
3214                                                 {
3215                                                         if(textEncodingType == AV_ID3V2_UTF16)
3216                                                         {
3217                                                                 pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->yearLen);
3218                                                         }
3219                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
3220                                                         {
3221                                                                 debug_warning ("not implemented\n");
3222                                                         }
3223                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3224                                                         {
3225                                                                 pInfo->pYear= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3226                                                                 memcpy(pInfo->pYear, pExtContent, realCpyFrameNum);
3227                                                                 pInfo->pYear[realCpyFrameNum] = '\0';
3228                                                                 /*string copy with '\0'*/
3229                                                                 pInfo->yearLen = realCpyFrameNum;
3230                                                                 _STRNCPY_EX (pInfo->pYear, pExtContent, pInfo->yearLen);
3231                                                         }
3232                                                         else
3233                                                         {
3234                                                                 pInfo->pYear = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->yearLen);
3235                                                         }
3236
3237                                                         #ifdef __MMFILE_TEST_MODE__
3238                                                         debug_msg ( "pInfo->pYear returned = (%s), pInfo->yearLen(%d)\n", pInfo->pYear, pInfo->yearLen);
3239                                                         #endif
3240                                                         pInfo->tagV2Info.bYearMarked = true;
3241                                                 }
3242                                                 else if(strncmp((char *)CompTmp, "COMM", 4) == 0 && pInfo->tagV2Info.bDescriptionMarked == false)
3243                                                 {
3244                                                         if(realCpyFrameNum > 3)
3245                                                         {
3246                                                                 realCpyFrameNum -= 3;
3247                                                                 tmp = 3;
3248
3249                                                                 if(textEncodingType == AV_ID3V2_UTF16 || textEncodingType == AV_ID3V2_UTF16_BE)
3250                                                                 {
3251                                                                         while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
3252                                                                         {
3253                                                                                 realCpyFrameNum -= 4;
3254                                                                                 tmp += 4;
3255                                                                         }
3256
3257                                                                         if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
3258                                                                         {
3259                                                                                 realCpyFrameNum -= 2;
3260                                                                                 tmp += 2;
3261                                                                                 textEncodingType = AV_ID3V2_UTF16;
3262                                                                         }
3263                                                                         else
3264                                                                         {
3265                                                                                 #ifdef __MMFILE_TEST_MODE__
3266                                                                                 debug_msg ( "pInfo->pComment Never Get Here!!\n");
3267                                                                                 #endif
3268                                                                         }
3269                                                                 }
3270                                                                 else if(textEncodingType == AV_ID3V2_UTF8)
3271                                                                 {
3272                                                                         while(pExtContent[tmp] < 0x20 && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
3273                                                                         {
3274                                                                                 realCpyFrameNum --;
3275                                                                                 tmp++;
3276                                                                         }
3277                                                                         textEncodingType = AV_ID3V2_UTF8;
3278                                                                 }
3279                                                                 else
3280                                                                 {
3281                                                                         while(pExtContent[tmp] < 0x20 && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
3282                                                                         {
3283                                                                                 realCpyFrameNum --;
3284                                                                                 tmp++;
3285                                                                         }
3286                                                                         textEncodingType = AV_ID3V2_ISO_8859;
3287                                                                 }
3288
3289                                                                 #ifdef __MMFILE_TEST_MODE__
3290                                                                 debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
3291                                                                 #endif
3292
3293                                                                 if(textEncodingType == AV_ID3V2_UTF16)
3294                                                                 {
3295                                                                         pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->commentLen);
3296                                                                 }
3297                                                                 else if(textEncodingType == AV_ID3V2_UTF16_BE)
3298                                                                 {
3299                                                                         debug_warning ("not implemented\n");
3300                                                                 }
3301                                                                 else if(textEncodingType == AV_ID3V2_UTF8)
3302                                                                 {
3303                                                                         pInfo->pComment= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3304                                                                         memset(pInfo->pComment, 0, (realCpyFrameNum+2));
3305                                                                         memcpy(pInfo->pComment, pExtContent+tmp, realCpyFrameNum);
3306                                                                         pInfo->pComment[realCpyFrameNum] = '\0';
3307                                                                         /*string copy with '\0'*/
3308                                                                         pInfo->commentLen = realCpyFrameNum;
3309                                                                         _STRNCPY_EX (pInfo->pComment, pExtContent, pInfo->commentLen);
3310                                                                 }
3311                                                                 else
3312                                                                 {
3313                                                                         pInfo->pComment = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->commentLen);
3314                                                                 }
3315                                                         }
3316                                                         else
3317                                                         {
3318                                                                 #ifdef __MMFILE_TEST_MODE__
3319                                                                 debug_msg (  "Description info too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum);
3320                                                                 #endif
3321                                                         }
3322
3323                                                         tmp = 0;
3324
3325                                                         #ifdef __MMFILE_TEST_MODE__
3326                                                         debug_msg ( "pInfo->pComment returned = (%s), pInfo->commentLen(%d)\n", pInfo->pComment, pInfo->commentLen);
3327                                                         #endif
3328                                                         pInfo->tagV2Info.bDescriptionMarked = true;
3329                                                 }
3330                                                 else if(strncmp((char *)CompTmp, "SYLT", 4) == 0 && pInfo->tagV2Info.bSyncLyricsMarked == false)
3331                                                 {
3332                                                         int idx = 0;
3333                                                         int copy_len = 0;
3334                                                         int copy_start_pos = tmp;
3335                                                         AvSynclyricsInfo *synclyrics_info = NULL;
3336                                                         GList *synclyrics_info_list = NULL;
3337                                                         
3338                                                         if(realCpyFrameNum > 5)
3339                                                         {
3340                                                                 realCpyFrameNum -= 5;
3341                                                                 tmp = 5;
3342
3343                                                                 if(textEncodingType == AV_ID3V2_UTF16 || textEncodingType == AV_ID3V2_UTF16_BE)
3344                                                                 {
3345                                                                         while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
3346                                                                         {
3347                                                                                 realCpyFrameNum -= 4;
3348                                                                                 tmp += 4;
3349                                                                         }
3350
3351                                                                         if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
3352                                                                         {
3353                                                                                 realCpyFrameNum -= 2;
3354                                                                                 tmp += 2;
3355                                                                                 textEncodingType = AV_ID3V2_UTF16;
3356                                                                         }
3357                                                                         else
3358                                                                         {
3359                                                                                 #ifdef __MMFILE_TEST_MODE__
3360                                                                                 debug_msg ( "pInfo->pSyncLyrics Never Get Here!!\n");
3361                                                                                 #endif
3362                                                                         }
3363                                                                 }
3364                                                                 else if(textEncodingType == AV_ID3V2_UTF8)
3365                                                                 {
3366                                                                         while(pExtContent[tmp] < 0x20 && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
3367                                                                         {
3368                                                                                 realCpyFrameNum --;
3369                                                                                 tmp++;
3370                                                                         }
3371                                                                         textEncodingType = AV_ID3V2_UTF8;
3372                                                                 }
3373                                                                 else
3374                                                                 {
3375                                                                         while(pExtContent[tmp] < 0x20 && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
3376                                                                         {
3377                                                                                 realCpyFrameNum --;
3378                                                                                 tmp++;
3379                                                                         }
3380                                                                         textEncodingType = AV_ID3V2_ISO_8859;
3381                                                                 }
3382
3383                                                                 #ifdef __MMFILE_TEST_MODE__
3384                                                                 debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
3385                                                                 #endif
3386
3387                                                                 if(realCpyFrameNum < MMFILE_SYNC_LYRIC_INFO_MIN_LEN)
3388                                                                 {
3389                                                                         #ifdef __MMFILE_TEST_MODE__
3390                                                                         debug_msg ( "failed to get Synchronised lyrics Info realCpyFramNum(%d)\n", realCpyFrameNum);
3391                                                                         #endif
3392                                                                         pInfo->syncLyricsNum = 0;
3393                                                                 }
3394                                                                 else
3395                                                                 {
3396                                                                         if(textEncodingType == AV_ID3V2_UTF16)
3397                                                                         {
3398                                                                                 debug_warning ("[AV_ID3V2_UTF16] not implemented\n");
3399                                                                         }
3400                                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3401                                                                         {
3402                                                                                 debug_warning ("[AV_ID3V2_UTF16_BE] not implemented\n");
3403                                                                         }
3404                                                                         else
3405                                                                         {
3406                                                                                 for(idx = 0; idx < realCpyFrameNum; idx++)
3407                                                                                 {
3408                                                                                         if(pExtContent[tmp+idx] == 0x00)
3409                                                                                         {
3410                                                                                                 synclyrics_info = (AvSynclyricsInfo *)malloc(sizeof(AvSynclyricsInfo));
3411
3412                                                                                                 if(textEncodingType == AV_ID3V2_UTF8) {
3413                                                                                                         synclyrics_info->lyric_info= mmfile_malloc(copy_len+1);
3414                                                                                                         memset(synclyrics_info->lyric_info, 0, copy_len+1);
3415                                                                                                         memcpy(synclyrics_info->lyric_info, pExtContent+copy_start_pos, copy_len);
3416                                                                                                         synclyrics_info->lyric_info[copy_len+1] = '\0';
3417                                                                                                 }
3418                                                                                                 else {
3419                                                                                                         synclyrics_info->lyric_info = mmfile_string_convert ((const char*)&pExtContent[copy_start_pos], copy_len, "UTF-8", locale, NULL, NULL);
3420                                                                                                 }
3421
3422                                                                                                 synclyrics_info->time_info= (unsigned long)pExtContent[tmp+idx+1] << 24 | (unsigned long)pExtContent[tmp+idx+2] << 16 | (unsigned long)pExtContent[tmp+idx+3] << 8  | (unsigned long)pExtContent[tmp+idx+4];
3423                                                                                                 idx += 4;
3424                                                                                                 copy_start_pos = tmp + idx + 1;
3425                                                                                                 #ifdef __MMFILE_TEST_MODE__
3426                                                                                                 debug_msg("[%d][%s] idx[%d], copy_len[%d] copy_start_pos[%d]", synclyrics_info->time_info, synclyrics_info->lyric_info, idx, copy_len, copy_start_pos);
3427                                                                                                 #endif
3428                                                                                                 copy_len = 0;
3429                                                                                                 synclyrics_info_list = g_list_append(synclyrics_info_list, synclyrics_info);
3430                                                                                         }
3431                                                                                         copy_len ++;
3432                                                                                 }
3433                                                                                 pInfo->pSyncLyrics = synclyrics_info_list;
3434                                                                                 pInfo->syncLyricsNum = g_list_length(pInfo->pSyncLyrics);
3435                                                                         }
3436                                                                 }
3437                                                         }
3438                                                         else
3439                                                         {
3440                                                                 #ifdef __MMFILE_TEST_MODE__
3441                                                                 debug_msg (  "SyncLyrics info too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum);
3442                                                                 #endif
3443                                                         }
3444
3445                                                         tmp = 0;
3446                                                         pInfo->tagV2Info.bSyncLyricsMarked = true;
3447                                                 }
3448                                                 else if(strncmp((char *)CompTmp, "USLT", 4) == 0 && pInfo->tagV2Info.bUnsyncLyricsMarked == false)
3449                                                 {
3450                                                         if(realCpyFrameNum > 3)
3451                                                         {
3452                                                                 realCpyFrameNum -= 3;
3453                                                                 tmp = 3;
3454
3455                                                                 if(textEncodingType == AV_ID3V2_UTF16 || textEncodingType == AV_ID3V2_UTF16_BE)
3456                                                                 {
3457                                                                         while((NEWLINE_OF_UTF16(pExtContent + tmp) || NEWLINE_OF_UTF16_R(pExtContent + tmp))&& realCpyFrameNum > 4)
3458                                                                         {
3459                                                                                 realCpyFrameNum -= 4;
3460                                                                                 tmp += 4;
3461                                                                         }
3462
3463                                                                         if((IS_ENCODEDBY_UTF16(pExtContent+tmp) || IS_ENCODEDBY_UTF16_R(pExtContent+tmp)) && realCpyFrameNum > 2)
3464                                                                         {
3465                                                                                 realCpyFrameNum -= 2;
3466                                                                                 tmp += 2;
3467                                                                                 textEncodingType = AV_ID3V2_UTF16;
3468                                                                         }
3469                                                                         else
3470                                                                         {
3471                                                                                 #ifdef __MMFILE_TEST_MODE__
3472                                                                                 debug_msg ( "pInfo->pUnsyncLyrics Never Get Here!!\n");
3473                                                                                 #endif
3474                                                                         }
3475                                                                 }
3476                                                                 else if(textEncodingType == AV_ID3V2_UTF8)
3477                                                                 {
3478                                                                         while(pExtContent[tmp] < 0x20 && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
3479                                                                         {
3480                                                                                 realCpyFrameNum --;
3481                                                                                 tmp++;
3482                                                                         }
3483                                                                         textEncodingType = AV_ID3V2_UTF8;
3484                                                                 }
3485                                                                 else
3486                                                                 {
3487                                                                         while(pExtContent[tmp] < 0x20 && (tmp < realCpyFrameNum)) // text string encoded by ISO-8859-1
3488                                                                         {
3489                                                                                 realCpyFrameNum --;
3490                                                                                 tmp++;
3491                                                                         }
3492                                                                         textEncodingType = AV_ID3V2_ISO_8859;
3493                                                                 }
3494
3495                                                                 #ifdef __MMFILE_TEST_MODE__
3496                                                                 debug_msg ( "tmp(%d) textEncodingType(%d), realCpyFrameNum(%d)\n", tmp, textEncodingType, realCpyFrameNum);
3497                                                                 #endif
3498
3499                                                                 if(textEncodingType == AV_ID3V2_UTF16)
3500                                                                 {
3501                                                                         pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->unsynclyricsLen);
3502                                                                 }
3503                                                                 else if(textEncodingType == AV_ID3V2_UTF16_BE)
3504                                                                 {
3505                                                                         debug_warning ("not implemented\n");
3506                                                                 }
3507                                                                 else if(textEncodingType == AV_ID3V2_UTF8)
3508                                                                 {
3509                                                                         pInfo->pUnsyncLyrics= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3510                                                                         memset(pInfo->pUnsyncLyrics, 0, (realCpyFrameNum+2));
3511                                                                         memcpy(pInfo->pUnsyncLyrics, pExtContent+tmp, realCpyFrameNum);
3512                                                                         pInfo->pUnsyncLyrics[realCpyFrameNum] = '\0';
3513                                                                         /*string copy with '\0'*/
3514                                                                         pInfo->unsynclyricsLen = realCpyFrameNum;
3515                                                                         _STRNCPY_EX (pInfo->pUnsyncLyrics, pExtContent, pInfo->unsynclyricsLen);
3516                                                                 }
3517                                                                 else
3518                                                                 {
3519                                                                         pInfo->pUnsyncLyrics = mmfile_string_convert ((const char*)&pExtContent[tmp], realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->unsynclyricsLen);
3520                                                                 }
3521                                                         }
3522                                                         else
3523                                                         {
3524                                                                 #ifdef __MMFILE_TEST_MODE__
3525                                                                 debug_msg (  "Description info too small to parse realCpyFrameNum(%d)\n", realCpyFrameNum);
3526                                                                 #endif
3527                                                         }
3528
3529                                                         tmp = 0;
3530
3531                                                         #ifdef __MMFILE_TEST_MODE__
3532                                                         debug_msg ( "pInfo->pUnsyncLyrics returned = (%s), pInfo->unsynclyricsLen(%d)\n", pInfo->pUnsyncLyrics, pInfo->unsynclyricsLen);
3533                                                         #endif
3534                                                         pInfo->tagV2Info.bDescriptionMarked = true;
3535                                                 }
3536                                                 else if(strncmp((char *)CompTmp, "TCON", 4) == 0 && pInfo->tagV2Info.bGenreMarked == false)
3537                                                 {
3538                                                         if(textEncodingType == AV_ID3V2_UTF16)
3539                                                         {
3540                                                                 pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->genreLen);
3541                                                         }
3542                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3543                                                         {
3544                                                                 debug_warning ("not implemented\n");
3545                                                         }
3546                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3547                                                         {
3548                                                                 pInfo->pGenre= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3549                                                                 memcpy(pInfo->pGenre, pExtContent, realCpyFrameNum);
3550                                                                 pInfo->pGenre[realCpyFrameNum] = '\0';
3551                                                                 /*string copy with '\0'*/
3552                                                                 pInfo->genreLen = realCpyFrameNum;
3553                                                                 _STRNCPY_EX (pInfo->pGenre, pExtContent, pInfo->genreLen);
3554                                                         }
3555                                                         else
3556                                                         {
3557                                                                 pInfo->pGenre = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->genreLen);
3558                                                         }
3559
3560                                                         #ifdef __MMFILE_TEST_MODE__
3561                                                         debug_msg ( "pInfo->pGenre returned = (%s), pInfo->genreLen(%d)\n", pInfo->pGenre, pInfo->genreLen);
3562                                                         #endif
3563
3564                                                         if((pInfo->pGenre != NULL) && (pInfo->genreLen > 0)) {
3565                                                                 int ret = 0;
3566                                                                 int int_genre = -1;
3567
3568                                                                 ret = sscanf( pInfo->pGenre, "%d", &int_genre);
3569
3570                                                                 if(ret == 1) {
3571                                                                         #ifdef __MMFILE_TEST_MODE__
3572                                                                         debug_msg("genre information is inteager [%d]\n", int_genre);
3573                                                                         #endif
3574
3575                                                                         //Change int to string
3576                                                                         if((0 <= int_genre) && (int_genre < GENRE_COUNT-1)) {
3577                                                                                 /*save genreinfo like "(123)". mm_file_id3tag_restore_content_info convert it to string*/
3578                                                                                 char tmp_genre[6] = {0,};       /*ex. "(123)+NULL"*/
3579                                                                                 int tmp_genre_len = 0;
3580
3581                                                                                 memset (tmp_genre, 0, 6);
3582                                                                                 snprintf(tmp_genre, sizeof(tmp_genre), "(%d)", int_genre);
3583
3584                                                                                 tmp_genre_len = strlen(tmp_genre);
3585                                                                                 if(tmp_genre_len > 0) {
3586                                                                                         if(pInfo->pGenre) _FREE_EX(pInfo->pGenre);
3587                                                                                         pInfo->pGenre = mmfile_malloc (sizeof(char) * (tmp_genre_len + 1) );
3588                                                                                         if (pInfo->pGenre)
3589                                                                                         {
3590                                                                                                 strncpy(pInfo->pGenre, tmp_genre, tmp_genre_len);
3591                                                                                                 pInfo->pGenre[tmp_genre_len] = 0;
3592                                                                                         }
3593                                                                                 }
3594                                                                         }
3595                                                                 }
3596                                                         }
3597
3598                                                         pInfo->tagV2Info.bGenreMarked = true;
3599                                                 }
3600                                                 else if(strncmp((char *)CompTmp, "TRCK", 4) == 0 && pInfo->tagV2Info.bTrackNumMarked == false)
3601                                                 {
3602                                                         if(textEncodingType == AV_ID3V2_UTF16)
3603                                                         {
3604                                                                 pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->tracknumLen);
3605                                                         }
3606                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3607                                                         {
3608                                                                 debug_warning ("not implemented\n");
3609                                                         }
3610                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3611                                                         {
3612                                                                 pInfo->pTrackNum= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3613                                                                 memcpy(pInfo->pTrackNum, pExtContent, realCpyFrameNum);
3614                                                                 pInfo->pTrackNum[realCpyFrameNum] = '\0';
3615                                                                 /*string copy with '\0'*/
3616                                                                 pInfo->tracknumLen = realCpyFrameNum;
3617                                                                 _STRNCPY_EX (pInfo->pTrackNum, pExtContent, pInfo->tracknumLen);
3618                                                         }
3619                                                         else
3620                                                         {
3621                                                                 pInfo->pTrackNum = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->tracknumLen);
3622                                                         }
3623
3624
3625                                                         #ifdef __MMFILE_TEST_MODE__
3626                                                         debug_msg ( "pInfo->pTrackNum returned = (%s), pInfo->tracknumLen(%d)\n", pInfo->pTrackNum, pInfo->tracknumLen);
3627                                                         #endif
3628                                                         pInfo->tagV2Info.bTrackNumMarked = true;
3629                                                 }
3630                                                 else if(strncmp((char *)CompTmp, "TENC", 4) == 0 && pInfo->tagV2Info.bEncByMarked == false)
3631                                                 {
3632                                                         if(textEncodingType == AV_ID3V2_UTF16)
3633                                                         {
3634                                                                 pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->encbyLen);
3635                                                         }
3636                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3637                                                         {
3638                                                                 debug_warning ("not implemented\n");
3639                                                         }
3640                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3641                                                         {
3642                                                                 pInfo->pEncBy= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3643                                                                 memcpy(pInfo->pEncBy, pExtContent, realCpyFrameNum);
3644                                                                 pInfo->pEncBy[realCpyFrameNum] = '\0';
3645                                                                 /*string copy with '\0'*/
3646                                                                 pInfo->encbyLen = realCpyFrameNum;
3647                                                                 _STRNCPY_EX (pInfo->pEncBy, pExtContent, pInfo->encbyLen);
3648                                                         }
3649                                                         else
3650                                                         {
3651                                                                 pInfo->pEncBy = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->encbyLen);
3652                                                         }
3653
3654                                                         #ifdef __MMFILE_TEST_MODE__
3655                                                         debug_msg ( "pInfo->pEncBy returned = (%s), pInfo->encbyLen(%d)\n", pInfo->pEncBy, pInfo->encbyLen);
3656                                                         #endif
3657                                                         pInfo->tagV2Info.bEncByMarked = true;
3658                                                 }
3659                                                 else if(strncmp((char *)CompTmp, "WXXX", 4) == 0 && pInfo->tagV2Info.bURLMarked == false)
3660                                                 {
3661                                                         if(textEncodingType == AV_ID3V2_UTF16)
3662                                                         {
3663                                                                 pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->urlLen);
3664                                                         }
3665                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
3666                                                         {
3667                                                                 debug_warning ("not implemented\n");
3668                                                         }
3669                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3670                                                         {
3671                                                                 pInfo->pURL= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3672                                                                 memcpy(pInfo->pURL, pExtContent, realCpyFrameNum);
3673                                                                 pInfo->pURL[realCpyFrameNum] = '\0';
3674                                                                 /*string copy with '\0'*/
3675                                                                 pInfo->urlLen = realCpyFrameNum;
3676                                                                 _STRNCPY_EX (pInfo->pURL, pExtContent, pInfo->urlLen);
3677                                                         }
3678                                                         else
3679                                                         {
3680                                                                 pInfo->pURL = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->urlLen);
3681                                                         }
3682
3683                                                         #ifdef __MMFILE_TEST_MODE__
3684                                                         debug_msg ( "pInfo->pURL returned = (%s), pInfo->urlLen(%d)\n", pInfo->pURL, pInfo->urlLen);
3685                                                         #endif
3686                                                         pInfo->tagV2Info.bURLMarked = true;
3687                                                 }
3688                                                 else if(strncmp((char *)CompTmp, "TCOP", 4) == 0 && pInfo->tagV2Info.bCopyRightMarked == false)
3689                                                 {
3690                                                         if(textEncodingType == AV_ID3V2_UTF16)
3691                                                         {
3692                                                                 pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->copyrightLen);
3693                                                         }
3694                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
3695                                                         {
3696                                                                 debug_warning ("not implemented\n");
3697                                                         }
3698                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3699                                                         {
3700                                                                 pInfo->pCopyright= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3701                                                                 memcpy(pInfo->pCopyright, pExtContent, realCpyFrameNum);
3702                                                                 pInfo->pCopyright[realCpyFrameNum] = '\0';
3703                                                                 /*string copy with '\0'*/
3704                                                                 pInfo->copyrightLen = realCpyFrameNum;
3705                                                                 _STRNCPY_EX (pInfo->pCopyright, pExtContent, pInfo->copyrightLen);
3706                                                         }
3707                                                         else
3708                                                         {
3709                                                                 pInfo->pCopyright = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->copyrightLen);
3710                                                         }
3711
3712                                                         #ifdef __MMFILE_TEST_MODE__
3713                                                         debug_msg ( "pInfo->pCopyright returned = (%s), pInfo->copyrightLen(%d)\n", pInfo->pCopyright, pInfo->copyrightLen);
3714                                                         #endif
3715                                                         pInfo->tagV2Info.bCopyRightMarked = true;
3716                                                 }
3717                                                 else if(strncmp((char *)CompTmp, "TOPE", 4) == 0 && pInfo->tagV2Info.bOriginArtistMarked == false)
3718                                                 {
3719                                                         if(textEncodingType == AV_ID3V2_UTF16)
3720                                                         {
3721                                                                 pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->originartistLen);
3722                                                         }
3723                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3724                                                         {
3725                                                                 debug_warning ("not implemented\n");
3726                                                         }
3727                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3728                                                         {
3729                                                                 pInfo->pOriginArtist= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3730                                                                 memcpy(pInfo->pOriginArtist, pExtContent, realCpyFrameNum);
3731                                                                 pInfo->pOriginArtist[realCpyFrameNum] = '\0';
3732                                                                 /*string copy with '\0'*/
3733                                                                 pInfo->originartistLen = realCpyFrameNum;
3734                                                                 _STRNCPY_EX (pInfo->pOriginArtist, pExtContent, pInfo->originartistLen);
3735                                                         }
3736                                                         else
3737                                                         {
3738                                                                 pInfo->pOriginArtist = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->originartistLen);
3739                                                         }
3740
3741                                                         #ifdef __MMFILE_TEST_MODE__
3742                                                         debug_msg ( "pInfo->pOriginArtist returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pOriginArtist, pInfo->originartistLen);
3743                                                         #endif
3744                                                         pInfo->tagV2Info.bOriginArtistMarked = true;
3745                                                 }
3746                                                 else if(strncmp((char *)CompTmp, "TCOM", 4) == 0 && pInfo->tagV2Info.bComposerMarked == false)
3747                                                 {
3748                                                         if(textEncodingType == AV_ID3V2_UTF16)
3749                                                         {
3750                                                                 pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->composerLen);
3751                                                         }
3752                                                         else if (textEncodingType == AV_ID3V2_UTF16_BE)
3753                                                         {
3754                                                                 debug_warning ("not implemented\n");
3755                                                         }
3756                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3757                                                         {
3758                                                                 pInfo->pComposer= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3759                                                                 memcpy(pInfo->pComposer, pExtContent, realCpyFrameNum);
3760                                                                 pInfo->pComposer[realCpyFrameNum] = '\0';
3761                                                                 /*string copy with '\0'*/
3762                                                                 pInfo->composerLen = realCpyFrameNum;
3763                                                                 _STRNCPY_EX (pInfo->pComposer, pExtContent, pInfo->composerLen);
3764                                                         }
3765                                                         else
3766                                                         {
3767                                                                 pInfo->pComposer = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->composerLen);
3768                                                         }
3769
3770                                                         #ifdef __MMFILE_TEST_MODE__
3771                                                         debug_msg ( "pInfo->pComposer returned = (%s), pInfo->originartistLen(%d)\n", pInfo->pComposer, pInfo->composerLen);
3772                                                         #endif
3773                                                         pInfo->tagV2Info.bComposerMarked = true;
3774                                                 }
3775                                                 else if(strncmp((char *)CompTmp, "TDRC", 4) == 0 && pInfo->tagV2Info.bRecDateMarked== false)    //TYER(year) and TRDA are replaced by the TDRC
3776                                                 {
3777                                                         if(textEncodingType == AV_ID3V2_UTF16)
3778                                                         {
3779                                                                 pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->recdateLen);
3780                                                         }
3781                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3782                                                         {
3783                                                                 debug_warning ("not implemented\n");
3784                                                         }
3785                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3786                                                         {
3787                                                                 pInfo->pRecDate= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3788                                                                 memcpy(pInfo->pRecDate, pExtContent, realCpyFrameNum);
3789                                                                 pInfo->pRecDate[realCpyFrameNum] = '\0';
3790                                                                 /*string copy with '\0'*/
3791                                                                 pInfo->recdateLen = realCpyFrameNum;
3792                                                                 _STRNCPY_EX (pInfo->pRecDate, pExtContent, pInfo->recdateLen);
3793                                                         }
3794                                                         else
3795                                                         {
3796                                                                 pInfo->pRecDate = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->recdateLen);
3797                                                         }
3798
3799                                                         #ifdef __MMFILE_TEST_MODE__
3800                                                         debug_msg ( "pInfo->pRecDate returned = (%s), pInfo->recdateLen(%d)\n", pInfo->pRecDate, pInfo->recdateLen);
3801                                                         #endif
3802                                                         pInfo->tagV2Info.bRecDateMarked = true;
3803                                                 }
3804                                                 else if(strncmp((char *)CompTmp, "TIT1", 4) == 0 && pInfo->tagV2Info.bContentGroupMarked== false)
3805                                                 {
3806                                                         if(textEncodingType == AV_ID3V2_UTF16)
3807                                                         {
3808                                                                 pInfo->pContentGroup = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", "UCS2", NULL, (unsigned int*)&pInfo->contentGroupLen);
3809                                                         }
3810                                                         else if(textEncodingType == AV_ID3V2_UTF16_BE)
3811                                                         {
3812                                                                 debug_warning ("not implemented\n");
3813                                                         }
3814                                                         else if(textEncodingType == AV_ID3V2_UTF8)
3815                                                         {
3816                                                                 pInfo->pContentGroup= mmfile_malloc (realCpyFrameNum+2);//Ignore NULL char for UTF16
3817                                                                 memcpy(pInfo->pContentGroup, pExtContent, realCpyFrameNum);
3818                                                                 pInfo->pContentGroup[realCpyFrameNum] = '\0';
3819                                                                 /*string copy with '\0'*/
3820                                                                 pInfo->contentGroupLen = realCpyFrameNum;
3821                                                                 _STRNCPY_EX (pInfo->pContentGroup, pExtContent, pInfo->contentGroupLen);
3822                                                         }
3823                                                         else
3824                                                         {
3825                                                                 pInfo->pContentGroup = mmfile_string_convert ((const char*)pExtContent, realCpyFrameNum, "UTF-8", locale, NULL, (unsigned int*)&pInfo->contentGroupLen);
3826                                                         }
3827                                                         #ifdef __MMFILE_TEST_MODE__
3828                                                         debug_msg ( "pInfo->pContentGroup returned = (%s), pInfo->contentGroupLen(%d)\n", pInfo->pContentGroup, pInfo->contentGroupLen);
3829                                                         #endif
3830                                                         pInfo->tagV2Info.bContentGroupMarked = true;
3831                                                 }
3832                                                 else if(strncmp((char *)CompTmp, "APIC", 4) == 0 && pInfo->tagV2Info.bImageMarked == false && realCpyFrameNum <= 2000000)
3833                                                 {
3834                                                         if(textEncodingType == AV_ID3V2_UTF16 || textEncodingType == AV_ID3V2_UTF16_BE || textEncodingType == AV_ID3V2_UTF8)
3835                                                         {
3836                                                                 #ifdef __MMFILE_TEST_MODE__
3837                                                                 debug_msg ( "mmf_file_id3tag_parse_v224: this is abnormal case!!\n");
3838                                                                 #endif
3839                                                         }
3840                                                         else
3841                                                         {
3842                                                                 if(pExtContent[0] != '\0')
3843                                                                 {
3844                                                                         for(inx = 0; inx < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1; inx++)
3845                                                                                 pInfo->imageInfo.imageMIMEType[inx] = '\0';//ini mimetype variable
3846
3847                                                                         while((checkImgMimeTypeMax < MP3_ID3_IMAGE_MIME_TYPE_MAX_LENGTH-1) && pExtContent[checkImgMimeTypeMax] != '\0')
3848                                                                         {
3849                                                                                 pInfo->imageInfo.imageMIMEType[checkImgMimeTypeMax] = pExtContent[checkImgMimeTypeMax];
3850                                                                                 checkImgMimeTypeMax++;
3851                                                                         }
3852                                                                         pInfo->imageInfo.imgMimetypeLen = checkImgMimeTypeMax;
3853                                                                 }
3854                                                                 else
3855                                                                 {
3856                                                                         pInfo->imageInfo.imgMimetypeLen = 0;
3857                                                                 }
3858
3859                                                                 imgstartOffset += checkImgMimeTypeMax;
3860
3861                                                                 if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
3862                                                                 {
3863                                                                         imgstartOffset++;//endofMIME(1byte)
3864
3865                                                                         if(pExtContent[imgstartOffset] < AV_ID3V2_PICTURE_TYPE_MAX)
3866                                                                         {
3867                                                                                 pInfo->imageInfo.pictureType = pExtContent[imgstartOffset];
3868                                                                         }
3869                                                                         imgstartOffset++;//PictureType(1byte)
3870
3871                                                                         if(pExtContent[imgstartOffset] != 0x0)
3872                                                                         {
3873                                                                                 for(inx = 0; inx < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1; inx++)
3874                                                                                         pInfo->imageInfo.imageDescription[inx] = '\0';//ini imgdescripiton variable
3875
3876                                                                                 while((checkImgDescriptionMax < MP3_ID3_IMAGE_DESCRIPTION_MAX_LENGTH-1) && pExtContent[imgstartOffset+checkImgDescriptionMax] != '\0')
3877                                                                                 {
3878                                                                                         pInfo->imageInfo.imageDescription[checkImgDescriptionMax] = pExtContent[imgstartOffset+checkImgDescriptionMax];
3879                                                                                         checkImgDescriptionMax++;
3880                                                                                 }
3881                                                                                 pInfo->imageInfo.imgDesLen= checkImgDescriptionMax;
3882                                                                         }
3883                                                                         else
3884                                                                         {
3885                                                                                 pInfo->imageInfo.imgDesLen= 0;
3886                                                                         }
3887
3888                                                                         imgstartOffset += checkImgDescriptionMax;
3889                                                                         if((pExtContent[imgstartOffset] == '\0') && (realCpyFrameNum - imgstartOffset > 0))
3890                                                                         {
3891                                                                                 imgstartOffset ++; // endofDesceriptionType(1byte)
3892
3893                                                                                 while(pExtContent[imgstartOffset] == '\0')      //some content has useless '\0' in front of picture data
3894                                                                                 {
3895                                                                                         imgstartOffset ++;
3896                                                                                 }
3897
3898                                                                                 #ifdef __MMFILE_TEST_MODE__
3899                                                                                 debug_msg ( "after scaning imgDescription imgstartOffset(%d) value!\n", imgstartOffset);
3900                                                                                 #endif
3901
3902                                                                                 if(realCpyFrameNum - imgstartOffset > 0)
3903                                                                                 {
3904                                                                                         pInfo->imageInfo.imageLen = realCpyFrameNum - imgstartOffset;
3905                                                                                         pInfo->imageInfo.pImageBuf= mmfile_malloc (pInfo->imageInfo.imageLen+1);
3906                                                                                         memcpy(pInfo->imageInfo.pImageBuf, pExtContent+ imgstartOffset, pInfo->imageInfo.imageLen);
3907                                                                                         pInfo->imageInfo.pImageBuf[pInfo->imageInfo.imageLen] = 0;
3908                                                                                         if(IS_INCLUDE_URL(pInfo->imageInfo.imageMIMEType))
3909                                                                                                 pInfo->imageInfo.bURLInfo = true; //if mimetype is "-->", image date has an URL
3910                                                                                 }
3911                                                                                 else
3912                                                                                 {
3913                                                                                         #ifdef __MMFILE_TEST_MODE__
3914                                                                                         debug_msg ( "No APIC image!! realCpyFrameNum(%d) - imgstartOffset(%d)\n", realCpyFrameNum, imgstartOffset);
3915                                                                                         #endif
3916                                                                                 }
3917                                                                         }
3918                                                                 }
3919                                                         }
3920
3921                                                         checkImgMimeTypeMax = 0;
3922                                                         checkImgDescriptionMax = 0;
3923                                                         inx = 0;
3924                                                         imgstartOffset = 0;
3925                                                         pInfo->tagV2Info.bImageMarked= true;
3926                                                 }
3927                                                 else
3928                                                 {
3929                                                         #ifdef __MMFILE_TEST_MODE__
3930                                                         debug_msg ( "CompTmp(%s) This Frame ID currently not Supports!!\n", CompTmp);
3931                                                         #endif
3932                                                 }
3933                                         }
3934
3935                                 }
3936                                 else
3937                                 {
3938                                         #ifdef __MMFILE_TEST_MODE__
3939                                         debug_msg ( "mmf_file_id3tag_parse_v224: All of the pExtContent Values are NULL\n");
3940                                         #endif
3941                                 }
3942
3943                         }
3944                         else
3945                         {
3946                                 curPos += purelyFramelen;
3947                                 if(purelyFramelen != 0)
3948                                         needToloopv2taglen = MP3_TAGv2_23_TXT_HEADER_LEN;
3949                         }
3950
3951                         if(pExtContent) _FREE_EX(pExtContent);
3952                         if(tmpConvert2Pcode)    _FREE_EX(tmpConvert2Pcode);
3953                         memset(CompTmp, 0, 4);
3954                         if(curPos < taglen)
3955                         {
3956                                 needToloopv2taglen -= oneFrameLen;
3957                                 v2numOfFrames++;
3958                         }
3959                         else
3960                                 needToloopv2taglen = MP3_TAGv2_23_TXT_HEADER_LEN;
3961
3962                         oneFrameLen = 0;
3963                         encodingOffSet = 0;
3964                         realCpyFrameNum = 0;
3965                         textEncodingType = 0;
3966                         purelyFramelen = 0;
3967
3968                 }
3969         }
3970
3971         if(taglen)
3972                 return true;
3973         else
3974                 return false;
3975
3976 }
3977
3978 EXPORT_API
3979 void mm_file_id3tag_restore_content_info(AvFileContentInfo* pInfo)
3980 {
3981         char    *mpegAudioGenre=NULL, *tmpGenreForV1Tag = NULL;
3982         bool    bAdditionGenre= false /*, bMpegAudioFrame = false*/;
3983         int     mpegAudioFileLen=0, idv2IntGenre=148, tmpinx=0/*, tmpinx2=0*/;
3984         char    *pGenreForUTF16;
3985
3986         // for Genre Info
3987         if(pInfo->tagV2Info.bGenreMarked == false)
3988         {
3989                 if(pInfo->bV1tagFound == true)
3990                 {
3991                         #ifdef __MMFILE_TEST_MODE__
3992                         debug_msg ( "Genre: %d\n", pInfo->genre);
3993                         #endif
3994                         if(pInfo->genre > 147)
3995                         {
3996                                 mpegAudioGenre = MpegAudio_Genre[148];
3997                         }
3998                         else
3999                         {
4000                                 mpegAudioGenre = MpegAudio_Genre[pInfo->genre];
4001                         }
4002
4003                         if(mpegAudioGenre!=NULL)
4004                         {
4005                                 pInfo->genreLen = strlen(mpegAudioGenre);
4006                                 if (pInfo->genreLen > 0)
4007                                 {
4008                                         // Give space for NULL character. Hence added "+1"
4009                                         pInfo->pGenre = mmfile_malloc (sizeof(char) * (pInfo->genreLen + 1) );
4010                                         if (pInfo->pGenre)
4011                                         {
4012                                                 strncpy(pInfo->pGenre, mpegAudioGenre, pInfo->genreLen);
4013                                                 pInfo->pGenre[pInfo->genreLen] = '\0';
4014                                         }
4015                                 }
4016                         }
4017                 }
4018                 else
4019                 {
4020                         #ifdef __MMFILE_TEST_MODE__
4021                         debug_msg ( "Genre was not Found.\n");
4022                         #endif
4023                 }
4024         }
4025         else if(pInfo->tagV2Info.bGenreMarked == true)
4026         {
4027                 if(pInfo->genreLen && pInfo->tagV2Info.bGenreUTF16)
4028                 {
4029                         pInfo->pGenre[pInfo->genreLen+1] = '\0';
4030                         mpegAudioGenre = mmfile_malloc (sizeof(char) * (pInfo->genreLen*AV_WM_LOCALCODE_SIZE_MAX + 1) );
4031                         pGenreForUTF16 = (char *)pInfo->pGenre;
4032 #ifdef _SM_ONLY
4033                         if(WmConvert2LCode(mpegAudioGenre, sizeof ( char ) * AV_WM_LOCALCODE_SIZE_MAX * ( pInfo->genreLen + 1 ), pGenreForUTF16))
4034                         {
4035                                 pInfo->genreLen = strlen(mpegAudioGenre);
4036                                 mpegAudioGenre[pInfo->genreLen] = '\0';
4037                         }
4038 #endif
4039                 }
4040                 else
4041                 {
4042                         #ifdef __MMFILE_TEST_MODE__
4043                         debug_msg (  "pInfo->genreLen size is Zero Or not UTF16 code! genreLen[%d] genre[%s]\n",pInfo->genreLen,pInfo->pGenre);
4044                         #endif
4045                         if (pInfo->pGenre) {
4046                                 pInfo->genreLen = strlen(pInfo->pGenre);
4047                                 mpegAudioGenre = mmfile_malloc (sizeof(char) * (pInfo->genreLen + 1) );
4048                                 mpegAudioGenre[pInfo->genreLen] = '\0';
4049                                 strncpy(mpegAudioGenre, pInfo->pGenre, pInfo->genreLen);
4050                         } else {
4051                                 pInfo->genreLen = 0;
4052                         }
4053                 }
4054
4055                 if(pInfo->pGenre) _FREE_EX(pInfo->pGenre);
4056
4057                 tmpinx = 0;
4058                 if(mpegAudioGenre!=NULL)
4059                 {
4060                         /**
4061                          *Genre number
4062                          * (XXX)        XXX is 0 - 148
4063                          */
4064                         pInfo->genreLen = strlen (mpegAudioGenre);
4065                         if (pInfo->genreLen >= 3 &&
4066                                 mpegAudioGenre[0] == '(' && mpegAudioGenre[pInfo->genreLen - 1] == ')') {
4067                                 bAdditionGenre = true;
4068                                 for (mpegAudioFileLen = 1; mpegAudioFileLen <= pInfo->genreLen - 2; mpegAudioFileLen++) {
4069                                         if(mpegAudioGenre[mpegAudioFileLen] < '0' || mpegAudioGenre[mpegAudioFileLen] > '9') {
4070                                                 bAdditionGenre = false;
4071                                                 break;
4072                                         }
4073                                 }
4074                         }
4075
4076                         if(bAdditionGenre == true)
4077                         {
4078                                 idv2IntGenre = atoi(mpegAudioGenre+1);
4079                                 if(idv2IntGenre > 147 || idv2IntGenre < 0)
4080                                 {
4081                                         tmpGenreForV1Tag = MpegAudio_Genre[148];
4082                                 }
4083                                 else
4084                                 {
4085                                         tmpGenreForV1Tag = MpegAudio_Genre[idv2IntGenre];
4086                                 }
4087                                 if(tmpGenreForV1Tag!=NULL)
4088                                 {
4089                                         pInfo->genreLen = strlen(tmpGenreForV1Tag);
4090                                         if (pInfo->genreLen > 0)
4091                                         {
4092                                                 // Give space for NULL character. Hence added "+1"
4093                                                 pInfo->pGenre = mmfile_malloc (sizeof(char) * (pInfo->genreLen + 1) );
4094                                                 if (pInfo->pGenre)
4095                                                 {
4096                                                         strncpy(pInfo->pGenre, tmpGenreForV1Tag, pInfo->genreLen);
4097                                                         pInfo->pGenre[pInfo->genreLen] = 0;
4098                                                 }
4099                                         }
4100                                 }
4101                                 #ifdef __MMFILE_TEST_MODE__
4102                                 debug_msg ( "pInfo->pGenre = %s\n", pInfo->pGenre);
4103                                 #endif
4104                         }
4105                         else if (bAdditionGenre == false && pInfo->genreLen > 0)
4106                         {
4107                                 /**
4108                                  * Genre string.
4109                                  */
4110                         
4111                                 // Give space for NULL character. Hence added "+1"
4112                                 pInfo->pGenre = mmfile_malloc (sizeof(char) * (pInfo->genreLen + 1) );
4113                                 if (pInfo->pGenre)
4114                                 {
4115                                         strncpy(pInfo->pGenre, mpegAudioGenre, pInfo->genreLen);
4116                                         pInfo->pGenre[pInfo->genreLen] = '\0';
4117                                 }
4118                                 #ifdef __MMFILE_TEST_MODE__
4119                                 debug_msg ( "pInfo->pGenre = %s, pInfo->genreLen = %d\n", pInfo->pGenre, pInfo->genreLen);
4120                                 #endif
4121                         }
4122                         else
4123                         {
4124                                 #ifdef __MMFILE_TEST_MODE__
4125                                 debug_msg ( "Failed to \"(...)\" value to genre = %s\n", pInfo->pGenre);
4126                                 #endif
4127                         }
4128                 }
4129                 else
4130                 {
4131                         #ifdef __MMFILE_TEST_MODE__
4132                         debug_msg ( "mpegAudioGenre = %x\n", mpegAudioGenre);
4133                         #endif
4134                 }
4135                 if(mpegAudioGenre)
4136                         _FREE_EX(mpegAudioGenre);
4137
4138         }
4139         else
4140         {
4141                 #ifdef __MMFILE_TEST_MODE__
4142                 debug_msg (  "Neither ID3 v1 nor v2 info doesn't have Genre Info.\n");
4143                 #endif
4144         }
4145
4146 }
4147
4148 void mm_file_free_synclyrics_list(GList * synclyrics_list)
4149 {
4150         int list_len = 0;
4151         int idx = 0;
4152         AvSynclyricsInfo *synclyrics_info = NULL;
4153
4154         if (synclyrics_list == NULL) {
4155                 return;
4156         }
4157
4158         list_len = g_list_length(synclyrics_list);
4159         for (idx = 0; idx < list_len; idx++) {
4160                 synclyrics_info = g_list_nth_data(synclyrics_list, idx);
4161
4162                 free(synclyrics_info->lyric_info);
4163                 synclyrics_info->lyric_info = NULL;
4164                 
4165                 free(synclyrics_info);
4166                 synclyrics_info = NULL;
4167         }
4168
4169         if (synclyrics_list != NULL) {
4170                 g_list_free(synclyrics_list);
4171                 synclyrics_list = NULL;
4172         }
4173         
4174         return;
4175 }
4176