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