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