| @@ -82,6 +82,9 @@ typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offs · 81 unmodified lines |
| 82 | 82 | extern "C" { |
| 83 | 83 | #endif |
| 84 | 84 | |
| 85 | +/* detect mp3/mpa format */ |
| 86 | +int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size); |
| 87 | +int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size); |
| 85 | 88 | /* decode whole buffer block */ |
| 86 | 89 | int 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); |
| 87 | 90 | int 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 |
| 95 | 98 | int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position); |
| 96 | 99 | size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples); |
| 97 | 100 | #ifndef MINIMP3_NO_STDIO |
| 98 | | −/* stdio versions of file load, iterate and stream */ |
| 101 | +/* stdio versions of file detect, load, iterate and stream */ |
| 102 | +int mp3dec_detect(const char *file_name); |
| 99 | 103 | int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data); |
| 100 | 104 | int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data); |
| 101 | 105 | int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method); |
| 102 | 106 | #ifdef _WIN32 |
| 107 | +int mp3dec_detect_w(const wchar_t *file_name); |
| 103 | 108 | int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data); |
| 104 | 109 | int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data); |
| 105 | 110 | int 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 | 222 | return 1; |
| 218 | 223 | } |
| 219 | 224 | |
| 225 | +int 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 | + |
| 230 | +int 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 | + |
| 220 | 266 | int 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 | 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 | 1190 | #endif |
| 1145 | 1191 | |
| 1192 | +static 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 | + |
| 1146 | 1199 | static 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 | 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 | 1219 | return ret; |
| 1167 | 1220 | } |
| 1168 | 1221 | |
| 1222 | +int 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 | + |
| 1169 | 1231 | int 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 | 1233 | int ret; |
| @@ -1241,13 +1303,22 @@ void mp3dec_ex_close(mp3dec_ex_t *dec) · 69 unmodified lines |
| 1241 | 1303 | } |
| 1242 | 1304 | |
| 1243 | 1305 | #ifdef _WIN32 |
| 1306 | +int 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 | + |
| 1244 | 1315 | int 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 | 1317 | int ret; |
| 1247 | 1318 | mp3dec_map_info_t map_info; |
| 1248 | 1319 | if ((ret = mp3dec_open_file_w(file_name, &map_info))) |
| 1249 | 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 | |
| 1253 | 1324 | int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data) |