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