diff options
author | Adam Boot <rotator@gmail.com> | 2006-06-27 22:27:21 +0000 |
---|---|---|
committer | Adam Boot <rotator@gmail.com> | 2006-06-27 22:27:21 +0000 |
commit | 71cf604d8d317b7c2b167aac37493795046431cd (patch) | |
tree | 1af80810541fe10dc0e974e7daf31c8ead0aa627 /apps/metadata.c | |
parent | 1f28a141e13a8c0096db3b3ff8f86dc29a629426 (diff) | |
download | rockbox-71cf604d8d317b7c2b167aac37493795046431cd.tar.gz rockbox-71cf604d8d317b7c2b167aac37493795046431cd.zip |
Fix for wav files where the fmt chunk is not close to the start of the file
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10149 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/metadata.c')
-rw-r--r-- | apps/metadata.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/apps/metadata.c b/apps/metadata.c index 9cb055608a..bdf65b2639 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -829,71 +829,84 @@ static bool get_wave_metadata(int fd, struct mp3entry* id3) | |||
829 | int read_bytes; | 829 | int read_bytes; |
830 | int i; | 830 | int i; |
831 | 831 | ||
832 | if ((lseek(fd, 0, SEEK_SET) < 0) | 832 | /* get RIFF chunk header */ |
833 | || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 44)) | 833 | if ((lseek(fd, 0, SEEK_SET) < 0) |
834 | || ((read_bytes = read(fd, buf, 12)) < 12)) | ||
834 | { | 835 | { |
835 | return false; | 836 | return false; |
836 | } | 837 | } |
837 | 838 | ||
838 | if ((memcmp(buf, "RIFF",4) != 0) | 839 | if ((memcmp(buf, "RIFF",4) != 0) |
839 | || (memcmp(&buf[8], "WAVE", 4) !=0 )) | 840 | || (memcmp(&buf[8], "WAVE", 4) !=0 )) |
840 | { | 841 | { |
841 | return false; | 842 | return false; |
842 | } | 843 | } |
843 | 844 | ||
844 | buf += 12; | 845 | /* iterate over WAVE chunks until 'data' chunk */ |
845 | read_bytes -= 12; | 846 | while (true) |
846 | |||
847 | while ((numbytes == 0) && (read_bytes >= 8)) | ||
848 | { | 847 | { |
848 | /* get chunk header */ | ||
849 | if ((read_bytes = read(fd, buf, 8)) < 8) | ||
850 | return false; | ||
851 | |||
849 | /* chunkSize */ | 852 | /* chunkSize */ |
850 | i = get_long(&buf[4]); | 853 | i = get_long(&buf[4]); |
851 | 854 | ||
852 | if (memcmp(buf, "fmt ", 4) == 0) | 855 | if (memcmp(buf, "fmt ", 4) == 0) |
853 | { | 856 | { |
857 | /* get rest of chunk */ | ||
858 | if ((read_bytes = read(fd, buf, 16)) < 16) | ||
859 | return false; | ||
860 | |||
861 | i -= 16; | ||
862 | |||
854 | /* skipping wFormatTag */ | 863 | /* skipping wFormatTag */ |
855 | /* wChannels */ | 864 | /* wChannels */ |
856 | channels = buf[10] | (buf[11] << 8); | 865 | channels = buf[2] | (buf[3] << 8); |
857 | /* dwSamplesPerSec */ | 866 | /* dwSamplesPerSec */ |
858 | id3->frequency = get_long(&buf[12]); | 867 | id3->frequency = get_long(&buf[4]); |
859 | /* dwAvgBytesPerSec */ | 868 | /* dwAvgBytesPerSec */ |
860 | id3->bitrate = (get_long(&buf[16]) * 8) / 1000; | 869 | id3->bitrate = (get_long(&buf[8]) * 8) / 1000; |
861 | /* skipping wBlockAlign */ | 870 | /* skipping wBlockAlign */ |
862 | /* wBitsPerSample */ | 871 | /* wBitsPerSample */ |
863 | bitspersample = buf[22] | (buf[23] << 8); | 872 | bitspersample = buf[14] | (buf[15] << 8); |
864 | } | 873 | } |
865 | else if (memcmp(buf, "data", 4) == 0) | 874 | else if (memcmp(buf, "data", 4) == 0) |
866 | { | 875 | { |
867 | numbytes = i; | 876 | numbytes = i; |
877 | break; | ||
868 | } | 878 | } |
869 | else if (memcmp(buf, "fact", 4) == 0) | 879 | else if (memcmp(buf, "fact", 4) == 0) |
870 | { | 880 | { |
871 | /* dwSampleLength */ | 881 | /* dwSampleLength */ |
872 | if (i >= 4) | 882 | if (i >= 4) |
873 | { | 883 | { |
874 | totalsamples = get_long(&buf[8]); | 884 | /* get rest of chunk */ |
885 | if ((read_bytes = read(fd, buf, 2)) < 2) | ||
886 | return false; | ||
887 | |||
888 | i -= 2; | ||
889 | totalsamples = get_long(buf); | ||
875 | } | 890 | } |
876 | } | 891 | } |
877 | 892 | ||
878 | /* go to next chunk (even chunk sizes must be padded) */ | 893 | /* seek to next chunk (even chunk sizes must be padded) */ |
879 | if (i & 0x01) | 894 | if (i & 0x01) |
880 | { | ||
881 | i++; | 895 | i++; |
882 | } | 896 | |
883 | 897 | if(lseek(fd, i, SEEK_CUR) < 0) | |
884 | buf += i + 8; | 898 | return false; |
885 | read_bytes -= i + 8; | ||
886 | } | 899 | } |
887 | 900 | ||
888 | if ((numbytes == 0) || (channels == 0)) | 901 | if ((numbytes == 0) || (channels == 0)) |
889 | { | 902 | { |
890 | return false; | 903 | return false; |
891 | } | 904 | } |
892 | 905 | ||
893 | if (totalsamples == 0) | 906 | if (totalsamples == 0) |
894 | { | 907 | { |
895 | /* for PCM only */ | 908 | /* for PCM only */ |
896 | totalsamples = numbytes | 909 | totalsamples = numbytes |
897 | / ((((bitspersample - 1) / 8) + 1) * channels); | 910 | / ((((bitspersample - 1) / 8) + 1) * channels); |
898 | } | 911 | } |
899 | 912 | ||
@@ -906,7 +919,6 @@ static bool get_wave_metadata(int fd, struct mp3entry* id3) | |||
906 | return true; | 919 | return true; |
907 | } | 920 | } |
908 | 921 | ||
909 | |||
910 | static bool get_m4a_metadata(int fd, struct mp3entry* id3) | 922 | static bool get_m4a_metadata(int fd, struct mp3entry* id3) |
911 | { | 923 | { |
912 | unsigned char* buf; | 924 | unsigned char* buf; |