4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Haejeong Kim <backto.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <string.h> /*memcmp*/
23 #include <stdlib.h> /*malloc*/
26 #include "mm_file_utils.h"
28 /* Description of return value
33 /***********************************************************************/
34 /* Internal functions */
35 /***********************************************************************/
36 static int _MMFileSearchID3Tag (MMFileIOHandle *fp, unsigned int *offset);
37 static int _MMFileIsMP3Header (void *header);
38 static int _MMFileIsOGGHeader (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);
52 /***********************************************************************/
53 /* MP3 Header Check API */
54 /***********************************************************************/
56 int MMFileFormatIsValidMP3 (const char *mmfileuri, int frameCnt)
58 #define _MMFILE_MP3_HEADER_LENGTH 4
59 #define _MMFILE_MP3_BUFFER_LENGTH 8200
61 MMFileIOHandle *fp = NULL;
62 unsigned char *buffer=NULL;
63 long long filesize = 0;
64 unsigned int sizeID3 = 0;
66 unsigned int startoffset = 0;
67 unsigned int endoffset = 0;
68 unsigned int i = 0, j = 0;
69 int ret = 0,frameSize,count,offset;
71 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
72 if(ret == MMFILE_UTIL_FAIL) {
73 debug_error ("error: mmfile_open\n");
77 mmfile_seek (fp, 0L, MMFILE_SEEK_END);
78 filesize = mmfile_tell (fp);
79 mmfile_seek (fp, 0L, MMFILE_SEEK_SET);
81 if (filesize < _MMFILE_MP3_HEADER_LENGTH) {
82 debug_error ( "header is too small.\n");
87 /* Search the existance of ID3 tag */
88 ret = _MMFileSearchID3Tag (fp, &sizeID3);
90 debug_error("Error in searching the ID3 tag\n");
96 /* set begin and end point at the file */
97 startoffset += sizeID3;
98 endoffset = startoffset + 102400;
99 if(endoffset > filesize - _MMFILE_MP3_HEADER_LENGTH)
100 endoffset = filesize - _MMFILE_MP3_HEADER_LENGTH;
106 buffer = mmfile_malloc (_MMFILE_MP3_BUFFER_LENGTH * sizeof(char));
108 if (NULL == buffer) {
109 debug_error("Error in allocating memory for MP3 buffer\n");
113 while (i < endoffset) {
114 mmfile_seek (fp, i, MMFILE_SEEK_SET);
115 readed = mmfile_read (fp, buffer, _MMFILE_MP3_BUFFER_LENGTH);
116 if (readed < _MMFILE_MP3_HEADER_LENGTH) {
117 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
123 for (j = 0; (j <= readed - _MMFILE_MP3_HEADER_LENGTH); j = j + offset) {
124 frameSize = _MMFileIsMP3Header (buffer+j);
130 if((j+frameSize) >= (endoffset-(i+_MMFILE_MP3_HEADER_LENGTH))) {
134 if((j+frameSize) >= (readed - _MMFILE_MP3_HEADER_LENGTH)) {
135 #ifdef __MMFILE_TEST_MODE__
136 debug_msg ( "MP3 coner hit %d %d\n", j, frameSize);
141 frameSize = _MMFileIsMP3Header (buffer+j+frameSize);
146 if(count == frameCnt) {
148 #ifdef __MMFILE_TEST_MODE__
149 debug_msg ( "Header Detected at %d\n", i+j);
162 #ifdef __MMFILE_TEST_MODE__
163 debug_msg ( "Header Not Detected at: %d\n",i+j);
168 mmfile_free (buffer);
180 /***********************************************************************/
181 /* AAC Header Check API */
182 /***********************************************************************/
184 int MMFileFormatIsValidAAC (const char *mmfileuri)
186 #define _MMFILE_AAC_HEADER_LENGTH 4
187 #define _MMFILE_AAC_BUFFER_LENGTH 8200
189 MMFileIOHandle *fp = NULL;
190 unsigned char *buffer=NULL;
191 unsigned int sizeID3 = 0;
192 long long filesize = 0;
194 unsigned int startoffset = 0;
195 unsigned int endoffset = 0;
196 unsigned int i = 0, j = 0;
198 unsigned int sync,frameSize;
200 if (NULL == mmfileuri) {
201 debug_error ("file source is NULL\n");
205 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
206 if (ret == MMFILE_UTIL_FAIL) {
207 debug_error ("error: mmfile_open\n");
211 /* Initialize the members of handle */
212 mmfile_seek (fp, 0, MMFILE_SEEK_END);
213 filesize = mmfile_tell(fp);
214 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
216 if (filesize < _MMFILE_AAC_HEADER_LENGTH) {
217 debug_error ( "header is too small.\n");
222 /* Search the existance of ID3 tag */
223 ret = _MMFileSearchID3Tag (fp, &sizeID3);
225 debug_error("Error in searching the ID3 tag\n");
231 /* set begin and end point at the file */
232 startoffset += sizeID3;
233 endoffset = startoffset + 10240;
234 if(endoffset > filesize - _MMFILE_AAC_HEADER_LENGTH)
235 endoffset = filesize - _MMFILE_AAC_HEADER_LENGTH;
237 buffer = mmfile_malloc (_MMFILE_AAC_BUFFER_LENGTH * sizeof(char));
239 if (NULL == buffer) {
240 debug_error("Error in allocating memory for AAC buffer\n");
246 while (i < endoffset) {
247 mmfile_seek (fp, i, MMFILE_SEEK_SET);
249 readed = mmfile_read (fp, buffer, _MMFILE_AAC_BUFFER_LENGTH);
251 if (readed < _MMFILE_AAC_HEADER_LENGTH) {
252 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
257 #ifdef __MMFILE_TEST_MODE__
258 debug_msg ( "read error. size = %d. i = %d\n", readed,i);
260 for(j=0; (j < readed - _MMFILE_AAC_HEADER_LENGTH); j++) {
262 sync = ((buffer[j]<<8)|(buffer[j+1]));
264 if ( (sync & 0xFFF6) == 0xFFF0) {
265 frameSize = (((buffer[j+3]&0x03)<<11) | (buffer[j+4]<<3) | ((buffer[j+5]&0xE0)>>5));
267 if(frameSize == 0 ) {
271 if((j+frameSize) >= (endoffset-(i+2))) {
274 if((j+frameSize) >= (readed - 2)) {
275 #ifdef __MMFILE_TEST_MODE__
276 debug_msg ( "AAC coner hit %d %d\n", j, frameSize);
281 sync = ( (buffer[j+frameSize]<<8) | (buffer[j+frameSize+1]));
283 if ((sync & 0xFFF6) == 0xFFF0) {
285 #ifdef __MMFILE_TEST_MODE__
286 debug_msg ( "AAC ADTS Header Detected at %d\n", i+j);
290 } else if (!memcmp((buffer+j),"ADIF",4)) {
292 #ifdef __MMFILE_TEST_MODE__
293 debug_msg ( "AAC ADIF Header Detected at %d\n", i+j);
303 #ifdef __MMFILE_TEST_MODE__
304 debug_msg ( "Header Detected Failed\n");
309 mmfile_free (buffer);
321 /***********************************************************************/
322 /* OGG Header Check API */
323 /***********************************************************************/
325 int MMFileFormatIsValidOGG (const char *mmfileuri)
327 #define _MMFILE_OGG_HEADER_LENGTH 4
328 #define _MMFILE_OGG_BUFFER_LENGTH 512
329 #define _MMFILE_OGG_CHECK_LIMIT (_MMFILE_OGG_HEADER_LENGTH * 1000)
331 MMFileIOHandle *fp = NULL;
332 unsigned char buffer[_MMFILE_OGG_BUFFER_LENGTH] = {0,};
333 unsigned int sizeID3 = 0;
334 long long filesize = 0;
336 unsigned int startoffset = 0;
337 unsigned int endoffset = 0;
338 unsigned int i = 0, j = 0;
340 unsigned int check_limit = 0;
342 if (NULL == mmfileuri) {
343 debug_error ("file source is NULL\n");
348 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
349 if (ret == MMFILE_UTIL_FAIL) {
350 debug_error ("error: mmfile_open\n");
355 /* Initialize the members of handle */
356 mmfile_seek (fp, 0, MMFILE_SEEK_END);
357 filesize = mmfile_tell(fp);
358 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
360 if (filesize < _MMFILE_OGG_HEADER_LENGTH) {
361 debug_error ( "header is too small.\n");
366 /* Search the existance of ID3 tag */
367 ret = _MMFileSearchID3Tag (fp, &sizeID3);
369 debug_error("Error in searching the ID3 tag\n");
375 /* set begin and end point at the file */
376 startoffset += sizeID3;
377 endoffset = filesize - _MMFILE_OGG_HEADER_LENGTH;
379 check_limit = (endoffset > _MMFILE_OGG_CHECK_LIMIT) ? _MMFILE_OGG_CHECK_LIMIT : endoffset;
382 while (i <= check_limit) {
383 mmfile_seek (fp, i, MMFILE_SEEK_SET);
384 readed = mmfile_read (fp, buffer, _MMFILE_OGG_BUFFER_LENGTH);
385 if (readed < _MMFILE_OGG_HEADER_LENGTH) {
386 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
391 for (j = 0; (j <= readed - _MMFILE_OGG_HEADER_LENGTH); j++) {
392 if (1 == _MMFileIsOGGHeader (buffer+j)) {
394 #ifdef __MMFILE_TEST_MODE__
395 debug_msg ( "Header Detected at %d\n", i+j);
401 memset (buffer, 0x00, _MMFILE_OGG_BUFFER_LENGTH);
416 /***********************************************************************/
417 /* MIDI Header Check API */
418 /***********************************************************************/
420 int MMFileFormatIsValidMID (const char *mmfileuri)
422 #define _MMFILE_MIDI_HEADER_LENGTH 4
423 #define _MMFILE_MIDI_BUFFER_LENGTH 512
424 #define _MMFILE_MIDI_CHECK_LIMIT (_MMFILE_MIDI_HEADER_LENGTH * 1024)
426 MMFileIOHandle *fp = NULL;
427 unsigned char buffer[_MMFILE_MIDI_BUFFER_LENGTH] = {0,};
428 long long filesize = 0;
430 unsigned int startoffset = 0;
431 unsigned int endoffset = 0;
432 unsigned int i = 0, j = 0;
434 unsigned int check_limit = 0;
436 if (NULL == mmfileuri) {
437 debug_error ("file source is NULL\n");
441 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
442 if (ret == MMFILE_UTIL_FAIL) {
443 debug_error ("error: mmfile_open\n");
447 /* Initialize the members of handle */
448 mmfile_seek (fp, 0, MMFILE_SEEK_END);
449 filesize = mmfile_tell(fp);
450 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
452 if (filesize < _MMFILE_MIDI_HEADER_LENGTH) {
453 debug_error ( "header is too small.\n");
460 /* set begin and end point at the file */
462 endoffset = filesize - _MMFILE_MIDI_HEADER_LENGTH;
464 check_limit = (endoffset > _MMFILE_MIDI_CHECK_LIMIT) ? _MMFILE_MIDI_CHECK_LIMIT : endoffset;
467 while (i <= check_limit) {
468 mmfile_seek (fp, i, MMFILE_SEEK_SET);
469 readed = mmfile_read (fp, buffer, _MMFILE_MIDI_BUFFER_LENGTH);
470 if (readed < _MMFILE_MIDI_HEADER_LENGTH) {
471 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
476 for (j = 0; (j <= readed - _MMFILE_MIDI_HEADER_LENGTH); j++) {
477 if (1 == _MMFileIsMIDHeader (buffer+j)) {
479 #ifdef __MMFILE_TEST_MODE__
480 debug_msg ( "Header Detected at %d\n", i+j);
486 memset (buffer, 0x00, _MMFILE_MIDI_BUFFER_LENGTH);
500 /***********************************************************************/
501 /* WAV Header Check API */
502 /***********************************************************************/
504 int MMFileFormatIsValidWAV (const char *mmfileuri)
506 #define _MMFILE_WAV_HEADER_LENGTH 15
508 MMFileIOHandle *fp = NULL;
509 unsigned char buffer[_MMFILE_WAV_HEADER_LENGTH] = {0,};
510 long long filesize = 0;
512 unsigned int startoffset = 0;
515 if (NULL == mmfileuri) {
516 debug_error ("file source is NULL\n");
520 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
521 if (ret == MMFILE_UTIL_FAIL) {
522 debug_error ("error: mmfile_open\n");
526 /* Initialize the members of handle */
527 mmfile_seek (fp, 0, MMFILE_SEEK_END);
528 filesize = mmfile_tell(fp);
529 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
531 if (filesize < _MMFILE_WAV_HEADER_LENGTH) {
532 debug_error ( "header is too small.\n");
539 /* set begin and end point at the file */
542 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
544 readed = mmfile_read (fp, buffer, _MMFILE_WAV_HEADER_LENGTH);
545 if (_MMFILE_WAV_HEADER_LENGTH != readed) {
546 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
551 if (1 == _MMFileIsWAVHeader (buffer)) {
552 #ifdef __MMFILE_TEST_MODE__
553 debug_msg ( "Header Detected\n");
570 /***********************************************************************/
571 /* MP4 Header Check API */
572 /***********************************************************************/
574 int MMFileFormatIsValidMP4 (const char *mmfileuri)
576 #define _MMFILE_MP4_HEADER_LENGTH 4
577 #define _MMFILE_MP4_CHECK_LIMIT (1024*10) /*10Kbyte*/
578 MMFileIOHandle *fp = NULL;
579 unsigned char buffer[_MMFILE_MP4_HEADER_LENGTH] = {0,};
580 long long filesize = 0;
582 unsigned int startoffset = 0;
584 unsigned int check_limit = 0;
586 if (NULL == mmfileuri) {
587 debug_error ("file source is NULL\n");
591 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
592 if (ret == MMFILE_UTIL_FAIL) {
593 debug_error ("error: mmfile_open\n");
597 /* Initialize the members of handle */
598 mmfile_seek (fp, 0, MMFILE_SEEK_END);
599 filesize = mmfile_tell(fp);
600 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
602 if (filesize < _MMFILE_MP4_HEADER_LENGTH) {
603 debug_error ( "header is too small.\n");
610 /**@note weak check*/
611 check_limit = (filesize > _MMFILE_MP4_CHECK_LIMIT) ? _MMFILE_MP4_CHECK_LIMIT: filesize;
612 for (startoffset = 0; check_limit - (startoffset + _MMFILE_MP4_HEADER_LENGTH) > 0; startoffset++) {
613 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
615 readed = mmfile_read (fp, buffer, _MMFILE_MP4_HEADER_LENGTH);
616 if (readed != _MMFILE_MP4_HEADER_LENGTH) {
617 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
623 if (1 == _MMFileIsMP4Header (buffer)) {
624 #ifdef __MMFILE_TEST_MODE__
625 debug_msg ("MP4 Header Detected\n");
641 /***********************************************************************/
642 /* AVI Header Check API */
643 /***********************************************************************/
645 int MMFileFormatIsValidAVI (const char *mmfileuri)
647 #define _MMFILE_AVI_HEADER_LENGTH 12
649 MMFileIOHandle *fp = NULL;
650 unsigned char buffer[_MMFILE_AVI_HEADER_LENGTH] = {0,};
651 long long filesize = 0;
653 unsigned int startoffset = 0;
656 if (NULL == mmfileuri) {
657 debug_error ("file source is NULL\n");
661 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
662 if (ret == MMFILE_UTIL_FAIL) {
663 debug_error ("error: mmfile_open\n");
667 /* Initialize the members of handle */
668 mmfile_seek (fp, 0, MMFILE_SEEK_END);
669 filesize = mmfile_tell(fp);
670 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
672 if (filesize < _MMFILE_AVI_HEADER_LENGTH) {
673 debug_error ( "header is too small.\n");
681 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
683 readed = mmfile_read (fp, buffer, _MMFILE_AVI_HEADER_LENGTH);
684 if (_MMFILE_AVI_HEADER_LENGTH != readed) {
685 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
690 if (1 == _MMFileIsAVIHeader (buffer)) {
691 #ifdef __MMFILE_TEST_MODE__
692 debug_msg ( "Header Detected \n");
708 /***********************************************************************/
709 /* ASF Header Check API */
710 /***********************************************************************/
712 int MMFileFormatIsValidASF (const char *mmfileuri)
714 #define _MMFILE_ASF_HEADER_LENGTH 16
715 MMFileIOHandle *fp = NULL;
716 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0,};
717 long long filesize = 0;
719 unsigned int startoffset = 0;
722 if (NULL == mmfileuri) {
723 debug_error ("file source is NULL\n");
727 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
728 if (ret == MMFILE_UTIL_FAIL) {
729 debug_error ("error: mmfile_open\n");
733 /* Initialize the members of handle */
734 mmfile_seek (fp, 0, MMFILE_SEEK_END);
735 filesize = mmfile_tell(fp);
736 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
738 if (filesize < _MMFILE_ASF_HEADER_LENGTH) {
739 debug_error ( "header is too small.\n");
747 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
749 readed = mmfile_read (fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
750 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
751 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
756 if (1 == _MMFileIsASFHeader (buffer)) {
757 #ifdef __MMFILE_TEST_MODE__
758 debug_msg ( "Header Detected\n");
772 /***********************************************************************/
773 /* WMA Header Check API */
774 /***********************************************************************/
776 int MMFileFormatIsValidWMA (const char *mmfileuri)
778 #define _MMFILE_ASF_HEADER_LENGTH 16
779 MMFileIOHandle *fp = NULL;
780 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0,};
781 long long filesize = 0;
783 unsigned int startoffset = 0;
786 if (NULL == mmfileuri) {
787 debug_error ("file source is NULL\n");
791 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
792 if (ret == MMFILE_UTIL_FAIL) {
793 debug_error ("error: mmfile_open\n");
797 /* Initialize the members of handle */
798 mmfile_seek (fp, 0, MMFILE_SEEK_END);
799 filesize = mmfile_tell(fp);
800 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
802 if (filesize < _MMFILE_ASF_HEADER_LENGTH) {
803 debug_error ( "header is too small.\n");
811 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
813 readed = mmfile_read (fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
814 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
815 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
820 if (1 == _MMFileIsASFHeader (buffer)) {
821 #ifdef __MMFILE_TEST_MODE__
822 debug_msg ( "Header Detected\n");
838 /***********************************************************************/
839 /* WMV Header Check API */
840 /***********************************************************************/
842 int MMFileFormatIsValidWMV (const char *mmfileuri)
844 #define _MMFILE_ASF_HEADER_LENGTH 16
845 MMFileIOHandle *fp = NULL;
846 unsigned char buffer[_MMFILE_ASF_HEADER_LENGTH] = {0,};
847 long long filesize = 0;
849 unsigned int startoffset = 0;
852 if (NULL == mmfileuri) {
853 debug_error ("file source is NULL\n");
857 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
858 if (ret == MMFILE_UTIL_FAIL) {
859 debug_error ("error: mmfile_open\n");
863 /* Initialize the members of handle */
864 mmfile_seek (fp, 0, MMFILE_SEEK_END);
865 filesize = mmfile_tell(fp);
866 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
868 if (filesize < _MMFILE_ASF_HEADER_LENGTH) {
869 debug_error ( "header is too small.\n");
877 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
879 readed = mmfile_read (fp, buffer, _MMFILE_ASF_HEADER_LENGTH);
880 if (_MMFILE_ASF_HEADER_LENGTH != readed) {
881 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
886 if (1 == _MMFileIsASFHeader (buffer)) {
887 #ifdef __MMFILE_TEST_MODE__
888 debug_msg ( "Header Detected\n");
903 /***********************************************************************/
904 /* MMF Header Check API */
905 /***********************************************************************/
907 int MMFileFormatIsValidMMF (const char *mmfileuri)
909 #define _MMFILE_MMF_HEADER_LENGTH 18
911 MMFileIOHandle *fp = NULL;
912 unsigned char buffer[_MMFILE_MMF_HEADER_LENGTH] = {0,};
913 long long filesize = 0;
915 unsigned int startoffset = 0;
918 if (NULL == mmfileuri) {
919 debug_error ("file source is NULL\n");
923 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
924 if (ret == MMFILE_UTIL_FAIL) {
925 debug_error ("error: mmfile_open\n");
929 /* Initialize the members of handle */
930 mmfile_seek (fp, 0, MMFILE_SEEK_END);
931 filesize = mmfile_tell(fp);
932 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
934 if (filesize < _MMFILE_MMF_HEADER_LENGTH) {
935 debug_error ( "header is too small.\n");
943 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
945 readed = mmfile_read (fp, buffer, _MMFILE_MMF_HEADER_LENGTH);
946 if (_MMFILE_MMF_HEADER_LENGTH != readed) {
947 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
952 if (1 == _MMFileIsMMFHeader (buffer)) {
953 #ifdef __MMFILE_TEST_MODE__
954 debug_msg ( "Header Detected\n");
970 /***********************************************************************/
971 /* MMF Header Check API */
972 /***********************************************************************/
974 int MMFileFormatIsValidIMY (const char *mmfileuri)
976 #define _MMFILE_IMY_HEADER_LENGTH 13
978 MMFileIOHandle *fp = NULL;
979 unsigned char buffer[_MMFILE_IMY_HEADER_LENGTH] = {0,};
980 long long filesize = 0;
982 unsigned int startoffset = 0;
985 if (NULL == mmfileuri) {
986 debug_error ("file source is NULL\n");
990 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
991 if (ret == MMFILE_UTIL_FAIL) {
992 debug_error ("error: mmfile_open\n");
996 /* Initialize the members of handle */
997 mmfile_seek (fp, 0, MMFILE_SEEK_END);
998 filesize = mmfile_tell(fp);
999 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
1001 if (filesize < _MMFILE_IMY_HEADER_LENGTH) {
1002 debug_error ( "header is too small.\n");
1010 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
1012 readed = mmfile_read (fp, buffer, _MMFILE_IMY_HEADER_LENGTH);
1013 if (_MMFILE_IMY_HEADER_LENGTH != readed) {
1014 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
1019 if (1 == _MMFileIsIMYHeader (buffer)) {
1020 #ifdef __MMFILE_TEST_MODE__
1021 debug_msg ( "Header Detected\n");
1037 /***********************************************************************/
1038 /* AMR Header Check API */
1039 /***********************************************************************/
1041 int MMFileFormatIsValidAMR (const char *mmfileuri)
1043 #define _MMFILE_AMR_MAX_HEADER_SIZE 15
1044 #define _MMFILE_AMR_MIN_HEADER_SIZE 6
1046 MMFileIOHandle *fp = NULL;
1047 unsigned char buffer[_MMFILE_AMR_MAX_HEADER_SIZE] = {0,};
1048 long long filesize = 0;
1050 unsigned int startoffset = 0;
1053 if (NULL == mmfileuri) {
1054 debug_error ("file source is NULL\n");
1058 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
1059 if (ret == MMFILE_UTIL_FAIL) {
1060 debug_error ("error: mmfile_open\n");
1064 /* Initialize the members of handle */
1065 mmfile_seek (fp, 0, MMFILE_SEEK_END);
1066 filesize = mmfile_tell(fp);
1067 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
1069 if (filesize < _MMFILE_AMR_MAX_HEADER_SIZE) {
1070 debug_error ("header is too small.\n");
1078 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
1080 readed = mmfile_read (fp, buffer, _MMFILE_AMR_MAX_HEADER_SIZE);
1081 if (_MMFILE_AMR_MAX_HEADER_SIZE != readed) {
1082 debug_error ("read error. size = %d. Maybe end of file.\n", readed);
1087 if (1 == _MMFileIsAMRHeader (buffer)) {
1088 #ifdef __MMFILE_TEST_MODE__
1089 debug_msg ( "Header Detected\n");
1103 /***********************************************************************/
1104 /* Matroska Header Check API */
1105 /***********************************************************************/
1108 int MMFileFormatIsValidMatroska (const char *mmfileuri)
1110 #define _MMFILE_EBML_MARKER_LENGTH 4
1112 MMFileIOHandle *fp = NULL;
1113 unsigned char* buffer = NULL;
1114 long long filesize = 0;
1116 unsigned int startoffset = 0;
1119 int len_mask = 0x80, size = 1, n = 1, total = 0;
1120 char probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
1122 if (NULL == mmfileuri) {
1123 debug_error ("file source is NULL\n");
1127 debug_msg ( "[%s][%d]\n", __func__, __LINE__);
1128 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
1129 if (ret == MMFILE_UTIL_FAIL) {
1130 debug_error ("error: mmfile_open\n");
1134 /* Initialize the members of handle */
1135 mmfile_seek (fp, 0, MMFILE_SEEK_END);
1136 filesize = mmfile_tell(fp);
1137 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
1141 /* set begin and end point at the file */
1144 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
1146 buffer = mmfile_malloc (_MMFILE_EBML_MARKER_LENGTH * sizeof(char));
1147 readed = mmfile_read (fp, buffer, _MMFILE_EBML_MARKER_LENGTH);
1148 if (_MMFILE_EBML_MARKER_LENGTH != readed) {
1149 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
1155 if (buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3) {
1156 debug_msg ("This is not a EBML format\n");
1161 /* length of header */
1162 mmfile_read (fp, (unsigned char*)(&total), 1);
1163 debug_msg ("Initial total header size = [0x%x]\n", total);
1165 while (size <= 8 && !(total & len_mask)) {
1166 debug_error ("This case can not be handled yet....")
1171 debug_error ("This case can not be handled yet....")
1175 total &= (len_mask - 1);
1177 debug_error ("This case can not be handled yet....")
1182 debug_msg ("Final total header size = [%d]\n", total);
1185 mmfile_free (buffer);
1186 buffer = mmfile_malloc (total * sizeof(char));
1187 mmfile_read (fp, buffer, total);
1189 for (n = 0; n <= total - sizeof (probe_data); n++) {
1190 if (!memcmp (&buffer[n], probe_data, sizeof (probe_data))) {
1191 debug_msg ("String matroska found!!!\n");
1199 mmfile_free (buffer);
1209 /***********************************************************************/
1210 /* QT Header Check API */
1211 /***********************************************************************/
1213 int MMFileFormatIsValidQT (const char *mmfileuri)
1218 /***********************************************************************/
1219 /* Flac Header Check API */
1220 /***********************************************************************/
1222 int MMFileFormatIsValidFLAC (const char *mmfileuri)
1224 #define _MMFILE_FLAC_HEADER_LENGTH 5 /*fLaC*/
1226 MMFileIOHandle *fp = NULL;
1227 unsigned char buffer[_MMFILE_FLAC_HEADER_LENGTH] = {0,};
1228 long long filesize = 0;
1230 unsigned int startoffset = 0;
1233 if (NULL == mmfileuri) {
1234 debug_error ("file source is NULL\n");
1238 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
1239 if (ret == MMFILE_UTIL_FAIL) {
1240 debug_error ("error: mmfile_open\n");
1244 /* Initialize the members of handle */
1245 mmfile_seek (fp, 0, MMFILE_SEEK_END);
1246 filesize = mmfile_tell(fp);
1247 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
1249 if (filesize < _MMFILE_FLAC_HEADER_LENGTH) {
1250 debug_error ( "header is too small.\n");
1257 /* set begin and end point at the file */
1260 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
1262 readed = mmfile_read (fp, buffer, _MMFILE_FLAC_HEADER_LENGTH);
1263 if (_MMFILE_FLAC_HEADER_LENGTH != readed) {
1264 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
1269 if (1 == _MMFileIsFLACHeader (buffer)) {
1270 #ifdef __MMFILE_TEST_MODE__
1271 debug_msg ( "Header Detected\n");
1286 /***********************************************************************/
1287 /* FLV(flash video) Header Check API */
1288 /***********************************************************************/
1290 int MMFileFormatIsValidFLV (const char *mmfileuri)
1292 #define _MMFILE_FLV_HEADER_LENGTH 4 /*FLV*/
1294 MMFileIOHandle *fp = NULL;
1295 unsigned char buffer[_MMFILE_FLV_HEADER_LENGTH] = {0,};
1296 long long filesize = 0;
1298 unsigned int startoffset = 0;
1301 if (NULL == mmfileuri) {
1302 debug_error ("file source is NULL\n");
1306 ret = mmfile_open (&fp, mmfileuri, MMFILE_RDONLY);
1307 if (ret == MMFILE_UTIL_FAIL) {
1308 debug_error ("error: mmfile_open\n");
1312 /* Initialize the members of handle */
1313 mmfile_seek (fp, 0, MMFILE_SEEK_END);
1314 filesize = mmfile_tell(fp);
1315 mmfile_seek (fp, 0, MMFILE_SEEK_SET);
1317 if (filesize < _MMFILE_FLV_HEADER_LENGTH) {
1318 debug_error ( "header is too small.\n");
1325 /* set begin and end point at the file */
1328 mmfile_seek (fp, startoffset, MMFILE_SEEK_SET);
1330 readed = mmfile_read (fp, buffer, _MMFILE_FLV_HEADER_LENGTH);
1331 if (_MMFILE_FLV_HEADER_LENGTH != readed) {
1332 debug_error ( "read error. size = %d. Maybe end of file.\n", readed);
1337 if (1 == _MMFileIsFLVHeader (buffer)) {
1338 #ifdef __MMFILE_TEST_MODE__
1339 debug_msg ( "Header Detected\n");
1354 /***********************************************************************/
1355 /* Implementation of Internal Functions */
1356 /***********************************************************************/
1357 static int _MMFileIsASFHeader (void *header)
1359 /* ID: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C */
1360 unsigned char *s = header;
1362 if ( (*(s + 0) == 0x30) &&
1363 (*(s + 1) == 0x26) &&
1364 (*(s + 2) == 0xB2) &&
1365 (*(s + 3) == 0x75) &&
1366 (*(s + 4) == 0x8E) &&
1367 (*(s + 5) == 0x66) &&
1368 (*(s + 6) == 0xCF) &&
1369 (*(s + 7) == 0x11) &&
1370 (*(s + 8) == 0xA6) &&
1371 (*(s + 9) == 0xD9) &&
1372 (*(s + 10) == 0x00) &&
1373 (*(s + 11) == 0xAA) &&
1374 (*(s + 12) == 0x00) &&
1375 (*(s + 13) == 0x62) &&
1376 (*(s + 14) == 0xCE) &&
1377 (*(s + 15) == 0x6C) ) {
1385 static int _MMFileIsAMRHeader (void *header)
1387 #define _MMFILE_AMR_SINGLE_CH_HEADER_SIZE 6
1388 #define _MMFILE_AMR_SINGLE_CH_HEADER "#!AMR\n"
1390 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE 9
1391 #define _MMFILE_AMR_WB_SINGLE_CH_HEADER "#!AMR-WB\n"
1393 #define _MMFILE_AMR_MULTI_CH_HEADER_SIZE 12
1394 #define _MMFILE_AMR_MULTI_CH_HEADER "#!AMR_MC1.0\n"
1396 #define _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE 15
1397 #define _MMFILE_AMR_WB_MULTI_CH_HEADER "#!AMR-WB_MC1.0\n"
1399 unsigned char *s = header;
1401 if (!memcmp (s, _MMFILE_AMR_SINGLE_CH_HEADER, _MMFILE_AMR_SINGLE_CH_HEADER_SIZE) ||
1402 !memcmp (s, _MMFILE_AMR_WB_SINGLE_CH_HEADER, _MMFILE_AMR_WB_SINGLE_CH_HEADER_SIZE) ||
1403 !memcmp (s, _MMFILE_AMR_MULTI_CH_HEADER, _MMFILE_AMR_MULTI_CH_HEADER_SIZE) ||
1404 !memcmp (s, _MMFILE_AMR_WB_MULTI_CH_HEADER, _MMFILE_AMR_WB_MULTI_CH_HEADER_SIZE)) {
1412 static int _MMFileIsIMYHeader (void *header)
1414 unsigned char *s = header;
1416 if (!memcmp(s, "BEGIN:IMELODY", 13)) {
1423 static int _MMFileIsMIDHeader (void *header)
1425 unsigned char *s = header;
1427 if (!memcmp(s, "MThd", 4)) { /*general MIDI*/
1429 } else if (!memcmp (s, "XMF_", 4)) { /*XMF*/
1431 } else if (!memcmp(s, "IREZ", 4)) {
1432 return 1; /*RMF format*/
1438 static int _MMFileIsMMFHeader (void *header)
1440 #define _MMFILE_MMF_TYPE_POSITION ((char)0x11)
1441 unsigned char *s = header;
1443 if(!memcmp (s, "MMMD", 4)) {
1444 /* warning: comparison is always true due to limited range of data type */
1445 if( *(s + _MMFILE_MMF_TYPE_POSITION) <= 0x2F ) {
1447 } else if (((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x30) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x38)) // MA3, MA5 type
1448 || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x40) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x48))
1449 || ((*(s + _MMFILE_MMF_TYPE_POSITION) >= 0x50) && (*(s + _MMFILE_MMF_TYPE_POSITION) <= 0x58))
1450 || ((*(s + _MMFILE_MMF_TYPE_POSITION) == 0xF0))) {
1460 static int _MMFileIsAVIHeader (void *header)
1462 unsigned char *s = header;
1464 if (!memcmp(s, "RIFF", 4) && !memcmp(s+8, "AVI", 3)) {
1472 static int _MMFileIsWAVHeader (void *header)
1474 unsigned char *s = header;
1476 if (!memcmp(s, "RIFF", 4) && !memcmp(s+8, "WAVE", 4)) {
1485 static int _MMFileIsMP4Header (void *header)
1487 unsigned char *s = header;
1489 if (!memcmp (s, "moov", 4) ||
1490 !memcmp (s, "mdat", 4) ||
1491 !memcmp (s, "ftyp", 4) ||
1492 !memcmp (s, "free", 4) ||
1493 !memcmp (s, "uuid", 4) ||
1494 !memcmp (s, "skip", 4) ||
1496 !memcmp (s, "PICT", 4) ||
1497 !memcmp (s, "wide", 4) ||
1498 !memcmp (s, "prfl", 4)) {
1505 static int _MMFileIsOGGHeader (void *header)
1507 unsigned char *s = header;
1509 if (!memcmp(s, "OggS", 4)) {
1516 static int _MMFileIsMP3Header (void *header)
1518 unsigned long head = 0;
1519 unsigned char *headc = header;
1520 unsigned int bitrate, layer, length, mode;
1521 unsigned int coef,samplerate, version, channels;
1522 static const unsigned int mp3types_bitrates[2][3][16] = {
1523 { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
1524 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
1525 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
1526 { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
1527 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
1528 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}},
1531 static const unsigned int mp3types_freqs[3][3] = {
1532 {11025, 12000, 8000},
1533 {22050, 24000, 16000},
1534 {44100, 48000, 32000}
1537 static const unsigned int mp3FrameCoef[4][4] = {{-1,48,144,72},{-1,-1,-1,-1},{-1,48,144,72},{-1,48,144,144}};
1540 head = (*(headc+0)<<24 | *(headc+1)<<16 | *(headc+2)<<8 | *(headc+3));
1542 if ((head & 0xffe00000) != 0xffe00000) {
1546 /* we don't need extension, copyright, original or
1547 * emphasis for the frame length */
1555 length = head & 0x1;
1558 /* sampling frequency */
1559 samplerate = head & 0x3;
1560 if (samplerate == 3) {
1566 bitrate = head & 0xF;
1568 if (bitrate == 15) {
1572 /* ignore error correction, too */
1576 layer = 4 - (head & 0x3);
1582 /* version 0=MPEG2.5; 2=MPEG2; 3=MPEG1 */
1583 version = head & 0x3;
1589 channels = (mode == 3) ? 1 : 2;
1590 samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
1593 bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
1594 coef = mp3FrameCoef[version][layer];
1598 length = length + ((coef*bitrate*1000)/samplerate);
1604 static int _MMFileSearchID3Tag (MMFileIOHandle *fp, unsigned int *offset)
1606 #define _MMFILE_MP3_TAGV2_HEADER_LEN 10
1607 #define _MMFILE_GET_INT_NUMBER(buff) (int)( (((int)(buff)[0]) << 24) | (((int)(buff)[1]) << 16) | (((int)(buff)[2]) << 8) | (((int)(buff)[3])))
1609 unsigned char tagHeader[_MMFILE_MP3_TAGV2_HEADER_LEN] = {0,};
1610 unsigned int tagInfoSize = 0;
1611 unsigned int acc_tagsize = 0;
1619 mmfile_seek(fp, 0, MMFILE_SEEK_SET);
1623 readed = mmfile_read (fp, tagHeader, _MMFILE_MP3_TAGV2_HEADER_LEN);
1624 if (readed != _MMFILE_MP3_TAGV2_HEADER_LEN) {
1625 debug_error ("read error occured.\n");
1629 if (memcmp (tagHeader, "ID3", 3) == 0) {
1630 #ifdef __MMFILE_TEST_MODE__
1631 debug_msg ("'ID3' found.\n");
1634 #ifdef __MMFILE_TEST_MODE__
1635 debug_msg ("'ID3' not found.\n");
1640 /**@note weak id3v2 tag checking*/
1641 if (tagHeader[3] != 0xFF && tagHeader[4] != 0xFF &&
1642 (tagHeader[6] & 0x80) == 0 && (tagHeader[7] & 0x80) == 0 &&
1643 (tagHeader[8] & 0x80) == 0 && (tagHeader[9] & 0x80) == 0) {
1644 #ifdef __MMFILE_TEST_MODE__
1645 debug_msg ("good ID3V2 tag.\n");
1648 debug_warning ("It's bad ID3V2 tag.\n");
1652 tagVersion = tagHeader[3];
1654 if (tagVersion > 4) {
1655 #ifdef __MMFILE_TEST_MODE__
1656 debug_msg("Tag version not supported\n");
1661 encSize = _MMFILE_GET_INT_NUMBER(&tagHeader[6]);
1662 tagInfoSize = _MMFILE_MP3_TAGV2_HEADER_LEN;
1663 tagInfoSize += (((encSize & 0x0000007F) >> 0) | ((encSize & 0x00007F00) >> 1) | ((encSize & 0x007F0000) >> 2) | ((encSize & 0x7F000000) >> 3));
1665 /**@note unfortunately, some contents has many id3 tag.*/
1666 acc_tagsize += tagInfoSize;
1667 #ifdef __MMFILE_TEST_MODE__
1668 debug_msg("tag size: %u, offset: %u\n", tagInfoSize, acc_tagsize);
1671 mmfile_seek(fp, acc_tagsize, MMFILE_SEEK_SET);
1672 *offset = acc_tagsize;
1673 goto _START_TAG_SEARCH;
1679 static int _MMFileIsFLACHeader (void *header)
1681 unsigned char *s = header;
1683 if (!memcmp(s, "fLaC", 4)) {
1690 static int _MMFileIsFLVHeader (void *header)
1692 unsigned char *s = header;
1694 if (!memcmp(s, "FLV", 3)) {