| @@ -2,7 +2,7 @@ · 1 unmodified line |
| 2 | 2 | /*#define MINIMP3_ONLY_SIMD*/ |
| 3 | 3 | /*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/ |
| 4 | 4 | #define MINIMP3_IMPLEMENTATION |
| 5 | | −#include "minimp3.h" |
| 5 | +#include "minimp3_ex.h" |
| 6 | 6 | #include <stdio.h> |
| 7 | 7 | #include <math.h> |
| 8 | 8 | #include <string.h> |
| @@ -58,76 +58,81 @@ static unsigned char *preload(FILE *file, int *data_size) · 49 unmodified lines |
| 58 | 58 | return data; |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | | −static void decode_file(const unsigned char *buf_mp3, int mp3_size, const unsigned char *buf_ref, int ref_size, FILE *file_out, const int wave_out) |
| 61 | +#ifdef MP4_MODE |
| 62 | +typedef struct |
| 62 | 63 | { |
| 63 | | − static mp3dec_t mp3d; |
| 64 | | − mp3dec_frame_info_t info; |
| 65 | | − int i, data_bytes, samples, total_samples = 0, maxdiff = 0; |
| 66 | | − double MSE = 0.0, psnr; |
| 64 | + mp3dec_t *mp3d; |
| 65 | + mp3dec_file_info_t *info; |
| 66 | + size_t allocated; |
| 67 | +} frames_iterate_data; |
| 67 | 68 | |
| 68 | | − if (mp3_size > 10 && !strncmp((char *)buf_mp3, "ID3", 3)) |
| 69 | +static int frames_iterate_cb(void *user_data, const uint8_t *frame, int frame_size, size_t offset, mp3dec_frame_info_t *info) |
| 70 | +{ |
| 71 | + (void)offset; |
| 72 | + frames_iterate_data *d = user_data; |
| 73 | + d->info->channels = info->channels; |
| 74 | + d->info->hz = info->hz; |
| 75 | + d->info->layer = info->layer; |
| 76 | + /*printf("%d %d %d\n", frame_size, (int)offset, info->channels);*/ |
| 77 | + if ((d->allocated - d->info->samples*2) < MINIMP3_MAX_SAMPLES_PER_FRAME*2) |
| 69 | 78 | { |
| 70 | | − int id3v2size = (((buf_mp3[6] & 0x7f) << 21) | ((buf_mp3[7] & 0x7f) << 14) | |
| 71 | | − ((buf_mp3[8] & 0x7f) << 7) | (buf_mp3[9] & 0x7f)) + 10; |
| 72 | | − if (mp3_size >= id3v2size) |
| 73 | | − { |
| 74 | | − printf("info: skipping %d bytes of id3v2\n", id3v2size); |
| 75 | | − buf_mp3 += id3v2size; |
| 76 | | − mp3_size -= id3v2size; |
| 77 | | − } |
| 79 | + if (!d->allocated) |
| 80 | + d->allocated = 1024*1024; |
| 81 | + else |
| 82 | + d->allocated *= 2; |
| 83 | + d->info->buffer = realloc(d->info->buffer, d->allocated); |
| 78 | 84 | } |
| 85 | + int samples = mp3dec_decode_frame(d->mp3d, frame, frame_size, d->info->buffer + d->info->samples, info); |
| 86 | + if (samples) |
| 87 | + { |
| 88 | + d->info->samples += samples*info->channels; |
| 89 | + } |
| 90 | + return 0; |
| 91 | +} |
| 92 | +#endif |
| 79 | 93 | |
| 80 | | − mp3dec_init(&mp3d); |
| 94 | +static void decode_file(const char *input_file_name, const unsigned char *buf_ref, int ref_size, FILE *file_out, const int wave_out) |
| 95 | +{ |
| 96 | + mp3dec_t mp3d; |
| 97 | + int i, data_bytes, total_samples = 0, maxdiff = 0; |
| 98 | + double MSE = 0.0, psnr; |
| 99 | + |
| 100 | + mp3dec_file_info_t info; |
| 81 | 101 | memset(&info, 0, sizeof(info)); |
| 102 | +#ifdef MP4_MODE |
| 103 | + frames_iterate_data d = { &mp3d, &info, 0 }; |
| 104 | + mp3dec_init(&mp3d); |
| 105 | + if (mp3dec_iterate(input_file_name, frames_iterate_cb, &d)) |
| 106 | +#else |
| 107 | + if (mp3dec_load(&mp3d, input_file_name, &info)) |
| 108 | +#endif |
| 109 | + { |
| 110 | + printf("error: file not found or read error"); |
| 111 | + exit(1); |
| 112 | + } |
| 82 | 113 | #ifndef MINIMP3_NO_WAV |
| 83 | 114 | if (wave_out && file_out) |
| 84 | 115 | fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out); |
| 85 | 116 | #endif |
| 86 | | − do |
| 117 | + if (info.samples) |
| 87 | 118 | { |
| 88 | | − short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; |
| 89 | | −#ifdef MP4_MODE |
| 90 | | − int free_format_bytes = 0, frame_size = 0; |
| 91 | | − i = mp3d_find_frame(buf_mp3, mp3_size, &free_format_bytes, &frame_size); |
| 92 | | − buf_mp3 += i; |
| 93 | | − mp3_size -= i; |
| 94 | | − if (i && !frame_size) |
| 95 | | − { |
| 96 | | − printf("warning: skipping %d bytes, frame_size=%d\n", i, frame_size); |
| 97 | | − continue; |
| 98 | | − } |
| 99 | | − if (frame_size > mp3_size) |
| 100 | | − { |
| 101 | | − printf("error: demux mp3 frame failed: i=%d, frame_size=%d\n", i, frame_size); |
| 102 | | − exit(1); |
| 103 | | − } |
| 104 | | − if (!frame_size) |
| 105 | | − break; |
| 106 | | − samples = mp3dec_decode_frame(&mp3d, buf_mp3, frame_size, pcm, &info); |
| 107 | | −#else |
| 108 | | − samples = mp3dec_decode_frame(&mp3d, buf_mp3, mp3_size, pcm, &info); |
| 109 | | −#endif |
| 110 | | − if (samples) |
| 119 | + total_samples += info.samples; |
| 120 | + if (buf_ref) |
| 111 | 121 | { |
| 112 | | − total_samples += samples*info.channels; |
| 113 | | − if (buf_ref && ref_size >= samples*info.channels*2) |
| 122 | + int max_samples = MINIMP3_MIN((size_t)ref_size/2, info.samples); |
| 123 | + for (i = 0; i < max_samples; i++) |
| 114 | 124 | { |
| 115 | | − for (i = 0; i < samples*info.channels; i++) |
| 116 | | − { |
| 117 | | − int MSEtemp = abs((int)pcm[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)])); |
| 118 | | − if (MSEtemp > maxdiff) |
| 119 | | − maxdiff = MSEtemp; |
| 120 | | − MSE += (float)MSEtemp*(float)MSEtemp; |
| 121 | | − } |
| 122 | | − buf_ref += samples*info.channels*2; |
| 123 | | − ref_size -= samples*info.channels*2; |
| 125 | + int MSEtemp = abs((int)info.buffer[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)])); |
| 126 | + if (MSEtemp > maxdiff) |
| 127 | + maxdiff = MSEtemp; |
| 128 | + MSE += (float)MSEtemp*(float)MSEtemp; |
| 124 | 129 | } |
| 125 | | − if (file_out) |
| 126 | | − fwrite(pcm, samples, 2*info.channels, file_out); |
| 127 | 130 | } |
| 128 | | − buf_mp3 += info.frame_bytes; |
| 129 | | − mp3_size -= info.frame_bytes; |
| 130 | | − } while (info.frame_bytes); |
| 131 | + if (file_out) |
| 132 | + fwrite(info.buffer, info.samples, sizeof(int16_t), file_out); |
| 133 | + free(info.buffer); |
| 134 | + } |
| 135 | + |
| 131 | 136 | #ifndef LIBFUZZER |
| 132 | 137 | MSE /= total_samples ? total_samples : 1; |
| 133 | 138 | if (0 == MSE) |
| @@ -173,7 +178,7 @@ int main2(int argc, char *argv[]) · 39 unmodified lines |
| 173 | 178 | int main(int argc, char *argv[]) |
| 174 | 179 | #endif |
| 175 | 180 | { |
| 176 | | − int wave_out = 0, ref_size, mp3_size; |
| 181 | + int wave_out = 0, ref_size; |
| 177 | 182 | char *ref_file_name = (argc > 2) ? argv[2] : NULL; |
| 178 | 183 | char *output_file_name = (argc > 3) ? argv[3] : NULL; |
| 179 | 184 | FILE *file_out = NULL; |
| @@ -200,17 +205,7 @@ int main(int argc, char *argv[]) · 20 unmodified lines |
| 200 | 205 | printf("error: no file names given\n"); |
| 201 | 206 | return 1; |
| 202 | 207 | } |
| 203 | | − FILE *file_mp3 = fopen(input_file_name, "rb"); |
| 204 | | − unsigned char *buf_mp3 = preload(file_mp3, &mp3_size); |
| 205 | | − if (file_mp3) |
| 206 | | − fclose(file_mp3); |
| 207 | | − if (!buf_mp3 || !mp3_size) |
| 208 | | − { |
| 209 | | − printf("error: no input data\n"); |
| 210 | | − return 1; |
| 211 | | − } |
| 212 | | − decode_file(buf_mp3, mp3_size, buf_ref, ref_size, file_out, wave_out); |
| 213 | | − free(buf_mp3); |
| 208 | + decode_file(input_file_name, buf_ref, ref_size, file_out, wave_out); |
| 214 | 209 | #ifdef __AFL_HAVE_MANUAL_CONTROL |
| 215 | 210 | } |
| 216 | 211 | #endif |