LCOV - code coverage report
Current view: top level - libavcodec - webp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 625 816 76.6 %
Date: 2017-12-14 08:27:08 Functions: 38 41 92.7 %

          Line data    Source code
       1             : /*
       2             :  * WebP (.webp) image decoder
       3             :  * Copyright (c) 2013 Aneesh Dogra <aneesh@sugarlabs.org>
       4             :  * Copyright (c) 2013 Justin Ruggles <justin.ruggles@gmail.com>
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : /**
      24             :  * @file
      25             :  * WebP image decoder
      26             :  *
      27             :  * @author Aneesh Dogra <aneesh@sugarlabs.org>
      28             :  * Container and Lossy decoding
      29             :  *
      30             :  * @author Justin Ruggles <justin.ruggles@gmail.com>
      31             :  * Lossless decoder
      32             :  * Compressed alpha for lossy
      33             :  *
      34             :  * @author James Almer <jamrial@gmail.com>
      35             :  * Exif metadata
      36             :  * ICC profile
      37             :  *
      38             :  * Unimplemented:
      39             :  *   - Animation
      40             :  *   - XMP metadata
      41             :  */
      42             : 
      43             : #include "libavutil/imgutils.h"
      44             : 
      45             : #define BITSTREAM_READER_LE
      46             : #include "avcodec.h"
      47             : #include "bytestream.h"
      48             : #include "exif.h"
      49             : #include "get_bits.h"
      50             : #include "internal.h"
      51             : #include "thread.h"
      52             : #include "vp8.h"
      53             : 
      54             : #define VP8X_FLAG_ANIMATION             0x02
      55             : #define VP8X_FLAG_XMP_METADATA          0x04
      56             : #define VP8X_FLAG_EXIF_METADATA         0x08
      57             : #define VP8X_FLAG_ALPHA                 0x10
      58             : #define VP8X_FLAG_ICC                   0x20
      59             : 
      60             : #define MAX_PALETTE_SIZE                256
      61             : #define MAX_CACHE_BITS                  11
      62             : #define NUM_CODE_LENGTH_CODES           19
      63             : #define HUFFMAN_CODES_PER_META_CODE     5
      64             : #define NUM_LITERAL_CODES               256
      65             : #define NUM_LENGTH_CODES                24
      66             : #define NUM_DISTANCE_CODES              40
      67             : #define NUM_SHORT_DISTANCES             120
      68             : #define MAX_HUFFMAN_CODE_LENGTH         15
      69             : 
      70             : static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE] = {
      71             :     NUM_LITERAL_CODES + NUM_LENGTH_CODES,
      72             :     NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
      73             :     NUM_DISTANCE_CODES
      74             : };
      75             : 
      76             : static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES] = {
      77             :     17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
      78             : };
      79             : 
      80             : static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2] = {
      81             :     {  0, 1 }, {  1, 0 }, {  1, 1 }, { -1, 1 }, {  0, 2 }, {  2, 0 }, {  1, 2 }, { -1, 2 },
      82             :     {  2, 1 }, { -2, 1 }, {  2, 2 }, { -2, 2 }, {  0, 3 }, {  3, 0 }, {  1, 3 }, { -1, 3 },
      83             :     {  3, 1 }, { -3, 1 }, {  2, 3 }, { -2, 3 }, {  3, 2 }, { -3, 2 }, {  0, 4 }, {  4, 0 },
      84             :     {  1, 4 }, { -1, 4 }, {  4, 1 }, { -4, 1 }, {  3, 3 }, { -3, 3 }, {  2, 4 }, { -2, 4 },
      85             :     {  4, 2 }, { -4, 2 }, {  0, 5 }, {  3, 4 }, { -3, 4 }, {  4, 3 }, { -4, 3 }, {  5, 0 },
      86             :     {  1, 5 }, { -1, 5 }, {  5, 1 }, { -5, 1 }, {  2, 5 }, { -2, 5 }, {  5, 2 }, { -5, 2 },
      87             :     {  4, 4 }, { -4, 4 }, {  3, 5 }, { -3, 5 }, {  5, 3 }, { -5, 3 }, {  0, 6 }, {  6, 0 },
      88             :     {  1, 6 }, { -1, 6 }, {  6, 1 }, { -6, 1 }, {  2, 6 }, { -2, 6 }, {  6, 2 }, { -6, 2 },
      89             :     {  4, 5 }, { -4, 5 }, {  5, 4 }, { -5, 4 }, {  3, 6 }, { -3, 6 }, {  6, 3 }, { -6, 3 },
      90             :     {  0, 7 }, {  7, 0 }, {  1, 7 }, { -1, 7 }, {  5, 5 }, { -5, 5 }, {  7, 1 }, { -7, 1 },
      91             :     {  4, 6 }, { -4, 6 }, {  6, 4 }, { -6, 4 }, {  2, 7 }, { -2, 7 }, {  7, 2 }, { -7, 2 },
      92             :     {  3, 7 }, { -3, 7 }, {  7, 3 }, { -7, 3 }, {  5, 6 }, { -5, 6 }, {  6, 5 }, { -6, 5 },
      93             :     {  8, 0 }, {  4, 7 }, { -4, 7 }, {  7, 4 }, { -7, 4 }, {  8, 1 }, {  8, 2 }, {  6, 6 },
      94             :     { -6, 6 }, {  8, 3 }, {  5, 7 }, { -5, 7 }, {  7, 5 }, { -7, 5 }, {  8, 4 }, {  6, 7 },
      95             :     { -6, 7 }, {  7, 6 }, { -7, 6 }, {  8, 5 }, {  7, 7 }, { -7, 7 }, {  8, 6 }, {  8, 7 }
      96             : };
      97             : 
      98             : enum AlphaCompression {
      99             :     ALPHA_COMPRESSION_NONE,
     100             :     ALPHA_COMPRESSION_VP8L,
     101             : };
     102             : 
     103             : enum AlphaFilter {
     104             :     ALPHA_FILTER_NONE,
     105             :     ALPHA_FILTER_HORIZONTAL,
     106             :     ALPHA_FILTER_VERTICAL,
     107             :     ALPHA_FILTER_GRADIENT,
     108             : };
     109             : 
     110             : enum TransformType {
     111             :     PREDICTOR_TRANSFORM      = 0,
     112             :     COLOR_TRANSFORM          = 1,
     113             :     SUBTRACT_GREEN           = 2,
     114             :     COLOR_INDEXING_TRANSFORM = 3,
     115             : };
     116             : 
     117             : enum PredictionMode {
     118             :     PRED_MODE_BLACK,
     119             :     PRED_MODE_L,
     120             :     PRED_MODE_T,
     121             :     PRED_MODE_TR,
     122             :     PRED_MODE_TL,
     123             :     PRED_MODE_AVG_T_AVG_L_TR,
     124             :     PRED_MODE_AVG_L_TL,
     125             :     PRED_MODE_AVG_L_T,
     126             :     PRED_MODE_AVG_TL_T,
     127             :     PRED_MODE_AVG_T_TR,
     128             :     PRED_MODE_AVG_AVG_L_TL_AVG_T_TR,
     129             :     PRED_MODE_SELECT,
     130             :     PRED_MODE_ADD_SUBTRACT_FULL,
     131             :     PRED_MODE_ADD_SUBTRACT_HALF,
     132             : };
     133             : 
     134             : enum HuffmanIndex {
     135             :     HUFF_IDX_GREEN = 0,
     136             :     HUFF_IDX_RED   = 1,
     137             :     HUFF_IDX_BLUE  = 2,
     138             :     HUFF_IDX_ALPHA = 3,
     139             :     HUFF_IDX_DIST  = 4
     140             : };
     141             : 
     142             : /* The structure of WebP lossless is an optional series of transformation data,
     143             :  * followed by the primary image. The primary image also optionally contains
     144             :  * an entropy group mapping if there are multiple entropy groups. There is a
     145             :  * basic image type called an "entropy coded image" that is used for all of
     146             :  * these. The type of each entropy coded image is referred to by the
     147             :  * specification as its role. */
     148             : enum ImageRole {
     149             :     /* Primary Image: Stores the actual pixels of the image. */
     150             :     IMAGE_ROLE_ARGB,
     151             : 
     152             :     /* Entropy Image: Defines which Huffman group to use for different areas of
     153             :      *                the primary image. */
     154             :     IMAGE_ROLE_ENTROPY,
     155             : 
     156             :     /* Predictors: Defines which predictor type to use for different areas of
     157             :      *             the primary image. */
     158             :     IMAGE_ROLE_PREDICTOR,
     159             : 
     160             :     /* Color Transform Data: Defines the color transformation for different
     161             :      *                       areas of the primary image. */
     162             :     IMAGE_ROLE_COLOR_TRANSFORM,
     163             : 
     164             :     /* Color Index: Stored as an image of height == 1. */
     165             :     IMAGE_ROLE_COLOR_INDEXING,
     166             : 
     167             :     IMAGE_ROLE_NB,
     168             : };
     169             : 
     170             : typedef struct HuffReader {
     171             :     VLC vlc;                            /* Huffman decoder context */
     172             :     int simple;                         /* whether to use simple mode */
     173             :     int nb_symbols;                     /* number of coded symbols */
     174             :     uint16_t simple_symbols[2];         /* symbols for simple mode */
     175             : } HuffReader;
     176             : 
     177             : typedef struct ImageContext {
     178             :     enum ImageRole role;                /* role of this image */
     179             :     AVFrame *frame;                     /* AVFrame for data */
     180             :     int color_cache_bits;               /* color cache size, log2 */
     181             :     uint32_t *color_cache;              /* color cache data */
     182             :     int nb_huffman_groups;              /* number of huffman groups */
     183             :     HuffReader *huffman_groups;         /* reader for each huffman group */
     184             :     int size_reduction;                 /* relative size compared to primary image, log2 */
     185             :     int is_alpha_primary;
     186             : } ImageContext;
     187             : 
     188             : typedef struct WebPContext {
     189             :     VP8Context v;                       /* VP8 Context used for lossy decoding */
     190             :     GetBitContext gb;                   /* bitstream reader for main image chunk */
     191             :     AVFrame *alpha_frame;               /* AVFrame for alpha data decompressed from VP8L */
     192             :     AVCodecContext *avctx;              /* parent AVCodecContext */
     193             :     int initialized;                    /* set once the VP8 context is initialized */
     194             :     int has_alpha;                      /* has a separate alpha chunk */
     195             :     enum AlphaCompression alpha_compression; /* compression type for alpha chunk */
     196             :     enum AlphaFilter alpha_filter;      /* filtering method for alpha chunk */
     197             :     uint8_t *alpha_data;                /* alpha chunk data */
     198             :     int alpha_data_size;                /* alpha chunk data size */
     199             :     int has_exif;                       /* set after an EXIF chunk has been processed */
     200             :     int has_iccp;                       /* set after an ICCP chunk has been processed */
     201             :     int width;                          /* image width */
     202             :     int height;                         /* image height */
     203             :     int lossless;                       /* indicates lossless or lossy */
     204             : 
     205             :     int nb_transforms;                  /* number of transforms */
     206             :     enum TransformType transforms[4];   /* transformations used in the image, in order */
     207             :     int reduced_width;                  /* reduced width for index image, if applicable */
     208             :     int nb_huffman_groups;              /* number of huffman groups in the primary image */
     209             :     ImageContext image[IMAGE_ROLE_NB];  /* image context for each role */
     210             : } WebPContext;
     211             : 
     212             : #define GET_PIXEL(frame, x, y) \
     213             :     ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
     214             : 
     215             : #define GET_PIXEL_COMP(frame, x, y, c) \
     216             :     (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
     217             : 
     218          50 : static void image_ctx_free(ImageContext *img)
     219             : {
     220             :     int i, j;
     221             : 
     222          50 :     av_free(img->color_cache);
     223          50 :     if (img->role != IMAGE_ROLE_ARGB && !img->is_alpha_primary)
     224          18 :         av_frame_free(&img->frame);
     225          50 :     if (img->huffman_groups) {
     226          64 :         for (i = 0; i < img->nb_huffman_groups; i++) {
     227         216 :             for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++)
     228         180 :                 ff_free_vlc(&img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE + j].vlc);
     229             :         }
     230          28 :         av_free(img->huffman_groups);
     231             :     }
     232          50 :     memset(img, 0, sizeof(*img));
     233          50 : }
     234             : 
     235             : 
     236             : /* Differs from get_vlc2() in the following ways:
     237             :  *   - codes are bit-reversed
     238             :  *   - assumes 8-bit table to make reversal simpler
     239             :  *   - assumes max depth of 2 since the max code length for WebP is 15
     240             :  */
     241      205886 : static av_always_inline int webp_get_vlc(GetBitContext *gb, VLC_TYPE (*table)[2])
     242             : {
     243             :     int n, nb_bits;
     244             :     unsigned int index;
     245             :     int code;
     246             : 
     247      205886 :     OPEN_READER(re, gb);
     248      205886 :     UPDATE_CACHE(re, gb);
     249             : 
     250      205886 :     index = SHOW_UBITS(re, gb, 8);
     251      205886 :     index = ff_reverse[index];
     252      205886 :     code  = table[index][0];
     253      205886 :     n     = table[index][1];
     254             : 
     255      205886 :     if (n < 0) {
     256        8280 :         LAST_SKIP_BITS(re, gb, 8);
     257        8280 :         UPDATE_CACHE(re, gb);
     258             : 
     259        8280 :         nb_bits = -n;
     260             : 
     261        8280 :         index = SHOW_UBITS(re, gb, nb_bits);
     262        8280 :         index = (ff_reverse[index] >> (8 - nb_bits)) + code;
     263        8280 :         code  = table[index][0];
     264        8280 :         n     = table[index][1];
     265             :     }
     266      205886 :     SKIP_BITS(re, gb, n);
     267             : 
     268      205886 :     CLOSE_READER(re, gb);
     269             : 
     270      205886 :     return code;
     271             : }
     272             : 
     273      277908 : static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb)
     274             : {
     275      277908 :     if (r->simple) {
     276       72022 :         if (r->nb_symbols == 1)
     277       71710 :             return r->simple_symbols[0];
     278             :         else
     279         312 :             return r->simple_symbols[get_bits1(gb)];
     280             :     } else
     281      205886 :         return webp_get_vlc(gb, r->vlc.table);
     282             : }
     283             : 
     284         156 : static int huff_reader_build_canonical(HuffReader *r, int *code_lengths,
     285             :                                        int alphabet_size)
     286             : {
     287         156 :     int len = 0, sym, code = 0, ret;
     288         156 :     int max_code_length = 0;
     289             :     uint16_t *codes;
     290             : 
     291             :     /* special-case 1 symbol since the vlc reader cannot handle it */
     292         706 :     for (sym = 0; sym < alphabet_size; sym++) {
     293         706 :         if (code_lengths[sym] > 0) {
     294         312 :             len++;
     295         312 :             code = sym;
     296         312 :             if (len > 1)
     297         156 :                 break;
     298             :         }
     299             :     }
     300         156 :     if (len == 1) {
     301           0 :         r->nb_symbols = 1;
     302           0 :         r->simple_symbols[0] = code;
     303           0 :         r->simple = 1;
     304           0 :         return 0;
     305             :     }
     306             : 
     307       22470 :     for (sym = 0; sym < alphabet_size; sym++)
     308       22314 :         max_code_length = FFMAX(max_code_length, code_lengths[sym]);
     309             : 
     310         156 :     if (max_code_length == 0 || max_code_length > MAX_HUFFMAN_CODE_LENGTH)
     311           0 :         return AVERROR(EINVAL);
     312             : 
     313         156 :     codes = av_malloc_array(alphabet_size, sizeof(*codes));
     314         156 :     if (!codes)
     315           0 :         return AVERROR(ENOMEM);
     316             : 
     317         156 :     code = 0;
     318         156 :     r->nb_symbols = 0;
     319        1226 :     for (len = 1; len <= max_code_length; len++) {
     320      196630 :         for (sym = 0; sym < alphabet_size; sym++) {
     321      195560 :             if (code_lengths[sym] != len)
     322      188272 :                 continue;
     323        7288 :             codes[sym] = code++;
     324        7288 :             r->nb_symbols++;
     325             :         }
     326        1070 :         code <<= 1;
     327             :     }
     328         156 :     if (!r->nb_symbols) {
     329           0 :         av_free(codes);
     330           0 :         return AVERROR_INVALIDDATA;
     331             :     }
     332             : 
     333         156 :     ret = init_vlc(&r->vlc, 8, alphabet_size,
     334             :                    code_lengths, sizeof(*code_lengths), sizeof(*code_lengths),
     335             :                    codes, sizeof(*codes), sizeof(*codes), 0);
     336         156 :     if (ret < 0) {
     337           0 :         av_free(codes);
     338           0 :         return ret;
     339             :     }
     340         156 :     r->simple = 0;
     341             : 
     342         156 :     av_free(codes);
     343         156 :     return 0;
     344             : }
     345             : 
     346         102 : static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
     347             : {
     348         102 :     hc->nb_symbols = get_bits1(&s->gb) + 1;
     349             : 
     350         102 :     if (get_bits1(&s->gb))
     351          14 :         hc->simple_symbols[0] = get_bits(&s->gb, 8);
     352             :     else
     353          88 :         hc->simple_symbols[0] = get_bits1(&s->gb);
     354             : 
     355         102 :     if (hc->nb_symbols == 2)
     356          10 :         hc->simple_symbols[1] = get_bits(&s->gb, 8);
     357             : 
     358         102 :     hc->simple = 1;
     359         102 : }
     360             : 
     361          78 : static int read_huffman_code_normal(WebPContext *s, HuffReader *hc,
     362             :                                     int alphabet_size)
     363             : {
     364          78 :     HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } };
     365          78 :     int *code_lengths = NULL;
     366          78 :     int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
     367             :     int i, symbol, max_symbol, prev_code_len, ret;
     368          78 :     int num_codes = 4 + get_bits(&s->gb, 4);
     369             : 
     370          78 :     if (num_codes > NUM_CODE_LENGTH_CODES)
     371           0 :         return AVERROR_INVALIDDATA;
     372             : 
     373        1154 :     for (i = 0; i < num_codes; i++)
     374        1076 :         code_length_code_lengths[code_length_code_order[i]] = get_bits(&s->gb, 3);
     375             : 
     376          78 :     ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths,
     377             :                                       NUM_CODE_LENGTH_CODES);
     378          78 :     if (ret < 0)
     379           0 :         goto finish;
     380             : 
     381          78 :     code_lengths = av_mallocz_array(alphabet_size, sizeof(*code_lengths));
     382          78 :     if (!code_lengths) {
     383           0 :         ret = AVERROR(ENOMEM);
     384           0 :         goto finish;
     385             :     }
     386             : 
     387          78 :     if (get_bits1(&s->gb)) {
     388           8 :         int bits   = 2 + 2 * get_bits(&s->gb, 3);
     389           8 :         max_symbol = 2 + get_bits(&s->gb, bits);
     390           8 :         if (max_symbol > alphabet_size) {
     391           0 :             av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n",
     392             :                    max_symbol, alphabet_size);
     393           0 :             ret = AVERROR_INVALIDDATA;
     394           0 :             goto finish;
     395             :         }
     396             :     } else {
     397          70 :         max_symbol = alphabet_size;
     398             :     }
     399             : 
     400          78 :     prev_code_len = 8;
     401          78 :     symbol        = 0;
     402        3300 :     while (symbol < alphabet_size) {
     403             :         int code_len;
     404             : 
     405        3152 :         if (!max_symbol--)
     406           8 :             break;
     407        3144 :         code_len = huff_reader_get_symbol(&code_len_hc, &s->gb);
     408        3144 :         if (code_len < 16) {
     409             :             /* Code length code [0..15] indicates literal code lengths. */
     410        1880 :             code_lengths[symbol++] = code_len;
     411        1880 :             if (code_len)
     412        1760 :                 prev_code_len = code_len;
     413             :         } else {
     414        1264 :             int repeat = 0, length = 0;
     415        1264 :             switch (code_len) {
     416         868 :             case 16:
     417             :                 /* Code 16 repeats the previous non-zero value [3..6] times,
     418             :                  * i.e., 3 + ReadBits(2) times. If code 16 is used before a
     419             :                  * non-zero value has been emitted, a value of 8 is repeated. */
     420         868 :                 repeat = 3 + get_bits(&s->gb, 2);
     421         868 :                 length = prev_code_len;
     422         868 :                 break;
     423         140 :             case 17:
     424             :                 /* Code 17 emits a streak of zeros [3..10], i.e.,
     425             :                  * 3 + ReadBits(3) times. */
     426         140 :                 repeat = 3 + get_bits(&s->gb, 3);
     427         140 :                 break;
     428         256 :             case 18:
     429             :                 /* Code 18 emits a streak of zeros of length [11..138], i.e.,
     430             :                  * 11 + ReadBits(7) times. */
     431         256 :                 repeat = 11 + get_bits(&s->gb, 7);
     432         256 :                 break;
     433             :             }
     434        1264 :             if (symbol + repeat > alphabet_size) {
     435           0 :                 av_log(s->avctx, AV_LOG_ERROR,
     436             :                        "invalid symbol %d + repeat %d > alphabet size %d\n",
     437             :                        symbol, repeat, alphabet_size);
     438           0 :                 ret = AVERROR_INVALIDDATA;
     439           0 :                 goto finish;
     440             :             }
     441       20618 :             while (repeat-- > 0)
     442       18090 :                 code_lengths[symbol++] = length;
     443             :         }
     444             :     }
     445             : 
     446          78 :     ret = huff_reader_build_canonical(hc, code_lengths, alphabet_size);
     447             : 
     448          78 : finish:
     449          78 :     ff_free_vlc(&code_len_hc.vlc);
     450          78 :     av_free(code_lengths);
     451          78 :     return ret;
     452             : }
     453             : 
     454             : static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
     455             :                                       int w, int h);
     456             : 
     457             : #define PARSE_BLOCK_SIZE(w, h) do {                                         \
     458             :     block_bits = get_bits(&s->gb, 3) + 2;                                   \
     459             :     blocks_w   = FFALIGN((w), 1 << block_bits) >> block_bits;               \
     460             :     blocks_h   = FFALIGN((h), 1 << block_bits) >> block_bits;               \
     461             : } while (0)
     462             : 
     463           4 : static int decode_entropy_image(WebPContext *s)
     464             : {
     465             :     ImageContext *img;
     466             :     int ret, block_bits, width, blocks_w, blocks_h, x, y, max;
     467             : 
     468           4 :     width = s->width;
     469           4 :     if (s->reduced_width > 0)
     470           0 :         width = s->reduced_width;
     471             : 
     472           4 :     PARSE_BLOCK_SIZE(width, s->height);
     473             : 
     474           4 :     ret = decode_entropy_coded_image(s, IMAGE_ROLE_ENTROPY, blocks_w, blocks_h);
     475           4 :     if (ret < 0)
     476           0 :         return ret;
     477             : 
     478           4 :     img = &s->image[IMAGE_ROLE_ENTROPY];
     479           4 :     img->size_reduction = block_bits;
     480             : 
     481             :     /* the number of huffman groups is determined by the maximum group number
     482             :      * coded in the entropy image */
     483           4 :     max = 0;
     484          68 :     for (y = 0; y < img->frame->height; y++) {
     485        1088 :         for (x = 0; x < img->frame->width; x++) {
     486        1024 :             int p0 = GET_PIXEL_COMP(img->frame, x, y, 1);
     487        1024 :             int p1 = GET_PIXEL_COMP(img->frame, x, y, 2);
     488        1024 :             int p  = p0 << 8 | p1;
     489        1024 :             max = FFMAX(max, p);
     490             :         }
     491             :     }
     492           4 :     s->nb_huffman_groups = max + 1;
     493             : 
     494           4 :     return 0;
     495             : }
     496             : 
     497           4 : static int parse_transform_predictor(WebPContext *s)
     498             : {
     499             :     int block_bits, blocks_w, blocks_h, ret;
     500             : 
     501           4 :     PARSE_BLOCK_SIZE(s->width, s->height);
     502             : 
     503           4 :     ret = decode_entropy_coded_image(s, IMAGE_ROLE_PREDICTOR, blocks_w,
     504             :                                      blocks_h);
     505           4 :     if (ret < 0)
     506           0 :         return ret;
     507             : 
     508           4 :     s->image[IMAGE_ROLE_PREDICTOR].size_reduction = block_bits;
     509             : 
     510           4 :     return 0;
     511             : }
     512             : 
     513           4 : static int parse_transform_color(WebPContext *s)
     514             : {
     515             :     int block_bits, blocks_w, blocks_h, ret;
     516             : 
     517           4 :     PARSE_BLOCK_SIZE(s->width, s->height);
     518             : 
     519           4 :     ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_TRANSFORM, blocks_w,
     520             :                                      blocks_h);
     521           4 :     if (ret < 0)
     522           0 :         return ret;
     523             : 
     524           4 :     s->image[IMAGE_ROLE_COLOR_TRANSFORM].size_reduction = block_bits;
     525             : 
     526           4 :     return 0;
     527             : }
     528             : 
     529           6 : static int parse_transform_color_indexing(WebPContext *s)
     530             : {
     531             :     ImageContext *img;
     532             :     int width_bits, index_size, ret, x;
     533             :     uint8_t *ct;
     534             : 
     535           6 :     index_size = get_bits(&s->gb, 8) + 1;
     536             : 
     537           6 :     if (index_size <= 2)
     538           0 :         width_bits = 3;
     539           6 :     else if (index_size <= 4)
     540           2 :         width_bits = 2;
     541           4 :     else if (index_size <= 16)
     542           0 :         width_bits = 1;
     543             :     else
     544           4 :         width_bits = 0;
     545             : 
     546           6 :     ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_INDEXING,
     547             :                                      index_size, 1);
     548           6 :     if (ret < 0)
     549           0 :         return ret;
     550             : 
     551           6 :     img = &s->image[IMAGE_ROLE_COLOR_INDEXING];
     552           6 :     img->size_reduction = width_bits;
     553           6 :     if (width_bits > 0)
     554           2 :         s->reduced_width = (s->width + ((1 << width_bits) - 1)) >> width_bits;
     555             : 
     556             :     /* color index values are delta-coded */
     557           6 :     ct  = img->frame->data[0] + 4;
     558        1422 :     for (x = 4; x < img->frame->width * 4; x++, ct++)
     559        1416 :         ct[0] += ct[-4];
     560             : 
     561           6 :     return 0;
     562             : }
     563             : 
     564       68752 : static HuffReader *get_huffman_group(WebPContext *s, ImageContext *img,
     565             :                                      int x, int y)
     566             : {
     567       68752 :     ImageContext *gimg = &s->image[IMAGE_ROLE_ENTROPY];
     568       68752 :     int group = 0;
     569             : 
     570       68752 :     if (gimg->size_reduction > 0) {
     571       65536 :         int group_x = x >> gimg->size_reduction;
     572       65536 :         int group_y = y >> gimg->size_reduction;
     573       65536 :         int g0      = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 1);
     574       65536 :         int g1      = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
     575       65536 :         group       = g0 << 8 | g1;
     576             :     }
     577             : 
     578       68752 :     return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE];
     579             : }
     580             : 
     581           0 : static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
     582             : {
     583           0 :     uint32_t cache_idx = (0x1E35A7BD * c) >> (32 - img->color_cache_bits);
     584           0 :     img->color_cache[cache_idx] = c;
     585           0 : }
     586             : 
     587          28 : static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
     588             :                                       int w, int h)
     589             : {
     590             :     ImageContext *img;
     591             :     HuffReader *hg;
     592             :     int i, j, ret, x, y, width;
     593             : 
     594          28 :     img       = &s->image[role];
     595          28 :     img->role = role;
     596             : 
     597          28 :     if (!img->frame) {
     598          18 :         img->frame = av_frame_alloc();
     599          18 :         if (!img->frame)
     600           0 :             return AVERROR(ENOMEM);
     601             :     }
     602             : 
     603          28 :     img->frame->format = AV_PIX_FMT_ARGB;
     604          28 :     img->frame->width  = w;
     605          28 :     img->frame->height = h;
     606             : 
     607          36 :     if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) {
     608           8 :         ThreadFrame pt = { .f = img->frame };
     609           8 :         ret = ff_thread_get_buffer(s->avctx, &pt, 0);
     610             :     } else
     611          20 :         ret = av_frame_get_buffer(img->frame, 1);
     612          28 :     if (ret < 0)
     613           0 :         return ret;
     614             : 
     615          28 :     if (get_bits1(&s->gb)) {
     616           0 :         img->color_cache_bits = get_bits(&s->gb, 4);
     617           0 :         if (img->color_cache_bits < 1 || img->color_cache_bits > 11) {
     618           0 :             av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n",
     619             :                    img->color_cache_bits);
     620           0 :             return AVERROR_INVALIDDATA;
     621             :         }
     622           0 :         img->color_cache = av_mallocz_array(1 << img->color_cache_bits,
     623             :                                             sizeof(*img->color_cache));
     624           0 :         if (!img->color_cache)
     625           0 :             return AVERROR(ENOMEM);
     626             :     } else {
     627          28 :         img->color_cache_bits = 0;
     628             :     }
     629             : 
     630          28 :     img->nb_huffman_groups = 1;
     631          28 :     if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) {
     632           4 :         ret = decode_entropy_image(s);
     633           4 :         if (ret < 0)
     634           0 :             return ret;
     635           4 :         img->nb_huffman_groups = s->nb_huffman_groups;
     636             :     }
     637          28 :     img->huffman_groups = av_mallocz_array(img->nb_huffman_groups *
     638             :                                            HUFFMAN_CODES_PER_META_CODE,
     639             :                                            sizeof(*img->huffman_groups));
     640          28 :     if (!img->huffman_groups)
     641           0 :         return AVERROR(ENOMEM);
     642             : 
     643          64 :     for (i = 0; i < img->nb_huffman_groups; i++) {
     644          36 :         hg = &img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE];
     645         216 :         for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) {
     646         180 :             int alphabet_size = alphabet_sizes[j];
     647         180 :             if (!j && img->color_cache_bits > 0)
     648           0 :                 alphabet_size += 1 << img->color_cache_bits;
     649             : 
     650         180 :             if (get_bits1(&s->gb)) {
     651         102 :                 read_huffman_code_simple(s, &hg[j]);
     652             :             } else {
     653          78 :                 ret = read_huffman_code_normal(s, &hg[j], alphabet_size);
     654          78 :                 if (ret < 0)
     655           0 :                     return ret;
     656             :             }
     657             :         }
     658             :     }
     659             : 
     660          28 :     width = img->frame->width;
     661          28 :     if (role == IMAGE_ROLE_ARGB && s->reduced_width > 0)
     662           2 :         width = s->reduced_width;
     663             : 
     664          28 :     x = 0; y = 0;
     665       68808 :     while (y < img->frame->height) {
     666             :         int v;
     667             : 
     668       68752 :         hg = get_huffman_group(s, img, x, y);
     669       68752 :         v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb);
     670       68752 :         if (v < NUM_LITERAL_CODES) {
     671             :             /* literal pixel values */
     672       68630 :             uint8_t *p = GET_PIXEL(img->frame, x, y);
     673       68630 :             p[2] = v;
     674       68630 :             p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED],   &s->gb);
     675       68630 :             p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE],  &s->gb);
     676       68630 :             p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb);
     677       68630 :             if (img->color_cache_bits)
     678           0 :                 color_cache_put(img, AV_RB32(p));
     679       68630 :             x++;
     680       68630 :             if (x == width) {
     681         700 :                 x = 0;
     682         700 :                 y++;
     683             :             }
     684         122 :         } else if (v < NUM_LITERAL_CODES + NUM_LENGTH_CODES) {
     685             :             /* LZ77 backwards mapping */
     686             :             int prefix_code, length, distance, ref_x, ref_y;
     687             : 
     688             :             /* parse length and distance */
     689         122 :             prefix_code = v - NUM_LITERAL_CODES;
     690         122 :             if (prefix_code < 4) {
     691          48 :                 length = prefix_code + 1;
     692             :             } else {
     693          74 :                 int extra_bits = (prefix_code - 2) >> 1;
     694          74 :                 int offset     = 2 + (prefix_code & 1) << extra_bits;
     695          74 :                 length = offset + get_bits(&s->gb, extra_bits) + 1;
     696             :             }
     697         122 :             prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb);
     698         122 :             if (prefix_code > 39U) {
     699           0 :                 av_log(s->avctx, AV_LOG_ERROR,
     700             :                        "distance prefix code too large: %d\n", prefix_code);
     701           0 :                 return AVERROR_INVALIDDATA;
     702             :             }
     703         122 :             if (prefix_code < 4) {
     704         122 :                 distance = prefix_code + 1;
     705             :             } else {
     706           0 :                 int extra_bits = prefix_code - 2 >> 1;
     707           0 :                 int offset     = 2 + (prefix_code & 1) << extra_bits;
     708           0 :                 distance = offset + get_bits(&s->gb, extra_bits) + 1;
     709             :             }
     710             : 
     711             :             /* find reference location */
     712         122 :             if (distance <= NUM_SHORT_DISTANCES) {
     713         122 :                 int xi = lz77_distance_offsets[distance - 1][0];
     714         122 :                 int yi = lz77_distance_offsets[distance - 1][1];
     715         122 :                 distance = FFMAX(1, xi + yi * width);
     716             :             } else {
     717           0 :                 distance -= NUM_SHORT_DISTANCES;
     718             :             }
     719         122 :             ref_x = x;
     720         122 :             ref_y = y;
     721         122 :             if (distance <= x) {
     722          36 :                 ref_x -= distance;
     723          36 :                 distance = 0;
     724             :             } else {
     725          86 :                 ref_x = 0;
     726          86 :                 distance -= x;
     727             :             }
     728         266 :             while (distance >= width) {
     729          22 :                 ref_y--;
     730          22 :                 distance -= width;
     731             :             }
     732         122 :             if (distance > 0) {
     733          64 :                 ref_x = width - distance;
     734          64 :                 ref_y--;
     735             :             }
     736         122 :             ref_x = FFMAX(0, ref_x);
     737         122 :             ref_y = FFMAX(0, ref_y);
     738             : 
     739             :             /* copy pixels
     740             :              * source and dest regions can overlap and wrap lines, so just
     741             :              * copy per-pixel */
     742         886 :             for (i = 0; i < length; i++) {
     743         770 :                 uint8_t *p_ref = GET_PIXEL(img->frame, ref_x, ref_y);
     744         770 :                 uint8_t *p     = GET_PIXEL(img->frame,     x,     y);
     745             : 
     746         770 :                 AV_COPY32(p, p_ref);
     747         770 :                 if (img->color_cache_bits)
     748           0 :                     color_cache_put(img, AV_RB32(p));
     749         770 :                 x++;
     750         770 :                 ref_x++;
     751         770 :                 if (x == width) {
     752          58 :                     x = 0;
     753          58 :                     y++;
     754             :                 }
     755         770 :                 if (ref_x == width) {
     756          58 :                     ref_x = 0;
     757          58 :                     ref_y++;
     758             :                 }
     759         770 :                 if (y == img->frame->height || ref_y == img->frame->height)
     760             :                     break;
     761             :             }
     762             :         } else {
     763             :             /* read from color cache */
     764           0 :             uint8_t *p = GET_PIXEL(img->frame, x, y);
     765           0 :             int cache_idx = v - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
     766             : 
     767           0 :             if (!img->color_cache_bits) {
     768           0 :                 av_log(s->avctx, AV_LOG_ERROR, "color cache not found\n");
     769           0 :                 return AVERROR_INVALIDDATA;
     770             :             }
     771           0 :             if (cache_idx >= 1 << img->color_cache_bits) {
     772           0 :                 av_log(s->avctx, AV_LOG_ERROR,
     773             :                        "color cache index out-of-bounds\n");
     774           0 :                 return AVERROR_INVALIDDATA;
     775             :             }
     776           0 :             AV_WB32(p, img->color_cache[cache_idx]);
     777           0 :             x++;
     778           0 :             if (x == width) {
     779           0 :                 x = 0;
     780           0 :                 y++;
     781             :             }
     782             :         }
     783             :     }
     784             : 
     785          28 :     return 0;
     786             : }
     787             : 
     788             : /* PRED_MODE_BLACK */
     789           4 : static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     790             :                           const uint8_t *p_t, const uint8_t *p_tr)
     791             : {
     792           4 :     AV_WB32(p, 0xFF000000);
     793           4 : }
     794             : 
     795             : /* PRED_MODE_L */
     796        5276 : static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     797             :                           const uint8_t *p_t, const uint8_t *p_tr)
     798             : {
     799        5276 :     AV_COPY32(p, p_l);
     800        5276 : }
     801             : 
     802             : /* PRED_MODE_T */
     803       20764 : static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     804             :                           const uint8_t *p_t, const uint8_t *p_tr)
     805             : {
     806       20764 :     AV_COPY32(p, p_t);
     807       20764 : }
     808             : 
     809             : /* PRED_MODE_TR */
     810        6336 : static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     811             :                           const uint8_t *p_t, const uint8_t *p_tr)
     812             : {
     813        6336 :     AV_COPY32(p, p_tr);
     814        6336 : }
     815             : 
     816             : /* PRED_MODE_TL */
     817        1248 : static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     818             :                           const uint8_t *p_t, const uint8_t *p_tr)
     819             : {
     820        1248 :     AV_COPY32(p, p_tl);
     821        1248 : }
     822             : 
     823             : /* PRED_MODE_AVG_T_AVG_L_TR */
     824        4832 : static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     825             :                           const uint8_t *p_t, const uint8_t *p_tr)
     826             : {
     827        4832 :     p[0] = p_t[0] + (p_l[0] + p_tr[0] >> 1) >> 1;
     828        4832 :     p[1] = p_t[1] + (p_l[1] + p_tr[1] >> 1) >> 1;
     829        4832 :     p[2] = p_t[2] + (p_l[2] + p_tr[2] >> 1) >> 1;
     830        4832 :     p[3] = p_t[3] + (p_l[3] + p_tr[3] >> 1) >> 1;
     831        4832 : }
     832             : 
     833             : /* PRED_MODE_AVG_L_TL */
     834         768 : static void inv_predict_6(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     835             :                           const uint8_t *p_t, const uint8_t *p_tr)
     836             : {
     837         768 :     p[0] = p_l[0] + p_tl[0] >> 1;
     838         768 :     p[1] = p_l[1] + p_tl[1] >> 1;
     839         768 :     p[2] = p_l[2] + p_tl[2] >> 1;
     840         768 :     p[3] = p_l[3] + p_tl[3] >> 1;
     841         768 : }
     842             : 
     843             : /* PRED_MODE_AVG_L_T */
     844        3072 : static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     845             :                           const uint8_t *p_t, const uint8_t *p_tr)
     846             : {
     847        3072 :     p[0] = p_l[0] + p_t[0] >> 1;
     848        3072 :     p[1] = p_l[1] + p_t[1] >> 1;
     849        3072 :     p[2] = p_l[2] + p_t[2] >> 1;
     850        3072 :     p[3] = p_l[3] + p_t[3] >> 1;
     851        3072 : }
     852             : 
     853             : /* PRED_MODE_AVG_TL_T */
     854        4512 : static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     855             :                           const uint8_t *p_t, const uint8_t *p_tr)
     856             : {
     857        4512 :     p[0] = p_tl[0] + p_t[0] >> 1;
     858        4512 :     p[1] = p_tl[1] + p_t[1] >> 1;
     859        4512 :     p[2] = p_tl[2] + p_t[2] >> 1;
     860        4512 :     p[3] = p_tl[3] + p_t[3] >> 1;
     861        4512 : }
     862             : 
     863             : /* PRED_MODE_AVG_T_TR */
     864       11488 : static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     865             :                           const uint8_t *p_t, const uint8_t *p_tr)
     866             : {
     867       11488 :     p[0] = p_t[0] + p_tr[0] >> 1;
     868       11488 :     p[1] = p_t[1] + p_tr[1] >> 1;
     869       11488 :     p[2] = p_t[2] + p_tr[2] >> 1;
     870       11488 :     p[3] = p_t[3] + p_tr[3] >> 1;
     871       11488 : }
     872             : 
     873             : /* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
     874        3236 : static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     875             :                            const uint8_t *p_t, const uint8_t *p_tr)
     876             : {
     877        3236 :     p[0] = (p_l[0] + p_tl[0] >> 1) + (p_t[0] + p_tr[0] >> 1) >> 1;
     878        3236 :     p[1] = (p_l[1] + p_tl[1] >> 1) + (p_t[1] + p_tr[1] >> 1) >> 1;
     879        3236 :     p[2] = (p_l[2] + p_tl[2] >> 1) + (p_t[2] + p_tr[2] >> 1) >> 1;
     880        3236 :     p[3] = (p_l[3] + p_tl[3] >> 1) + (p_t[3] + p_tr[3] >> 1) >> 1;
     881        3236 : }
     882             : 
     883             : /* PRED_MODE_SELECT */
     884        3488 : static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     885             :                            const uint8_t *p_t, const uint8_t *p_tr)
     886             : {
     887       10464 :     int diff = (FFABS(p_l[0] - p_tl[0]) - FFABS(p_t[0] - p_tl[0])) +
     888        6976 :                (FFABS(p_l[1] - p_tl[1]) - FFABS(p_t[1] - p_tl[1])) +
     889        3488 :                (FFABS(p_l[2] - p_tl[2]) - FFABS(p_t[2] - p_tl[2])) +
     890        3488 :                (FFABS(p_l[3] - p_tl[3]) - FFABS(p_t[3] - p_tl[3]));
     891        3488 :     if (diff <= 0)
     892        2296 :         AV_COPY32(p, p_t);
     893             :     else
     894        1192 :         AV_COPY32(p, p_l);
     895        3488 : }
     896             : 
     897             : /* PRED_MODE_ADD_SUBTRACT_FULL */
     898           0 : static void inv_predict_12(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     899             :                            const uint8_t *p_t, const uint8_t *p_tr)
     900             : {
     901           0 :     p[0] = av_clip_uint8(p_l[0] + p_t[0] - p_tl[0]);
     902           0 :     p[1] = av_clip_uint8(p_l[1] + p_t[1] - p_tl[1]);
     903           0 :     p[2] = av_clip_uint8(p_l[2] + p_t[2] - p_tl[2]);
     904           0 :     p[3] = av_clip_uint8(p_l[3] + p_t[3] - p_tl[3]);
     905           0 : }
     906             : 
     907        2048 : static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
     908             : {
     909        2048 :     int d = a + b >> 1;
     910        2048 :     return av_clip_uint8(d + (d - c) / 2);
     911             : }
     912             : 
     913             : /* PRED_MODE_ADD_SUBTRACT_HALF */
     914         512 : static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
     915             :                            const uint8_t *p_t, const uint8_t *p_tr)
     916             : {
     917         512 :     p[0] = clamp_add_subtract_half(p_l[0], p_t[0], p_tl[0]);
     918         512 :     p[1] = clamp_add_subtract_half(p_l[1], p_t[1], p_tl[1]);
     919         512 :     p[2] = clamp_add_subtract_half(p_l[2], p_t[2], p_tl[2]);
     920         512 :     p[3] = clamp_add_subtract_half(p_l[3], p_t[3], p_tl[3]);
     921         512 : }
     922             : 
     923             : typedef void (*inv_predict_func)(uint8_t *p, const uint8_t *p_l,
     924             :                                  const uint8_t *p_tl, const uint8_t *p_t,
     925             :                                  const uint8_t *p_tr);
     926             : 
     927             : static const inv_predict_func inverse_predict[14] = {
     928             :     inv_predict_0,  inv_predict_1,  inv_predict_2,  inv_predict_3,
     929             :     inv_predict_4,  inv_predict_5,  inv_predict_6,  inv_predict_7,
     930             :     inv_predict_8,  inv_predict_9,  inv_predict_10, inv_predict_11,
     931             :     inv_predict_12, inv_predict_13,
     932             : };
     933             : 
     934       65536 : static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
     935             : {
     936             :     uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr;
     937             :     uint8_t p[4];
     938             : 
     939       65536 :     dec  = GET_PIXEL(frame, x,     y);
     940       65536 :     p_l  = GET_PIXEL(frame, x - 1, y);
     941       65536 :     p_tl = GET_PIXEL(frame, x - 1, y - 1);
     942       65536 :     p_t  = GET_PIXEL(frame, x,     y - 1);
     943       65536 :     if (x == frame->width - 1)
     944         512 :         p_tr = GET_PIXEL(frame, 0, y);
     945             :     else
     946       65024 :         p_tr = GET_PIXEL(frame, x + 1, y - 1);
     947             : 
     948       65536 :     inverse_predict[m](p, p_l, p_tl, p_t, p_tr);
     949             : 
     950       65536 :     dec[0] += p[0];
     951       65536 :     dec[1] += p[1];
     952       65536 :     dec[2] += p[2];
     953       65536 :     dec[3] += p[3];
     954       65536 : }
     955             : 
     956           4 : static int apply_predictor_transform(WebPContext *s)
     957             : {
     958           4 :     ImageContext *img  = &s->image[IMAGE_ROLE_ARGB];
     959           4 :     ImageContext *pimg = &s->image[IMAGE_ROLE_PREDICTOR];
     960             :     int x, y;
     961             : 
     962         516 :     for (y = 0; y < img->frame->height; y++) {
     963       66048 :         for (x = 0; x < img->frame->width; x++) {
     964       65536 :             int tx = x >> pimg->size_reduction;
     965       65536 :             int ty = y >> pimg->size_reduction;
     966       65536 :             enum PredictionMode m = GET_PIXEL_COMP(pimg->frame, tx, ty, 2);
     967             : 
     968       65536 :             if (x == 0) {
     969         512 :                 if (y == 0)
     970           4 :                     m = PRED_MODE_BLACK;
     971             :                 else
     972         508 :                     m = PRED_MODE_T;
     973       65024 :             } else if (y == 0)
     974         508 :                 m = PRED_MODE_L;
     975             : 
     976       65536 :             if (m > 13) {
     977           0 :                 av_log(s->avctx, AV_LOG_ERROR,
     978             :                        "invalid predictor mode: %d\n", m);
     979           0 :                 return AVERROR_INVALIDDATA;
     980             :             }
     981       65536 :             inverse_prediction(img->frame, m, x, y);
     982             :         }
     983             :     }
     984           4 :     return 0;
     985             : }
     986             : 
     987      196608 : static av_always_inline uint8_t color_transform_delta(uint8_t color_pred,
     988             :                                                       uint8_t color)
     989             : {
     990      196608 :     return (int)ff_u8_to_s8(color_pred) * ff_u8_to_s8(color) >> 5;
     991             : }
     992             : 
     993           4 : static int apply_color_transform(WebPContext *s)
     994             : {
     995             :     ImageContext *img, *cimg;
     996             :     int x, y, cx, cy;
     997             :     uint8_t *p, *cp;
     998             : 
     999           4 :     img  = &s->image[IMAGE_ROLE_ARGB];
    1000           4 :     cimg = &s->image[IMAGE_ROLE_COLOR_TRANSFORM];
    1001             : 
    1002         516 :     for (y = 0; y < img->frame->height; y++) {
    1003       66048 :         for (x = 0; x < img->frame->width; x++) {
    1004       65536 :             cx = x >> cimg->size_reduction;
    1005       65536 :             cy = y >> cimg->size_reduction;
    1006       65536 :             cp = GET_PIXEL(cimg->frame, cx, cy);
    1007       65536 :             p  = GET_PIXEL(img->frame,   x,  y);
    1008             : 
    1009       65536 :             p[1] += color_transform_delta(cp[3], p[2]);
    1010      131072 :             p[3] += color_transform_delta(cp[2], p[2]) +
    1011       65536 :                     color_transform_delta(cp[1], p[1]);
    1012             :         }
    1013             :     }
    1014           4 :     return 0;
    1015             : }
    1016             : 
    1017           4 : static int apply_subtract_green_transform(WebPContext *s)
    1018             : {
    1019             :     int x, y;
    1020           4 :     ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
    1021             : 
    1022         516 :     for (y = 0; y < img->frame->height; y++) {
    1023       66048 :         for (x = 0; x < img->frame->width; x++) {
    1024       65536 :             uint8_t *p = GET_PIXEL(img->frame, x, y);
    1025       65536 :             p[1] += p[2];
    1026       65536 :             p[3] += p[2];
    1027             :         }
    1028             :     }
    1029           4 :     return 0;
    1030             : }
    1031             : 
    1032           6 : static int apply_color_indexing_transform(WebPContext *s)
    1033             : {
    1034             :     ImageContext *img;
    1035             :     ImageContext *pal;
    1036             :     int i, x, y;
    1037             :     uint8_t *p;
    1038             : 
    1039           6 :     img = &s->image[IMAGE_ROLE_ARGB];
    1040           6 :     pal = &s->image[IMAGE_ROLE_COLOR_INDEXING];
    1041             : 
    1042           6 :     if (pal->size_reduction > 0) {
    1043             :         GetBitContext gb_g;
    1044             :         uint8_t *line;
    1045           2 :         int pixel_bits = 8 >> pal->size_reduction;
    1046             : 
    1047           2 :         line = av_malloc(img->frame->linesize[0] + AV_INPUT_BUFFER_PADDING_SIZE);
    1048           2 :         if (!line)
    1049           0 :             return AVERROR(ENOMEM);
    1050             : 
    1051          18 :         for (y = 0; y < img->frame->height; y++) {
    1052          16 :             p = GET_PIXEL(img->frame, 0, y);
    1053          16 :             memcpy(line, p, img->frame->linesize[0]);
    1054          16 :             init_get_bits(&gb_g, line, img->frame->linesize[0] * 8);
    1055          16 :             skip_bits(&gb_g, 16);
    1056          16 :             i = 0;
    1057         208 :             for (x = 0; x < img->frame->width; x++) {
    1058         192 :                 p    = GET_PIXEL(img->frame, x, y);
    1059         192 :                 p[2] = get_bits(&gb_g, pixel_bits);
    1060         192 :                 i++;
    1061         192 :                 if (i == 1 << pal->size_reduction) {
    1062          48 :                     skip_bits(&gb_g, 24);
    1063          48 :                     i = 0;
    1064             :                 }
    1065             :             }
    1066             :         }
    1067           2 :         av_free(line);
    1068             :     }
    1069             : 
    1070             :     // switch to local palette if it's worth initializing it
    1071           6 :     if (img->frame->height * img->frame->width > 300) {
    1072             :         uint8_t palette[256 * 4];
    1073           0 :         const int size = pal->frame->width * 4;
    1074           0 :         av_assert0(size <= 1024U);
    1075           0 :         memcpy(palette, GET_PIXEL(pal->frame, 0, 0), size);   // copy palette
    1076             :         // set extra entries to transparent black
    1077           0 :         memset(palette + size, 0, 256 * 4 - size);
    1078           0 :         for (y = 0; y < img->frame->height; y++) {
    1079           0 :             for (x = 0; x < img->frame->width; x++) {
    1080           0 :                 p = GET_PIXEL(img->frame, x, y);
    1081           0 :                 i = p[2];
    1082           0 :                 AV_COPY32(p, &palette[i * 4]);
    1083             :             }
    1084             :         }
    1085             :     } else {
    1086          54 :         for (y = 0; y < img->frame->height; y++) {
    1087         624 :             for (x = 0; x < img->frame->width; x++) {
    1088         576 :                 p = GET_PIXEL(img->frame, x, y);
    1089         576 :                 i = p[2];
    1090         576 :                 if (i >= pal->frame->width) {
    1091           0 :                     AV_WB32(p, 0x00000000);
    1092             :                 } else {
    1093         576 :                     const uint8_t *pi = GET_PIXEL(pal->frame, i, 0);
    1094         576 :                     AV_COPY32(p, pi);
    1095             :                 }
    1096             :             }
    1097             :         }
    1098             :     }
    1099             : 
    1100           6 :     return 0;
    1101             : }
    1102             : 
    1103          14 : static void update_canvas_size(AVCodecContext *avctx, int w, int h)
    1104             : {
    1105          14 :     WebPContext *s = avctx->priv_data;
    1106          14 :     if (s->width && s->width != w) {
    1107           0 :         av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n",
    1108             :                s->width, w);
    1109             :     }
    1110          14 :     s->width = w;
    1111          14 :     if (s->height && s->height != h) {
    1112           0 :         av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n",
    1113             :                s->height, h);
    1114             :     }
    1115          14 :     s->height = h;
    1116          14 : }
    1117             : 
    1118          10 : static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
    1119             :                                      int *got_frame, uint8_t *data_start,
    1120             :                                      unsigned int data_size, int is_alpha_chunk)
    1121             : {
    1122          10 :     WebPContext *s = avctx->priv_data;
    1123             :     int w, h, ret, i, used;
    1124             : 
    1125          10 :     if (!is_alpha_chunk) {
    1126           8 :         s->lossless = 1;
    1127           8 :         avctx->pix_fmt = AV_PIX_FMT_ARGB;
    1128             :     }
    1129             : 
    1130          10 :     ret = init_get_bits8(&s->gb, data_start, data_size);
    1131          10 :     if (ret < 0)
    1132           0 :         return ret;
    1133             : 
    1134          10 :     if (!is_alpha_chunk) {
    1135           8 :         if (get_bits(&s->gb, 8) != 0x2F) {
    1136           0 :             av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n");
    1137           0 :             return AVERROR_INVALIDDATA;
    1138             :         }
    1139             : 
    1140           8 :         w = get_bits(&s->gb, 14) + 1;
    1141           8 :         h = get_bits(&s->gb, 14) + 1;
    1142             : 
    1143           8 :         update_canvas_size(avctx, w, h);
    1144             : 
    1145           8 :         ret = ff_set_dimensions(avctx, s->width, s->height);
    1146           8 :         if (ret < 0)
    1147           0 :             return ret;
    1148             : 
    1149           8 :         s->has_alpha = get_bits1(&s->gb);
    1150             : 
    1151           8 :         if (get_bits(&s->gb, 3) != 0x0) {
    1152           0 :             av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n");
    1153           0 :             return AVERROR_INVALIDDATA;
    1154             :         }
    1155             :     } else {
    1156           2 :         if (!s->width || !s->height)
    1157           0 :             return AVERROR_BUG;
    1158           2 :         w = s->width;
    1159           2 :         h = s->height;
    1160             :     }
    1161             : 
    1162             :     /* parse transformations */
    1163          10 :     s->nb_transforms = 0;
    1164          10 :     s->reduced_width = 0;
    1165          10 :     used = 0;
    1166          38 :     while (get_bits1(&s->gb)) {
    1167          18 :         enum TransformType transform = get_bits(&s->gb, 2);
    1168          18 :         if (used & (1 << transform)) {
    1169           0 :             av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n",
    1170             :                    transform);
    1171           0 :             ret = AVERROR_INVALIDDATA;
    1172           0 :             goto free_and_return;
    1173             :         }
    1174          18 :         used |= (1 << transform);
    1175          18 :         s->transforms[s->nb_transforms++] = transform;
    1176          18 :         switch (transform) {
    1177           4 :         case PREDICTOR_TRANSFORM:
    1178           4 :             ret = parse_transform_predictor(s);
    1179           4 :             break;
    1180           4 :         case COLOR_TRANSFORM:
    1181           4 :             ret = parse_transform_color(s);
    1182           4 :             break;
    1183           6 :         case COLOR_INDEXING_TRANSFORM:
    1184           6 :             ret = parse_transform_color_indexing(s);
    1185           6 :             break;
    1186             :         }
    1187          18 :         if (ret < 0)
    1188           0 :             goto free_and_return;
    1189             :     }
    1190             : 
    1191             :     /* decode primary image */
    1192          10 :     s->image[IMAGE_ROLE_ARGB].frame = p;
    1193          10 :     if (is_alpha_chunk)
    1194           2 :         s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
    1195          10 :     ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h);
    1196          10 :     if (ret < 0)
    1197           0 :         goto free_and_return;
    1198             : 
    1199             :     /* apply transformations */
    1200          28 :     for (i = s->nb_transforms - 1; i >= 0; i--) {
    1201          18 :         switch (s->transforms[i]) {
    1202           4 :         case PREDICTOR_TRANSFORM:
    1203           4 :             ret = apply_predictor_transform(s);
    1204           4 :             break;
    1205           4 :         case COLOR_TRANSFORM:
    1206           4 :             ret = apply_color_transform(s);
    1207           4 :             break;
    1208           4 :         case SUBTRACT_GREEN:
    1209           4 :             ret = apply_subtract_green_transform(s);
    1210           4 :             break;
    1211           6 :         case COLOR_INDEXING_TRANSFORM:
    1212           6 :             ret = apply_color_indexing_transform(s);
    1213           6 :             break;
    1214             :         }
    1215          18 :         if (ret < 0)
    1216           0 :             goto free_and_return;
    1217             :     }
    1218             : 
    1219          10 :     *got_frame   = 1;
    1220          10 :     p->pict_type = AV_PICTURE_TYPE_I;
    1221          10 :     p->key_frame = 1;
    1222          10 :     ret          = data_size;
    1223             : 
    1224          10 : free_and_return:
    1225          60 :     for (i = 0; i < IMAGE_ROLE_NB; i++)
    1226          50 :         image_ctx_free(&s->image[i]);
    1227             : 
    1228          10 :     return ret;
    1229             : }
    1230             : 
    1231           0 : static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
    1232             : {
    1233             :     int x, y, ls;
    1234             :     uint8_t *dec;
    1235             : 
    1236           0 :     ls = frame->linesize[3];
    1237             : 
    1238             :     /* filter first row using horizontal filter */
    1239           0 :     dec = frame->data[3] + 1;
    1240           0 :     for (x = 1; x < frame->width; x++, dec++)
    1241           0 :         *dec += *(dec - 1);
    1242             : 
    1243             :     /* filter first column using vertical filter */
    1244           0 :     dec = frame->data[3] + ls;
    1245           0 :     for (y = 1; y < frame->height; y++, dec += ls)
    1246           0 :         *dec += *(dec - ls);
    1247             : 
    1248             :     /* filter the rest using the specified filter */
    1249           0 :     switch (m) {
    1250           0 :     case ALPHA_FILTER_HORIZONTAL:
    1251           0 :         for (y = 1; y < frame->height; y++) {
    1252           0 :             dec = frame->data[3] + y * ls + 1;
    1253           0 :             for (x = 1; x < frame->width; x++, dec++)
    1254           0 :                 *dec += *(dec - 1);
    1255             :         }
    1256           0 :         break;
    1257           0 :     case ALPHA_FILTER_VERTICAL:
    1258           0 :         for (y = 1; y < frame->height; y++) {
    1259           0 :             dec = frame->data[3] + y * ls + 1;
    1260           0 :             for (x = 1; x < frame->width; x++, dec++)
    1261           0 :                 *dec += *(dec - ls);
    1262             :         }
    1263           0 :         break;
    1264           0 :     case ALPHA_FILTER_GRADIENT:
    1265           0 :         for (y = 1; y < frame->height; y++) {
    1266           0 :             dec = frame->data[3] + y * ls + 1;
    1267           0 :             for (x = 1; x < frame->width; x++, dec++)
    1268           0 :                 dec[0] += av_clip_uint8(*(dec - 1) + *(dec - ls) - *(dec - ls - 1));
    1269             :         }
    1270           0 :         break;
    1271             :     }
    1272           0 : }
    1273             : 
    1274           2 : static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p,
    1275             :                                   uint8_t *data_start,
    1276             :                                   unsigned int data_size)
    1277             : {
    1278           2 :     WebPContext *s = avctx->priv_data;
    1279             :     int x, y, ret;
    1280             : 
    1281           2 :     if (s->alpha_compression == ALPHA_COMPRESSION_NONE) {
    1282             :         GetByteContext gb;
    1283             : 
    1284           0 :         bytestream2_init(&gb, data_start, data_size);
    1285           0 :         for (y = 0; y < s->height; y++)
    1286           0 :             bytestream2_get_buffer(&gb, p->data[3] + p->linesize[3] * y,
    1287           0 :                                    s->width);
    1288           2 :     } else if (s->alpha_compression == ALPHA_COMPRESSION_VP8L) {
    1289             :         uint8_t *ap, *pp;
    1290           2 :         int alpha_got_frame = 0;
    1291             : 
    1292           2 :         s->alpha_frame = av_frame_alloc();
    1293           2 :         if (!s->alpha_frame)
    1294           0 :             return AVERROR(ENOMEM);
    1295             : 
    1296           2 :         ret = vp8_lossless_decode_frame(avctx, s->alpha_frame, &alpha_got_frame,
    1297             :                                         data_start, data_size, 1);
    1298           2 :         if (ret < 0) {
    1299           0 :             av_frame_free(&s->alpha_frame);
    1300           0 :             return ret;
    1301             :         }
    1302           2 :         if (!alpha_got_frame) {
    1303           0 :             av_frame_free(&s->alpha_frame);
    1304           0 :             return AVERROR_INVALIDDATA;
    1305             :         }
    1306             : 
    1307             :         /* copy green component of alpha image to alpha plane of primary image */
    1308          18 :         for (y = 0; y < s->height; y++) {
    1309          16 :             ap = GET_PIXEL(s->alpha_frame, 0, y) + 2;
    1310          16 :             pp = p->data[3] + p->linesize[3] * y;
    1311         208 :             for (x = 0; x < s->width; x++) {
    1312         192 :                 *pp = *ap;
    1313         192 :                 pp++;
    1314         192 :                 ap += 4;
    1315             :             }
    1316             :         }
    1317           2 :         av_frame_free(&s->alpha_frame);
    1318             :     }
    1319             : 
    1320             :     /* apply alpha filtering */
    1321           2 :     if (s->alpha_filter)
    1322           0 :         alpha_inverse_prediction(p, s->alpha_filter);
    1323             : 
    1324           2 :     return 0;
    1325             : }
    1326             : 
    1327           6 : static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p,
    1328             :                                   int *got_frame, uint8_t *data_start,
    1329             :                                   unsigned int data_size)
    1330             : {
    1331           6 :     WebPContext *s = avctx->priv_data;
    1332             :     AVPacket pkt;
    1333             :     int ret;
    1334             : 
    1335           6 :     if (!s->initialized) {
    1336           6 :         ff_vp8_decode_init(avctx);
    1337           6 :         s->initialized = 1;
    1338           6 :         s->v.actually_webp = 1;
    1339             :     }
    1340           6 :     avctx->pix_fmt = s->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
    1341           6 :     s->lossless = 0;
    1342             : 
    1343           6 :     if (data_size > INT_MAX) {
    1344           0 :         av_log(avctx, AV_LOG_ERROR, "unsupported chunk size\n");
    1345           0 :         return AVERROR_PATCHWELCOME;
    1346             :     }
    1347             : 
    1348           6 :     av_init_packet(&pkt);
    1349           6 :     pkt.data = data_start;
    1350           6 :     pkt.size = data_size;
    1351             : 
    1352           6 :     ret = ff_vp8_decode_frame(avctx, p, got_frame, &pkt);
    1353           6 :     if (ret < 0)
    1354           0 :         return ret;
    1355             : 
    1356           6 :     if (!*got_frame)
    1357           0 :         return AVERROR_INVALIDDATA;
    1358             : 
    1359           6 :     update_canvas_size(avctx, avctx->width, avctx->height);
    1360             : 
    1361           6 :     if (s->has_alpha) {
    1362           2 :         ret = vp8_lossy_decode_alpha(avctx, p, s->alpha_data,
    1363           2 :                                      s->alpha_data_size);
    1364           2 :         if (ret < 0)
    1365           0 :             return ret;
    1366             :     }
    1367           6 :     return ret;
    1368             : }
    1369             : 
    1370          14 : static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
    1371             :                              AVPacket *avpkt)
    1372             : {
    1373          14 :     AVFrame * const p = data;
    1374          14 :     WebPContext *s = avctx->priv_data;
    1375             :     GetByteContext gb;
    1376             :     int ret;
    1377             :     uint32_t chunk_type, chunk_size;
    1378          14 :     int vp8x_flags = 0;
    1379             : 
    1380          14 :     s->avctx     = avctx;
    1381          14 :     s->width     = 0;
    1382          14 :     s->height    = 0;
    1383          14 :     *got_frame   = 0;
    1384          14 :     s->has_alpha = 0;
    1385          14 :     s->has_exif  = 0;
    1386          14 :     s->has_iccp  = 0;
    1387          14 :     bytestream2_init(&gb, avpkt->data, avpkt->size);
    1388             : 
    1389          14 :     if (bytestream2_get_bytes_left(&gb) < 12)
    1390           0 :         return AVERROR_INVALIDDATA;
    1391             : 
    1392          14 :     if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
    1393           0 :         av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
    1394           0 :         return AVERROR_INVALIDDATA;
    1395             :     }
    1396             : 
    1397          14 :     chunk_size = bytestream2_get_le32(&gb);
    1398          14 :     if (bytestream2_get_bytes_left(&gb) < chunk_size)
    1399           0 :         return AVERROR_INVALIDDATA;
    1400             : 
    1401          14 :     if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) {
    1402           0 :         av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n");
    1403           0 :         return AVERROR_INVALIDDATA;
    1404             :     }
    1405             : 
    1406          50 :     while (bytestream2_get_bytes_left(&gb) > 8) {
    1407          22 :         char chunk_str[5] = { 0 };
    1408             : 
    1409          22 :         chunk_type = bytestream2_get_le32(&gb);
    1410          22 :         chunk_size = bytestream2_get_le32(&gb);
    1411          22 :         if (chunk_size == UINT32_MAX)
    1412           0 :             return AVERROR_INVALIDDATA;
    1413          22 :         chunk_size += chunk_size & 1;
    1414             : 
    1415          22 :         if (bytestream2_get_bytes_left(&gb) < chunk_size)
    1416           0 :             return AVERROR_INVALIDDATA;
    1417             : 
    1418          22 :         switch (chunk_type) {
    1419           6 :         case MKTAG('V', 'P', '8', ' '):
    1420           6 :             if (!*got_frame) {
    1421           6 :                 ret = vp8_lossy_decode_frame(avctx, p, got_frame,
    1422           6 :                                              avpkt->data + bytestream2_tell(&gb),
    1423             :                                              chunk_size);
    1424           6 :                 if (ret < 0)
    1425           0 :                     return ret;
    1426             :             }
    1427           6 :             bytestream2_skip(&gb, chunk_size);
    1428           6 :             break;
    1429           8 :         case MKTAG('V', 'P', '8', 'L'):
    1430           8 :             if (!*got_frame) {
    1431           8 :                 ret = vp8_lossless_decode_frame(avctx, p, got_frame,
    1432           8 :                                                 avpkt->data + bytestream2_tell(&gb),
    1433             :                                                 chunk_size, 0);
    1434           8 :                 if (ret < 0)
    1435           0 :                     return ret;
    1436           8 :                 avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
    1437             :             }
    1438           8 :             bytestream2_skip(&gb, chunk_size);
    1439           8 :             break;
    1440           4 :         case MKTAG('V', 'P', '8', 'X'):
    1441           4 :             if (s->width || s->height || *got_frame) {
    1442           0 :                 av_log(avctx, AV_LOG_ERROR, "Canvas dimensions are already set\n");
    1443           0 :                 return AVERROR_INVALIDDATA;
    1444             :             }
    1445           4 :             vp8x_flags = bytestream2_get_byte(&gb);
    1446           4 :             bytestream2_skip(&gb, 3);
    1447           4 :             s->width  = bytestream2_get_le24(&gb) + 1;
    1448           4 :             s->height = bytestream2_get_le24(&gb) + 1;
    1449           4 :             ret = av_image_check_size(s->width, s->height, 0, avctx);
    1450           4 :             if (ret < 0)
    1451           0 :                 return ret;
    1452           4 :             break;
    1453           2 :         case MKTAG('A', 'L', 'P', 'H'): {
    1454             :             int alpha_header, filter_m, compression;
    1455             : 
    1456           2 :             if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
    1457           0 :                 av_log(avctx, AV_LOG_WARNING,
    1458             :                        "ALPHA chunk present, but alpha bit not set in the "
    1459             :                        "VP8X header\n");
    1460             :             }
    1461           2 :             if (chunk_size == 0) {
    1462           0 :                 av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
    1463           0 :                 return AVERROR_INVALIDDATA;
    1464             :             }
    1465           2 :             alpha_header       = bytestream2_get_byte(&gb);
    1466           2 :             s->alpha_data      = avpkt->data + bytestream2_tell(&gb);
    1467           2 :             s->alpha_data_size = chunk_size - 1;
    1468           2 :             bytestream2_skip(&gb, s->alpha_data_size);
    1469             : 
    1470           2 :             filter_m    = (alpha_header >> 2) & 0x03;
    1471           2 :             compression =  alpha_header       & 0x03;
    1472             : 
    1473           2 :             if (compression > ALPHA_COMPRESSION_VP8L) {
    1474           0 :                 av_log(avctx, AV_LOG_VERBOSE,
    1475             :                        "skipping unsupported ALPHA chunk\n");
    1476             :             } else {
    1477           2 :                 s->has_alpha         = 1;
    1478           2 :                 s->alpha_compression = compression;
    1479           2 :                 s->alpha_filter      = filter_m;
    1480             :             }
    1481             : 
    1482           2 :             break;
    1483             :         }
    1484           2 :         case MKTAG('E', 'X', 'I', 'F'): {
    1485           2 :             int le, ifd_offset, exif_offset = bytestream2_tell(&gb);
    1486           2 :             AVDictionary *exif_metadata = NULL;
    1487             :             GetByteContext exif_gb;
    1488             : 
    1489           2 :             if (s->has_exif) {
    1490           0 :                 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n");
    1491           0 :                 goto exif_end;
    1492             :             }
    1493           2 :             if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA))
    1494           0 :                 av_log(avctx, AV_LOG_WARNING,
    1495             :                        "EXIF chunk present, but Exif bit not set in the "
    1496             :                        "VP8X header\n");
    1497             : 
    1498           2 :             s->has_exif = 1;
    1499           2 :             bytestream2_init(&exif_gb, avpkt->data + exif_offset,
    1500           2 :                              avpkt->size - exif_offset);
    1501           2 :             if (ff_tdecode_header(&exif_gb, &le, &ifd_offset) < 0) {
    1502           0 :                 av_log(avctx, AV_LOG_ERROR, "invalid TIFF header "
    1503             :                        "in Exif data\n");
    1504           0 :                 goto exif_end;
    1505             :             }
    1506             : 
    1507           2 :             bytestream2_seek(&exif_gb, ifd_offset, SEEK_SET);
    1508           2 :             if (ff_exif_decode_ifd(avctx, &exif_gb, le, 0, &exif_metadata) < 0) {
    1509           0 :                 av_log(avctx, AV_LOG_ERROR, "error decoding Exif data\n");
    1510           0 :                 goto exif_end;
    1511             :             }
    1512             : 
    1513           2 :             av_dict_copy(&((AVFrame *) data)->metadata, exif_metadata, 0);
    1514             : 
    1515           2 : exif_end:
    1516           2 :             av_dict_free(&exif_metadata);
    1517           2 :             bytestream2_skip(&gb, chunk_size);
    1518           2 :             break;
    1519             :         }
    1520           0 :         case MKTAG('I', 'C', 'C', 'P'): {
    1521             :             AVFrameSideData *sd;
    1522             : 
    1523           0 :             if (s->has_iccp) {
    1524           0 :                 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra ICCP chunk\n");
    1525           0 :                 bytestream2_skip(&gb, chunk_size);
    1526           0 :                 break;
    1527             :             }
    1528           0 :             if (!(vp8x_flags & VP8X_FLAG_ICC))
    1529           0 :                 av_log(avctx, AV_LOG_WARNING,
    1530             :                        "ICCP chunk present, but ICC Profile bit not set in the "
    1531             :                        "VP8X header\n");
    1532             : 
    1533           0 :             s->has_iccp = 1;
    1534           0 :             sd = av_frame_new_side_data(p, AV_FRAME_DATA_ICC_PROFILE, chunk_size);
    1535           0 :             if (!sd)
    1536           0 :                 return AVERROR(ENOMEM);
    1537             : 
    1538           0 :             bytestream2_get_buffer(&gb, sd->data, chunk_size);
    1539           0 :             break;
    1540             :         }
    1541           0 :         case MKTAG('A', 'N', 'I', 'M'):
    1542             :         case MKTAG('A', 'N', 'M', 'F'):
    1543             :         case MKTAG('X', 'M', 'P', ' '):
    1544           0 :             AV_WL32(chunk_str, chunk_type);
    1545           0 :             av_log(avctx, AV_LOG_WARNING, "skipping unsupported chunk: %s\n",
    1546             :                    chunk_str);
    1547           0 :             bytestream2_skip(&gb, chunk_size);
    1548           0 :             break;
    1549           0 :         default:
    1550           0 :             AV_WL32(chunk_str, chunk_type);
    1551           0 :             av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
    1552             :                    chunk_str);
    1553           0 :             bytestream2_skip(&gb, chunk_size);
    1554           0 :             break;
    1555             :         }
    1556             :     }
    1557             : 
    1558          14 :     if (!*got_frame) {
    1559           0 :         av_log(avctx, AV_LOG_ERROR, "image data not found\n");
    1560           0 :         return AVERROR_INVALIDDATA;
    1561             :     }
    1562             : 
    1563          14 :     return avpkt->size;
    1564             : }
    1565             : 
    1566          14 : static av_cold int webp_decode_close(AVCodecContext *avctx)
    1567             : {
    1568          14 :     WebPContext *s = avctx->priv_data;
    1569             : 
    1570          14 :     if (s->initialized)
    1571           6 :         return ff_vp8_decode_free(avctx);
    1572             : 
    1573           8 :     return 0;
    1574             : }
    1575             : 
    1576             : AVCodec ff_webp_decoder = {
    1577             :     .name           = "webp",
    1578             :     .long_name      = NULL_IF_CONFIG_SMALL("WebP image"),
    1579             :     .type           = AVMEDIA_TYPE_VIDEO,
    1580             :     .id             = AV_CODEC_ID_WEBP,
    1581             :     .priv_data_size = sizeof(WebPContext),
    1582             :     .decode         = webp_decode_frame,
    1583             :     .close          = webp_decode_close,
    1584             :     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
    1585             : };

Generated by: LCOV version 1.13