Improve 'MMFileFormatIsValidXXX' function to reduce DC
[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         return MMFileFormatIsValidASF(pFileIO, mmfileuri, dummy);
671 }
672
673
674
675 /***********************************************************************/
676 /*                     WMV Header Check API                            */
677 /***********************************************************************/
678 EXPORT_API
679 int MMFileFormatIsValidWMV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
680 {
681         return MMFileFormatIsValidASF(pFileIO, mmfileuri, dummy);
682 }
683
684
685 /***********************************************************************/
686 /*                     MMF Header Check API                            */
687 /***********************************************************************/
688 EXPORT_API
689 int MMFileFormatIsValidMMF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
690 {
691 #define _MMFILE_MMF_HEADER_LENGTH 18
692
693         MMFileIOHandle *fp = pFileIO;
694         unsigned char buffer[_MMFILE_MMF_HEADER_LENGTH] = {0, };
695         int           readed = 0;
696         int ret = 0;
697
698         if (fp == NULL) {
699                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
700                 if (ret == MMFILE_IO_FAILED) {
701                         debug_error(DEBUG, "error: mmfile_open\n");
702                         goto exit;
703                 }
704         }
705
706         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
707
708         readed = mmfile_read(fp, buffer, _MMFILE_MMF_HEADER_LENGTH);
709
710         if (_MMFILE_MMF_HEADER_LENGTH != readed) {
711                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
712                 ret = 0;
713                 goto exit;
714         }
715
716         if (1 == _MMFileIsMMFHeader(buffer)) {
717                 debug_msg(RELEASE, "Header Detected\n");
718                 ret = 1;
719                 goto exit;
720         }
721
722 exit:
723         if (pFileIO == NULL && fp != NULL)
724                 mmfile_close(fp);
725
726         return ret;
727 }
728
729
730
731 /***********************************************************************/
732 /*                     MMF Header Check API                            */
733 /***********************************************************************/
734 EXPORT_API
735 int MMFileFormatIsValidIMY(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
736 {
737 #define _MMFILE_IMY_HEADER_LENGTH 13
738
739         MMFileIOHandle *fp = pFileIO;
740         unsigned char buffer[_MMFILE_IMY_HEADER_LENGTH] = {0, };
741         int           readed = 0;
742         int ret = 0;
743
744         if (fp == NULL) {
745                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
746                 if (ret == MMFILE_IO_FAILED) {
747                         debug_error(DEBUG, "error: mmfile_open\n");
748                         goto exit;
749                 }
750         }
751
752         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
753
754         readed = mmfile_read(fp, buffer, _MMFILE_IMY_HEADER_LENGTH);
755
756         if (_MMFILE_IMY_HEADER_LENGTH != readed) {
757                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
758                 ret = 0;
759                 goto exit;
760         }
761
762         if (1 == _MMFileIsIMYHeader(buffer)) {
763                 debug_msg(RELEASE, "Header Detected\n");
764                 ret = 1;
765                 goto exit;
766         }
767
768 exit:
769         if (pFileIO == NULL && fp != NULL)
770                 mmfile_close(fp);
771
772         return ret;
773 }
774
775
776
777 /***********************************************************************/
778 /*                     AMR Header Check API                            */
779 /***********************************************************************/
780 EXPORT_API
781 int MMFileFormatIsValidAMR(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
782 {
783 #define _MMFILE_AMR_MAX_HEADER_SIZE 15
784 #define _MMFILE_AMR_MIN_HEADER_SIZE 6
785
786         MMFileIOHandle *fp = pFileIO;
787         unsigned char buffer[_MMFILE_AMR_MAX_HEADER_SIZE] = {0, };
788         int           readed = 0;
789         int ret = 0;
790
791         if (fp == NULL) {
792                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
793                 if (ret == MMFILE_IO_FAILED) {
794                         debug_error(DEBUG, "error: mmfile_open\n");
795                         goto exit;
796                 }
797         }
798
799         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
800
801         readed = mmfile_read(fp, buffer, _MMFILE_AMR_MAX_HEADER_SIZE);
802
803         if (_MMFILE_AMR_MAX_HEADER_SIZE != readed) {
804                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
805                 ret = 0;
806                 goto exit;
807         }
808
809         if (1 == _MMFileIsAMRHeader(buffer)) {
810                 debug_msg(RELEASE, "Header Detected\n");
811                 ret = 1;
812                 goto exit;
813         }
814
815 exit:
816         if (pFileIO == NULL && fp != NULL)
817                 mmfile_close(fp);
818
819         return ret;
820 }
821
822 /***********************************************************************/
823 /*                     Matroska Header Check API                       */
824 /***********************************************************************/
825 EXPORT_API
826 int MMFileFormatIsValidMatroska(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
827 {
828 #define _MMFILE_EBML_MARKER_LENGTH      4
829 #define _MMFILE_MKV_READ_BUFFER_LENGTH 2048
830
831         MMFileIOHandle *fp = pFileIO;
832         unsigned char buffer[_MMFILE_MKV_READ_BUFFER_LENGTH] = {0, };
833         int           readed = 0;
834         int ret = 0;
835         int len_mask = 0x80;
836         unsigned int size = 1, n = 1, total = 0;
837         //char probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
838         /*support webm, add probe data*/
839         const char * probe_data[2] = { "matroska", "webm" };
840         if (fp == NULL) {
841                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
842                 if (ret == MMFILE_IO_FAILED) {
843                         debug_error(DEBUG, "error: mmfile_open\n");
844                         goto exit;
845                 }
846         }
847
848         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
849
850         readed = mmfile_read(fp, buffer, _MMFILE_MKV_READ_BUFFER_LENGTH);
851
852         if (_MMFILE_MKV_READ_BUFFER_LENGTH != readed) {
853                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
854                 ret = 0;
855                 goto exit;
856         }
857
858         /* ebml header? */
859         if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
860                 debug_msg(RELEASE, "This is not a EBML format\n");
861                 ret = 0;
862                 goto exit;
863         }
864
865         /* length of header */
866         total = buffer[4];
867
868         debug_msg(RELEASE, "Initial total header size = [0x%x]\n", total);
869
870         while (size <= 8 && !(total & len_mask)) {
871                 debug_msg(DEBUG, "This case can not be handled yet....");
872                 size++;
873                 len_mask >>= 1;
874         }
875
876         debug_msg(RELEASE, "Final total header size = [%d]\n", total);
877
878         if (size > 8) {
879                 debug_msg(DEBUG, "This case can not be handled yet....");
880                 ret = 0;
881                 goto exit;
882         }
883
884         total &= (len_mask - 1);
885
886         while (n < size) {
887                 total = (total << 8) | buffer[4 + n++];
888                 debug_msg(DEBUG, "This case can not be handled yet....");
889         }
890
891         /* Does the probe data contain the whole header? */
892         if (_MMFILE_MKV_READ_BUFFER_LENGTH < 4 + size + total)
893                 return 0;
894
895         /*compare two kinds of probe data*/
896         for (int i = 0; i < 2; i++) {
897                 unsigned int probelen = strlen(probe_data[i]);
898                 if (total < probelen)
899                         continue;
900                 for (n = 4 + size ; n <= 4 + size + total - probelen; n++) {
901                         if (!memcmp(&buffer[n], probe_data[i], probelen)) {
902                                 debug_msg(RELEASE, "String %s found!!!\n", probe_data[i]);
903                                 ret = 1;
904                                 goto exit;
905                         }
906                 }
907         }
908
909 exit:
910         if (pFileIO == NULL && fp != NULL)
911                 mmfile_close(fp);
912
913         return ret;
914 }
915
916 /***********************************************************************/
917 /*                     QT Header Check API                       */
918 /***********************************************************************/
919 EXPORT_API
920 int MMFileFormatIsValidQT(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
921 {
922         return 1;
923 }
924
925 /***********************************************************************/
926 /*                     Flac Header Check API                       */
927 /***********************************************************************/
928 EXPORT_API
929 int MMFileFormatIsValidFLAC(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
930 {
931 #define _MMFILE_FLAC_HEADER_LENGTH 5    /*fLaC*/
932
933         MMFileIOHandle *fp = pFileIO;
934         unsigned char buffer[_MMFILE_FLAC_HEADER_LENGTH] = {0, };
935         int readed = 0;
936         int ret = 0;
937
938         if (fp == NULL) {
939                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
940                 if (ret == MMFILE_IO_FAILED) {
941                         debug_error(DEBUG, "error: mmfile_open\n");
942                         goto exit;
943                 }
944         }
945
946         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
947
948         readed = mmfile_read(fp, buffer, _MMFILE_FLAC_HEADER_LENGTH);
949
950         if (_MMFILE_FLAC_HEADER_LENGTH != readed) {
951                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
952                 ret = 0;
953                 goto exit;
954         }
955
956         if (1 == _MMFileIsFLACHeader(buffer)) {
957                 debug_msg(RELEASE, "Header Detected\n");
958                 ret = 1;
959                 goto exit;
960         }
961
962 exit:
963         if (pFileIO == NULL && fp != NULL)
964                 mmfile_close(fp);
965
966         return ret;
967 }
968
969 /***********************************************************************/
970 /*                     FLV(flash video) Header Check API                       */
971 /***********************************************************************/
972 EXPORT_API
973 int MMFileFormatIsValidFLV(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
974 {
975 #define _MMFILE_FLV_HEADER_LENGTH 4     /*FLV*/
976
977         MMFileIOHandle *fp = pFileIO;
978         unsigned char buffer[_MMFILE_FLV_HEADER_LENGTH] = {0, };
979         int readed = 0;
980         int ret = 0;
981
982         if (fp == NULL) {
983                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
984                 if (ret == MMFILE_IO_FAILED) {
985                         debug_error(DEBUG, "error: mmfile_open\n");
986                         goto exit;
987                 }
988         }
989
990         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
991
992         readed = mmfile_read(fp, buffer, _MMFILE_FLV_HEADER_LENGTH);
993
994         if (_MMFILE_FLV_HEADER_LENGTH != readed) {
995                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
996                 ret = 0;
997                 goto exit;
998         }
999
1000         if (1 == _MMFileIsFLVHeader(buffer)) {
1001                 debug_msg(RELEASE, "Header Detected\n");
1002                 ret = 1;
1003                 goto exit;
1004         }
1005
1006 exit:
1007         if (pFileIO == NULL && fp != NULL)
1008                 mmfile_close(fp);
1009
1010         return ret;
1011 }
1012
1013
1014 /***********************************************************************/
1015 /*                     REAL Header Check API                            */
1016 /***********************************************************************/
1017 EXPORT_API
1018 int MMFileFormatIsValidREAL(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1019 {
1020 #define _MMFILE_RMVB_HEADER_LENGTH 4    /*RMF*/
1021
1022         MMFileIOHandle *fp = pFileIO;
1023         unsigned char buffer[_MMFILE_RMVB_HEADER_LENGTH] = {0, };
1024         int readed = 0;
1025         int ret = 0;
1026
1027         if (fp == NULL) {
1028                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1029                 if (ret == MMFILE_IO_FAILED) {
1030                         debug_error(DEBUG, "error: mmfile_open\n");
1031                         goto exit;
1032                 }
1033         }
1034
1035         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1036
1037         readed = mmfile_read(fp, buffer, _MMFILE_RMVB_HEADER_LENGTH);
1038
1039         if (_MMFILE_RMVB_HEADER_LENGTH != readed) {
1040                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1041                 ret = 0;
1042                 goto exit;
1043         }
1044
1045         if (1 == _MMFileIsREALHeader(buffer)) {
1046                 debug_msg(RELEASE, "Header Detected\n");
1047
1048                 ret = 1;
1049                 goto exit;
1050         }
1051
1052 exit:
1053         if (pFileIO == NULL && fp != NULL)
1054                 mmfile_close(fp);
1055
1056         return ret;
1057 }
1058
1059 /***********************************************************************/
1060 /*                     MPEGTS Header Check API                            */
1061 /***********************************************************************/
1062 #define MPEGTS_NONE     0x00
1063 #define MPEGTS_FECE             0x10
1064 #define MPEGTS_DVHS     0x20
1065 #define MPEGTS_PACKET   0x40
1066
1067 #define TS_PACKET_SIZE          188
1068 #define TS_DVHS_PACKET_SIZE     192
1069 #define TS_FEC_PACKET_SIZE      204
1070 #define TS_MAX_PACKET_SIZE      204
1071
1072 EXPORT_API
1073 int MMFileFormatIsValidMPEGTS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1074 {
1075         MMFileIOHandle *fp = pFileIO;
1076         unsigned char buffer[TS_MAX_PACKET_SIZE] = {0, };
1077         int readed = 0;
1078         int ret = 0;
1079
1080         if (fp == NULL) {
1081                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1082                 if (ret == MMFILE_IO_FAILED) {
1083                         debug_error(DEBUG, "error: mmfile_open\n");
1084                         goto exit;
1085                 }
1086         }
1087
1088         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1089
1090         readed = mmfile_read(fp, buffer, TS_MAX_PACKET_SIZE);
1091
1092         if (TS_MAX_PACKET_SIZE != readed) {
1093                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1094                 ret = 0;
1095                 goto exit;
1096         }
1097
1098         if (_MMFileIsMPEGTSHeader(fp) != MPEGTS_NONE) {
1099                 debug_msg(RELEASE, "Header Detected\n");
1100                 ret = 1;
1101                 goto exit;
1102         }
1103
1104 exit:
1105         if (pFileIO == NULL && fp != NULL)
1106                 mmfile_close(fp);
1107
1108         return ret;
1109 }
1110
1111 /***********************************************************************/
1112 /*                     MPEG-PS Header Check API                            */
1113 /***********************************************************************/
1114 EXPORT_API
1115 int MMFileFormatIsValidMPEGPS(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1116 {
1117 #define _MMFILE_MPEGPS_HEADER_LENGTH 4
1118
1119         MMFileIOHandle *fp = pFileIO;
1120         unsigned char buffer[_MMFILE_MPEGPS_HEADER_LENGTH] = {0, };
1121         int readed = 0;
1122         int ret = 0;
1123
1124         if (fp == NULL) {
1125                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1126                 if (ret == MMFILE_IO_FAILED) {
1127                         debug_error(DEBUG, "error: mmfile_open\n");
1128                         goto exit;
1129                 }
1130         }
1131
1132         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1133
1134         readed = mmfile_read(fp, buffer, _MMFILE_MPEGPS_HEADER_LENGTH);
1135
1136         if (_MMFILE_MPEGPS_HEADER_LENGTH != readed) {
1137                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1138                 ret = 0;
1139                 goto exit;
1140         }
1141
1142         if (1 == _MMFileIsMPEGPSHeader(buffer)) {
1143                 debug_msg(RELEASE, "Header Detected\n");
1144                 ret = 1;
1145                 goto exit;
1146         }
1147
1148 exit:
1149         if (pFileIO == NULL && fp != NULL)
1150                 mmfile_close(fp);
1151
1152         return ret;
1153 }
1154
1155 /***********************************************************************/
1156 /*                     MPEG AUDIO Header Check API                            */
1157 /***********************************************************************/
1158 EXPORT_API
1159 int MMFileFormatIsValidMPEGAUDIO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1160 {
1161 #define _MMFILE_MPEGAUDIO_HEADER_LENGTH 4
1162
1163         MMFileIOHandle *fp = pFileIO;
1164         unsigned char buffer[_MMFILE_MPEGAUDIO_HEADER_LENGTH] = {0, };
1165         int readed = 0;
1166         int ret = 0;
1167
1168         if (fp == NULL) {
1169                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1170                 if (ret == MMFILE_IO_FAILED) {
1171                         debug_error(DEBUG, "error: mmfile_open\n");
1172                         goto exit;
1173                 }
1174         }
1175
1176         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1177
1178         readed = mmfile_read(fp, buffer, _MMFILE_MPEGAUDIO_HEADER_LENGTH);
1179
1180         if (_MMFILE_MPEGAUDIO_HEADER_LENGTH != readed) {
1181                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1182                 ret = 0;
1183                 goto exit;
1184         }
1185
1186         if (1 == _MMFileIsMPEGAUDIOHeader(buffer)) {
1187                 debug_msg(RELEASE, "Header Detected\n");
1188                 ret = 1;
1189                 goto exit;
1190         }
1191
1192 exit:
1193         if (pFileIO == NULL && fp != NULL)
1194                 mmfile_close(fp);
1195
1196         return ret;
1197 }
1198
1199 /***********************************************************************/
1200 /*                     MPEG VIDEO Header Check API                            */
1201 /***********************************************************************/
1202 EXPORT_API
1203 int MMFileFormatIsValidMPEGVIDEO(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1204 {
1205 #define _MMFILE_MPEGVIDEO_HEADER_LENGTH 4
1206
1207         MMFileIOHandle *fp = pFileIO;
1208         unsigned char buffer[_MMFILE_MPEGVIDEO_HEADER_LENGTH] = {0, };
1209         int readed = 0;
1210         int ret = 0;
1211
1212         if (fp == NULL) {
1213                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1214                 if (ret == MMFILE_IO_FAILED) {
1215                         debug_error(DEBUG, "error: mmfile_open\n");
1216                         goto exit;
1217                 }
1218         }
1219
1220         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1221
1222         readed = mmfile_read(fp, buffer, _MMFILE_MPEGVIDEO_HEADER_LENGTH);
1223
1224         if (_MMFILE_MPEGVIDEO_HEADER_LENGTH != readed) {
1225                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1226                 ret = 0;
1227                 goto exit;
1228         }
1229
1230         if (1 == _MMFileIsMPEGVIDEOHeader(buffer)) {
1231                 debug_msg(RELEASE, "Header Detected\n");
1232                 ret = 1;
1233                 goto exit;
1234         }
1235
1236 exit:
1237         if (pFileIO == NULL && fp != NULL)
1238                 mmfile_close(fp);
1239
1240         return ret;
1241 }
1242
1243 /***********************************************************************/
1244 /*                     AIFF Header Check API                                  */
1245 /***********************************************************************/
1246 EXPORT_API
1247 int MMFileFormatIsValidAIFF(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1248 {
1249 #define _MMFILE_AIFF_HEADER_LENGTH 13
1250
1251         MMFileIOHandle *fp = pFileIO;
1252         unsigned char buffer[_MMFILE_AIFF_HEADER_LENGTH] = {0, };
1253         int           readed = 0;
1254         int ret = 0;
1255
1256         if (fp == NULL) {
1257                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1258                 if (ret == MMFILE_IO_FAILED) {
1259                         debug_error(DEBUG, "error: mmfile_open\n");
1260                         goto exit;
1261                 }
1262         }
1263
1264         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1265
1266         readed = mmfile_read(fp, buffer, _MMFILE_AIFF_HEADER_LENGTH);
1267
1268         if (_MMFILE_AIFF_HEADER_LENGTH != readed) {
1269                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1270                 ret = 0;
1271                 goto exit;
1272         }
1273
1274         if (1 == _MMFileIsAIFFHeader(buffer)) {
1275                 debug_msg(RELEASE, "Header Detected\n");
1276                 ret = 1;
1277                 goto exit;
1278         }
1279
1280 exit:
1281         if (pFileIO == NULL && fp != NULL)
1282                 mmfile_close(fp);
1283
1284         return ret;
1285 }
1286
1287 EXPORT_API
1288 int MMFileFormatIsValidAPE(MMFileIOHandle *pFileIO, const char *mmfileuri, int dummy)
1289 {
1290 #define _MMFILE_APE_HEADER_LENGTH 4     /*APE*/
1291
1292         MMFileIOHandle *fp = pFileIO;
1293         unsigned char buffer[_MMFILE_APE_HEADER_LENGTH] = {0, };
1294         int readed = 0;
1295         int ret = 0;
1296
1297         if (fp == NULL) {
1298                 ret = mmfile_open(&fp, mmfileuri, MMFILE_RDONLY);
1299                 if (ret == MMFILE_IO_FAILED) {
1300                         debug_error(DEBUG, "error: mmfile_open\n");
1301                         goto exit;
1302                 }
1303         }
1304
1305         mmfile_seek(fp, 0L, MMFILE_SEEK_SET);
1306
1307         readed = mmfile_read(fp, buffer, _MMFILE_APE_HEADER_LENGTH);
1308
1309         if (_MMFILE_APE_HEADER_LENGTH != readed) {
1310                 debug_error(RELEASE, "read error. size = %d. Maybe end of file.\n", readed);
1311                 ret = 0;
1312                 goto exit;
1313         }
1314
1315         if (1 == _MMFileIsAPEHeader(buffer)) {
1316                 debug_msg(RELEASE, "Header Detected\n");
1317                 ret = 1;
1318                 goto exit;
1319         }
1320
1321 exit:
1322         if (pFileIO == NULL && fp != NULL)
1323                 mmfile_close(fp);
1324
1325         return ret;
1326 }
1327
1328 /***********************************************************************/
1329 /*            Implementation of Internal Functions                     */
1330 /***********************************************************************/
1331 static int _MMFileIsASFHeader(void *header)
1332 {
1333         /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */
1334         unsigned char *s = header;
1335
1336         if ((*(s +  0) == 0x30) &&
1337             (*(s +  1) == 0x26) &&
1338             (*(s +  2) == 0xB2) &&
1339             (*(s +  3) == 0x75) &&
1340             (*(s +  4) == 0x8E) &&
1341             (*(s +  5) == 0x66) &&
1342             (*(s +  6) == 0xCF) &&
1343             (*(s +  7) == 0x11) &&
1344             (*(s +  8) == 0xA6) &&
1345             (*(s +  9) == 0xD9) &&
1346             (*(s + 10) == 0x00) &&
1347             (*(s + 11) == 0xAA) &&
1348             (*(s + 12) == 0x00) &&
1349             (*(s + 13) == 0x62) &&
1350             (*(s + 14) == 0xCE) &&
1351             (*(s + 15) == 0x6C)) {
1352
1353                 return 1;
1354         }
1355
1356         return 0;
1357 }
1358
1359 static int _MMFileIsAMRHeader(void *header)
1360 {
1361 #define _MMFILE_AMR_SINGLE_CH_HEADER_SIZE       6
1362 #define _MMFILE_AMR_SINGLE_CH_HEADER            "#!AMR\n"
1363
1364 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE    9
1365 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER         "#!AMR-WB\n"
1366
1367 #define _MMFILE_AMR_MULTI_CH_HEADER_SIZE        12
1368 #define _MMFILE_AMR_MULTI_CH_HEADER             "#!AMR_MC1.0\n"
1369
1370 #define _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE     15
1371 #define _MMFILE_AMR_WB_MULTI_CH_HEADER          "#!AMR-WB_MC1.0\n"
1372
1373         unsigned char *s = header;
1374
1375         if (!memcmp(s, _MMFILE_AMR_SINGLE_CH_HEADER,    _MMFILE_AMR_SINGLE_CH_HEADER_SIZE) ||
1376             !memcmp(s, _MMFILE_AMR_WB_SINGLE_CH_HEADER, _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE) ||
1377             !memcmp(s, _MMFILE_AMR_MULTI_CH_HEADER,     _MMFILE_AMR_MULTI_CH_HEADER_SIZE) ||
1378             !memcmp(s, _MMFILE_AMR_WB_MULTI_CH_HEADER,  _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE)) {
1379
1380                 return 1;
1381         }
1382
1383         return 0;
1384 }
1385
1386 static int _MMFileIsIMYHeader(void *header)
1387 {
1388         unsigned char *s = header;
1389
1390         if (!memcmp(s, "BEGIN:IMELODY", 13)) {
1391                 return 1;
1392         }
1393
1394         return 0;
1395 }
1396
1397 static int _MMFileIsMIDHeader(void *header)
1398 {
1399         unsigned char *s = header;
1400
1401         if (!memcmp(s, "MThd", 4)) {    /*general MIDI*/
1402                 return 1;
1403         } else if (!memcmp(s, "XMF_", 4)) {     /*XMF*/
1404                 return 1;
1405         } else if (!memcmp(s, "IREZ", 4)) {
1406                 return 1;       /*RMF format*/
1407         }
1408
1409         return 0;
1410 }
1411
1412 static int _MMFileIsMMFHeader(void *header)
1413 {
1414 #define _MMFILE_MMF_TYPE_POSITION    ((char)0x11)
1415         unsigned char *s = header;
1416
1417         if (!memcmp(s, "MMMD", 4)) {
1418                 /* warning: comparison is always true due to limited range of data type */
1419                 if (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x2F) {
1420                         return 1;
1421                 } else if (((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x30) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x38)) /* MA3, MA5 type */
1422                         || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x40) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x48))
1423                         || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x50) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x58))
1424                         || ((*(s + _MMFILE_MMF_TYPE_POSITION) == 0xF0))) {
1425
1426                         return 1;
1427                 }
1428         }
1429
1430         return 0;
1431 }
1432
1433
1434 static int _MMFileIsAVIHeader(void *header)
1435 {
1436         unsigned char *s = header;
1437
1438         if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "AVI", 3)) {
1439                 return 1;
1440         }
1441
1442         return 0;
1443 }
1444
1445
1446 static int _MMFileIsWAVHeader(void *header)
1447 {
1448         unsigned char *s = header;
1449
1450         if (!memcmp(s, "RIFF", 4) && !memcmp(s + 8, "WAVE", 4)) {
1451                 return 1;
1452         }
1453
1454         return 0;
1455 }
1456
1457
1458
1459 static int _MMFileIsMP4Header(void *header)
1460 {
1461         unsigned char *s = header;
1462
1463         if (!memcmp(s, "moov", 4) ||
1464             !memcmp(s, "mdat", 4) ||
1465             !memcmp(s, "ftyp", 4) ||
1466             !memcmp(s, "free", 4) ||
1467             !memcmp(s, "uuid", 4) ||
1468             !memcmp(s, "skip", 4) ||
1469
1470             !memcmp(s, "PICT", 4) ||
1471             !memcmp(s, "wide", 4) ||
1472             !memcmp(s, "prfl", 4)) {
1473                 return 1;
1474         }
1475
1476         return 0;
1477 }
1478
1479 static int _MMFileIsOGGHeader(void *header)
1480 {
1481         unsigned char *s = header;
1482
1483         if (!memcmp(s, "OggS", 4)) {
1484                 return 1;
1485         }
1486
1487         return 0;
1488 }
1489
1490 static int _MMFileIsREALHeader(void *header)
1491 {
1492         unsigned char *s = header;
1493
1494         if (!memcmp(s, ".RMF", 4)) {
1495                 return 1;
1496         }
1497
1498         return 0;
1499 }
1500
1501 static int _MMFileIsMPEGTSHeader(MMFileIOHandle *fp)
1502 {
1503         unsigned char header[TS_MAX_PACKET_SIZE] = {0, };
1504         unsigned char *s = NULL;
1505
1506         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1507         mmfile_read(fp, header, sizeof(header));
1508
1509         s = (unsigned char *)memchr(header, 0x47, sizeof(header));
1510
1511         if (s) {
1512                 unsigned char buffer[TS_PACKET_SIZE] = {0, };
1513                 unsigned int  startoffset = s - header + 1;
1514
1515                 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1516                 mmfile_read(fp, buffer, sizeof(buffer));
1517
1518                 if (buffer[sizeof(buffer) - 1] & 0x47) {
1519                         return MPEGTS_PACKET;
1520                 } else {
1521                         unsigned char dvhs_buf[TS_DVHS_PACKET_SIZE] = {0, };
1522
1523                         mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1524                         mmfile_read(fp, dvhs_buf, sizeof(dvhs_buf));
1525
1526                         if (dvhs_buf[sizeof(dvhs_buf) - 1] & 0x47) {
1527                                 return MPEGTS_DVHS;
1528                         } else {
1529                                 unsigned char fec_buf[TS_FEC_PACKET_SIZE] = {0, };
1530
1531                                 mmfile_seek(fp, startoffset, MMFILE_SEEK_SET);
1532                                 mmfile_read(fp, fec_buf, sizeof(fec_buf));
1533
1534                                 if (fec_buf[sizeof(fec_buf) - 1] & 0x47) {
1535                                         return MPEGTS_FECE;
1536                                 }
1537                         }
1538                 }
1539         }
1540
1541         return MPEGTS_NONE;
1542 }
1543
1544 static int _MMFileIsMPEGPSHeader(void *header)
1545 {
1546         unsigned char *s = header;
1547
1548         if ((*(s +  0) == 0x00) &&
1549             (*(s +  1) == 0x00) &&
1550             (*(s +  2) == 0x01) &&
1551             (*(s +  3) == 0xba)) {      /* mpeg-ps header */
1552                 return 1;
1553         }
1554
1555         return 0;
1556 }
1557
1558 static int _MMFileIsMPEGAUDIOHeader(void *header)
1559 {
1560         unsigned char *s = header;
1561
1562         if ((*(s + 0) == 0xFF) &&
1563             ((*(s + 1) == 0xFE) || (*(s + 1) == 0xFF))) {       /* mpeg audio layer 1 header ,FE: protected by CRC ,FF: not protected */
1564                 return 1;
1565         }
1566
1567         return 0;
1568 }
1569
1570 static int _MMFileIsMPEGVIDEOHeader(void *header)
1571 {
1572         unsigned char *s = header;
1573
1574         if ((*(s +  0) == 0x00) &&
1575             (*(s +  1) == 0x00) &&
1576             (*(s +  2) == 0x01) &&
1577             (*(s +  3) == 0xb3)) {      /* mpeg1 video header */
1578                 return 1;
1579         }
1580
1581         return 0;
1582 }
1583
1584 static int _MMFileIsMP3Header(void *header)
1585 {
1586         unsigned long head = 0;
1587         unsigned char *headc = header;
1588         unsigned int bitrate, layer, length/*, mode*/;
1589         unsigned int coef, samplerate, version/*, channels*/;
1590         static const unsigned int mp3types_bitrates[2][3][16] = {
1591                 {       {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
1592                         {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
1593                         {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
1594                 },
1595                 {       {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
1596                         {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
1597                         {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
1598                 },
1599         };
1600
1601         static const unsigned int mp3types_freqs[3][3] = {
1602                 {11025, 12000, 8000},
1603                 {22050, 24000, 16000},
1604                 {44100, 48000, 32000}
1605         };
1606
1607         static const unsigned int mp3FrameCoef[4][4] = {
1608                 { -1, 48, 144, 72},
1609                 { -1, -1, -1, -1},
1610                 { -1, 48, 144, 72},
1611                 { -1, 48, 144, 144}
1612         };
1613
1614         /* header */
1615         head = (*(headc + 0) << 24 | *(headc + 1) << 16 | *(headc + 2) << 8 | *(headc + 3));
1616
1617         if ((head & 0xffe00000) != 0xffe00000) {
1618                 return 0;
1619         }
1620
1621         /* we don't need extension, copyright, original or
1622         * emphasis for the frame length */
1623         head >>= 6;
1624
1625         /* mode */
1626         /*mode = head & 0x3;*/
1627         head >>= 3;
1628
1629         /* padding */
1630         length = head & 0x1;
1631         head >>= 1;
1632
1633         /* sampling frequency */
1634         samplerate = head & 0x3;
1635         if (samplerate == 3) {
1636                 return 0;
1637         }
1638         head >>= 2;
1639
1640         /* bitrate index */
1641         bitrate = head & 0xF;
1642
1643         if (bitrate == 15) {
1644                 return 0;
1645         }
1646
1647         /* ignore error correction, too */
1648         head >>= 5;
1649
1650         /* layer */
1651         layer = 4 - (head & 0x3);
1652         if (layer == 4) {
1653                 return 0;
1654         }
1655         head >>= 2;
1656
1657         /* version 0=MPEG2.5; 2=MPEG2; 3=MPEG1 */
1658         version = head & 0x3;
1659         if (version == 1) {
1660                 return 0;
1661         }
1662
1663         /* lookup */
1664         /*channels = (mode == 3) ? 1 : 2;*/
1665         samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
1666         {
1667                 /* calculating */
1668                 bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
1669                 coef = mp3FrameCoef[version][layer];
1670                 if (layer == 1)
1671                         length = length * 4;
1672
1673                 length = length + ((coef * bitrate * 1000) / samplerate);
1674         }
1675
1676         return length;
1677 }
1678
1679 static int _MMFileSearchID3Tag(MMFileIOHandle *fp, unsigned int *offset)
1680 {
1681 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
1682 #define _MMFILE_GET_INT_NUMBER(buff) (int)((((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
1683
1684         unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0, };
1685         unsigned int tagInfoSize = 0;
1686         unsigned int acc_tagsize = 0;
1687         int tagVersion = 0;
1688         int encSize = 0;
1689         int readed = 0;
1690         int ret = 0;
1691
1692         /*init offset*/
1693         *offset = 0;
1694
1695         mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1696
1697 _START_TAG_SEARCH:
1698
1699         readed = mmfile_read(fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
1700         if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
1701                 debug_error(RELEASE, "read error occured.\n");
1702                 return 0;
1703         }
1704
1705         if (memcmp(tagHeader, "ID3", 3) == 0) {
1706                 debug_msg(RELEASE, "'ID3' found.\n");
1707         } else {
1708                 debug_msg(RELEASE, "'ID3' not found.\n");
1709                 goto search_end;
1710         }
1711
1712         /**@note weak id3v2 tag checking*/
1713         if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
1714             (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
1715             (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
1716                 debug_msg(RELEASE, "good ID3V2 tag.\n");
1717         } else {
1718                 debug_warning(DEBUG, "It's bad ID3V2 tag.\n");
1719                 goto search_end;
1720         }
1721
1722         tagVersion = tagHeader[3];
1723
1724         if (tagVersion > 4) {
1725                 debug_msg(RELEASE, "Tag version not supported\n");
1726                 goto search_end;
1727         }
1728
1729         encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
1730         tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
1731         tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
1732
1733         /**@note unfortunately, some contents has many id3 tag.*/
1734         acc_tagsize += tagInfoSize;
1735         debug_msg(RELEASE, "tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
1736
1737         mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
1738         *offset = acc_tagsize;
1739
1740         ret = 1;
1741
1742         goto _START_TAG_SEARCH;
1743
1744 search_end:
1745         return ret;
1746 }
1747
1748 static int _MMFileIsFLACHeader(void *header)
1749 {
1750         unsigned char *s = header;
1751
1752         if (!memcmp(s, "fLaC", 4)) {
1753                 return 1;
1754         }
1755
1756         return 0;
1757 }
1758
1759 static int _MMFileIsFLVHeader(void *header)
1760 {
1761         unsigned char *s = header;
1762
1763         if (!memcmp(s, "FLV", 3)) {
1764                 return 1;
1765         }
1766
1767         return 0;
1768 }
1769
1770 static int _MMFileIsAIFFHeader(void *header)
1771 {
1772         unsigned char *s = header;
1773
1774         if (!memcmp(s, "FORM", 4) && !memcmp(s + 8, "AIFF", 4)) {
1775                 return 1;
1776         }
1777
1778         return 0;
1779 }
1780 static int _MMFileIsAPEHeader(void *header)
1781 {
1782         unsigned char *s = header;
1783
1784         if (!memcmp(s, "MAC ", 4)) {
1785                 return 1;
1786         }
1787
1788         return 0;
1789 }