shithub: mp3dec

Download patch

ref: a0b3bfd8c6bd68d2a3492e24d3d79eae5d7064d8
parent: 1518f298b35feecf2f6e5c0aae83e4eab64b3e72
author: lieff <lieff@users.noreply.github.com>
date: Sat Feb 22 20:07:00 EST 2020

mp3dec_ex: fix MP3D_SEEK_TO_BYTE mode + test

--- a/minimp3_ex.h
+++ b/minimp3_ex.h
@@ -591,14 +591,11 @@
     dec->file.size   = buf_size;
     dec->seek_method = seek_method;
     mp3dec_init(&dec->mp3d);
-    if (MP3D_SEEK_TO_SAMPLE == dec->seek_method)
-    {
-        int ret = mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
-        if (ret && MP3D_E_USER != ret)
-            return ret;
-        mp3dec_init(&dec->mp3d);
-        dec->buffer_samples = 0;
-    }
+    int ret = mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
+    if (ret && MP3D_E_USER != ret)
+        return ret;
+    mp3dec_init(&dec->mp3d);
+    dec->buffer_samples = 0;
     return 0;
 }
 
@@ -635,8 +632,7 @@
     {
         if (dec->io)
         {
-            if (dec->io->seek(position, dec->io->seek_data))
-                return MP3D_E_IOERROR;
+            dec->offset = position;
         } else
         {
             dec->offset = MINIMP3_MIN(position, dec->file.size);
@@ -1176,18 +1172,15 @@
     dec->seek_method = seek_method;
     dec->io = io;
     mp3dec_init(&dec->mp3d);
-    if (MP3D_SEEK_TO_SAMPLE == dec->seek_method)
-    {
-        if (io->seek(0, io->seek_data))
-            return MP3D_E_IOERROR;
-        int ret = mp3dec_iterate_cb(io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
-        if (ret && MP3D_E_USER != ret)
-            return ret;
-        if (dec->io->seek(dec->start_offset, dec->io->seek_data))
-            return MP3D_E_IOERROR;
-        mp3dec_init(&dec->mp3d);
-        dec->buffer_samples = 0;
-    }
+    if (io->seek(0, io->seek_data))
+        return MP3D_E_IOERROR;
+    int ret = mp3dec_iterate_cb(io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
+    if (ret && MP3D_E_USER != ret)
+        return ret;
+    if (dec->io->seek(dec->start_offset, dec->io->seek_data))
+        return MP3D_E_IOERROR;
+    mp3dec_init(&dec->mp3d);
+    dec->buffer_samples = 0;
     return 0;
 }
 
--- a/minimp3_test.c
+++ b/minimp3_test.c
@@ -71,6 +71,7 @@
 }
 
 static int io_num, fail_io_num = -1;
+static int wave_out = 0, mode = 0, position = 0, portion = 0, seek_to_byte = 0;
 
 static size_t read_cb(void *buf, size_t size, void *user_data)
 {
@@ -123,7 +124,7 @@
     return 0;
 }
 
-static void decode_file(const char *input_file_name, const unsigned char *buf_ref, int ref_size, FILE *file_out, const int wave_out, const int mode, int position, int portion)
+static void decode_file(const char *input_file_name, const unsigned char *buf_ref, int ref_size, FILE *file_out)
 {
     mp3dec_t mp3d;
     int i, res = -1, data_bytes, total_samples = 0, maxdiff = 0;
@@ -186,7 +187,7 @@
         uint8_t *buf = 0;
         if (MODE_STREAM == mode)
         {
-            res = mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE);
+            res = mp3dec_ex_open(&dec, input_file_name, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE);
         } else if (MODE_STREAM_BUF == mode)
         {
             int size = 0;
@@ -193,12 +194,12 @@
             FILE *file = fopen(input_file_name, "rb");
             buf = preload(file, &size);
             fclose(file);
-            res = buf ? mp3dec_ex_open_buf(&dec, buf, size, MP3D_SEEK_TO_SAMPLE) : MP3D_E_IOERROR;
+            res = buf ? mp3dec_ex_open_buf(&dec, buf, size, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) : MP3D_E_IOERROR;
         } else if (MODE_STREAM_CB == mode)
         {
             FILE *file = fopen(input_file_name, "rb");
             io.read_data = io.seek_data = file;
-            res = file ? mp3dec_ex_open_cb(&dec, &io, MP3D_SEEK_TO_SAMPLE) : MP3D_E_IOERROR;
+            res = file ? mp3dec_ex_open_cb(&dec, &io, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) : MP3D_E_IOERROR;
         }
         if (res)
         {
@@ -226,10 +227,13 @@
         {
             if (-2 == position)
                 position = 0;
-            info.samples -= MINIMP3_MIN(info.samples, (size_t)position);
-            int skip_ref = MINIMP3_MIN((size_t)ref_size, position*sizeof(int16_t));
-            buf_ref  += skip_ref;
-            ref_size -= skip_ref;
+            if (!seek_to_byte)
+            {
+                info.samples -= MINIMP3_MIN(info.samples, (size_t)position);
+                int skip_ref = MINIMP3_MIN((size_t)ref_size, position*sizeof(int16_t));
+                buf_ref  += skip_ref;
+                ref_size -= skip_ref;
+            }
             res = mp3dec_ex_seek(&dec, position);
             if (res)
             {
@@ -249,13 +253,15 @@
         {
             int to_read = MINIMP3_MIN(samples, portion);
             readed = mp3dec_ex_read(&dec, info.buffer + samples_readed, to_read);
+            samples -= readed;
+            samples_readed += readed;
             if (readed != (size_t)to_read)
             {
+                if (seek_to_byte && readed < (size_t)to_read)
+                    break;
                 printf("error: mp3dec_ex_read() readed less than expected, last_error=%d\n", dec.last_error);
                 exit(1);
             }
-            samples -= to_read;
-            samples_readed += to_read;
         }
         readed = mp3dec_ex_read(&dec, info.buffer, 1);
         if (readed)
@@ -263,6 +269,10 @@
             printf("error: mp3dec_ex_read() readed more than expected, last_error=%d\n", dec.last_error);
             exit(1);
         }
+        if (seek_to_byte)
+        {
+            info.samples = samples_readed;
+        }
         mp3dec_ex_close(&dec);
         if (MODE_STREAM_BUF == mode && buf)
             free(buf);
@@ -353,7 +363,7 @@
 int main(int argc, char *argv[])
 #endif
 {
-    int wave_out = 0, mode = 0, position = 0, portion = 0, i, ref_size;
+    int i, ref_size;
     for(i = 1; i < argc; i++)
     {
         if (argv[i][0] != '-')
@@ -364,6 +374,7 @@
         case 's': i++; if (i < argc) position = atoi(argv[i]); break;
         case 'p': i++; if (i < argc) portion  = atoi(argv[i]); break;
         case 'e': i++; if (i < argc) fail_io_num = atoi(argv[i]); break;
+        case 'b': seek_to_byte = 1; break;
         default:
             printf("error: unrecognized option\n");
             return 1;
@@ -395,7 +406,7 @@
         printf("error: no file names given\n");
         return 1;
     }
-    decode_file(input_file_name, buf_ref, ref_size, file_out, wave_out, mode, position, portion);
+    decode_file(input_file_name, buf_ref, ref_size, file_out);
 #ifdef __AFL_HAVE_MANUAL_CONTROL
     }
 #endif
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -60,7 +60,16 @@
 
 [[ "$(./minimp3 -m 2 vectors/l3-nonstandard-small.bit vectors/l3-nonstandard-small.pcm)" != "rate=0 samples=0 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
 [[ "$(./minimp3 -m 5 vectors/l3-nonstandard-small.bit vectors/l3-nonstandard-small.pcm)" != "rate=0 samples=0 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
+
+[[ "$(./minimp3 -m 6 -s 215 -b vectors/l3-sin1k0db.bit -)" != "rate=44100 samples=725760 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
+[[ "$(./minimp3 -m 6 -s 633 -b vectors/l3-sin1k0db.bit -)" != "rate=44100 samples=723456 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
 set -e
+
+./minimp3 -m 6 -s 215 -b vectors/l3-sin1k0db.bit vectors/l3-sin1k0db.pcm
+./minimp3 -m 6 -s 633 -b vectors/l3-sin1k0db.bit vectors/l3-sin1k0db_ofs633.pcm
+./minimp3 -m 8 -s 215 -b vectors/l3-sin1k0db.bit vectors/l3-sin1k0db.pcm
+./minimp3 -m 8 -s 633 -b vectors/l3-sin1k0db.bit vectors/l3-sin1k0db_ofs633.pcm
+
 gcov minimp3_test.c
 
 echo testing x86 w/o sse...
binary files /dev/null b/vectors/l3-sin1k0db_ofs633.pcm differ