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