On Mon, Sep 16, 2013 at 11:11:24AM -0400, Justin Ruggles wrote:
> --- /dev/null
> +++ b/libavcodec/webp.c
> @@ -0,0 +1,1327 @@
> +
> +/* The structure of WebP lossless is an optional series of transformation 
> data,
> + * followed by the primary image. The primary image also optionally contains
> + * an entropy group mapping if there are multiple entropy groups. There is a
> + * basic image type called an "entropy coded image" that is used for all of
> + * these. The type of each entropy coded image is referred to by the
> + * specification as its role. */
> +enum ImageRole {
> +    /* Primary Image: Stores the actual pixels of the image. */
> +    IMAGE_ROLE_ARGB,
> +
> +    /* Entropy Image: Defines which Huffman group to use for different areas 
> of
> +     *                the primary image. */
> +    IMAGE_ROLE_ENTROPY,
> +
> +    /* Predictors: Defines which predictor type to use for different areas of
> +     *             the primary image. */
> +    IMAGE_ROLE_PREDICTOR,
> +
> +    /* Color Transform Data: Defines the color transformation for different
> +     *                       areas of the primary image. */
> +    IMAGE_ROLE_COLOR_TRANSFORM,
> +
> +    /* Color Index: Stored as an image of height == 1. */
> +    IMAGE_ROLE_COLOR_INDEXING,
> +
> +    IMAGE_ROLE_NB,
> +};
> +
> +typedef struct HuffReader {
> +    VLC vlc;                            /**< Huffman decoder context */
> +    int simple;                         /**< whether to use simple mode */
> +    int nb_symbols;                     /**< number of coded symbols */
> +    uint16_t simple_symbols[2];         /**< symbols for simple mode */
> +} HuffReader;
> +
> +typedef struct ImageContext {
> +    enum ImageRole role;                /**< role of this image */
> +    AVFrame *frame;                     /**< AVFrame for data */
> +    int color_cache_bits;               /**< color cache size, log2 */
> +    uint32_t *color_cache;              /**< color cache data */
> +    int nb_huffman_groups;              /**< number of huffman groups */
> +    HuffReader *huffman_groups;         /**< reader for each huffman group */
> +    int size_reduction;                 /**< relative size compared to 
> primary image, log2 */
> +} ImageContext;
> +
> +typedef struct WebPContext {
> +    VP8Context v;                       /**< VP8 Context used for lossy 
> decoding */
> +    GetBitContext gb;                   /**< bitstream reader for main image 
> chunk */
> +    GetByteContext alpha_gb;            /**< bitstream reader for alpha 
> channel chunk */
> +    AVCodecContext *avctx;              /**< parent AVCodecContext */
> +    int initialized;                    /**< set once the VP8 context is 
> initialized */
> +    int has_alpha;                      /**< has a separate alpha chunk */
> +    int width;                          /**< image width */
> +    int height;                         /**< image height */
> +    int lossless;                       /**< indicates lossless or lossy */
> +
> +    int nb_transforms;                  /**< number of transforms */
> +    enum TransformType transforms[4];   /**< transformations used in the 
> image, in order */
> +    int reduced_width;                  /**< reduced width for index image, 
> if applicable */
> +    int nb_huffman_groups;              /**< number of huffman groups in the 
> primary image */
> +    ImageContext image[IMAGE_ROLE_NB];  /**< image context for each role */
> +} WebPContext;

The comments for the struct members are Doxygen, but the structs are
not visible outside of the file.

> +static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb)
> +{
> +    if (r->simple) {
> +        if (r->nb_symbols == 1) {
> +            return r->simple_symbols[0];
> +        } else {
> +            return r->simple_symbols[get_bits1(gb)];
> +        }

nit: drop {}

> +        } else {
> +            int repeat = 0, length = 0;
> +            if (code_len == 16) {
> +                /* Code 16 repeats the previous non-zero value [3..6] times,
> +                 * i.e., 3 + ReadBits(2) times. If code 16 is used before a
> +                 * non-zero value has been emitted, a value of 8 is 
> repeated. */
> +                repeat = 3 + get_bits(&s->gb, 2);
> +                length = prev_code_len;
> +            } else if (code_len == 17) {
> +                /* Code 17 emits a streak of zeros [3..10], i.e.,
> +                 * 3 + ReadBits(3) times. */
> +                repeat = 3 + get_bits(&s->gb, 3);
> +            } else if (code_len == 18) {
> +                /* Code 18 emits a streak of zeros of length [11..138], i.e.,
> +                 * 11 + ReadBits(7) times. */
> +                repeat = 11 + get_bits(&s->gb, 7);
> +            }

switch/case?

> +static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
> +                                     int *got_frame, uint8_t *data_start,
> +                                     unsigned int data_size)
> +{
> +    WebPContext *s = avctx->priv_data;
> +    int w, h, ret, i;
> +
> +    s->lossless = 1;
> +    avctx->pix_fmt = AV_PIX_FMT_ARGB;
> +
> +    ret = init_get_bits(&s->gb, data_start, data_size * 8);
> +    if (ret < 0)
> +        return ret;
> +
> +    if (get_bits(&s->gb, 8) != 0x2F) {
> +        av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    w = get_bits(&s->gb, 14) + 1;
> +    h = get_bits(&s->gb, 14) + 1;
> +    if (s->width && s->width != w) {
> +        av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n",
> +               s->width, w);
> +    }
> +    s->width = w;
> +    if (s->height && s->height != h) {
> +        av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n",
> +               s->width, w);
> +    }
> +    s->height = h;
> +    ret = av_image_check_size(s->width, s->height, 0, avctx);
> +    if (ret < 0)
> +        return ret;
> +    avcodec_set_dimensions(avctx, s->width, s->height);
> +
> +    s->has_alpha = get_bits1(&s->gb);
> +
> +    if (get_bits(&s->gb, 3) != 0x0) {
> +        av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    /* parse transformations */
> +    s->nb_transforms = 0;
> +    s->reduced_width = 0;
> +    ret              = 0;

Assigning ret here is pointless.

> +    /* apply transformations */
> +    for (i = s->nb_transforms - 1; i >= 0; i--) {
> +        ret = 0;

same

> +        case MKTAG('A', 'L', 'P', 'H'): {
> +            int alpha_header, filter_m, compression;
> +            int av_unused pre_p;
> +
> +            if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
> +                av_log(avctx, AV_LOG_WARNING,
> +                       "ALPHA chunk present, but alpha bit not set in the "
> +                       "VP8X header\n");
> +            }
> +            s->alpha_gb = gb;
> +            bytestream2_skip(&gb, chunk_size);
> +            alpha_header = bytestream2_get_byte(&s->alpha_gb);
> +
> +            pre_p       = (alpha_header >> 4) & 0x03;
> +            filter_m    = (alpha_header >> 2) & 0x03;
> +            compression =  alpha_header       & 0x03;

Do you plan to use pre_p later?  Setting it seems pointless.

> +AVCodec ff_webp_decoder = {
> +    .name           = "webp",
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_WEBP,
> +    .decode         = webp_decode_frame,
> +    .close          = webp_decode_close,
> +    .capabilities   = CODEC_CAP_DR1,
> +    .priv_data_size = sizeof(WebPContext),
> +    .long_name      = NULL_IF_CONFIG_SMALL("WebP image"),

nit: Move .long_name after .name.

Diego
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to