mp3dec_ex: improve error handling

This commit is contained in:
lieff
2020-02-15 02:10:49 +03:00
parent 8d34278783
commit b004823d33
3 changed files with 144 additions and 106 deletions
+4 -4
View File
@@ -201,8 +201,8 @@ typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offs
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);
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);
/* iterate through frames */
size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
/* streaming decoder with seeking capability */
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method);
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method);
@@ -212,11 +212,11 @@ size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
#ifndef MINIMP3_NO_STDIO
/* stdio versions of file load, iterate and stream */
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
size_t mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);
#ifdef _WIN32
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);
size_t mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);
#endif
#endif
+136 -98
View File
@@ -17,8 +17,10 @@
#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
#define MINIMP3_ENABLE_RING 0 /* enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */
#define MP3D_E_MEMORY -1
#define MP3D_E_IOERROR -2
#define MP3D_E_PARAM -1
#define MP3D_E_MEMORY -2
#define MP3D_E_IOERROR -3
#define MP3D_E_USER -4
typedef struct
{
@@ -69,6 +71,7 @@ typedef struct
int is_file, seek_method, vbr_tag_found;
int free_format_bytes;
int buffer_samples, buffer_consumed, to_skip, start_delay;
int last_error;
} mp3dec_ex_t;
typedef int (*MP3D_ITERATE_CB)(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info);
@@ -82,8 +85,8 @@ extern "C" {
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);
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);
/* iterate through frames */
size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
/* streaming decoder with seeking capability */
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method);
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method);
@@ -93,11 +96,11 @@ size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
#ifndef MINIMP3_NO_STDIO
/* stdio versions of file load, iterate and stream */
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
size_t mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);
#ifdef _WIN32
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);
size_t mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);
#endif
#endif
@@ -222,23 +225,36 @@ int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size
mp3dec_frame_info_t frame_info;
memset(info, 0, sizeof(*info));
memset(&frame_info, 0, sizeof(frame_info));
if (!dec || !buf || !info || (size_t)-1 == buf_size)
return MP3D_E_PARAM;
/* skip id3 */
size_t filled, consumed;
int eof;
if (io)
{
io->seek(0, io->seek_data);
if (io->seek(0, io->seek_data))
return MP3D_E_IOERROR;
filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0, eof = 0;
if (filled > MINIMP3_ID3_DETECT_SIZE)
return MP3D_E_IOERROR;
if (MINIMP3_ID3_DETECT_SIZE != filled)
return 0;
size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
if (id3v2size)
{
io->seek(id3v2size, io->seek_data);
if (io->seek(id3v2size, io->seek_data))
return MP3D_E_IOERROR;
filled = io->read(buf, buf_size, io->read_data);
if (filled > buf_size)
return MP3D_E_IOERROR;
} else
filled += io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
{
size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
return MP3D_E_IOERROR;
filled += readed;
}
if (filled < MINIMP3_BUF_SIZE)
mp3dec_skip_id3v1(buf, &filled);
} else
@@ -263,6 +279,8 @@ int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size
filled -= consumed;
consumed = 0;
size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
if (readed > (buf_size - filled))
return MP3D_E_IOERROR;
if (readed != (buf_size - filled))
eof = 1;
filled += readed;
@@ -376,7 +394,11 @@ int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size
avg_bitrate_kbps += frame_info.bitrate_kbps;
frames++;
if (progress_cb)
progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info);
{
int ret = progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info);
if (ret)
return ret;
}
}
} while (frame_info.frame_bytes);
if (detected_samples && info->samples > detected_samples)
@@ -389,10 +411,11 @@ int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size
return 0;
}
size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
{
size_t frames = 0;
const uint8_t *orig_buf = buf;
if (!buf || (size_t)-1 == buf_size)
return MP3D_E_PARAM;
/* skip id3 */
mp3dec_skip_id3(&buf, &buf_size);
if (!buf_size)
@@ -401,7 +424,7 @@ size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB c
memset(&frame_info, 0, sizeof(frame_info));
do
{
int free_format_bytes = 0, frame_size = 0;
int free_format_bytes = 0, frame_size = 0, ret;
int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
buf += i;
buf_size -= i;
@@ -416,42 +439,51 @@ size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB c
frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
frame_info.frame_bytes = frame_size;
frames++;
if (callback)
{
if (callback(user_data, hdr, frame_size, free_format_bytes, buf_size, hdr - orig_buf, &frame_info))
break;
if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, buf_size, hdr - orig_buf, &frame_info)))
return ret;
}
buf += frame_size;
buf_size -= frame_size;
} while (1);
return frames;
return 0;
}
uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
{
if (buf_size < MINIMP3_BUF_SIZE)
return 0;
if (!io || !buf || (size_t)-1 == buf_size || buf_size < MINIMP3_BUF_SIZE)
return MP3D_E_PARAM;
size_t filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0;
uint64_t readed = 0, frames = 0;
mp3dec_frame_info_t frame_info;
int eof = 0;
memset(&frame_info, 0, sizeof(frame_info));
if (filled > MINIMP3_ID3_DETECT_SIZE)
return MP3D_E_IOERROR;
if (MINIMP3_ID3_DETECT_SIZE != filled)
return 0;
size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
if (id3v2size)
{
io->seek(id3v2size, io->seek_data);
if (io->seek(id3v2size, io->seek_data))
return MP3D_E_IOERROR;
filled = io->read(buf, buf_size, io->read_data);
if (filled > buf_size)
return MP3D_E_IOERROR;
readed += id3v2size;
} else
filled += io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
{
size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
return MP3D_E_IOERROR;
filled += readed;
}
if (filled < MINIMP3_BUF_SIZE)
mp3dec_skip_id3v1(buf, &filled);
do
{
int free_format_bytes = 0, frame_size = 0;
int free_format_bytes = 0, frame_size = 0, ret;
int i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
if (i && !frame_size)
{
@@ -471,8 +503,8 @@ uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_
frames++;
if (callback)
{
if (callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed, &frame_info))
break;
if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed, &frame_info)))
return ret;
}
readed += frame_size;
consumed += i + frame_size;
@@ -482,6 +514,8 @@ uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_
filled -= consumed;
consumed = 0;
size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
if (readed > (buf_size - filled))
return MP3D_E_IOERROR;
if (readed != (buf_size - filled))
eof = 1;
filled += readed;
@@ -489,7 +523,7 @@ uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_
mp3dec_skip_id3v1(buf, &filled);
}
} while (1);
return frames;
return 0;
}
static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info)
@@ -516,7 +550,7 @@ static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_si
dec->detected_samples = dec->samples;
dec->start_offset = dec->offset = offset + frame_size;
dec->vbr_tag_found = 1;
return 1;
return MP3D_E_USER;
}
}
if (dec->index.num_frames + 1 > dec->index.capacity)
@@ -544,6 +578,8 @@ static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_si
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method)
{
if (!dec || !buf || (size_t)-1 == buf_size)
return MP3D_E_PARAM;
memset(dec, 0, sizeof(*dec));
dec->file.buffer = buf;
dec->file.size = buf_size;
@@ -551,8 +587,9 @@ int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, in
mp3dec_init(&dec->mp3d);
if (MP3D_SEEK_TO_SAMPLE == dec->seek_method)
{
if (mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec) > 0 && !dec->index.frames && !dec->vbr_tag_found)
return MP3D_E_MEMORY;
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;
}
@@ -586,9 +623,18 @@ static size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position)
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position)
{
size_t i;
if (!dec)
return MP3D_E_PARAM;
if (MP3D_SEEK_TO_BYTE == dec->seek_method)
{
dec->offset = MINIMP3_MIN(position, dec->file.size);
if (dec->io)
{
if (dec->io->seek(position, dec->io->seek_data))
return MP3D_E_IOERROR;
} else
{
dec->offset = MINIMP3_MIN(position, dec->file.size);
}
dec->cur_sample = 0;
goto do_exit;
}
@@ -607,13 +653,16 @@ seek_zero:
dec->buffer_samples = 0;
if (dec->io)
{
dec->io->seek(dec->start_offset, dec->io->seek_data);
if (mp3dec_iterate_cb(dec->io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec) > 0 && !dec->index.frames)
return MP3D_E_MEMORY;
if (dec->io->seek(dec->start_offset, dec->io->seek_data))
return MP3D_E_IOERROR;
int ret = mp3dec_iterate_cb(dec->io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
if (ret && MP3D_E_USER != ret)
return ret;
} else
{
if (mp3dec_iterate_buf(dec->file.buffer + dec->start_offset, dec->file.size - dec->start_offset, mp3dec_load_index, dec) > 0 && !dec->index.frames)
return MP3D_E_MEMORY;
int ret = mp3dec_iterate_buf(dec->file.buffer + dec->start_offset, dec->file.size - dec->start_offset, mp3dec_load_index, dec);
if (ret && MP3D_E_USER != ret)
return ret;
}
for (i = 0; i < dec->index.num_frames; i++)
dec->index.frames[i].offset += dec->start_offset;
@@ -650,7 +699,8 @@ seek_zero:
if (dec->io)
{
hdr = dec->file.buffer;
dec->io->seek(dec->index.frames[i - 1].offset, dec->io->seek_data);
if (dec->io->seek(dec->index.frames[i - 1].offset, dec->io->seek_data))
return MP3D_E_IOERROR;
size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
if (readed != HDR_SIZE)
return MP3D_E_IOERROR;
@@ -685,7 +735,10 @@ seek_zero:
}
do_exit:
if (dec->io)
dec->io->seek(dec->offset, dec->io->seek_data);
{
if (dec->io->seek(dec->offset, dec->io->seek_data))
return MP3D_E_IOERROR;
}
dec->buffer_samples = 0;
dec->buffer_consumed = 0;
dec->input_consumed = 0;
@@ -696,6 +749,8 @@ do_exit:
size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples)
{
if (!dec || !buf)
return MP3D_E_PARAM;
uint64_t end_offset = dec->end_offset ? dec->end_offset : dec->file.size;
size_t samples_requested = samples;
int eof = 0;
@@ -730,6 +785,7 @@ size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples)
dec->input_filled -= dec->input_consumed;
dec->input_consumed = 0;
size_t readed = dec->io->read((uint8_t*)dec->file.buffer + dec->input_filled, dec->file.size - dec->input_filled, dec->io->read_data);
dec->last_error = (readed > (dec->file.size - dec->input_filled)) ? MP3D_E_IOERROR : 0;
if (readed != (dec->file.size - dec->input_filled))
eof = 1;
dec->input_filled += readed;
@@ -810,6 +866,8 @@ static void mp3dec_close_file(mp3dec_map_info_t *map_info)
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
{
if (!file_name)
return MP3D_E_PARAM;
int file;
struct stat st;
memset(map_info, 0, sizeof(*map_info));
@@ -820,7 +878,7 @@ retry_open:
if (file < 0 || fstat(file, &st) < 0)
{
close(file);
return -1;
return MP3D_E_IOERROR;
}
map_info->size = st.st_size;
@@ -830,7 +888,7 @@ retry_mmap:
goto retry_mmap;
close(file);
if (MAP_FAILED == map_info->buffer)
return -1;
return MP3D_E_IOERROR;
return 0;
}
@@ -871,7 +929,7 @@ static int mp3dec_open_ring(mp3dec_map_info_t *map_info, size_t size)
#if defined(__linux__) && defined(_GNU_SOURCE)
memfd = memfd_create("mp3_ring", 0);
if (memfd < 0)
return -1;
return MP3D_E_MEMORY;
retry_ftruncate:
res = ftruncate(memfd, map_info->size);
@@ -904,11 +962,11 @@ retry_mmap3:
error:
close(memfd);
mp3dec_close_ring(map_info);
return -1;
return MP3D_E_MEMORY;
#else
memfd = shmget(IPC_PRIVATE, map_info->size, IPC_CREAT | 0700);
if (memfd < 0)
return -1;
return MP3D_E_MEMORY;
retry_mmap:
map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_PRIVATE, -1, 0);
if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
@@ -920,12 +978,12 @@ retry_mmap:
if ((map_info->buffer + map_info->size) != shmat(memfd, map_info->buffer + map_info->size, 0))
goto error;
if (shmctl(memfd, IPC_RMID, NULL) < 0)
return -1;
return MP3D_E_MEMORY;
return 0;
error:
shmctl(memfd, IPC_RMID, NULL);
mp3dec_close_ring(map_info);
return -1;
return MP3D_E_MEMORY;
#endif
}
#endif /*MINIMP3_ENABLE_RING*/
@@ -964,60 +1022,28 @@ static int mp3dec_open_file_h(HANDLE file, mp3dec_map_info_t *map_info)
error:
mp3dec_close_file(map_info);
CloseHandle(file);
return -1;
return MP3D_E_IOERROR;
}
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
{
if (!file_name)
return MP3D_E_PARAM;
HANDLE file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE == file)
return -1;
return MP3D_E_IOERROR;
return mp3dec_open_file_h(file, map_info);
}
static int mp3dec_open_file_w(const wchar_t *file_name, mp3dec_map_info_t *map_info)
{
if (!file_name)
return MP3D_E_PARAM;
HANDLE file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE == file)
return -1;
return MP3D_E_IOERROR;
return mp3dec_open_file_h(file, map_info);
}
#if 0
#define MINIMP3_HAVE_RING
static void mp3dec_close_ring(mp3dec_map_info_t *map_info)
{
if (map_info->buffer)
{
UnmapViewOfFile(map_info->buffer);
UnmapViewOfFile(map_info->buffer + map_info->size);
}
map_info->buffer = 0;
map_info->size = 0;
}
static int mp3dec_open_ring(mp3dec_map_info_t *map_info, size_t size)
{
map_info->size = size;
HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, NULL);
if (INVALID_HANDLE_VALUE == hMap)
return -1;
/* TODO: do not works with VirtualAlloc, but no guarantee enough free address space without it */
map_info->buffer = (const uint8_t *)VirtualAlloc(0, size*2, MEM_RESERVE, PAGE_READWRITE);
if (!map_info->buffer)
goto error;
if (!MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0, 0, size, (LPVOID)map_info->buffer))
goto error;
if (!MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0, 0, size, (LPVOID)(map_info->buffer + size)))
goto error;
CloseHandle(hMap);
return 0;
error:
mp3dec_close_ring(map_info);
CloseHandle(hMap);
return -1;
}
#endif /*0*/
#else
#include <stdio.h>
@@ -1031,10 +1057,13 @@ static void mp3dec_close_file(mp3dec_map_info_t *map_info)
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
{
if (!file_name)
return MP3D_E_PARAM;
memset(map_info, 0, sizeof(*map_info));
FILE *file = fopen(file_name, "rb");
if (!file)
return -1;
return MP3D_E_IOERROR;
int res = MP3D_E_IOERROR;
long size = -1;
if (fseek(file, 0, SEEK_END))
goto error;
@@ -1046,7 +1075,10 @@ static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
goto error;
map_info->buffer = (uint8_t *)malloc(map_info->size);
if (!map_info->buffer)
{
res = MP3D_E_MEMORY;
goto error;
}
if (fread((void *)map_info->buffer, 1, map_info->size, file) != map_info->size)
goto error;
fclose(file);
@@ -1054,22 +1086,22 @@ static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
error:
mp3dec_close_file(map_info);
fclose(file);
return -1;
return res;
}
#endif
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)
{
mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);
int ret = mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);
mp3dec_close_file(map_info);
return info->samples ? 0 : -1;
return ret;
}
static size_t mp3dec_iterate_mapinfo(mp3dec_map_info_t *map_info, MP3D_ITERATE_CB callback, void *user_data)
static int mp3dec_iterate_mapinfo(mp3dec_map_info_t *map_info, MP3D_ITERATE_CB callback, void *user_data)
{
size_t res = mp3dec_iterate_buf(map_info->buffer, map_info->size, callback, user_data);
int ret = mp3dec_iterate_buf(map_info->buffer, map_info->size, callback, user_data);
mp3dec_close_file(map_info);
return res;
return ret;
}
static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int seek_method)
@@ -1087,10 +1119,10 @@ int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info,
mp3dec_map_info_t map_info;
if ((ret = mp3dec_open_file(file_name, &map_info)))
return ret;
return mp3dec_load_mapinfo(dec, &map_info,info, progress_cb, user_data);
return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
}
size_t mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data)
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data)
{
int ret;
mp3dec_map_info_t map_info;
@@ -1109,10 +1141,13 @@ int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method)
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method)
{
if (!dec || !io)
return MP3D_E_PARAM;
memset(dec, 0, sizeof(*dec));
#ifdef MINIMP3_HAVE_RING
if (mp3dec_open_ring(&dec->file, MINIMP3_IO_SIZE))
return MP3D_E_MEMORY;
int ret;
if (ret = mp3dec_open_ring(&dec->file, MINIMP3_IO_SIZE))
return ret;
#else
dec->file.size = MINIMP3_IO_SIZE;
dec->file.buffer = (const uint8_t*)malloc(dec->file.size);
@@ -1124,10 +1159,13 @@ int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method)
mp3dec_init(&dec->mp3d);
if (MP3D_SEEK_TO_SAMPLE == dec->seek_method)
{
io->seek(0, io->seek_data);
if (mp3dec_iterate_cb(io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec) > 0 && !dec->index.frames && !dec->vbr_tag_found)
return MP3D_E_MEMORY;
dec->io->seek(dec->start_offset, dec->io->seek_data);
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;
}
+4 -4
View File
@@ -148,7 +148,7 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re
{
frames_iterate_data d = { &mp3d, &info, 0 };
mp3dec_init(&mp3d);
res = mp3dec_iterate(input_file_name, frames_iterate_cb, &d) > 0 ? 0 : -1;
res = mp3dec_iterate(input_file_name, frames_iterate_cb, &d);
} else if (MODE_ITERATE_BUF == mode)
{
int size = 0;
@@ -157,7 +157,7 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re
fclose(file);
frames_iterate_data d = { &mp3d, &info, 0 };
mp3dec_init(&mp3d);
res = mp3dec_iterate_buf(buf, size, frames_iterate_cb, &d) > 0 ? 0 : -1;
res = mp3dec_iterate_buf(buf, size, frames_iterate_cb, &d);
free(buf);
} else if (MODE_ITERATE_CB == mode)
{
@@ -166,7 +166,7 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re
io.read_data = io.seek_data = file;
frames_iterate_data d = { &mp3d, &info, 0 };
mp3dec_init(&mp3d);
res = mp3dec_iterate_cb(&io, io_buf, MINIMP3_IO_SIZE, frames_iterate_cb, &d) > 0 ? 0 : -1;
res = mp3dec_iterate_cb(&io, io_buf, MINIMP3_IO_SIZE, frames_iterate_cb, &d);
fclose((FILE*)io.read_data);
free(io_buf);
} else if (MODE_STREAM == mode || MODE_STREAM_BUF == mode || MODE_STREAM_CB == mode)
@@ -183,7 +183,7 @@ static void decode_file(const char *input_file_name, const unsigned char *buf_re
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) : -1;
res = mp3dec_ex_open_buf(&dec, buf, size, MP3D_SEEK_TO_SAMPLE);
} else if (MODE_STREAM_CB == mode)
{
FILE *file = fopen(input_file_name, "rb");