version 0.44 (by Andreas Neuper)
[FAPG] / fapg.c
diff --git a/fapg.c b/fapg.c
index 58f3f20..e9d2b4d 100644 (file)
--- a/fapg.c
+++ b/fapg.c
 
 #define MP3_BASE 1024
 #define OGG_BASE 1024*10
 
 #define MP3_BASE 1024
 #define OGG_BASE 1024*10
-#define MAX 1024*200            /* 200ko for ID3 with JPEG images in it */
+#define MAX 1024*250            /* 250ko for ID3 with JPEG images in it */
+#define MAX_ITEM 1024
 
 
-#define FORMAT_M3U 0
+#define FORMAT_M3U 0  /* "0" is not a good choice for debugging, but OK for a default */
 #define FORMAT_PLS 1
 #define FORMAT_HTML 2
 #define FORMAT_RSS 3
 #define FORMAT_PLS 1
 #define FORMAT_HTML 2
 #define FORMAT_RSS 3
@@ -74,9 +75,9 @@ unsigned char buffer[MAX];
 
 int counter = 0;
 
 
 int counter = 0;
 
-unsigned char artist[1024];
-unsigned char title[1024];
-unsigned char genrebuf[1024];
+unsigned char artist[MAX_ITEM];
+unsigned char title[MAX_ITEM];
+unsigned char genrebuf[MAX_ITEM];
 unsigned char genre = 0;
 int duration;
 #define MP2ENC 1
 unsigned char genre = 0;
 int duration;
 #define MP2ENC 1
@@ -85,11 +86,13 @@ int duration;
 #define MPPENC 4
 #define OGGENC 5
 #define WAVENC 6
 #define MPPENC 4
 #define OGGENC 5
 #define WAVENC 6
+#define WMAENC 7
 
 char *magic[] = { NULL,
     "audio/mpeg", "audio/mpeg",
     "audio/mpeg", "audio/mpeg",
     "audio/ogg-vorbis", "audio/x-wav",
 
 char *magic[] = { NULL,
     "audio/mpeg", "audio/mpeg",
     "audio/mpeg", "audio/mpeg",
     "audio/ogg-vorbis", "audio/x-wav",
+    "audio/x-ms-wma", 
     NULL
 };
 
     NULL
 };
 
@@ -257,6 +260,23 @@ void mywebputstr(const char *c)
     }
 }
 
     }
 }
 
+void utf16toutf8(char *c,int n)
+{
+    /* check whether the we need to convert UTF-16 to UTF-8 strings */
+    if ( ( c[0] != '\377' ) || ( c[1] != '\376' ) ) { return; }
+    /* only continue here, if the first 2 letters are 0xfffe *
+     * c references an UTF-16 input, where latin letters are *
+     * separated by zero bytes, which we need to eliminate   */
+    int i=0; --n;
+    for(int j=2; (j<n) && (j<MAX_ITEM); j++ ) {
+      if( isprint(c[j]) ) { /* this is not perfect ! */
+            c[i++]=c[j];
+    }   }   c[i+1]=c[i]='\0';
+    /* the index i follows the zero-terminated "string" *
+     * now the read buffer is modified, not the file    */
+    return;
+}
+
 void myplaputstr(const char *c)
 {
     while(*c != 0) {
 void myplaputstr(const char *c)
 {
     while(*c != 0) {
@@ -423,7 +443,7 @@ void print_webpath(const char *path)
 {
     const char *c = path;
 
 {
     const char *c = path;
 
-    printf(prefix);             /* we must not modify this part */
+    printf("%s", prefix);             /* we must not modify this part */
     if(*c == '.' && c[1] == '/') {      /* remove leading "./" when parsing current directory */
         c += 2;
         /* maybe there follow many slashes */
     if(*c == '.' && c[1] == '/') {      /* remove leading "./" when parsing current directory */
         c += 2;
         /* maybe there follow many slashes */
@@ -441,7 +461,7 @@ void print_webpath(const char *path)
 void print_path(const char *path)
 {
     const char *c = path;
 void print_path(const char *path)
 {
     const char *c = path;
-    printf(prefix);
+    printf("%s", prefix);
     /* skip leading "./" when parsing current directory */
     if(*c == '.' && *(c + 1) == '/') {
         c += 2;
     /* skip leading "./" when parsing current directory */
     if(*c == '.' && *(c + 1) == '/') {
         c += 2;
@@ -498,7 +518,6 @@ void reference(const char *title)
     pipe = popen(command, "r");
     if(pipe == NULL) {
         fprintf(stderr, "Warning >> can't open pipe >%s< !\n", command);
     pipe = popen(command, "r");
     if(pipe == NULL) {
         fprintf(stderr, "Warning >> can't open pipe >%s< !\n", command);
-        free(command);
         return;
     }
     fgets(buffer, 1020, pipe);
         return;
     }
     fgets(buffer, 1020, pipe);
@@ -525,7 +544,8 @@ void parse_options(int argc, char **argv)
         {"recursive", no_argument, NULL, 'r'},
         {"stdin", no_argument, NULL, 's'},
         {"windows", no_argument, NULL, 'w'},
         {"recursive", no_argument, NULL, 'r'},
         {"stdin", no_argument, NULL, 's'},
         {"windows", no_argument, NULL, 'w'},
-        {"exclude", required_argument, NULL, 'x'}
+        {"exclude", required_argument, NULL, 'x'},
+        {NULL, 0, NULL, 0}
     };
     int c;
     int option_index = 0;
     };
     int c;
     int option_index = 0;
@@ -690,7 +710,7 @@ void parse_mp3(unsigned char *file)
         fprintf(stderr, "Debug >> parsing mp3 : %s\n", file);
 
     /* read header */
         fprintf(stderr, "Debug >> parsing mp3 : %s\n", file);
 
     /* read header */
-    if((fic = fopen(file, "r")) == NULL) {
+    if((fic = fopen(file, "rb")) == NULL) {
         fprintf(stderr, "Warning >> can't open file : %s\n", file);
         return;
     }
         fprintf(stderr, "Warning >> can't open file : %s\n", file);
         return;
     }
@@ -730,10 +750,12 @@ void parse_mp3(unsigned char *file)
                 if(*c == 0)
                     break;
                 if(strncmp(c, "TT2", 3) == 0) {
                 if(*c == 0)
                     break;
                 if(strncmp(c, "TT2", 3) == 0) {
+                    utf16toutf8(c+7,size);
                     strncpy(title, c + 7, size - 1);
                     title[size - 1] = '\0';
                 }
                 if(strncmp(c, "TP1", 3) == 0) {
                     strncpy(title, c + 7, size - 1);
                     title[size - 1] = '\0';
                 }
                 if(strncmp(c, "TP1", 3) == 0) {
+                    utf16toutf8(c+7,size);
                     strncpy(artist, c + 7, size - 1);
                     artist[size - 1] = '\0';
                 }
                     strncpy(artist, c + 7, size - 1);
                     artist[size - 1] = '\0';
                 }
@@ -753,10 +775,12 @@ void parse_mp3(unsigned char *file)
                 if(*c == 0)
                     break;
                 if(strncmp(c, "TIT2", 4) == 0) {
                 if(*c == 0)
                     break;
                 if(strncmp(c, "TIT2", 4) == 0) {
+                    utf16toutf8(c+11,size);
                     strncpy(title, c + 11, size - 1);
                     title[size - 1] = '\0';
                 }
                 if(strncmp(c, "TPE1", 4) == 0) {
                     strncpy(title, c + 11, size - 1);
                     title[size - 1] = '\0';
                 }
                 if(strncmp(c, "TPE1", 4) == 0) {
+                    utf16toutf8(c+11,size);
                     strncpy(artist, c + 11, size - 1);
                     artist[size - 1] = '\0';
                 }
                     strncpy(artist, c + 11, size - 1);
                     artist[size - 1] = '\0';
                 }
@@ -766,6 +790,9 @@ void parse_mp3(unsigned char *file)
                     /* genre=atoi(&genrebuf[1]); */
                     genre = atoi(c + 12);
                 }
                     /* genre=atoi(&genrebuf[1]); */
                     genre = atoi(c + 12);
                 }
+                if(strncmp(c, "TLEN", 4) == 0) {
+                    duration = atoi(c + 11) / 1000;
+                }
                 c += size + 10;
             }
     }
                 c += size + 10;
             }
     }
@@ -840,7 +867,7 @@ void parse_ogg(unsigned char *file)
     lus = fread(buffer, 1, OGG_BASE, fic);
 
     /* try Ogg */
     lus = fread(buffer, 1, OGG_BASE, fic);
 
     /* try Ogg */
-    if(buffer[0] != 'O' && buffer[1] != 'g' && buffer[2] != 'g') {
+    if(strncmp(buffer, "Ogg", 3) != 0) {
         fprintf(stderr, "Warning >> not a Ogg header : %s\n", file);
         return;
     }
         fprintf(stderr, "Warning >> not a Ogg header : %s\n", file);
         return;
     }
@@ -859,6 +886,13 @@ void parse_ogg(unsigned char *file)
             title[size - 6] = '\0';
             c += size;
         }
             title[size - 6] = '\0';
             c += size;
         }
+        if(strncasecmp(c, "ALBUM ARTIST=", 13) == 0) {
+            // ignore tag
+            size =
+                *(c - 4) + (*(c - 3) << 8) + (*(c - 2) << 16) +
+                (*(c - 1) << 24);
+            c += size;
+        }
         if(strncasecmp(c, "ARTIST=", 7) == 0) {
             size =
                 *(c - 4) + (*(c - 3) << 8) + (*(c - 2) << 16) +
         if(strncasecmp(c, "ARTIST=", 7) == 0) {
             size =
                 *(c - 4) + (*(c - 3) << 8) + (*(c - 2) << 16) +
@@ -923,7 +957,7 @@ void parse_mpc(unsigned char *file)
     lus = fread(buffer, 1, 12, fic);
 
     /* try Musepack */
     lus = fread(buffer, 1, 12, fic);
 
     /* try Musepack */
-    if(buffer[0] != 'M' && buffer[1] != 'P' && buffer[2] != '+') {
+    if (strncmp(buffer, "MP+", 3) != 0) {
         fprintf(stderr, "Warning >> not a Musepack header : %s\n", file);
         return;
     }
         fprintf(stderr, "Warning >> not a Musepack header : %s\n", file);
         return;
     }
@@ -1280,9 +1314,15 @@ void parse_file(unsigned char *newpath, unsigned char * original_path)
         encoding = OGGENC;
     }
     if(strcmp(".wav", ext) == 0) {
         encoding = OGGENC;
     }
     if(strcmp(".wav", ext) == 0) {
-        duration = -1;          /* parse_wav(newpath); */
+        duration = -1;
+        /* parse_wav(newpath); */
         encoding = WAVENC;
     }
         encoding = WAVENC;
     }
+    if(strcmp(".wma", ext) == 0) {
+        duration = -1;
+        /* parse_wma(newpath); */
+        encoding = WMAENC;
+    }
     /* guesstitle() */
     if((strlen(artist) == 0) && (strlen(title) == 0)) {
         // there are no tag infos read
     /* guesstitle() */
     if((strlen(artist) == 0) && (strlen(title) == 0)) {
         // there are no tag infos read
@@ -1320,12 +1360,10 @@ void parse_file(unsigned char *newpath, unsigned char * original_path)
         counter++;
         switch (format) {
         case FORMAT_M3U:
         counter++;
         switch (format) {
         case FORMAT_M3U:
-            if(duration != -1) {
-                printf("#EXTINF:%d,", duration);
-                if(strlen(artist) != 0)
-                    printf("%s - ", artist);
-                printf("%s%s", title, eol);
-            }
+            printf("#EXTINF:%d,", duration);
+            if(strlen(artist) != 0)
+                printf("%s - ", artist);
+            printf("%s%s", title, eol);
             print_path(newpath);
             printf("%s", eol);
             break;
             print_path(newpath);
             printf("%s", eol);
             break;