vss: Add documentation of MAP_POPULATE.
[paraslash.git] / wma_afh.c
index 4c9d87e047af8d1d5873096db54ab4a9d17ab966..e6048a868710e1e1b62213fda895d1dfc90a2bd1 100644 (file)
--- a/wma_afh.c
+++ b/wma_afh.c
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file wma_afh.c The audio format handler for WMA files. */
 
@@ -38,8 +34,7 @@ static int count_frames(const char *buf, int buf_size, uint32_t packet_size,
                sfc++;
        }
        PARA_INFO_LOG("%d frames, %d superframes\n", fc, sfc);
-       if (num_superframes)
-               *num_superframes = sfc;
+       *num_superframes = sfc;
        return fc;
 }
 
@@ -68,7 +63,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) {
@@ -229,6 +224,7 @@ static int wma_make_chunk_table(char *buf, size_t buf_size, uint32_t 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:
@@ -316,22 +312,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);
@@ -340,6 +338,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);
@@ -351,8 +351,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;
@@ -363,8 +361,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 */
@@ -376,17 +373,21 @@ static int make_cdo(struct taginfo *tags, const struct asf_object *cdo,
        ret = convert_utf8_to_utf16(tags->artist, &artist);
        if (ret < 0)
                return ret;
+       assert(artist);
        artist_bytes = ret;
        ret = convert_utf8_to_utf16(tags->title, &title);
        if (ret < 0)
                goto out;
+       assert(title);
        title_bytes = ret;
        ret = convert_utf8_to_utf16(tags->comment, &comment);
        if (ret < 0)
                goto out;
+       assert(comment);
        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
@@ -400,10 +401,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;
@@ -459,10 +457,12 @@ static int make_ecdo(struct taginfo *tags, struct asf_object *result)
        ret = convert_utf8_to_utf16(tags->album, &album);
        if (ret < 0)
                return ret;
+       assert(album);
        album_bytes = ret;
        ret = convert_utf8_to_utf16(tags->year, &year);
        if (ret < 0)
                goto out;
+       assert(year);
        year_bytes = ret;
        result->size = 16 + 8 + 2; /* GUID, size, count */
        /* name_length + name + null + data type + val length + val */