fixed format warnings
[swftools.git] / lib / wav.c
index 9afd6b1..5bd30d7 100644 (file)
--- a/lib/wav.c
+++ b/lib/wav.c
@@ -25,7 +25,7 @@
 #include "wav.h"
 
 struct WAVBlock {
-    char id[4];
+    char id[5];
     unsigned int size;
 };
 
@@ -35,6 +35,7 @@ int getWAVBlock(FILE*fi, struct WAVBlock*block)
     unsigned char b[4];
     if(fread(block->id,1,4,fi)<4)
        return 0;
+    block->id[4] = 0;
     if(fread(b,1,4,fi)<4)
        return 0;
     block->size = b[0]|b[1]<<8|b[2]<<16|b[3]<<24;
@@ -45,15 +46,16 @@ int getWAVBlock(FILE*fi, struct WAVBlock*block)
     return 1;
 }
 
-int wav_read(char* filename, struct WAV*wav)
+int wav_read(struct WAV*wav, const char* filename)
 {
     FILE*fi = fopen(filename, "rb");
     unsigned char b[16];
     long int filesize;
     struct WAVBlock block;
     long int pos;
+    
     if(!fi)
-       return 0;
+        return 0;
     fseek(fi, 0, SEEK_END);
     filesize = ftell(fi);
     fseek(fi, 0, SEEK_SET);
@@ -61,59 +63,93 @@ int wav_read(char* filename, struct WAV*wav)
     //printf("Filesize: %d\n", filesize);
 
     if(!getWAVBlock (fi, &block))
-       return 0;
-    if(strncmp(block.id,"RIFF",4)) {
-       fprintf(stderr, "wav_read: not a WAV file\n");
-       return 0;
+    {
+        fclose(fi);
+        return 0;
+    }
+    if(strncmp(block.id,"RIFF",4))
+    {
+        fprintf(stderr, "wav_read: not a WAV file\n");
+        fclose(fi);
+        return 0;
     }
     if(block.size + 8 < filesize)
-       fprintf(stderr, "wav_read: warning - more tags (%d extra bytes)\n",
-               filesize - block.size - 8);
+        fprintf(stderr, "wav_read: warning - more tags (%lu extra bytes)\n", filesize - block.size - 8);
+
+    if(block.size == filesize)
+       /* some buggy software doesn't generate the right tag length */
+        block.size = filesize - 8;
+
     if(block.size + 8 > filesize)
-       fprintf(stderr, "wav_read: warning - short file (%d bytes missing)\n",
-               block.size + 8 -  filesize);
-    if(fread(b, 1, 4, fi) < 4) {
-       return 0;
-    }
-    if(strncmp(b, "WAVE", 4)) {
-       fprintf(stderr, "wav_read: not a WAV file (2)\n");
-       return 0;
-    }
-    do
+        fprintf(stderr, "wav_read: warning - short file (%lu bytes missing)\n", block.size + 8 -  filesize);
+    if(fread(b, 1, 4, fi) < 4)
     {
-       getWAVBlock(fi, &block);
-       pos = ftell(fi);
-       if(!strncmp(block.id, "fmt ", 4)) {
-           if(fread(&b, 1, 16, fi)<16)
+        fclose(fi);
                return 0;
-           wav->tag = b[0]|b[1]<<8;
-           wav->channels = b[2]|b[3]<<8;
-           wav->sampsPerSec = b[4]|b[5]<<8|b[6]<<16|b[7]<<24;
-           wav->bytesPerSec = b[8]|b[9]<<8|b[10]<<16|b[11]<<24;
-           wav->align = b[12]|b[13]<<8;
-           wav->bps = b[14]|b[15]<<8;
-       } else if (!strncmp(block.id, "LIST", 4)) {
-           // subchunk ICMT (comment) may exist
-       } else if (!strncmp(block.id, "data", 4)) {
-           wav->data = malloc(block.size);
-           if(!wav->data) {
-               fprintf(stderr, "Out of memory (%d bytes needed)", block.size);
-               return 0;
-           }
-           if(fread(wav->data, 1, block.size, fi) < block.size)
+    }
+    if(strncmp((const char*)b, "WAVE", 4))
+    {
+        fprintf(stderr, "wav_read: not a WAV file (2)\n");
+        fclose(fi);
                return 0;
-           wav->size = block.size;
        }
-       pos+=block.size;
-       fseek(fi, pos, SEEK_SET);
+    do
+    {
+        getWAVBlock(fi, &block);
+        pos = ftell(fi);
+        if(!strncmp(block.id, "fmt ", 4))
+        {
+            if(fread(&b, 1, 16, fi)<16)
+            {
+                fclose(fi);
+                return 0;
+            }
+            wav->tag = b[0]|b[1]<<8;
+            wav->channels = b[2]|b[3]<<8;
+            wav->sampsPerSec = b[4]|b[5]<<8|b[6]<<16|b[7]<<24;
+            wav->bytesPerSec = b[8]|b[9]<<8|b[10]<<16|b[11]<<24;
+            wav->align = b[12]|b[13]<<8;
+            wav->bps = b[14]|b[15]<<8;
+        }
+        else
+            if (!strncmp(block.id, "LIST", 4))
+            {
+        // subchunk ICMT (comment) may exist
+            }
+            else
+                if (!strncmp(block.id, "data", 4))
+                {
+                    int l;
+                    wav->data = (unsigned char*)malloc(block.size);
+                    if(!wav->data)
+                    {
+                        fprintf(stderr, "Out of memory (%d bytes needed)", block.size);
+                        fclose(fi);
+                        return 0;
+                    }
+                    l = fread(wav->data, 1, block.size, fi);
+                    if(l<=0) {
+                        fprintf(stderr, "Error: Couldn't read WAV data block\n");
+                        fclose(fi);
+                        return 0;
+                    } else if(l < block.size)
+                    {
+                        fprintf(stderr, "Warning: data block of size %d is only %d bytes (%d bytes missing)\n", block.size, l, block.size-l);
+                        wav->size = l;
+                    } else {
+                        wav->size = block.size;
+                    }
+                }
+                pos+=block.size;
+                fseek(fi, pos, SEEK_SET);
     }
     while (pos < filesize);
-
+    fclose(fi);
     return 1;
 }
 
-int wav_write(char*filename, struct WAV*wav)
+int wav_write(struct WAV*wav, const char*filename)
 {
     FILE*fi = fopen(filename, "wb");
     char*b="RIFFWAVEfmt \x10\0\0\0data";
@@ -160,7 +196,7 @@ int wav_write(char*filename, struct WAV*wav)
 
 void wav_print(struct WAV*wav)
 {
-    printf("tag:%04x channels:%d samples/sec:%d bytes/sec:%d align:%d bits/sample:%d size:%d\n",
+    printf("tag:%04x channels:%d samples/sec:%lu bytes/sec:%lu align:%d bits/sample:%d size:%d\n",
            wav->tag, wav->channels, wav->sampsPerSec, wav->bytesPerSec, 
            wav->align, wav->bps, wav->size);
 }
@@ -248,6 +284,8 @@ int wav_convert2mono(struct WAV*src, struct WAV*dest, int rate)
                pos += ratio;
            }
        }
+    } else {
+       fprintf(stderr, "Unsupported bitspersample value: %d\n", bps);
     }
     return 1;
 }