| @@ -2,7 +2,7 @@ · 1 unmodified line |
| 2 | /*#define MINIMP3_ONLY_SIMD*/ | 2 | /*#define MINIMP3_ONLY_SIMD*/ |
| 3 | /*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/ | 3 | /*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/ |
| 4 | #define MINIMP3_IMPLEMENTATION | 4 | #define MINIMP3_IMPLEMENTATION |
| 5 | #include "minimp3.h" | 5 | #include "minimp3_ex.h" |
| 6 | #include <stdio.h> | 6 | #include <stdio.h> |
| 7 | #include <math.h> | 7 | #include <math.h> |
| 8 | #include <string.h> | 8 | #include <string.h> |
| @@ -58,76 +58,81 @@ static unsigned char *preload(FILE *file, int *data_size) · 49 unmodified lines |
| 58 | return data; | 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_t *mp3d; |
| 64 | mp3dec_frame_info_t info; | 65 | mp3dec_file_info_t *info; |
| 65 | int i, data_bytes, samples, total_samples = 0, maxdiff = 0; | 66 | size_t allocated; |
| 66 | double MSE = 0.0, psnr; | 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) | | 79 | if (!d->allocated) |
| 71 | ((buf_mp3[8] & 0x7f) << 7) | (buf_mp3[9] & 0x7f)) + 10; | 80 | d->allocated = 1024*1024; |
| 72 | if (mp3_size >= id3v2size) | 81 | else |
| 73 | { | 82 | d->allocated *= 2; |
| 74 | printf("info: skipping %d bytes of id3v2\n", id3v2size); | 83 | d->info->buffer = realloc(d->info->buffer, d->allocated); |
| 75 | buf_mp3 += id3v2size; | | |
| 76 | mp3_size -= id3v2size; | | |
| 77 | } | | |
| 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 | memset(&info, 0, sizeof(info)); | 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 | #ifndef MINIMP3_NO_WAV | 113 | #ifndef MINIMP3_NO_WAV |
| 83 | if (wave_out && file_out) | 114 | if (wave_out && file_out) |
| 84 | fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out); | 115 | fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out); |
| 85 | #endif | 116 | #endif |
| 86 | do | 117 | if (info.samples) |
| 87 | { | 118 | { |
| 88 | short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; | 119 | total_samples += info.samples; |
| 89 | #ifdef MP4_MODE | 120 | if (buf_ref) |
| 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) | | |
| 111 | { | 121 | { |
| 112 | total_samples += samples*info.channels; | 122 | int max_samples = MINIMP3_MIN((size_t)ref_size/2, info.samples); |
| 113 | if (buf_ref && ref_size >= samples*info.channels*2) | 123 | for (i = 0; i < max_samples; i++) |
| 114 | { | 124 | { |
| 115 | for (i = 0; i < samples*info.channels; i++) | 125 | int MSEtemp = abs((int)info.buffer[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)])); |
| 116 | { | 126 | if (MSEtemp > maxdiff) |
| 117 | int MSEtemp = abs((int)pcm[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)])); | 127 | maxdiff = MSEtemp; |
| 118 | if (MSEtemp > maxdiff) | 128 | MSE += (float)MSEtemp*(float)MSEtemp; |
| 119 | maxdiff = MSEtemp; | | |
| 120 | MSE += (float)MSEtemp*(float)MSEtemp; | | |
| 121 | } | | |
| 122 | buf_ref += samples*info.channels*2; | | |
| 123 | ref_size -= samples*info.channels*2; | | |
| 124 | } | 129 | } |
| 125 | if (file_out) | | |
| 126 | fwrite(pcm, samples, 2*info.channels, file_out); | | |
| 127 | } | 130 | } |
| 128 | buf_mp3 += info.frame_bytes; | 131 | if (file_out) |
| 129 | mp3_size -= info.frame_bytes; | 132 | fwrite(info.buffer, info.samples, sizeof(int16_t), file_out); |
| 130 | } while (info.frame_bytes); | 133 | free(info.buffer); |
| | 134 | } |
| | 135 | |
| 131 | #ifndef LIBFUZZER | 136 | #ifndef LIBFUZZER |
| 132 | MSE /= total_samples ? total_samples : 1; | 137 | MSE /= total_samples ? total_samples : 1; |
| 133 | if (0 == MSE) | 138 | if (0 == MSE) |
| @@ -173,7 +178,7 @@ int main2(int argc, char *argv[]) · 39 unmodified lines |
| 173 | int main(int argc, char *argv[]) | 178 | int main(int argc, char *argv[]) |
| 174 | #endif | 179 | #endif |
| 175 | { | 180 | { |
| 176 | int wave_out = 0, ref_size, mp3_size; | 181 | int wave_out = 0, ref_size; |
| 177 | char *ref_file_name = (argc > 2) ? argv[2] : NULL; | 182 | char *ref_file_name = (argc > 2) ? argv[2] : NULL; |
| 178 | char *output_file_name = (argc > 3) ? argv[3] : NULL; | 183 | char *output_file_name = (argc > 3) ? argv[3] : NULL; |
| 179 | FILE *file_out = NULL; | 184 | FILE *file_out = NULL; |
| @@ -200,17 +205,7 @@ int main(int argc, char *argv[]) · 20 unmodified lines |
| 200 | printf("error: no file names given\n"); | 205 | printf("error: no file names given\n"); |
| 201 | return 1; | 206 | return 1; |
| 202 | } | 207 | } |
| 203 | FILE *file_mp3 = fopen(input_file_name, "rb"); | 208 | decode_file(input_file_name, buf_ref, ref_size, file_out, wave_out); |
| 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); | | |
| 214 | #ifdef __AFL_HAVE_MANUAL_CONTROL | 209 | #ifdef __AFL_HAVE_MANUAL_CONTROL |
| 215 | } | 210 | } |
| 216 | #endif | 211 | #endif |