History

mp3dec_ex: add mp3dec_detect_* functions + test

lieff committed 6 years ago

Commit 0a2ff3b1 parent 728ff803 files · +112 −3Browse files

Unified · Split

3 files
  1. minimp3_ex.h +73 −2
  2. minimp3_test.c +36 −1
  3. scripts/build.sh +3 −0
minimp3_ex.h+73−2
@@ -82,6 +82,9 @@ typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offs · 81 unmodified lines
82extern "C" {82extern "C" {
83#endif83#endif
84 84
85/* detect mp3/mpa format */
86int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size);
87int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size);
85/* decode whole buffer block */88/* decode whole buffer block */
86int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);89int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
87int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);90int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
@@ -95,11 +98,13 @@ void mp3dec_ex_close(mp3dec_ex_t *dec); · 7 unmodified lines
95int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);98int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
96size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);99size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
97#ifndef MINIMP3_NO_STDIO100#ifndef MINIMP3_NO_STDIO
98/* stdio versions of file load, iterate and stream */101/* stdio versions of file detect, load, iterate and stream */
102int mp3dec_detect(const char *file_name);
99int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);103int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
100int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);104int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
101int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);105int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);
102#ifdef _WIN32106#ifdef _WIN32
107int mp3dec_detect_w(const wchar_t *file_name);
103int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);108int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
104int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);109int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
105int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);110int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);
@@ -217,6 +222,47 @@ static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *f · 111 unmodified lines
217 return 1;222 return 1;
218}223}
219 224
225int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size)
226{
227 return mp3dec_detect_cb(0, (uint8_t *)buf, buf_size);
228}
229
230int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size)
231{
232 if (!buf || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
233 return MP3D_E_PARAM;
234 size_t filled = buf_size;
235 if (io)
236 {
237 if (io->seek(0, io->seek_data))
238 return MP3D_E_IOERROR;
239 filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
240 if (filled > MINIMP3_ID3_DETECT_SIZE)
241 return MP3D_E_IOERROR;
242 if (MINIMP3_ID3_DETECT_SIZE != filled)
243 return MP3D_E_USER;
244 }
245 if (mp3dec_skip_id3v2(buf, filled))
246 return 0; /* id3v2 tag is enough evidence */
247 if (io)
248 {
249 size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
250 if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
251 return MP3D_E_IOERROR;
252 filled += readed;
253 if (filled < MINIMP3_BUF_SIZE)
254 mp3dec_skip_id3v1(buf, &filled);
255 } else
256 {
257 mp3dec_skip_id3v1(buf, &filled);
258 }
259 int free_format_bytes, frame_size;
260 mp3d_find_frame(buf, MINIMP3_MIN(filled, (size_t)INT_MAX), &free_format_bytes, &frame_size);
261 if (frame_size)
262 return 0; /* MAX_FRAME_SYNC_MATCHES consecutive frames found */
263 return MP3D_E_USER;
264}
265
220int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)266int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
221{267{
222 return mp3dec_load_cb(dec, 0, (uint8_t *)buf, buf_size, info, progress_cb, user_data);268 return mp3dec_load_cb(dec, 0, (uint8_t *)buf, buf_size, info, progress_cb, user_data);
@@ -1143,6 +1189,13 @@ error: · 920 unmodified lines
1143}1189}
1144#endif1190#endif
1145 1191
1192static int mp3dec_detect_mapinfo(mp3dec_map_info_t *map_info)
1193{
1194 int ret = mp3dec_detect_buf(map_info->buffer, map_info->size);
1195 mp3dec_close_file(map_info);
1196 return ret;
1197}
1198
1146static int mp3dec_load_mapinfo(mp3dec_t *dec, mp3dec_map_info_t *map_info, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)1199static int mp3dec_load_mapinfo(mp3dec_t *dec, mp3dec_map_info_t *map_info, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1147{1200{
1148 int ret = mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);1201 int ret = mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);
@@ -1166,6 +1219,15 @@ static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int seek_method) · 17 unmodified lines
1166 return ret;1219 return ret;
1167}1220}
1168 1221
1222int mp3dec_detect(const char *file_name)
1223{
1224 int ret;
1225 mp3dec_map_info_t map_info;
1226 if ((ret = mp3dec_open_file(file_name, &map_info)))
1227 return ret;
1228 return mp3dec_detect_mapinfo(&map_info);
1229}
1230
1169int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)1231int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1170{1232{
1171 int ret;1233 int ret;
@@ -1241,13 +1303,22 @@ void mp3dec_ex_close(mp3dec_ex_t *dec) · 69 unmodified lines
1241}1303}
1242 1304
1243#ifdef _WIN321305#ifdef _WIN32
1306int mp3dec_detect_w(const wchar_t *file_name)
1307{
1308 int ret;
1309 mp3dec_map_info_t map_info;
1310 if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1311 return ret;
1312 return mp3dec_detect_mapinfo(&map_info);
1313}
1314
1244int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)1315int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1245{1316{
1246 int ret;1317 int ret;
1247 mp3dec_map_info_t map_info;1318 mp3dec_map_info_t map_info;
1248 if ((ret = mp3dec_open_file_w(file_name, &map_info)))1319 if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1249 return ret;1320 return ret;
1250 return mp3dec_load_mapinfo(dec, &map_info,info, progress_cb, user_data);1321 return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
1251}1322}
1252 1323
1253int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data)1324int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data)
minimp3_test.c+36−1
@@ -57,6 +57,9 @@ void *local_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t o · 56 unmodified lines
57#define MODE_STREAM 657#define MODE_STREAM 6
58#define MODE_STREAM_BUF 758#define MODE_STREAM_BUF 7
59#define MODE_STREAM_CB 859#define MODE_STREAM_CB 8
60#define MODE_DETECT 9
61#define MODE_DETECT_BUF 10
62#define MODE_DETECT_CB 11
60 63
61static int16_t read16le(const void *p)64static int16_t read16le(const void *p)
62{65{
@@ -178,6 +181,7 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re · 115 unmodified lines
178 mp3dec_t mp3d;181 mp3dec_t mp3d;
179 int i, res = -1, data_bytes, total_samples = 0, maxdiff = 0;182 int i, res = -1, data_bytes, total_samples = 0, maxdiff = 0;
180 int no_std_vec = strstr(input_file_name, "nonstandard") || strstr(input_file_name, "ILL");183 int no_std_vec = strstr(input_file_name, "nonstandard") || strstr(input_file_name, "ILL");
184 uint8_t *buf = 0;
181 double MSE = 0.0, psnr;185 double MSE = 0.0, psnr;
182 186
183 mp3dec_io_t io;187 mp3dec_io_t io;
@@ -235,7 +239,6 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re · 51 unmodified lines
235 {239 {
236 mp3dec_ex_t dec;240 mp3dec_ex_t dec;
237 size_t readed;241 size_t readed;
238 uint8_t *buf = 0;
239 if (MODE_STREAM == mode)242 if (MODE_STREAM == mode)
240 {243 {
241 res = mp3dec_ex_open(&dec, input_file_name, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE);244 res = mp3dec_ex_open(&dec, input_file_name, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE);
@@ -330,6 +333,38 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re · 88 unmodified lines
330 free(buf);333 free(buf);
331 if (MODE_STREAM_CB == mode)334 if (MODE_STREAM_CB == mode)
332 fclose((FILE*)io.read_data);335 fclose((FILE*)io.read_data);
336 } else if (MODE_DETECT == mode || MODE_DETECT_BUF == mode || MODE_DETECT_CB == mode)
337 {
338 if (MODE_DETECT == mode)
339 {
340 res = mp3dec_detect(input_file_name);
341 } else if (MODE_DETECT_BUF == mode)
342 {
343 int size = 0;
344 FILE *file = fopen(input_file_name, "rb");
345 buf = preload(file, &size);
346 fclose(file);
347 res = buf ? mp3dec_detect_buf(buf, size) : MP3D_E_IOERROR;
348 } else if (MODE_DETECT_CB == mode)
349 {
350 uint8_t *io_buf = malloc(MINIMP3_BUF_SIZE);
351 FAIL_MEM(io_buf);
352 FILE *file = fopen(input_file_name, "rb");
353 io.read_data = io.seek_data = file;
354 res = file ? mp3dec_detect_cb(&io, io_buf, MINIMP3_BUF_SIZE) : MP3D_E_IOERROR;
355 free(io_buf);
356 }
357 if (MP3D_E_USER == res)
358 {
359 printf("info: not an mp3/mpa file\n");
360 exit(1);
361 } else if (res)
362 {
363 printf("error: mp3dec_detect*()=%d failed\n", res);
364 exit(1);
365 }
366 printf("info: mp3/mpa file detected\n");
367 exit(0);
333 } else368 } else
334 {369 {
335 printf("error: unknown mode\n");370 printf("error: unknown mode\n");
scripts/build.sh+3−0
@@ -30,6 +30,9 @@ scripts/test_mode.sh 8 -1 -1 · 29 unmodified lines
30scripts/test_mode.sh 6 -2 -130scripts/test_mode.sh 6 -2 -1
31scripts/test_mode.sh 7 -2 -131scripts/test_mode.sh 7 -2 -1
32scripts/test_mode.sh 8 -2 -132scripts/test_mode.sh 8 -2 -1
33scripts/test_mode.sh 9 0 0
34scripts/test_mode.sh 10 0 0
35scripts/test_mode.sh 11 0 0
33set +e36set +e
34[[ "$(./minimp3)" != "error: no file names given" ]] && echo fail && exit 1 || echo pass37[[ "$(./minimp3)" != "error: no file names given" ]] && echo fail && exit 1 || echo pass
35[[ "$(./minimp3 do_not_exist)" != "error: read function failed, code=-3" ]] && echo fail && exit 1 || echo pass38[[ "$(./minimp3 do_not_exist)" != "error: read function failed, code=-3" ]] && echo fail && exit 1 || echo pass

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t