X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=wma_afh.c;h=ebb2f9c34c97dbb445b312dd1e8ab2004b0d5bc6;hp=0b6081cfdb9ea919537532d19dadab004a5fa825;hb=a85b3b947174c64ce06b4d6e438677055bf3f1ae;hpb=0f4910b50116416fefb09ca67a615679067ef359 diff --git a/wma_afh.c b/wma_afh.c index 0b6081cf..ebb2f9c3 100644 --- a/wma_afh.c +++ b/wma_afh.c @@ -18,28 +18,27 @@ #include "wma.h" #include "fd.h" -#define FOR_EACH_FRAME(_f, _buf, _size, _ba) for (_f = (_buf); \ - _f + (_ba) + WMA_FRAME_SKIP < (_buf) + (_size); \ - _f += (_ba) + WMA_FRAME_SKIP) +#define FOR_EACH_FRAME(_f, _buf, _size, _ps) for (_f = (_buf); \ + _f + (_ps) < (_buf) + (_size); \ + _f += (_ps)) /* * Must be called on a frame boundary, e.g. start + header_len. * \return Frame count, superframe count via *num_superframes. */ -static int count_frames(const char *buf, int buf_size, int block_align, +static int count_frames(const char *buf, int buf_size, uint32_t packet_size, int *num_superframes) { int fc = 0, sfc = 0; /* frame count, superframe count */ const uint8_t *p; - FOR_EACH_FRAME(p, (uint8_t *)buf, buf_size, block_align) { + FOR_EACH_FRAME(p, (uint8_t *)buf, buf_size, packet_size) { fc += p[WMA_FRAME_SKIP] & 0x0f; sfc++; } PARA_INFO_LOG("%d frames, %d superframes\n", fc, sfc); - if (num_superframes) - *num_superframes = sfc; + *num_superframes = sfc; return fc; } @@ -68,7 +67,7 @@ static int put_utf8(uint32_t val, char *result) *out++ = in; return 1; } - bytes = (wma_log2(in) + 4) / 5; + bytes = DIV_ROUND_UP(wma_log2(in), 5); shift = (bytes - 1) * 6; *out++ = (256 - (256 >> bytes)) | (in >> shift); while (shift >= 6) { @@ -192,7 +191,7 @@ static void set_chunk_tv(int frames_per_chunk, int frequency, } /* Must be called on a frame boundary. */ -static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align, +static int wma_make_chunk_table(char *buf, size_t buf_size, uint32_t packet_size, struct afh_info *afhi) { const uint8_t *f, *start = (uint8_t *)buf; @@ -204,7 +203,7 @@ static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align, afhi->chunk_table[0] = 0; afhi->chunk_table[1] = afhi->header_len; - num_frames = count_frames(buf, buf_size, block_align, + num_frames = count_frames(buf, buf_size, packet_size, &num_superframes); ret = -E_NO_WMA; if (num_frames == 0 || num_superframes == 0) @@ -214,7 +213,7 @@ static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align, frames_per_chunk = num_frames / num_superframes / 2; PARA_INFO_LOG("%d frames per chunk\n", frames_per_chunk); j = 1; - FOR_EACH_FRAME(f, start, buf_size, block_align) { + FOR_EACH_FRAME(f, start, buf_size, packet_size) { count += f[WMA_FRAME_SKIP] & 0x0f; while (count > j * frames_per_chunk) { j++; @@ -224,10 +223,12 @@ static int wma_make_chunk_table(char *buf, size_t buf_size, int block_align, afhi->chunk_table, ct_size * sizeof(uint32_t)); } - afhi->chunk_table[j] = f - start + afhi->header_len + block_align + WMA_FRAME_SKIP; + afhi->chunk_table[j] = f - start + afhi->header_len + + packet_size; } } afhi->chunks_total = j; + set_max_chunk_size(afhi); set_chunk_tv(frames_per_chunk, afhi->frequency, &afhi->chunk_tv); return 1; fail: @@ -262,7 +263,7 @@ static int wma_get_file_info(char *map, size_t numbytes, __a_unused int fd, ahi.use_variable_block_len? "vbl" : "" ); wma_make_chunk_table(map + ahi.header_len, numbytes - ahi.header_len, - ahi.block_align, afhi); + ahi.packet_size, afhi); read_asf_tags(map, ahi.header_len, &afhi->tags); return 0; } @@ -315,22 +316,24 @@ static const char top_level_header_object_guid[] = { static int convert_utf8_to_utf16(char *src, char **dst) { - /* - * Without specifying LE (little endian), iconv includes a byte order - * mark (e.g. 0xFFFE) at the beginning. - */ - iconv_t cd = iconv_open("UTF-16LE", "UTF-8"); + iconv_t cd; size_t sz, inbytes, outbytes, inbytesleft, outbytesleft; char *inbuf, *outbuf; int ret; if (!src || !*src) { *dst = para_calloc(2); - ret = 0; - goto out; + return 0; } - if (cd == (iconv_t) -1) + /* + * Without specifying LE (little endian), iconv includes a byte order + * mark (e.g. 0xFFFE) at the beginning. + */ + cd = iconv_open("UTF-16LE", "UTF-8"); + if (cd == (iconv_t)-1) { + *dst = NULL; return -ERRNO_TO_PARA_ERROR(errno); + } inbuf = src; /* even though src is in UTF-8, strlen() should DTRT */ inbytes = inbytesleft = strlen(src); @@ -339,6 +342,8 @@ static int convert_utf8_to_utf16(char *src, char **dst) sz = iconv(cd, ICONV_CAST &inbuf, &inbytesleft, &outbuf, &outbytesleft); if (sz == (size_t)-1) { ret = -ERRNO_TO_PARA_ERROR(errno); + free(*dst); + *dst = NULL; goto out; } assert(outbytes >= outbytesleft); @@ -350,8 +355,6 @@ static int convert_utf8_to_utf16(char *src, char **dst) *dst = outbuf; PARA_INFO_LOG("converted %s to %d UTF-16 bytes\n", src, ret); out: - if (ret < 0) - free(*dst); if (iconv_close(cd) < 0) PARA_WARNING_LOG("iconv_close: %s\n", strerror(errno)); return ret; @@ -362,8 +365,7 @@ static int make_cdo(struct taginfo *tags, const struct asf_object *cdo, struct asf_object *result) { const char *cr, *rating; /* orig data */ - uint16_t orig_title_bytes, orig_artist_bytes, orig_cr_bytes, - orig_comment_bytes, orig_rating_bytes; + uint16_t orig_cr_bytes, orig_rating_bytes; /* pointers to new UTF-16 tags */ char *artist = NULL, *title = NULL, *comment = NULL; /* number of bytes in UTF-16 for the new tags */ @@ -386,6 +388,7 @@ static int make_cdo(struct taginfo *tags, const struct asf_object *cdo, comment_bytes = ret; if (cdo) { + uint16_t orig_title_bytes, orig_artist_bytes, orig_comment_bytes; /* * Sizes of the five fields (stored as 16-bit numbers) are * located after the header (16 bytes) and the cdo size (8 @@ -399,10 +402,7 @@ static int make_cdo(struct taginfo *tags, const struct asf_object *cdo, cr = cdo->ptr + 34 + orig_title_bytes + orig_artist_bytes; rating = cr + orig_cr_bytes + orig_comment_bytes; } else { - orig_title_bytes = 2; - orig_artist_bytes = 2; orig_cr_bytes = 2; - orig_comment_bytes = 2; orig_rating_bytes = 2; cr = null; rating = null; @@ -642,7 +642,7 @@ out: return ret; } -static const char* wma_suffixes[] = {"wma", NULL}; +static const char * const wma_suffixes[] = {"wma", NULL}; /** * The init function of the wma audio format handler.