summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrobi <robi>2010-11-15 21:41:39 +0000
committerrobi <robi>2010-11-15 21:41:39 +0000
commit7a375a5121ff6ca37e81533879f662c055209b46 (patch)
tree35875cfdcbaba44ae660cf02cd3183ecc3d19dc2 /src
parent9c8e7e0fc0c90d9959585a814a646f0a4b25dff2 (diff)
mp3() Version 1
Diffstat (limited to 'src')
-rw-r--r--src/file_type.c197
1 files changed, 196 insertions, 1 deletions
diff --git a/src/file_type.c b/src/file_type.c
index c6bbd0a..e7b182d 100644
--- a/src/file_type.c
+++ b/src/file_type.c
@@ -1336,6 +1336,201 @@ int file_ogg(unsigned char *buf, int *size, __u32 scan , int flag, struct found_
}
+//mp3
+int file_mp3(unsigned char *buf, int *size, __u32 scan , int flag, struct found_data_t* f_data){
+#define MPEG_V25 0
+#define MPEG_V2 2
+#define MPEG_V1 3
+#define MPEG_L3 0x01
+#define MPEG_L2 0x02
+#define MPEG_L1 0x03
+int ret = 0;
+__u32 frame_offset = 0 ;
+int frame_flag = 0;
+int mpeg_version;
+int mpeg_layer;
+int bit_rate_key;
+int sampling_rate_key;
+int padding;
+int bit_rate;
+int sample_rate;
+__u32 frameLength;
+int i=1023;
+unsigned char head[5]={0,0,0,0,0};
+
+
+static const unsigned int sample_rate_table[4][4]={
+ {11025, 12000, 8000, 0}, /* MPEG_V25 */
+ { 0, 0, 0, 0},
+ {22050, 24000, 16000, 0}, /* MPEG_V2 */
+ {44100, 48000, 32000, 0} /* MPEG_V1 */
+};
+
+static const unsigned int bit_rate_table[4][4][16]=
+{
+/* MPEG_V25 */
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}
+ },
+/* MPEG_INVALID */
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ },
+ /* MPEG_V2 */
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}
+ },
+ /* MPEG_V1 */
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
+ { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 294, 416, 448, 0}
+ },
+};
+
+
+switch (flag){
+ case 0 :
+ if ((f_data->size) && (f_data->size <= f_data->inode->i_size)){
+ if( f_data->size < (12 * current_fs->blocksize)){
+ f_data->inode->i_size = (f_data->size + current_fs->blocksize -1) & ~(current_fs->blocksize-1);
+ *size = f_data->size % current_fs->blocksize;
+ }
+ ret = 1;
+ }
+ else {
+ ret =0;
+ }
+ break;
+ case 1 :
+ return (scan & (M_IS_META | M_CLASS_1 | M_BLANK )) ? 0 :1 ;
+ break;
+ case 2 :
+
+ frameLength = 0;
+ if(buf[frame_offset + 0]=='I' && buf[frame_offset + 1]=='D' && buf[frame_offset + 2]=='3' && (buf[frame_offset + 3]==2 || buf[frame_offset + 3]==3 || buf[frame_offset + 3]==4) && buf[frame_offset + 4]==0){
+
+ if(buf[frame_offset + 3]==4 && (buf[frame_offset + 5]&0x10)==0x10)
+ frameLength = 10 ;
+
+ frameLength += ((buf[frame_offset + 6]&0x7f)<<21) + ((buf[frame_offset + 7]&0x7f)<<14) + ((buf[frame_offset + 8]&0x7f)<<7) + (buf[frame_offset + 9]&0x7f)+ 10;
+ frame_offset += frameLength ;
+ frame_flag++;
+ while (!(buf[frame_offset]) && i--)
+ frame_offset++;
+#ifdef DEBUG_MAGIC_MP3_STREAM
+ fprintf (stderr,"ID3-TAG : block %lu ; size %u ; padding %u\n",f_data->first, frameLength, 1023-i);
+#endif
+ }
+ while (frame_offset < (12 * current_fs->blocksize)){
+ if((buf[frame_offset + 0]==0xFF && ((buf[frame_offset + 1]&0xFE)==0xFA || (buf[frame_offset + 1]&0xFE)==0xF2 || (buf[frame_offset + 1]&0xFE)==0xE2))){
+ mpeg_version = (buf[frame_offset + 1]>>3) & 0x03;
+ mpeg_layer = (buf[frame_offset + 1]>>1) & 0x03;
+ bit_rate_key = (buf[frame_offset + 2]>>4) & 0x0F;
+ sampling_rate_key = (buf[frame_offset + 2]>>2) & 0x03;
+ padding = (buf[frame_offset + 2]>>1) & 0x01;
+ bit_rate = bit_rate_table[mpeg_version][mpeg_layer][bit_rate_key];
+ sample_rate = sample_rate_table[mpeg_version][sampling_rate_key];
+ frameLength = 0;
+
+ if(sample_rate==0 || bit_rate==0 || mpeg_layer==MPEG_L1){
+ f_data->func = file_none;
+ return 0;
+ }
+ if(mpeg_layer==MPEG_L3) {
+ if(mpeg_version==MPEG_V1)
+ frameLength = 144000 * bit_rate / sample_rate + padding;
+ else
+ frameLength = 72000 * bit_rate / sample_rate + padding;
+ }
+ else{
+ if(mpeg_layer==MPEG_L2)
+ frameLength = 144000 * bit_rate / sample_rate + padding;
+ else
+ frameLength = (12000 * bit_rate / sample_rate + padding) * 4;
+ }
+//#ifdef DEBUG_MAGIC_MP3_STREAM
+// fprintf(stderr,"MP3-STREAM %8u-> framesize: %u, layer: %u, bitrate: %u, padding: %u\n",
+// frame_flag, frameLength, 4-mpeg_layer, bit_rate, padding);
+//#endif
+ if( ! frameLength ){
+ f_data->func = file_none;
+ return 0;
+ }
+
+ if (! frame_flag) {
+ head[0] = buf[frame_offset];
+ head[1] = buf[frame_offset +1];
+ head[2] = buf[frame_offset +2];
+ head[3] = (unsigned char)((frameLength-padding) >>8);
+ head[4] = (unsigned char)((frameLength-padding) & 0xff);
+ }
+
+ frame_offset += frameLength;
+ frame_flag++;
+ }
+ else{
+ if( ! ( buf[frame_offset + 0]) && ( ! ( buf[frame_offset + 1]) )){
+#ifdef DEBUG_MAGIC_MP3_STREAM
+ fprintf (stderr,"\nMP3-END : blk %lu : offset %lu : last_frame %lu\n", f_data->first, frame_offset, frameLength);
+#endif
+ break;
+ }
+ if((buf[frame_offset + 0] =='T') && (buf[frame_offset + 1] == 'A') && (buf[frame_offset + 2] == 'G')){
+ frame_offset += 128 ;
+#ifdef DEBUG_MAGIC_MP3_STREAM
+ fprintf (stderr,"\nMP3-TAG-END : blk %lu : offset %lu : last_frame %lu\n", f_data->first, frame_offset, frameLength);
+#endif
+ break;
+ }
+ else {
+#ifdef DEBUG_MAGIC_MP3_STREAM
+ fprintf (stderr,"MP3-STREAM_END : blk %lu : offset %lu : last_frame %lu\n", f_data->first, frame_offset, frameLength);
+ blockhex(stderr,(void*)(buf+frame_offset),0,64);
+#endif
+ return 0;
+ }
+ }
+
+ }
+ if (frame_flag > 2){
+#ifdef DEBUG_MAGIC_MP3_STREAM
+ fprintf(stderr,"MP3-STREAM layer: %u, bitrate: %u, testet last offset %u\n",
+ 4-mpeg_layer, bit_rate,frame_offset );
+#endif
+ f_data->size = frame_offset;
+ if (head[0]){
+ __u16 reverse = (__u16)(head[3]<<8) + head[4];
+ __u32 offset = current_fs->blocksize;
+ unsigned char *v_buf = buf - offset;
+ if (reverse < (offset -1)){
+ if (((v_buf[offset-reverse] == head[0]) && (v_buf[offset-reverse +1 ] == head[1]) && (v_buf[offset-reverse+2] == head[2] & ~0x2)) ||
+ ((v_buf[offset-reverse-1] == head[0]) && (v_buf[offset-reverse] == (head[1])) && (v_buf[offset-reverse+1] == head[2] | 0x2))){
+#ifdef DEBUG_MAGIC_MP3_STREAM
+ fprintf(stderr,"MP3-CHECK: Block %lu : is mp3-data but not begin of file\n", f_data->first);
+ blockhex(stderr,(void*)(v_buf+offset-reverse-16),0,64);
+#endif
+ f_data->func = file_none;
+ }
+ }
+ }
+ return 1;
+ }
+ break;
+} //switch
+
+return ret;
+}//end mp3
//change this only carefully
@@ -1802,7 +1997,7 @@ void get_file_property(struct found_data_t* this){
break;
case 0x0204 : //mpeg
- // this->func = file_mpeg ;
+ this->func = file_mp3 ;
strncat(this->name,".mp3",7);
break;