mpg audio clip can't play , fix check mpeg audio layer 1 header
[platform/core/multimedia/libmm-fileinfo.git] / utils / mm_file_util_validity.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 <string.h>     /*memcmp*/
23 #include <stdlib.h>     /*malloc*/
24 #include "mm_file_debug.h"
25 #include "mm_file_utils.h"
26
27 /* Description of return value
28  * 0: false
29  * 1: true
30  */
31
32 /***********************************************************************/
33 /*                     Internal functions                              */
34 /***********************************************************************/
35 static int _MMFileSearchID3Tag(MMFileIOHandle *fp, unsigned int *offset);
36 static int _MMFileIsMP3Header(void *header);
37 static int _MMFileIsOGGHeader(void *header);
38 static int _MMFileIsREALHeader(void *header);
39 static int _MMFileIsMP4Header(void *header);
40 static int _MMFileIsWAVHeader(void *header);
41 static int _MMFileIsAVIHeader(void *header);
42 static int _MMFileIsMIDHeader(void *header);
43 static int _MMFileIsMMFHeader(void *header);
44 static int _MMFileIsIMYHeader(void *header);
45 static int _MMFileIsASFHeader(void *header);
46 static int _MMFileIsAMRHeader(void *header);
47 static int _MMFileIsFLACHeader(void *header);
48 static int _MMFileIsFLVHeader(void *header);
49 static int _MMFileIsMPEGTSHeader(MMFileIOHandle *fp);
50 static int _MMFileIsMPEGPSHeader(void *header);
51 static int _MMFileIsMPEGAUDIOHeader(void *header);
52 static int _MMFileIsMPEGVIDEOHeader(void *header);
53
54 /***********************************************************************/
55 /*                     MP3 Header Check API                            */
56 /***********************************************************************/
57 EXPORT_API
58 int MMFileFormatIsValidMP3(MMFileIOHandle *pFileIO, const char *mmfileuri, int frameCnt)
59 {
60 #define _MMFILE_MP3_HEADER_LENGTH   4
61 #define _MMFILE_MP3_BUFFER_LENGTH   8200
62
63         MMFileIOHandle *fp = pFileIO;
64         unsigned char buffer[_MMFILE_MP3_BUFFER_LENGTH] = {0, };
65         long long  filesize = 0;
66         unsigned int sizeID3 = 0;
67         int readed = 0, i = 0, j = 0;;
68         unsigned int startoffset = 0;
69         int endoffset = 0;
70         int frameSize = 0;
71         int ret = 0, count = 0, offset = 0;
72
73         if (fp == NULL) {
74                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
75                 if (ret == MMFILE_IO_FAILED) {
76                         debug_error(DEBUG, "error: mmfile_open\n");
77                         goto exit;
78                 }
79         }
80
81         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
82
83         mmfile_seek(fp, 0L, MMFILE_SEEK_END);
84         filesize = mmfile_tell(fp);
85         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
86
87         if (filesize < _MMFILE_MP3_HEADER_LENGTH) {
88                 debug_error(DEBUG, "header is too small.\n");
89                 ret = 0;
90                 goto exit;
91         }
92
93         /* Search the existance of ID3 tag */
94         ret = _MMFileSearchID3Tag(fp, &sizeID3);
95         if (ret == 0) {
96                 debug_error(RELEASE, "Error in searching the ID3 tag\n");
97         /* goto exit; */
98         }
99
100         ret = 0;
101
102         /* set begin and end point at the file */
103         startoffset += sizeID3;
104         endoffset = startoffset + 102400;
105         if (endoffset > filesize - _MMFILE_MP3_HEADER_LENGTH)
106                 endoffset = filesize - _MMFILE_MP3_HEADER_LENGTH;
107
108         /* find sync bit */
109         i = startoffset;
110         count = 0;
111
112         while (i < endoffset) {
113                 mmfile_seek(fp, i, MMFILE_SEEK_SET);
114                 readed = mmfile_read(fp, buffer, _MMFILE_MP3_BUFFER_LENGTH);
115                 if (readed < _MMFILE_MP3_HEADER_LENGTH) {
116                         debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
117                         ret = 0;
118                         break;
119                 }
120
121                 offset = 1;
122                 for (j = 0; (j <= readed - _MMFILE_MP3_HEADER_LENGTH); j = j + offset) {
123                         frameSize = _MMFileIsMP3Header(buffer + j);
124
125                         offset = 1;
126
127                         if (frameSize) {
128
129                                 if ((j + frameSize) >= (endoffset - (i + _MMFILE_MP3_HEADER_LENGTH))) {
130                                         goto failMP3;
131                                 }
132
133                                 if ((j + frameSize) >= (readed - _MMFILE_MP3_HEADER_LENGTH)) {
134                                         debug_msg(RELEASE, "MP3 coner hit %d %d\n", j, frameSize);
135                                         break;
136                                 }
137
138                                 frameSize = _MMFileIsMP3Header(buffer + j + frameSize);
139
140                                 if (frameSize) {
141                                         offset = frameSize;
142                                         count++;
143                                         if (count == frameCnt) {
144                                                 ret = 1;
145                                                 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
146                                                 goto exit;
147                                         }
148                                 } else {
149                                         offset = 1;
150                                 }
151                         }
152                 }
153
154                 /*If j is zero, this loop is infinite */
155                 if (j == 0) j++;
156
157                 i = i + j;
158         }
159
160 failMP3:
161         debug_msg(RELEASE, "Header Not Detected at: %d\n", i + j);
162  exit:
163         if (pFileIO == NULL && fp != NULL)
164                 mmfile_close(fp);
165
166         return ret;
167 }
168
169
170
171 /***********************************************************************/
172 /*                     AAC Header Check API                            */
173 /***********************************************************************/
174 EXPORT_API
175 int MMFileFormatIsValidAAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
176 {
177 #define _MMFILE_AAC_HEADER_LENGTH   4
178 #define _MMFILE_AAC_BUFFER_LENGTH   8200
179
180         MMFileIOHandle *fp = pFileIO;
181         unsigned char buffer[_MMFILE_AAC_BUFFER_LENGTH] = {0, };
182         unsigned int sizeID3 = 0;
183         long long    filesize = 0;
184         int readed = 0, i = 0, j = 0;
185         int startoffset = 0;
186         int endoffset = 0;
187         int ret = 0;
188         unsigned int sync = 0;
189         int frameSize = 0;
190
191         if (fp == NULL) {
192                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
193                 if (ret == MMFILE_IO_FAILED) {
194                         debug_error(DEBUG, "error: mmfile_open\n");
195                         goto exit;
196                 }
197         }
198
199         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
200
201         /* Initialize the members of handle */
202         mmfile_seek(fp, 0, MMFILE_SEEK_END);
203         filesize = mmfile_tell(fp);
204         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
205
206         if (filesize < _MMFILE_AAC_HEADER_LENGTH) {
207                 debug_error(DEBUG, "header is too small.\n");
208                 ret = 0;
209                 goto exit;
210         }
211
212         /* Search the existance of ID3 tag */
213         ret = _MMFileSearchID3Tag(fp, &sizeID3);
214         if (ret == 0) {
215                 debug_error(RELEASE, "Error in searching the ID3 tag\n");
216         /* goto exit; */
217         }
218
219         ret = 0;
220
221         /* set begin and end point at the file */
222         startoffset += sizeID3;
223         endoffset = startoffset + 10240;
224         if (endoffset > filesize - _MMFILE_AAC_HEADER_LENGTH)
225                 endoffset = filesize - _MMFILE_AAC_HEADER_LENGTH;
226
227         i = startoffset;
228
229         while (i < endoffset) {
230                 mmfile_seek(fp, i, MMFILE_SEEK_SET);
231
232                 readed = mmfile_read(fp, buffer, _MMFILE_AAC_BUFFER_LENGTH);
233
234                 if (readed < _MMFILE_AAC_HEADER_LENGTH) {
235                         debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
236                         ret = 0;
237                         break;
238                 }
239
240                 debug_msg(RELEASE, "read error. size = %d. i = %d\n", readed, i);
241
242                 for (j = 0; (j < readed - _MMFILE_AAC_HEADER_LENGTH); j++) {
243
244                         sync = ((buffer[j] << 8) | (buffer[j + 1]));
245
246                         if ((sync & 0xFFF6) == 0xFFF0) {
247                                 frameSize = (((buffer[j + 3] & 0x03) << 11) | (buffer[j + 4] << 3) | ((buffer[j + 5] & 0xE0) >> 5));
248
249                                 if (frameSize == 0) {
250                                         continue;
251                                 }
252
253                                 if ((j + frameSize) >= (endoffset - (i + 2))) {
254                                         goto fail;
255                                 }
256                                 if ((j + frameSize) >= (readed - 2)) {
257                                         debug_msg(RELEASE, "AAC coner hit %d %d\n", j, frameSize);
258                                         break;
259                                 }
260
261                                 sync = ((buffer[j + frameSize] << 8) | (buffer[j + frameSize + 1]));
262
263                                 if ((sync & 0xFFF6) == 0xFFF0) {
264                                         ret = 1;
265                                         debug_msg(RELEASE, "AAC ADTS Header Detected at %d\n", i + j);
266                                         goto exit;
267                                 }
268                         } else if (!memcmp((buffer + j), "ADIF", 4)) {
269                                 ret = 1;
270                                 debug_msg(RELEASE, "AAC ADIF Header Detected at %d\n", i + j);
271                                 goto exit;
272                         }
273                 }
274                 /*If j is zero, this loop is infinite */
275                 if (j == 0) j++;
276
277                 i = i + j;
278         }
279
280
281 fail:
282         debug_msg(RELEASE, "Header Detected Failed\n");
283 exit:
284         if (pFileIO == NULL && fp != NULL)
285                 mmfile_close(fp);
286
287         return ret;
288 }
289
290
291
292 /***********************************************************************/
293 /*                     OGG Header Check API                            */
294 /***********************************************************************/
295 EXPORT_API
296 int MMFileFormatIsValidOGG(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
297 {
298 #define _MMFILE_OGG_HEADER_LENGTH   4
299 #define _MMFILE_OGG_BUFFER_LENGTH   512
300 #define _MMFILE_OGG_CHECK_LIMIT         (_MMFILE_OGG_HEADER_LENGTH * 1000)
301
302         MMFileIOHandle *fp = pFileIO;
303         unsigned char buffer[_MMFILE_OGG_BUFFER_LENGTH] = {0, };
304         unsigned int sizeID3 = 0;
305         long long    filesize = 0;
306         int readed = 0, i = 0, j = 0;
307         int startoffset = 0;
308         int endoffset = 0;
309         int ret = 0;
310         int check_limit = 0;
311
312         if (fp == NULL) {
313                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
314                 if (ret == MMFILE_IO_FAILED) {
315                         debug_error(DEBUG, "error: mmfile_open\n");
316                         ret = 0;
317                         goto exit;
318                 }
319         }
320
321         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
322
323         /* Initialize the members of handle */
324         mmfile_seek(fp, 0, MMFILE_SEEK_END);
325         filesize = mmfile_tell(fp);
326         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
327
328         if (filesize < _MMFILE_OGG_HEADER_LENGTH) {
329                 debug_error(DEBUG, "header is too small.\n");
330                 ret = 0;
331                 goto exit;
332         }
333
334         /* Search the existance of ID3 tag */
335         ret = _MMFileSearchID3Tag(fp, &sizeID3);
336         if (ret == 0) {
337                 debug_error(RELEASE, "Error in searching the ID3 tag\n");
338         /* goto exit; */
339         }
340
341         ret = 0;
342
343         /* set begin and end point at the file */
344         startoffset += sizeID3;
345         endoffset = filesize - _MMFILE_OGG_HEADER_LENGTH;
346
347         check_limit = (endoffset > _MMFILE_OGG_CHECK_LIMIT) ? _MMFILE_OGG_CHECK_LIMIT : endoffset;
348
349         i = startoffset;
350         while (i <= check_limit) {
351                 mmfile_seek(fp, i, MMFILE_SEEK_SET);
352                 readed = mmfile_read(fp, buffer, _MMFILE_OGG_BUFFER_LENGTH);
353                 if (readed < _MMFILE_OGG_HEADER_LENGTH) {
354                         debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
355                         ret = 0;
356                         break;
357                 }
358
359                 for (j = 0; (j <= readed - _MMFILE_OGG_HEADER_LENGTH); j++) {
360                         if (1 == _MMFileIsOGGHeader(buffer + j)) {
361                                 ret = 1;
362                                 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
363                                 goto exit;
364                         }
365                 }
366
367                 memset(buffer, 0x00, _MMFILE_OGG_BUFFER_LENGTH);
368
369                 i = i + j;
370         }
371
372 exit:
373         if (pFileIO == NULL && fp != NULL)
374                 mmfile_close(fp);
375
376         return ret;
377 }
378
379
380
381 /***********************************************************************/
382 /*                     MIDI Header Check API                           */
383 /***********************************************************************/
384 EXPORT_API
385 int MMFileFormatIsValidMID(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
386 {
387 #define _MMFILE_MIDI_HEADER_LENGTH 4
388 #define _MMFILE_MIDI_BUFFER_LENGTH 512
389 #define _MMFILE_MIDI_CHECK_LIMIT        (_MMFILE_MIDI_HEADER_LENGTH * 1024)
390
391         MMFileIOHandle *fp = pFileIO;
392         unsigned char buffer[_MMFILE_MIDI_BUFFER_LENGTH] = {0, };
393         long long    filesize = 0;
394         int readed = 0, i = 0, j = 0;
395         int startoffset = 0;
396         int endoffset = 0;
397         int ret = 0;
398         int check_limit = 0;
399
400         if (fp == NULL) {
401                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
402                 if (ret == MMFILE_IO_FAILED) {
403                         debug_error(DEBUG, "error: mmfile_open\n");
404                         goto exit;
405                 }
406         }
407
408         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
409
410         /* Initialize the members of handle */
411         mmfile_seek(fp, 0, MMFILE_SEEK_END);
412         filesize = mmfile_tell(fp);
413         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
414
415         if (filesize < _MMFILE_MIDI_HEADER_LENGTH) {
416                 debug_error(DEBUG, "header is too small.\n");
417                 ret = 0;
418                 goto exit;
419         }
420
421         ret = 0;
422
423         /* set begin and end point at the file */
424         startoffset = 0;
425         endoffset = filesize - _MMFILE_MIDI_HEADER_LENGTH;
426
427         check_limit = (endoffset > _MMFILE_MIDI_CHECK_LIMIT) ? _MMFILE_MIDI_CHECK_LIMIT : endoffset;
428
429         i = startoffset;
430         while (i <= check_limit) {
431                 mmfile_seek(fp, i, MMFILE_SEEK_SET);
432                 readed = mmfile_read(fp, buffer, _MMFILE_MIDI_BUFFER_LENGTH);
433                 if (readed < _MMFILE_MIDI_HEADER_LENGTH) {
434                         debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
435                         ret = 0;
436                         break;
437                 }
438
439                 for (j = 0; (j <= readed - _MMFILE_MIDI_HEADER_LENGTH); j++) {
440                         if (1 == _MMFileIsMIDHeader(buffer + j)) {
441                                 ret = 1;
442                                 debug_msg(RELEASE, "Header Detected at %d\n", i + j);
443                                 goto exit;
444                         }
445                 }
446
447                 memset(buffer, 0x00, _MMFILE_MIDI_BUFFER_LENGTH);
448
449                 i = i + j;
450         }
451
452 exit:
453         if (pFileIO == NULL && fp != NULL)
454                 mmfile_close(fp);
455
456         return ret;
457 }
458
459
460 /***********************************************************************/
461 /*                     WAV Header Check API                            */
462 /***********************************************************************/
463 EXPORT_API
464 int MMFileFormatIsValidWAV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
465 {
466 #define _MMFILE_WAV_HEADER_LENGTH 15
467
468         MMFileIOHandle *fp = pFileIO;
469         unsigned char buffer[_MMFILE_WAV_HEADER_LENGTH] = {0, };
470         int           readed = 0;
471         int ret = 0;
472
473         if (fp == NULL) {
474                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
475                 if (ret == MMFILE_IO_FAILED) {
476                         debug_error(DEBUG, "error: mmfile_open\n");
477                         goto exit;
478                 }
479         }
480
481         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
482
483         readed = mmfile_read(fp, buffer, _MMFILE_WAV_HEADER_LENGTH);
484
485         if (_MMFILE_WAV_HEADER_LENGTH != readed) {
486                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
487                 ret = 0;
488                 goto exit;
489         }
490
491         if (1 == _MMFileIsWAVHeader(buffer)) {
492                 debug_msg(RELEASE, "Header Detected\n");
493                 ret = 1;
494                 goto exit;
495         }
496
497 exit:
498         if (pFileIO == NULL && fp != NULL)
499                 mmfile_close(fp);
500
501         return ret;
502 }
503
504
505
506 /***********************************************************************/
507 /*                     MP4 Header Check API                            */
508 /***********************************************************************/
509 EXPORT_API
510 int MMFileFormatIsValidMP4(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
511 {
512 #define _MMFILE_MP4_HEADER_LENGTH 4
513 #define _MMFILE_MP4_CHECK_LIMIT         (1024*10)       /*10Kbyte*/
514         MMFileIOHandle *fp = pFileIO;
515         unsigned char buffer[_MMFILE_MP4_HEADER_LENGTH] = {0, };
516         long long     filesize = 0;
517         int           readed = 0;
518         unsigned int  startoffset = 0;
519         int ret = 0;
520         unsigned int check_limit = 0;
521
522         if (fp == NULL) {
523                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
524                 if (ret == MMFILE_IO_FAILED) {
525                         debug_error(DEBUG, "error: mmfile_open\n");
526                         goto exit;
527                 }
528         }
529
530         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
531
532         /* Initialize the members of handle */
533         mmfile_seek(fp, 0, MMFILE_SEEK_END);
534         filesize = mmfile_tell(fp);
535         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
536
537         if (filesize < _MMFILE_MP4_HEADER_LENGTH) {
538                 debug_error(DEBUG, "header is too small.\n");
539                 ret = 0;
540                 goto exit;
541         }
542
543         ret = 0;
544
545         /**@note weak check*/
546         check_limit = (filesize > _MMFILE_MP4_CHECK_LIMIT) ? _MMFILE_MP4_CHECK_LIMIT : filesize;
547         for (startoffset = 0; check_limit - (startoffset + _MMFILE_MP4_HEADER_LENGTH) > 0; startoffset++) {
548                 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
549
550                 readed = mmfile_read(fp, buffer, _MMFILE_MP4_HEADER_LENGTH);
551                 if (readed != _MMFILE_MP4_HEADER_LENGTH) {
552                         debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
553                         ret = 0;
554                         goto exit;
555                 }
556
557                 /*input is 4byte*/
558                 if (1 == _MMFileIsMP4Header(buffer)) {
559                         debug_msg(RELEASE, "MP4 Header Detected\n");
560                         ret = 1;
561                         goto exit;
562                 }
563         }
564
565 exit:
566         if (pFileIO == NULL && fp != NULL)
567                 mmfile_close(fp);
568
569         return ret;
570 }
571
572
573 /***********************************************************************/
574 /*                     AVI Header Check API                            */
575 /***********************************************************************/
576 EXPORT_API
577 int MMFileFormatIsValidAVI(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
578 {
579 #define _MMFILE_AVI_HEADER_LENGTH 12
580
581         MMFileIOHandle *fp = pFileIO;
582         unsigned char buffer[_MMFILE_AVI_HEADER_LENGTH] = {0, };
583         int           readed = 0;
584         int ret = 0;
585
586         if (fp == NULL) {
587                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
588                 if (ret == MMFILE_IO_FAILED) {
589                         debug_error(DEBUG, "error: mmfile_open\n");
590                         goto exit;
591                 }
592         }
593
594         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
595
596         readed = mmfile_read(fp, buffer, _MMFILE_AVI_HEADER_LENGTH);
597
598         if (_MMFILE_AVI_HEADER_LENGTH != readed) {
599                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
600                 ret = 0;
601                 goto exit;
602         }
603
604         if (1 == _MMFileIsAVIHeader(buffer)) {
605                 debug_msg(RELEASE, "Header Detected \n");
606                 ret = 1;
607                 goto exit;
608         }
609
610 exit:
611         if (pFileIO == NULL && fp != NULL)
612                 mmfile_close(fp);
613
614         return ret;
615 }
616
617
618
619 /***********************************************************************/
620 /*                     ASF Header Check API                            */
621 /***********************************************************************/
622 EXPORT_API
623 int MMFileFormatIsValidASF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
624 {
625 #define _MMFILE_ASF_HEADER_LENGTH 16
626         MMFileIOHandle *fp = pFileIO;
627         unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
628         int           readed = 0;
629         int ret = 0;
630
631         if (fp == NULL) {
632                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
633                 if (ret == MMFILE_IO_FAILED) {
634                         debug_error(DEBUG, "error: mmfile_open\n");
635                         goto exit;
636                 }
637         }
638
639         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
640
641         readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
642
643         if (_MMFILE_ASF_HEADER_LENGTH != readed) {
644                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
645                 ret = 0;
646                 goto exit;
647         }
648
649         if (1 == _MMFileIsASFHeader(buffer)) {
650                 debug_msg(RELEASE, "Header Detected\n");
651                 ret = 1;
652                 goto exit;
653         }
654
655 exit:
656         if (pFileIO == NULL && fp != NULL)
657                 mmfile_close(fp);
658
659         return ret;
660 }
661
662 /***********************************************************************/
663 /*                     WMA Header Check API                            */
664 /***********************************************************************/
665 EXPORT_API
666 int MMFileFormatIsValidWMA(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
667 {
668 #define _MMFILE_ASF_HEADER_LENGTH 16
669         MMFileIOHandle *fp = pFileIO;
670         unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
671         int           readed = 0;
672         int ret = 0;
673
674         if (fp == NULL) {
675                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
676                 if (ret == MMFILE_IO_FAILED) {
677                         debug_error(DEBUG, "error: mmfile_open\n");
678                         goto exit;
679                 }
680         }
681
682         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
683
684         readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
685
686         if (_MMFILE_ASF_HEADER_LENGTH != readed) {
687                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
688
689                 ret = 0;
690                 goto exit;
691         }
692
693         if (1 == _MMFileIsASFHeader(buffer)) {
694                 debug_msg(RELEASE, "Header Detected\n");
695                 ret = 1;
696                 goto exit;
697         }
698
699 exit:
700         if (pFileIO == NULL && fp != NULL)
701                 mmfile_close(fp);
702
703         return ret;
704 }
705
706
707
708 /***********************************************************************/
709 /*                     WMV Header Check API                            */
710 /***********************************************************************/
711 EXPORT_API
712 int MMFileFormatIsValidWMV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
713 {
714 #define _MMFILE_ASF_HEADER_LENGTH 16
715         MMFileIOHandle *fp = pFileIO;
716         unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0, };
717         int           readed = 0;
718         int ret = 0;
719
720         if (fp == NULL) {
721                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
722                 if (ret == MMFILE_IO_FAILED) {
723                         debug_error(DEBUG, "error: mmfile_open\n");
724                         goto exit;
725                 }
726         }
727
728         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
729
730         readed = mmfile_read(fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
731
732         if (_MMFILE_ASF_HEADER_LENGTH != readed) {
733                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
734                 ret = 0;
735                 goto exit;
736         }
737
738         if (1 == _MMFileIsASFHeader(buffer)) {
739                 debug_msg(RELEASE, "Header Detected\n");
740                 ret = 1;
741                 goto exit;
742         }
743
744 exit:
745         if (pFileIO == NULL && fp != NULL)
746                 mmfile_close(fp);
747
748         return ret;
749 }
750
751
752 /***********************************************************************/
753 /*                     MMF Header Check API                            */
754 /***********************************************************************/
755 EXPORT_API
756 int MMFileFormatIsValidMMF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
757 {
758 #define _MMFILE_MMF_HEADER_LENGTH 18
759
760         MMFileIOHandle *fp = pFileIO;
761         unsigned char buffer[_MMFILE_MMF_HEADER_LENGTH] = {0, };
762         int           readed = 0;
763         int ret = 0;
764
765         if (fp == NULL) {
766                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
767                 if (ret == MMFILE_IO_FAILED) {
768                         debug_error(DEBUG, "error: mmfile_open\n");
769                         goto exit;
770                 }
771         }
772
773         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
774
775         readed = mmfile_read(fp, buffer, _MMFILE_MMF_HEADER_LENGTH);
776
777         if (_MMFILE_MMF_HEADER_LENGTH != readed) {
778                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
779                 ret = 0;
780                 goto exit;
781         }
782
783         if (1 == _MMFileIsMMFHeader(buffer)) {
784                 debug_msg(RELEASE, "Header Detected\n");
785                 ret = 1;
786                 goto exit;
787         }
788
789 exit:
790         if (pFileIO == NULL && fp != NULL)
791                 mmfile_close(fp);
792
793         return ret;
794 }
795
796
797
798 /***********************************************************************/
799 /*                     MMF Header Check API                            */
800 /***********************************************************************/
801 EXPORT_API
802 int MMFileFormatIsValidIMY(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
803 {
804 #define _MMFILE_IMY_HEADER_LENGTH 13
805
806         MMFileIOHandle *fp = pFileIO;
807         unsigned char buffer[_MMFILE_IMY_HEADER_LENGTH] = {0, };
808         int           readed = 0;
809         int ret = 0;
810
811         if (fp == NULL) {
812                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
813                 if (ret == MMFILE_IO_FAILED) {
814                         debug_error(DEBUG, "error: mmfile_open\n");
815                         goto exit;
816                 }
817         }
818
819         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
820
821         readed = mmfile_read(fp, buffer, _MMFILE_IMY_HEADER_LENGTH);
822
823         if (_MMFILE_IMY_HEADER_LENGTH != readed) {
824                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
825                 ret = 0;
826                 goto exit;
827         }
828
829         if (1 == _MMFileIsIMYHeader(buffer)) {
830                 debug_msg(RELEASE, "Header Detected\n");
831                 ret = 1;
832                 goto exit;
833         }
834
835 exit:
836         if (pFileIO == NULL && fp != NULL)
837                 mmfile_close(fp);
838
839         return ret;
840 }
841
842
843
844 /***********************************************************************/
845 /*                     AMR Header Check API                            */
846 /***********************************************************************/
847 EXPORT_API
848 int MMFileFormatIsValidAMR(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
849 {
850 #define _MMFILE_AMR_MAX_HEADER_SIZE 15
851 #define _MMFILE_AMR_MIN_HEADER_SIZE 6
852
853         MMFileIOHandle *fp = pFileIO;
854         unsigned char buffer[_MMFILE_AMR_MAX_HEADER_SIZE] = {0, };
855         int           readed = 0;
856         int ret = 0;
857
858         if (fp == NULL) {
859                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
860                 if (ret == MMFILE_IO_FAILED) {
861                         debug_error(DEBUG, "error: mmfile_open\n");
862                         goto exit;
863                 }
864         }
865
866         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
867
868         readed = mmfile_read(fp, buffer, _MMFILE_AMR_MAX_HEADER_SIZE);
869
870         if (_MMFILE_AMR_MAX_HEADER_SIZE != readed) {
871                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
872                 ret = 0;
873                 goto exit;
874         }
875
876         if (1 == _MMFileIsAMRHeader(buffer)) {
877                 debug_msg(RELEASE, "Header Detected\n");
878                 ret = 1;
879                 goto exit;
880         }
881
882 exit:
883         if (pFileIO == NULL && fp != NULL)
884                 mmfile_close(fp);
885
886         return ret;
887 }
888
889 /***********************************************************************/
890 /*                     Matroska Header Check API                       */
891 /***********************************************************************/
892 EXPORT_API
893 int MMFileFormatIsValidMatroska(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
894 {
895 #define _MMFILE_EBML_MARKER_LENGTH      4
896 #define _MMFILE_MKV_READ_BUFFER_LENGTH 2048
897
898         MMFileIOHandle *fp = pFileIO;
899         unsigned char buffer[_MMFILE_MKV_READ_BUFFER_LENGTH] = {0, };
900         int           readed = 0;
901         int ret = 0;
902         int len_mask = 0x80;
903         unsigned int size = 1, n = 1, total = 0;
904         char probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
905
906         if (fp == NULL) {
907                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
908                 if (ret == MMFILE_IO_FAILED) {
909                         debug_error(DEBUG, "error: mmfile_open\n");
910                         goto exit;
911                 }
912         }
913
914         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
915
916         readed = mmfile_read(fp, buffer, _MMFILE_MKV_READ_BUFFER_LENGTH);
917
918         if (_MMFILE_MKV_READ_BUFFER_LENGTH != readed) {
919                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
920                 ret = 0;
921                 goto exit;
922         }
923
924         /* ebml header? */
925         if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
926                 debug_msg(RELEASE, "This is not a EBML format\n");
927                 ret = 0;
928                 goto exit;
929         }
930
931         /* length of header */
932         total = buffer[4];
933
934         debug_msg(RELEASE, "Initial total header size = [0x%x]\n", total);
935
936         while (size <= 8 && !(total & len_mask)) {
937                 debug_msg(DEBUG, "This case can not be handled yet....");
938                 size++;
939                 len_mask >>= 1;
940         }
941
942         debug_msg(RELEASE, "Final total header size = [%d]\n", total);
943
944         if (size > 8) {
945                 debug_msg(DEBUG, "This case can not be handled yet....");
946                 ret = 0;
947                 goto exit;
948         }
949
950         total &= (len_mask - 1);
951
952         while (n < size) {
953                 total = (total << 8) | buffer[4 + n++];
954                 debug_msg(DEBUG, "This case can not be handled yet....");
955         }
956
957         /* Does the probe data contain the whole header? */
958         if (_MMFILE_MKV_READ_BUFFER_LENGTH < 4 + size + total)
959                 return 0;
960
961         for (n = 4 + size ; n <= 4 + size + total - sizeof(probe_data); n++) {
962                 if (!memcmp(&buffer[n], probe_data, sizeof(probe_data))) {
963                         debug_msg(RELEASE, "String matroska found!!!\n");
964                         ret = 1;
965                         goto exit;
966                 }
967         }
968
969 exit:
970         if (pFileIO == NULL && fp != NULL)
971                 mmfile_close(fp);
972
973         return ret;
974 }
975
976 /***********************************************************************/
977 /*                     QT Header Check API                       */
978 /***********************************************************************/
979 EXPORT_API
980 int MMFileFormatIsValidQT(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
981 {
982         return 1;
983 }
984
985 /***********************************************************************/
986 /*                     Flac Header Check API                       */
987 /***********************************************************************/
988 EXPORT_API
989 int MMFileFormatIsValidFLAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
990 {
991 #define _MMFILE_FLAC_HEADER_LENGTH 5    /*fLaC*/
992
993         MMFileIOHandle *fp = pFileIO;
994         unsigned char buffer[_MMFILE_FLAC_HEADER_LENGTH] = {0, };
995         int readed = 0;
996         int ret = 0;
997
998         if (fp == NULL) {
999                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1000                 if (ret == MMFILE_IO_FAILED) {
1001                         debug_error(DEBUG, "error: mmfile_open\n");
1002                         goto exit;
1003                 }
1004         }
1005
1006         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1007
1008         readed = mmfile_read(fp, buffer, _MMFILE_FLAC_HEADER_LENGTH);
1009
1010         if (_MMFILE_FLAC_HEADER_LENGTH != readed) {
1011                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1012                 ret = 0;
1013                 goto exit;
1014         }
1015
1016         if (1 == _MMFileIsFLACHeader(buffer)) {
1017                 debug_msg(RELEASE, "Header Detected\n");
1018                 ret = 1;
1019                 goto exit;
1020         }
1021
1022 exit:
1023         if (pFileIO == NULL && fp != NULL)
1024                 mmfile_close(fp);
1025
1026         return ret;
1027 }
1028
1029 /***********************************************************************/
1030 /*                     FLV(flash video) Header Check API                       */
1031 /***********************************************************************/
1032 EXPORT_API
1033 int MMFileFormatIsValidFLV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1034 {
1035 #define _MMFILE_FLV_HEADER_LENGTH 4     /*FLV*/
1036
1037         MMFileIOHandle *fp = pFileIO;
1038         unsigned char buffer[_MMFILE_FLV_HEADER_LENGTH] = {0, };
1039         int readed = 0;
1040         int ret = 0;
1041
1042         if (fp == NULL) {
1043                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1044                 if (ret == MMFILE_IO_FAILED) {
1045                         debug_error(DEBUG, "error: mmfile_open\n");
1046                         goto exit;
1047                 }
1048         }
1049
1050         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1051
1052         readed = mmfile_read(fp, buffer, _MMFILE_FLV_HEADER_LENGTH);
1053
1054         if (_MMFILE_FLV_HEADER_LENGTH != readed) {
1055                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1056                 ret = 0;
1057                 goto exit;
1058         }
1059
1060         if (1 == _MMFileIsFLVHeader(buffer)) {
1061                 debug_msg(RELEASE, "Header Detected\n");
1062                 ret = 1;
1063                 goto exit;
1064         }
1065
1066 exit:
1067         if (pFileIO == NULL && fp != NULL)
1068                 mmfile_close(fp);
1069
1070         return ret;
1071 }
1072
1073
1074 /***********************************************************************/
1075 /*                     REAL Header Check API                            */
1076 /***********************************************************************/
1077 EXPORT_API
1078 int MMFileFormatIsValidREAL(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1079 {
1080 #define _MMFILE_RMVB_HEADER_LENGTH 4    /*RMF*/
1081
1082         MMFileIOHandle *fp = pFileIO;
1083         unsigned char buffer[_MMFILE_RMVB_HEADER_LENGTH] = {0, };
1084         int readed = 0;
1085         int ret = 0;
1086
1087         if (fp == NULL) {
1088                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1089                 if (ret == MMFILE_IO_FAILED) {
1090                         debug_error(DEBUG, "error: mmfile_open\n");
1091                         goto exit;
1092                 }
1093         }
1094
1095         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1096
1097         readed = mmfile_read(fp, buffer, _MMFILE_RMVB_HEADER_LENGTH);
1098
1099         if (_MMFILE_RMVB_HEADER_LENGTH != readed) {
1100                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1101                 ret = 0;
1102                 goto exit;
1103         }
1104
1105         if (1 == _MMFileIsREALHeader(buffer)) {
1106                 debug_msg(RELEASE, "Header Detected\n");
1107
1108                 ret = 1;
1109                 goto exit;
1110         }
1111
1112 exit:
1113         if (pFileIO == NULL && fp != NULL)
1114                 mmfile_close(fp);
1115
1116         return ret;
1117 }
1118
1119 /***********************************************************************/
1120 /*                     MPEGTS Header Check API                            */
1121 /***********************************************************************/
1122 #define MPEGTS_NONE     0x00
1123 #define MPEGTS_FECE             0x10
1124 #define MPEGTS_DVHS     0x20
1125 #define MPEGTS_PACKET   0x40
1126
1127 #define TS_PACKET_SIZE          188
1128 #define TS_DVHS_PACKET_SIZE     192
1129 #define TS_FEC_PACKET_SIZE      204
1130 #define TS_MAX_PACKET_SIZE      204
1131
1132 EXPORT_API
1133 int MMFileFormatIsValidMPEGTS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1134 {
1135         MMFileIOHandle *fp = pFileIO;
1136         unsigned char buffer[TS_MAX_PACKET_SIZE] = {0, };
1137         int readed = 0;
1138         int ret = 0;
1139
1140         if (fp == NULL) {
1141                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1142                 if (ret == MMFILE_IO_FAILED) {
1143                         debug_error(DEBUG, "error: mmfile_open\n");
1144                         goto exit;
1145                 }
1146         }
1147
1148         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1149
1150         readed = mmfile_read(fp, buffer, TS_MAX_PACKET_SIZE);
1151
1152         if (TS_MAX_PACKET_SIZE != readed) {
1153                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1154                 ret = 0;
1155                 goto exit;
1156         }
1157
1158         if (_MMFileIsMPEGTSHeader(fp) != MPEGTS_NONE) {
1159                 debug_msg(RELEASE, "Header Detected\n");
1160                 ret = 1;
1161                 goto exit;
1162         }
1163
1164 exit:
1165         if (pFileIO == NULL && fp != NULL)
1166                 mmfile_close(fp);
1167
1168         return ret;
1169 }
1170
1171 /***********************************************************************/
1172 /*                     MPEG-PS Header Check API                            */
1173 /***********************************************************************/
1174 EXPORT_API
1175 int MMFileFormatIsValidMPEGPS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1176 {
1177 #define _MMFILE_MPEGPS_HEADER_LENGTH 4
1178
1179         MMFileIOHandle *fp = pFileIO;
1180         unsigned char buffer[_MMFILE_MPEGPS_HEADER_LENGTH] = {0, };
1181         int readed = 0;
1182         int ret = 0;
1183
1184         if (fp == NULL) {
1185                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1186                 if (ret == MMFILE_IO_FAILED) {
1187                         debug_error(DEBUG, "error: mmfile_open\n");
1188                         goto exit;
1189                 }
1190         }
1191
1192         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1193
1194         readed = mmfile_read(fp, buffer, _MMFILE_MPEGPS_HEADER_LENGTH);
1195
1196         if (_MMFILE_MPEGPS_HEADER_LENGTH != readed) {
1197                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1198                 ret = 0;
1199                 goto exit;
1200         }
1201
1202         if (1 == _MMFileIsMPEGPSHeader(buffer)) {
1203                 debug_msg(RELEASE, "Header Detected\n");
1204                 ret = 1;
1205                 goto exit;
1206         }
1207
1208 exit:
1209         if (pFileIO == NULL && fp != NULL)
1210                 mmfile_close(fp);
1211
1212         return ret;
1213 }
1214
1215 /***********************************************************************/
1216 /*                     MPEG AUDIO Header Check API                            */
1217 /***********************************************************************/
1218 EXPORT_API
1219 int MMFileFormatIsValidMPEGAUDIO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1220 {
1221 #define _MMFILE_MPEGAUDIO_HEADER_LENGTH 4
1222
1223         MMFileIOHandle *fp = pFileIO;
1224         unsigned char buffer[_MMFILE_MPEGAUDIO_HEADER_LENGTH] = {0, };
1225         int readed = 0;
1226         int ret = 0;
1227
1228         if (fp == NULL) {
1229                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1230                 if (ret == MMFILE_IO_FAILED) {
1231                         debug_error(DEBUG, "error: mmfile_open\n");
1232                         goto exit;
1233                 }
1234         }
1235
1236         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1237
1238         readed = mmfile_read(fp, buffer, _MMFILE_MPEGAUDIO_HEADER_LENGTH);
1239
1240         if (_MMFILE_MPEGAUDIO_HEADER_LENGTH != readed) {
1241                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1242                 ret = 0;
1243                 goto exit;
1244         }
1245
1246         if (1 == _MMFileIsMPEGAUDIOHeader(buffer)) {
1247                 debug_msg(RELEASE, "Header Detected\n");
1248                 ret = 1;
1249                 goto exit;
1250         }
1251
1252 exit:
1253         if (pFileIO == NULL && fp != NULL)
1254                 mmfile_close(fp);
1255
1256         return ret;
1257 }
1258
1259 /***********************************************************************/
1260 /*                     MPEG VIDEO Header Check API                            */
1261 /***********************************************************************/
1262 EXPORT_API
1263 int MMFileFormatIsValidMPEGVIDEO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1264 {
1265 #define _MMFILE_MPEGVIDEO_HEADER_LENGTH 4
1266
1267         MMFileIOHandle *fp = pFileIO;
1268         unsigned char buffer[_MMFILE_MPEGVIDEO_HEADER_LENGTH] = {0, };
1269         int readed = 0;
1270         int ret = 0;
1271
1272         if (fp == NULL) {
1273                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1274                 if (ret == MMFILE_IO_FAILED) {
1275                         debug_error(DEBUG, "error: mmfile_open\n");
1276                         goto exit;
1277                 }
1278         }
1279
1280         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1281
1282         readed = mmfile_read(fp, buffer, _MMFILE_MPEGVIDEO_HEADER_LENGTH);
1283
1284         if (_MMFILE_MPEGVIDEO_HEADER_LENGTH != readed) {
1285                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1286                 ret = 0;
1287                 goto exit;
1288         }
1289
1290         if (1 == _MMFileIsMPEGVIDEOHeader(buffer)) {
1291                 debug_msg(RELEASE, "Header Detected\n");
1292                 ret = 1;
1293                 goto exit;
1294         }
1295
1296 exit:
1297         if (pFileIO == NULL && fp != NULL)
1298                 mmfile_close(fp);
1299
1300         return ret;
1301 }
1302
1303
1304
1305
1306 /***********************************************************************/
1307 /*            Implementation of Internal Functions                     */
1308 /***********************************************************************/
1309 static int _MMFileIsASFHeader(void *header)
1310 {
1311         /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */
1312         unsigned char *s = header;
1313
1314         if ((*(s +  0) == 0x30) &&
1315             (*(s +  1) == 0x26) &&
1316             (*(s +  2) == 0xB2) &&
1317             (*(s +  3) == 0x75) &&
1318             (*(s +  4) == 0x8E) &&
1319             (*(s +  5) == 0x66) &&
1320             (*(s +  6) == 0xCF) &&
1321             (*(s +  7) == 0x11) &&
1322             (*(s +  8) == 0xA6) &&
1323             (*(s +  9) == 0xD9) &&
1324             (*(s + 10) == 0x00) &&
1325             (*(s + 11) == 0xAA) &&
1326             (*(s + 12) == 0x00) &&
1327             (*(s + 13) == 0x62) &&
1328             (*(s + 14) == 0xCE) &&
1329             (*(s + 15) == 0x6C)) {
1330
1331                 return 1;
1332         }
1333
1334         return 0;
1335 }
1336
1337 static int _MMFileIsAMRHeader(void *header)
1338 {
1339 #define _MMFILE_AMR_SINGLE_CH_HEADER_SIZE       6
1340 #define _MMFILE_AMR_SINGLE_CH_HEADER            "#!AMR\n"
1341
1342 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE    9
1343 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER         "#!AMR-WB\n"
1344
1345 #define _MMFILE_AMR_MULTI_CH_HEADER_SIZE        12
1346 #define _MMFILE_AMR_MULTI_CH_HEADER             "#!AMR_MC1.0\n"
1347
1348 #define _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE     15
1349 #define _MMFILE_AMR_WB_MULTI_CH_HEADER          "#!AMR-WB_MC1.0\n"
1350
1351         unsigned char *s = header;
1352
1353         if (!memcmp(s, _MMFILE_AMR_SINGLE_CH_HEADER,    _MMFILE_AMR_SINGLE_CH_HEADER_SIZE) ||
1354             !memcmp(s, _MMFILE_AMR_WB_SINGLE_CH_HEADER, _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE) ||
1355             !memcmp(s, _MMFILE_AMR_MULTI_CH_HEADER,     _MMFILE_AMR_MULTI_CH_HEADER_SIZE) ||
1356             !memcmp(s, _MMFILE_AMR_WB_MULTI_CH_HEADER,  _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE)) {
1357
1358                 return 1;
1359         }
1360
1361         return 0;
1362 }
1363
1364 static int _MMFileIsIMYHeader(void *header)
1365 {
1366         unsigned char *s = header;
1367
1368         if (!memcmp(s, "BEGIN:IMELODY", 13)) {
1369                 return 1;
1370         }
1371
1372         return 0;
1373 }
1374
1375 static int _MMFileIsMIDHeader(void *header)
1376 {
1377         unsigned char *s = header;
1378
1379         if (!memcmp(s, "MThd", 4)) {    /*general MIDI*/
1380                 return 1;
1381         } else if (!memcmp(s, "XMF_", 4)) {     /*XMF*/
1382                 return 1;
1383         } else if (!memcmp(s, "IREZ", 4)) {
1384                 return 1;       /*RMF format*/
1385         }
1386
1387         return 0;
1388 }
1389
1390 static int _MMFileIsMMFHeader(void *header)
1391 {
1392 #define _MMFILE_MMF_TYPE_POSITION    ((char)0x11)
1393         unsigned char *s = header;
1394
1395         if (!memcmp(s, "MMMD", 4)) {
1396                 /* warning: comparison is always true due to limited range of data type */
1397                 if (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x2F) {
1398                         return 1;
1399                 } else if (((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x30) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x38)) /* MA3, MA5 type */
1400                         || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x40) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x48))
1401                         || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x50) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x58))
1402                         || ((*(s + _MMFILE_MMF_TYPE_POSITION) == 0xF0))) {
1403
1404                         return 1;
1405                 }
1406         }
1407
1408         return 0;
1409 }
1410
1411
1412 static int _MMFileIsAVIHeader(void *header)
1413 {
1414         unsigned char *s = header;
1415
1416         if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "AVI", 3)) {
1417                 return 1;
1418         }
1419
1420         return 0;
1421 }
1422
1423
1424 static int _MMFileIsWAVHeader(void *header)
1425 {
1426         unsigned char *s = header;
1427
1428         if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "WAVE", 4)) {
1429                 return 1;
1430         }
1431
1432         return 0;
1433 }
1434
1435
1436
1437 static int _MMFileIsMP4Header(void *header)
1438 {
1439         unsigned char *s = header;
1440
1441         if (!memcmp(s, "moov", 4) ||
1442             !memcmp(s, "mdat", 4) ||
1443             !memcmp(s, "ftyp", 4) ||
1444             !memcmp(s, "free", 4) ||
1445             !memcmp(s, "uuid", 4) ||
1446             !memcmp(s, "skip", 4) ||
1447
1448             !memcmp(s, "PICT", 4) ||
1449             !memcmp(s, "wide", 4) ||
1450             !memcmp(s, "prfl", 4)) {
1451                 return 1;
1452         }
1453
1454         return 0;
1455 }
1456
1457 static int _MMFileIsOGGHeader(void *header)
1458 {
1459         unsigned char *s = header;
1460
1461         if (!memcmp(s, "OggS", 4)) {
1462                 return 1;
1463         }
1464
1465         return 0;
1466 }
1467
1468 static int _MMFileIsREALHeader(void *header)
1469 {
1470         unsigned char *s = header;
1471
1472         if (!memcmp(s, ".RMF", 4)) {
1473                 return 1;
1474         }
1475
1476         return 0;
1477 }
1478
1479 static int _MMFileIsMPEGTSHeader(MMFileIOHandle *fp)
1480 {
1481         unsigned char header[TS_MAX_PACKET_SIZE] = {0, };
1482         unsigned char *s = NULL;
1483
1484         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1485         mmfile_read(fp, header, sizeof(header));
1486
1487         s = (unsigned char *)memchr(header, 0x47, sizeof(header));
1488
1489         if (s) {
1490                 unsigned char buffer[TS_PACKET_SIZE] = {0, };
1491                 unsigned int  startoffset = s - header + 1;
1492
1493                 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1494                 mmfile_read(fp, buffer, sizeof(buffer));
1495
1496                 if (buffer[sizeof(buffer) - 1] & 0x47) {
1497                         return MPEGTS_PACKET;
1498                 } else {
1499                         unsigned char dvhs_buf[TS_DVHS_PACKET_SIZE] = {0, };
1500
1501                         mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1502                         mmfile_read(fp, dvhs_buf, sizeof(dvhs_buf));
1503
1504                         if (dvhs_buf[sizeof(dvhs_buf) - 1] & 0x47) {
1505                                 return MPEGTS_DVHS;
1506                         } else {
1507                                 unsigned char fec_buf[TS_FEC_PACKET_SIZE] = {0, };
1508
1509                                 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1510                                 mmfile_read(fp, fec_buf, sizeof(fec_buf));
1511
1512                                 if (fec_buf[sizeof(fec_buf) - 1] & 0x47) {
1513                                         return MPEGTS_FECE;
1514                                 }
1515                         }
1516                 }
1517         }
1518
1519         return MPEGTS_NONE;
1520 }
1521
1522 static int _MMFileIsMPEGPSHeader(void *header)
1523 {
1524         unsigned char *s = header;
1525
1526         if ((*(s +  0) == 0x00) &&
1527             (*(s +  1) == 0x00) &&
1528             (*(s +  2) == 0x01) &&
1529             (*(s +  3) == 0xba)) {      /* mpeg-ps header */
1530                 return 1;
1531         }
1532
1533         return 0;
1534 }
1535
1536 static int _MMFileIsMPEGAUDIOHeader(void *header)
1537 {
1538         unsigned char *s = header;
1539
1540         if ((*(s + 0) == 0xFF) &&
1541             ((*(s + 1) == 0xFE) || (*(s + 1) == 0xFF))) {       /* mpeg audio layer 1 header ,FE: protected by CRC ,FF: not protected */
1542                 return 1;
1543         }
1544
1545         return 0;
1546 }
1547
1548 static int _MMFileIsMPEGVIDEOHeader(void *header)
1549 {
1550         unsigned char *s = header;
1551
1552         if ((*(s +  0) == 0x00) &&
1553             (*(s +  1) == 0x00) &&
1554             (*(s +  2) == 0x01) &&
1555             (*(s +  3) == 0xb3)) {      /* mpeg1 video header */
1556                 return 1;
1557         }
1558
1559         return 0;
1560 }
1561
1562 static int _MMFileIsMP3Header(void *header)
1563 {
1564         unsigned long head = 0;
1565         unsigned char *headc = header;
1566         unsigned int bitrate, layer, length/*, mode*/;
1567         unsigned int coef, samplerate, version/*, channels*/;
1568         static const unsigned int mp3types_bitrates[2][3][16] = {
1569                 {       {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
1570                         {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
1571                         {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
1572                 },
1573                 {       {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
1574                         {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
1575                         {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
1576                 },
1577         };
1578
1579         static const unsigned int mp3types_freqs[3][3] = {
1580                 {11025, 12000, 8000},
1581                 {22050, 24000, 16000},
1582                 {44100, 48000, 32000}
1583         };
1584
1585         static const unsigned int mp3FrameCoef[4][4] = {
1586                 { -1, 48, 144, 72},
1587                 { -1, -1, -1, -1},
1588                 { -1, 48, 144, 72},
1589                 { -1, 48, 144, 144}
1590         };
1591
1592         /* header */
1593         head = (*(headc + 0) << 24 | *(headc + 1) << 16 | *(headc + 2) << 8 | *(headc + 3));
1594
1595         if ((head & 0xffe00000) != 0xffe00000) {
1596                 return 0;
1597         }
1598
1599         /* we don't need extension, copyright, original or
1600         * emphasis for the frame length */
1601         head >>= 6;
1602
1603         /* mode */
1604         /*mode = head & 0x3;*/
1605         head >>= 3;
1606
1607         /* padding */
1608         length = head & 0x1;
1609         head >>= 1;
1610
1611         /* sampling frequency */
1612         samplerate = head & 0x3;
1613         if (samplerate == 3) {
1614                 return 0;
1615         }
1616         head >>= 2;
1617
1618         /* bitrate index */
1619         bitrate = head & 0xF;
1620
1621         if (bitrate == 15) {
1622                 return 0;
1623         }
1624
1625         /* ignore error correction, too */
1626         head >>= 5;
1627
1628         /* layer */
1629         layer = 4 - (head & 0x3);
1630         if (layer == 4) {
1631                 return 0;
1632         }
1633         head >>= 2;
1634
1635         /* version 0=MPEG2.5; 2=MPEG2; 3=MPEG1 */
1636         version = head & 0x3;
1637         if (version == 1) {
1638                 return 0;
1639         }
1640
1641         /* lookup */
1642         /*channels = (mode == 3) ? 1 : 2;*/
1643         samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
1644         {
1645                 /* calculating */
1646                 bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
1647                 coef = mp3FrameCoef[version][layer];
1648                 if (layer == 1)
1649                         length = length * 4;
1650
1651                 length = length + ((coef * bitrate * 1000) / samplerate);
1652         }
1653
1654         return length;
1655 }
1656
1657 static int _MMFileSearchID3Tag(MMFileIOHandle *fp, unsigned int *offset)
1658 {
1659 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
1660 #define _MMFILE_GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
1661
1662         unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0, };
1663         unsigned int tagInfoSize = 0;
1664         unsigned int acc_tagsize = 0;
1665         int tagVersion = 0;
1666         int encSize = 0;
1667         int readed = 0;
1668         int ret = 0;
1669
1670         /*init offset*/
1671         *offset = 0;
1672
1673         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1674
1675 _START_TAG_SEARCH:
1676
1677         readed = mmfile_read(fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
1678         if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
1679                 debug_error(RELEASE, "read error occured.\n");
1680                 return 0;
1681         }
1682
1683         if (memcmp(tagHeader, "ID3", 3) == 0) {
1684                 debug_msg(RELEASE, "'ID3' found.\n");
1685         } else {
1686                 debug_msg(RELEASE, "'ID3' not found.\n");
1687                 goto search_end;
1688         }
1689
1690         /**@note weak id3v2 tag checking*/
1691         if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
1692             (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
1693             (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
1694                 debug_msg(RELEASE, "good ID3V2 tag.\n");
1695         } else {
1696                 debug_warning(DEBUG, "It's bad ID3V2 tag.\n");
1697                 goto search_end;
1698         }
1699
1700         tagVersion = tagHeader[3];
1701
1702         if (tagVersion > 4) {
1703                 debug_msg(RELEASE, "Tag version not supported\n");
1704                 goto search_end;
1705         }
1706
1707         encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
1708         tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
1709         tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
1710
1711         /**@note unfortunately, some contents has many id3 tag.*/
1712         acc_tagsize += tagInfoSize;
1713         debug_msg(RELEASE, "tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
1714
1715         mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
1716         *offset = acc_tagsize;
1717
1718         ret = 1;
1719
1720         goto _START_TAG_SEARCH;
1721
1722 search_end:
1723         return ret;
1724 }
1725
1726 static int _MMFileIsFLACHeader(void *header)
1727 {
1728         unsigned char *s = header;
1729
1730         if (!memcmp(s, "fLaC", 4)) {
1731                 return 1;
1732         }
1733
1734         return 0;
1735 }
1736
1737 static int _MMFileIsFLVHeader(void *header)
1738 {
1739         unsigned char *s = header;
1740
1741         if (!memcmp(s, "FLV", 3)) {
1742                 return 1;
1743         }
1744
1745         return 0;
1746 }