2 * WebP (.webp) image decoder
3 * Copyright (c) 2013 Aneesh Dogra <aneesh@sugarlabs.org>
4 * Copyright (c) 2013 Justin Ruggles <justin.ruggles@gmail.com>
6 * This file is part of Libav.
8 * Libav 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.
13 * Libav 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.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 * @author Aneesh Dogra <aneesh@sugarlabs.org>
28 * Container and Lossy decoding
30 * @author Justin Ruggles <justin.ruggles@gmail.com>
32 * Compressed alpha for lossy
37 * - Exif and XMP metadata
40 #include "libavutil/imgutils.h"
42 #define BITSTREAM_READER_LE
44 #include "bitstream.h"
45 #include "bytestream.h"
50 #define VP8X_FLAG_ANIMATION 0x02
51 #define VP8X_FLAG_XMP_METADATA 0x04
52 #define VP8X_FLAG_EXIF_METADATA 0x08
53 #define VP8X_FLAG_ALPHA 0x10
54 #define VP8X_FLAG_ICC 0x20
56 #define MAX_PALETTE_SIZE 256
57 #define MAX_CACHE_BITS 11
58 #define NUM_CODE_LENGTH_CODES 19
59 #define HUFFMAN_CODES_PER_META_CODE 5
60 #define NUM_LITERAL_CODES 256
61 #define NUM_LENGTH_CODES 24
62 #define NUM_DISTANCE_CODES 40
63 #define NUM_SHORT_DISTANCES 120
64 #define MAX_HUFFMAN_CODE_LENGTH 15
66 static const uint16_t alphabet_sizes
[HUFFMAN_CODES_PER_META_CODE
] = {
67 NUM_LITERAL_CODES
+ NUM_LENGTH_CODES
,
68 NUM_LITERAL_CODES
, NUM_LITERAL_CODES
, NUM_LITERAL_CODES
,
72 static const uint8_t code_length_code_order
[NUM_CODE_LENGTH_CODES
] = {
73 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
76 static const int8_t lz77_distance_offsets
[NUM_SHORT_DISTANCES
][2] = {
77 { 0, 1 }, { 1, 0 }, { 1, 1 }, { -1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { -1, 2 },
78 { 2, 1 }, { -2, 1 }, { 2, 2 }, { -2, 2 }, { 0, 3 }, { 3, 0 }, { 1, 3 }, { -1, 3 },
79 { 3, 1 }, { -3, 1 }, { 2, 3 }, { -2, 3 }, { 3, 2 }, { -3, 2 }, { 0, 4 }, { 4, 0 },
80 { 1, 4 }, { -1, 4 }, { 4, 1 }, { -4, 1 }, { 3, 3 }, { -3, 3 }, { 2, 4 }, { -2, 4 },
81 { 4, 2 }, { -4, 2 }, { 0, 5 }, { 3, 4 }, { -3, 4 }, { 4, 3 }, { -4, 3 }, { 5, 0 },
82 { 1, 5 }, { -1, 5 }, { 5, 1 }, { -5, 1 }, { 2, 5 }, { -2, 5 }, { 5, 2 }, { -5, 2 },
83 { 4, 4 }, { -4, 4 }, { 3, 5 }, { -3, 5 }, { 5, 3 }, { -5, 3 }, { 0, 6 }, { 6, 0 },
84 { 1, 6 }, { -1, 6 }, { 6, 1 }, { -6, 1 }, { 2, 6 }, { -2, 6 }, { 6, 2 }, { -6, 2 },
85 { 4, 5 }, { -4, 5 }, { 5, 4 }, { -5, 4 }, { 3, 6 }, { -3, 6 }, { 6, 3 }, { -6, 3 },
86 { 0, 7 }, { 7, 0 }, { 1, 7 }, { -1, 7 }, { 5, 5 }, { -5, 5 }, { 7, 1 }, { -7, 1 },
87 { 4, 6 }, { -4, 6 }, { 6, 4 }, { -6, 4 }, { 2, 7 }, { -2, 7 }, { 7, 2 }, { -7, 2 },
88 { 3, 7 }, { -3, 7 }, { 7, 3 }, { -7, 3 }, { 5, 6 }, { -5, 6 }, { 6, 5 }, { -6, 5 },
89 { 8, 0 }, { 4, 7 }, { -4, 7 }, { 7, 4 }, { -7, 4 }, { 8, 1 }, { 8, 2 }, { 6, 6 },
90 { -6, 6 }, { 8, 3 }, { 5, 7 }, { -5, 7 }, { 7, 5 }, { -7, 5 }, { 8, 4 }, { 6, 7 },
91 { -6, 7 }, { 7, 6 }, { -7, 6 }, { 8, 5 }, { 7, 7 }, { -7, 7 }, { 8, 6 }, { 8, 7 }
94 enum AlphaCompression
{
95 ALPHA_COMPRESSION_NONE
,
96 ALPHA_COMPRESSION_VP8L
,
101 ALPHA_FILTER_HORIZONTAL
,
102 ALPHA_FILTER_VERTICAL
,
103 ALPHA_FILTER_GRADIENT
,
107 PREDICTOR_TRANSFORM
= 0,
110 COLOR_INDEXING_TRANSFORM
= 3,
113 enum PredictionMode
{
119 PRED_MODE_AVG_T_AVG_L_TR
,
124 PRED_MODE_AVG_AVG_L_TL_AVG_T_TR
,
126 PRED_MODE_ADD_SUBTRACT_FULL
,
127 PRED_MODE_ADD_SUBTRACT_HALF
,
138 /* The structure of WebP lossless is an optional series of transformation data,
139 * followed by the primary image. The primary image also optionally contains
140 * an entropy group mapping if there are multiple entropy groups. There is a
141 * basic image type called an "entropy coded image" that is used for all of
142 * these. The type of each entropy coded image is referred to by the
143 * specification as its role. */
145 /* Primary Image: Stores the actual pixels of the image. */
148 /* Entropy Image: Defines which Huffman group to use for different areas of
149 * the primary image. */
152 /* Predictors: Defines which predictor type to use for different areas of
153 * the primary image. */
154 IMAGE_ROLE_PREDICTOR
,
156 /* Color Transform Data: Defines the color transformation for different
157 * areas of the primary image. */
158 IMAGE_ROLE_COLOR_TRANSFORM
,
160 /* Color Index: Stored as an image of height == 1. */
161 IMAGE_ROLE_COLOR_INDEXING
,
166 typedef struct HuffReader
{
167 VLC vlc
; /* Huffman decoder context */
168 int simple
; /* whether to use simple mode */
169 int nb_symbols
; /* number of coded symbols */
170 uint16_t simple_symbols
[2]; /* symbols for simple mode */
173 typedef struct ImageContext
{
174 enum ImageRole role
; /* role of this image */
175 AVFrame
*frame
; /* AVFrame for data */
176 int color_cache_bits
; /* color cache size, log2 */
177 uint32_t *color_cache
; /* color cache data */
178 int nb_huffman_groups
; /* number of huffman groups */
179 HuffReader
*huffman_groups
; /* reader for each huffman group */
180 int size_reduction
; /* relative size compared to primary image, log2 */
181 int is_alpha_primary
;
184 typedef struct WebPContext
{
185 VP8Context v
; /* VP8 Context used for lossy decoding */
186 BitstreamContext bc
; /* bitstream reader for main image chunk */
187 AVFrame
*alpha_frame
; /* AVFrame for alpha data decompressed from VP8L */
188 AVCodecContext
*avctx
; /* parent AVCodecContext */
189 int initialized
; /* set once the VP8 context is initialized */
190 int has_alpha
; /* has a separate alpha chunk */
191 enum AlphaCompression alpha_compression
; /* compression type for alpha chunk */
192 enum AlphaFilter alpha_filter
; /* filtering method for alpha chunk */
193 uint8_t *alpha_data
; /* alpha chunk data */
194 int alpha_data_size
; /* alpha chunk data size */
195 int width
; /* image width */
196 int height
; /* image height */
197 int lossless
; /* indicates lossless or lossy */
199 int nb_transforms
; /* number of transforms */
200 enum TransformType transforms
[4]; /* transformations used in the image, in order */
201 int reduced_width
; /* reduced width for index image, if applicable */
202 int nb_huffman_groups
; /* number of huffman groups in the primary image */
203 ImageContext image
[IMAGE_ROLE_NB
]; /* image context for each role */
206 #define GET_PIXEL(frame, x, y) \
207 ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
209 #define GET_PIXEL_COMP(frame, x, y, c) \
210 (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
212 static void image_ctx_free(ImageContext
*img
)
216 av_free(img
->color_cache
);
217 if (img
->role
!= IMAGE_ROLE_ARGB
&& !img
->is_alpha_primary
)
218 av_frame_free(&img
->frame
);
219 if (img
->huffman_groups
) {
220 for (i
= 0; i
< img
->nb_huffman_groups
; i
++) {
221 for (j
= 0; j
< HUFFMAN_CODES_PER_META_CODE
; j
++)
222 ff_free_vlc(&img
->huffman_groups
[i
* HUFFMAN_CODES_PER_META_CODE
+ j
].vlc
);
224 av_free(img
->huffman_groups
);
226 memset(img
, 0, sizeof(*img
));
230 /* Differs from get_vlc2() in the following ways:
231 * - codes are bit-reversed
232 * - assumes 8-bit table to make reversal simpler
233 * - assumes max depth of 2 since the max code length for WebP is 15
235 static av_always_inline
int webp_get_vlc(BitstreamContext
*bc
, VLC_TYPE (*table
)[2])
241 index
= bitstream_peek(bc
, 8);
242 index
= ff_reverse
[index
];
243 code
= table
[index
][0];
247 bitstream_skip(bc
, 8);
251 index
= bitstream_peek(bc
, nb_bits
);
252 index
= (ff_reverse
[index
] >> (8 - nb_bits
)) + code
;
253 code
= table
[index
][0];
256 bitstream_skip(bc
, n
);
261 static int huff_reader_get_symbol(HuffReader
*r
, BitstreamContext
*bc
)
264 if (r
->nb_symbols
== 1)
265 return r
->simple_symbols
[0];
267 return r
->simple_symbols
[bitstream_read_bit(bc
)];
269 return webp_get_vlc(bc
, r
->vlc
.table
);
272 static int huff_reader_build_canonical(HuffReader
*r
, int *code_lengths
,
275 int len
= 0, sym
, code
= 0, ret
;
276 int max_code_length
= 0;
279 /* special-case 1 symbol since the vlc reader cannot handle it */
280 for (sym
= 0; sym
< alphabet_size
; sym
++) {
281 if (code_lengths
[sym
] > 0) {
290 r
->simple_symbols
[0] = code
;
295 for (sym
= 0; sym
< alphabet_size
; sym
++)
296 max_code_length
= FFMAX(max_code_length
, code_lengths
[sym
]);
298 if (max_code_length
== 0 || max_code_length
> MAX_HUFFMAN_CODE_LENGTH
)
299 return AVERROR(EINVAL
);
301 codes
= av_malloc(alphabet_size
* sizeof(*codes
));
303 return AVERROR(ENOMEM
);
307 for (len
= 1; len
<= max_code_length
; len
++) {
308 for (sym
= 0; sym
< alphabet_size
; sym
++) {
309 if (code_lengths
[sym
] != len
)
316 if (!r
->nb_symbols
) {
318 return AVERROR_INVALIDDATA
;
321 ret
= init_vlc(&r
->vlc
, 8, alphabet_size
,
322 code_lengths
, sizeof(*code_lengths
), sizeof(*code_lengths
),
323 codes
, sizeof(*codes
), sizeof(*codes
), 0);
334 static void read_huffman_code_simple(WebPContext
*s
, HuffReader
*hc
)
336 hc
->nb_symbols
= bitstream_read_bit(&s
->bc
) + 1;
338 if (bitstream_read_bit(&s
->bc
))
339 hc
->simple_symbols
[0] = bitstream_read(&s
->bc
, 8);
341 hc
->simple_symbols
[0] = bitstream_read_bit(&s
->bc
);
343 if (hc
->nb_symbols
== 2)
344 hc
->simple_symbols
[1] = bitstream_read(&s
->bc
, 8);
349 static int read_huffman_code_normal(WebPContext
*s
, HuffReader
*hc
,
352 HuffReader code_len_hc
= { { 0 }, 0, 0, { 0 } };
353 int *code_lengths
= NULL
;
354 int code_length_code_lengths
[NUM_CODE_LENGTH_CODES
] = { 0 };
355 int i
, symbol
, max_symbol
, prev_code_len
, ret
;
356 int num_codes
= 4 + bitstream_read(&s
->bc
, 4);
358 if (num_codes
> NUM_CODE_LENGTH_CODES
)
359 return AVERROR_INVALIDDATA
;
361 for (i
= 0; i
< num_codes
; i
++)
362 code_length_code_lengths
[code_length_code_order
[i
]] = bitstream_read(&s
->bc
, 3);
364 ret
= huff_reader_build_canonical(&code_len_hc
, code_length_code_lengths
,
365 NUM_CODE_LENGTH_CODES
);
369 code_lengths
= av_mallocz_array(alphabet_size
, sizeof(*code_lengths
));
371 ret
= AVERROR(ENOMEM
);
375 if (bitstream_read_bit(&s
->bc
)) {
376 int bits
= 2 + 2 * bitstream_read(&s
->bc
, 3);
377 max_symbol
= 2 + bitstream_read(&s
->bc
, bits
);
378 if (max_symbol
> alphabet_size
) {
379 av_log(s
->avctx
, AV_LOG_ERROR
, "max symbol %d > alphabet size %d\n",
380 max_symbol
, alphabet_size
);
381 ret
= AVERROR_INVALIDDATA
;
385 max_symbol
= alphabet_size
;
390 while (symbol
< alphabet_size
) {
395 code_len
= huff_reader_get_symbol(&code_len_hc
, &s
->bc
);
397 /* Code length code [0..15] indicates literal code lengths. */
398 code_lengths
[symbol
++] = code_len
;
400 prev_code_len
= code_len
;
402 int repeat
= 0, length
= 0;
405 /* Code 16 repeats the previous non-zero value [3..6] times,
406 * i.e., 3 + ReadBits(2) times. If code 16 is used before a
407 * non-zero value has been emitted, a value of 8 is repeated. */
408 repeat
= 3 + bitstream_read(&s
->bc
, 2);
409 length
= prev_code_len
;
412 /* Code 17 emits a streak of zeros [3..10], i.e.,
413 * 3 + ReadBits(3) times. */
414 repeat
= 3 + bitstream_read(&s
->bc
, 3);
417 /* Code 18 emits a streak of zeros of length [11..138], i.e.,
418 * 11 + ReadBits(7) times. */
419 repeat
= 11 + bitstream_read(&s
->bc
, 7);
422 if (symbol
+ repeat
> alphabet_size
) {
423 av_log(s
->avctx
, AV_LOG_ERROR
,
424 "invalid symbol %d + repeat %d > alphabet size %d\n",
425 symbol
, repeat
, alphabet_size
);
426 ret
= AVERROR_INVALIDDATA
;
430 code_lengths
[symbol
++] = length
;
434 ret
= huff_reader_build_canonical(hc
, code_lengths
, alphabet_size
);
437 ff_free_vlc(&code_len_hc
.vlc
);
438 av_free(code_lengths
);
442 static int decode_entropy_coded_image(WebPContext
*s
, enum ImageRole role
,
445 #define PARSE_BLOCK_SIZE(w, h) do { \
446 block_bits = bitstream_read(&s->bc, 3) + 2; \
447 blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \
448 blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \
451 static int decode_entropy_image(WebPContext
*s
)
454 int ret
, block_bits
, width
, blocks_w
, blocks_h
, x
, y
, max
;
457 if (s
->reduced_width
> 0)
458 width
= s
->reduced_width
;
460 PARSE_BLOCK_SIZE(width
, s
->height
);
462 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_ENTROPY
, blocks_w
, blocks_h
);
466 img
= &s
->image
[IMAGE_ROLE_ENTROPY
];
467 img
->size_reduction
= block_bits
;
469 /* the number of huffman groups is determined by the maximum group number
470 * coded in the entropy image */
472 for (y
= 0; y
< img
->frame
->height
; y
++) {
473 for (x
= 0; x
< img
->frame
->width
; x
++) {
474 int p0
= GET_PIXEL_COMP(img
->frame
, x
, y
, 1);
475 int p1
= GET_PIXEL_COMP(img
->frame
, x
, y
, 2);
476 int p
= p0
<< 8 | p1
;
480 s
->nb_huffman_groups
= max
+ 1;
485 static int parse_transform_predictor(WebPContext
*s
)
487 int block_bits
, blocks_w
, blocks_h
, ret
;
489 PARSE_BLOCK_SIZE(s
->width
, s
->height
);
491 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_PREDICTOR
, blocks_w
,
496 s
->image
[IMAGE_ROLE_PREDICTOR
].size_reduction
= block_bits
;
501 static int parse_transform_color(WebPContext
*s
)
503 int block_bits
, blocks_w
, blocks_h
, ret
;
505 PARSE_BLOCK_SIZE(s
->width
, s
->height
);
507 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_COLOR_TRANSFORM
, blocks_w
,
512 s
->image
[IMAGE_ROLE_COLOR_TRANSFORM
].size_reduction
= block_bits
;
517 static int parse_transform_color_indexing(WebPContext
*s
)
520 int width_bits
, index_size
, ret
, x
;
523 index_size
= bitstream_read(&s
->bc
, 8) + 1;
527 else if (index_size
<= 4)
529 else if (index_size
<= 16)
534 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_COLOR_INDEXING
,
539 img
= &s
->image
[IMAGE_ROLE_COLOR_INDEXING
];
540 img
->size_reduction
= width_bits
;
542 s
->reduced_width
= (s
->width
+ ((1 << width_bits
) - 1)) >> width_bits
;
544 /* color index values are delta-coded */
545 ct
= img
->frame
->data
[0] + 4;
546 for (x
= 4; x
< img
->frame
->width
* 4; x
++, ct
++)
552 static HuffReader
*get_huffman_group(WebPContext
*s
, ImageContext
*img
,
555 ImageContext
*gimg
= &s
->image
[IMAGE_ROLE_ENTROPY
];
558 if (gimg
->size_reduction
> 0) {
559 int group_x
= x
>> gimg
->size_reduction
;
560 int group_y
= y
>> gimg
->size_reduction
;
561 int g0
= GET_PIXEL_COMP(gimg
->frame
, group_x
, group_y
, 1);
562 int g1
= GET_PIXEL_COMP(gimg
->frame
, group_x
, group_y
, 2);
563 group
= g0
<< 8 | g1
;
566 return &img
->huffman_groups
[group
* HUFFMAN_CODES_PER_META_CODE
];
569 static av_always_inline
void color_cache_put(ImageContext
*img
, uint32_t c
)
571 uint32_t cache_idx
= (0x1E35A7BD * c
) >> (32 - img
->color_cache_bits
);
572 img
->color_cache
[cache_idx
] = c
;
575 static int decode_entropy_coded_image(WebPContext
*s
, enum ImageRole role
,
580 int i
, j
, ret
, x
, y
, width
;
582 img
= &s
->image
[role
];
586 img
->frame
= av_frame_alloc();
588 return AVERROR(ENOMEM
);
591 img
->frame
->format
= AV_PIX_FMT_ARGB
;
592 img
->frame
->width
= w
;
593 img
->frame
->height
= h
;
595 if (role
== IMAGE_ROLE_ARGB
&& !img
->is_alpha_primary
) {
596 ThreadFrame pt
= { .f
= img
->frame
};
597 ret
= ff_thread_get_buffer(s
->avctx
, &pt
, 0);
599 ret
= av_frame_get_buffer(img
->frame
, 1);
603 if (bitstream_read_bit(&s
->bc
)) {
604 img
->color_cache_bits
= bitstream_read(&s
->bc
, 4);
605 if (img
->color_cache_bits
< 1 || img
->color_cache_bits
> 11) {
606 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid color cache bits: %d\n",
607 img
->color_cache_bits
);
608 return AVERROR_INVALIDDATA
;
610 img
->color_cache
= av_mallocz_array(1 << img
->color_cache_bits
,
611 sizeof(*img
->color_cache
));
612 if (!img
->color_cache
)
613 return AVERROR(ENOMEM
);
615 img
->color_cache_bits
= 0;
618 img
->nb_huffman_groups
= 1;
619 if (role
== IMAGE_ROLE_ARGB
&& bitstream_read_bit(&s
->bc
)) {
620 ret
= decode_entropy_image(s
);
623 img
->nb_huffman_groups
= s
->nb_huffman_groups
;
625 img
->huffman_groups
= av_mallocz_array(img
->nb_huffman_groups
*
626 HUFFMAN_CODES_PER_META_CODE
,
627 sizeof(*img
->huffman_groups
));
628 if (!img
->huffman_groups
)
629 return AVERROR(ENOMEM
);
631 for (i
= 0; i
< img
->nb_huffman_groups
; i
++) {
632 hg
= &img
->huffman_groups
[i
* HUFFMAN_CODES_PER_META_CODE
];
633 for (j
= 0; j
< HUFFMAN_CODES_PER_META_CODE
; j
++) {
634 int alphabet_size
= alphabet_sizes
[j
];
635 if (!j
&& img
->color_cache_bits
> 0)
636 alphabet_size
+= 1 << img
->color_cache_bits
;
638 if (bitstream_read_bit(&s
->bc
)) {
639 read_huffman_code_simple(s
, &hg
[j
]);
641 ret
= read_huffman_code_normal(s
, &hg
[j
], alphabet_size
);
648 width
= img
->frame
->width
;
649 if (role
== IMAGE_ROLE_ARGB
&& s
->reduced_width
> 0)
650 width
= s
->reduced_width
;
653 while (y
< img
->frame
->height
) {
656 hg
= get_huffman_group(s
, img
, x
, y
);
657 v
= huff_reader_get_symbol(&hg
[HUFF_IDX_GREEN
], &s
->bc
);
658 if (v
< NUM_LITERAL_CODES
) {
659 /* literal pixel values */
660 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
662 p
[1] = huff_reader_get_symbol(&hg
[HUFF_IDX_RED
], &s
->bc
);
663 p
[3] = huff_reader_get_symbol(&hg
[HUFF_IDX_BLUE
], &s
->bc
);
664 p
[0] = huff_reader_get_symbol(&hg
[HUFF_IDX_ALPHA
], &s
->bc
);
665 if (img
->color_cache_bits
)
666 color_cache_put(img
, AV_RB32(p
));
672 } else if (v
< NUM_LITERAL_CODES
+ NUM_LENGTH_CODES
) {
673 /* LZ77 backwards mapping */
674 int prefix_code
, length
, distance
, ref_x
, ref_y
;
676 /* parse length and distance */
677 prefix_code
= v
- NUM_LITERAL_CODES
;
678 if (prefix_code
< 4) {
679 length
= prefix_code
+ 1;
681 int extra_bits
= (prefix_code
- 2) >> 1;
682 int offset
= 2 + (prefix_code
& 1) << extra_bits
;
683 length
= offset
+ bitstream_read(&s
->bc
, extra_bits
) + 1;
685 prefix_code
= huff_reader_get_symbol(&hg
[HUFF_IDX_DIST
], &s
->bc
);
686 if (prefix_code
> 39) {
687 av_log(s
->avctx
, AV_LOG_ERROR
,
688 "distance prefix code too large: %d\n", prefix_code
);
689 return AVERROR_INVALIDDATA
;
691 if (prefix_code
< 4) {
692 distance
= prefix_code
+ 1;
694 int extra_bits
= prefix_code
- 2 >> 1;
695 int offset
= 2 + (prefix_code
& 1) << extra_bits
;
696 distance
= offset
+ bitstream_read(&s
->bc
, extra_bits
) + 1;
699 /* find reference location */
700 if (distance
<= NUM_SHORT_DISTANCES
) {
701 int xi
= lz77_distance_offsets
[distance
- 1][0];
702 int yi
= lz77_distance_offsets
[distance
- 1][1];
703 distance
= FFMAX(1, xi
+ yi
* width
);
705 distance
-= NUM_SHORT_DISTANCES
;
716 while (distance
>= width
) {
721 ref_x
= width
- distance
;
724 ref_x
= FFMAX(0, ref_x
);
725 ref_y
= FFMAX(0, ref_y
);
728 * source and dest regions can overlap and wrap lines, so just
730 for (i
= 0; i
< length
; i
++) {
731 uint8_t *p_ref
= GET_PIXEL(img
->frame
, ref_x
, ref_y
);
732 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
735 if (img
->color_cache_bits
)
736 color_cache_put(img
, AV_RB32(p
));
743 if (ref_x
== width
) {
747 if (y
== img
->frame
->height
|| ref_y
== img
->frame
->height
)
751 /* read from color cache */
752 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
753 int cache_idx
= v
- (NUM_LITERAL_CODES
+ NUM_LENGTH_CODES
);
755 if (!img
->color_cache_bits
) {
756 av_log(s
->avctx
, AV_LOG_ERROR
, "color cache not found\n");
757 return AVERROR_INVALIDDATA
;
759 if (cache_idx
>= 1 << img
->color_cache_bits
) {
760 av_log(s
->avctx
, AV_LOG_ERROR
,
761 "color cache index out-of-bounds\n");
762 return AVERROR_INVALIDDATA
;
764 AV_WB32(p
, img
->color_cache
[cache_idx
]);
776 /* PRED_MODE_BLACK */
777 static void inv_predict_0(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
778 const uint8_t *p_t
, const uint8_t *p_tr
)
780 AV_WB32(p
, 0xFF000000);
784 static void inv_predict_1(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
785 const uint8_t *p_t
, const uint8_t *p_tr
)
791 static void inv_predict_2(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
792 const uint8_t *p_t
, const uint8_t *p_tr
)
798 static void inv_predict_3(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
799 const uint8_t *p_t
, const uint8_t *p_tr
)
805 static void inv_predict_4(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
806 const uint8_t *p_t
, const uint8_t *p_tr
)
811 /* PRED_MODE_AVG_T_AVG_L_TR */
812 static void inv_predict_5(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
813 const uint8_t *p_t
, const uint8_t *p_tr
)
815 p
[0] = p_t
[0] + (p_l
[0] + p_tr
[0] >> 1) >> 1;
816 p
[1] = p_t
[1] + (p_l
[1] + p_tr
[1] >> 1) >> 1;
817 p
[2] = p_t
[2] + (p_l
[2] + p_tr
[2] >> 1) >> 1;
818 p
[3] = p_t
[3] + (p_l
[3] + p_tr
[3] >> 1) >> 1;
821 /* PRED_MODE_AVG_L_TL */
822 static void inv_predict_6(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
823 const uint8_t *p_t
, const uint8_t *p_tr
)
825 p
[0] = p_l
[0] + p_tl
[0] >> 1;
826 p
[1] = p_l
[1] + p_tl
[1] >> 1;
827 p
[2] = p_l
[2] + p_tl
[2] >> 1;
828 p
[3] = p_l
[3] + p_tl
[3] >> 1;
831 /* PRED_MODE_AVG_L_T */
832 static void inv_predict_7(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
833 const uint8_t *p_t
, const uint8_t *p_tr
)
835 p
[0] = p_l
[0] + p_t
[0] >> 1;
836 p
[1] = p_l
[1] + p_t
[1] >> 1;
837 p
[2] = p_l
[2] + p_t
[2] >> 1;
838 p
[3] = p_l
[3] + p_t
[3] >> 1;
841 /* PRED_MODE_AVG_TL_T */
842 static void inv_predict_8(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
843 const uint8_t *p_t
, const uint8_t *p_tr
)
845 p
[0] = p_tl
[0] + p_t
[0] >> 1;
846 p
[1] = p_tl
[1] + p_t
[1] >> 1;
847 p
[2] = p_tl
[2] + p_t
[2] >> 1;
848 p
[3] = p_tl
[3] + p_t
[3] >> 1;
851 /* PRED_MODE_AVG_T_TR */
852 static void inv_predict_9(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
853 const uint8_t *p_t
, const uint8_t *p_tr
)
855 p
[0] = p_t
[0] + p_tr
[0] >> 1;
856 p
[1] = p_t
[1] + p_tr
[1] >> 1;
857 p
[2] = p_t
[2] + p_tr
[2] >> 1;
858 p
[3] = p_t
[3] + p_tr
[3] >> 1;
861 /* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
862 static void inv_predict_10(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
863 const uint8_t *p_t
, const uint8_t *p_tr
)
865 p
[0] = (p_l
[0] + p_tl
[0] >> 1) + (p_t
[0] + p_tr
[0] >> 1) >> 1;
866 p
[1] = (p_l
[1] + p_tl
[1] >> 1) + (p_t
[1] + p_tr
[1] >> 1) >> 1;
867 p
[2] = (p_l
[2] + p_tl
[2] >> 1) + (p_t
[2] + p_tr
[2] >> 1) >> 1;
868 p
[3] = (p_l
[3] + p_tl
[3] >> 1) + (p_t
[3] + p_tr
[3] >> 1) >> 1;
871 /* PRED_MODE_SELECT */
872 static void inv_predict_11(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
873 const uint8_t *p_t
, const uint8_t *p_tr
)
875 int diff
= (FFABS(p_l
[0] - p_tl
[0]) - FFABS(p_t
[0] - p_tl
[0])) +
876 (FFABS(p_l
[1] - p_tl
[1]) - FFABS(p_t
[1] - p_tl
[1])) +
877 (FFABS(p_l
[2] - p_tl
[2]) - FFABS(p_t
[2] - p_tl
[2])) +
878 (FFABS(p_l
[3] - p_tl
[3]) - FFABS(p_t
[3] - p_tl
[3]));
885 /* PRED_MODE_ADD_SUBTRACT_FULL */
886 static void inv_predict_12(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
887 const uint8_t *p_t
, const uint8_t *p_tr
)
889 p
[0] = av_clip_uint8(p_l
[0] + p_t
[0] - p_tl
[0]);
890 p
[1] = av_clip_uint8(p_l
[1] + p_t
[1] - p_tl
[1]);
891 p
[2] = av_clip_uint8(p_l
[2] + p_t
[2] - p_tl
[2]);
892 p
[3] = av_clip_uint8(p_l
[3] + p_t
[3] - p_tl
[3]);
895 static av_always_inline
uint8_t clamp_add_subtract_half(int a
, int b
, int c
)
898 return av_clip_uint8(d
+ (d
- c
) / 2);
901 /* PRED_MODE_ADD_SUBTRACT_HALF */
902 static void inv_predict_13(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
903 const uint8_t *p_t
, const uint8_t *p_tr
)
905 p
[0] = clamp_add_subtract_half(p_l
[0], p_t
[0], p_tl
[0]);
906 p
[1] = clamp_add_subtract_half(p_l
[1], p_t
[1], p_tl
[1]);
907 p
[2] = clamp_add_subtract_half(p_l
[2], p_t
[2], p_tl
[2]);
908 p
[3] = clamp_add_subtract_half(p_l
[3], p_t
[3], p_tl
[3]);
911 typedef void (*inv_predict_func
)(uint8_t *p
, const uint8_t *p_l
,
912 const uint8_t *p_tl
, const uint8_t *p_t
,
913 const uint8_t *p_tr
);
915 static const inv_predict_func inverse_predict
[14] = {
916 inv_predict_0
, inv_predict_1
, inv_predict_2
, inv_predict_3
,
917 inv_predict_4
, inv_predict_5
, inv_predict_6
, inv_predict_7
,
918 inv_predict_8
, inv_predict_9
, inv_predict_10
, inv_predict_11
,
919 inv_predict_12
, inv_predict_13
,
922 static void inverse_prediction(AVFrame
*frame
, enum PredictionMode m
, int x
, int y
)
924 uint8_t *dec
, *p_l
, *p_tl
, *p_t
, *p_tr
;
927 dec
= GET_PIXEL(frame
, x
, y
);
928 p_l
= GET_PIXEL(frame
, x
- 1, y
);
929 p_tl
= GET_PIXEL(frame
, x
- 1, y
- 1);
930 p_t
= GET_PIXEL(frame
, x
, y
- 1);
931 if (x
== frame
->width
- 1)
932 p_tr
= GET_PIXEL(frame
, 0, y
);
934 p_tr
= GET_PIXEL(frame
, x
+ 1, y
- 1);
936 inverse_predict
[m
](p
, p_l
, p_tl
, p_t
, p_tr
);
944 static int apply_predictor_transform(WebPContext
*s
)
946 ImageContext
*img
= &s
->image
[IMAGE_ROLE_ARGB
];
947 ImageContext
*pimg
= &s
->image
[IMAGE_ROLE_PREDICTOR
];
950 for (y
= 0; y
< img
->frame
->height
; y
++) {
951 for (x
= 0; x
< img
->frame
->width
; x
++) {
952 int tx
= x
>> pimg
->size_reduction
;
953 int ty
= y
>> pimg
->size_reduction
;
954 enum PredictionMode m
= GET_PIXEL_COMP(pimg
->frame
, tx
, ty
, 2);
965 av_log(s
->avctx
, AV_LOG_ERROR
,
966 "invalid predictor mode: %d\n", m
);
967 return AVERROR_INVALIDDATA
;
969 inverse_prediction(img
->frame
, m
, x
, y
);
975 static av_always_inline
uint8_t color_transform_delta(uint8_t color_pred
,
978 return (int)ff_u8_to_s8(color_pred
) * ff_u8_to_s8(color
) >> 5;
981 static int apply_color_transform(WebPContext
*s
)
983 ImageContext
*img
, *cimg
;
987 img
= &s
->image
[IMAGE_ROLE_ARGB
];
988 cimg
= &s
->image
[IMAGE_ROLE_COLOR_TRANSFORM
];
990 for (y
= 0; y
< img
->frame
->height
; y
++) {
991 for (x
= 0; x
< img
->frame
->width
; x
++) {
992 cx
= x
>> cimg
->size_reduction
;
993 cy
= y
>> cimg
->size_reduction
;
994 cp
= GET_PIXEL(cimg
->frame
, cx
, cy
);
995 p
= GET_PIXEL(img
->frame
, x
, y
);
997 p
[1] += color_transform_delta(cp
[3], p
[2]);
998 p
[3] += color_transform_delta(cp
[2], p
[2]) +
999 color_transform_delta(cp
[1], p
[1]);
1005 static int apply_subtract_green_transform(WebPContext
*s
)
1008 ImageContext
*img
= &s
->image
[IMAGE_ROLE_ARGB
];
1010 for (y
= 0; y
< img
->frame
->height
; y
++) {
1011 for (x
= 0; x
< img
->frame
->width
; x
++) {
1012 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
1020 static int apply_color_indexing_transform(WebPContext
*s
)
1027 img
= &s
->image
[IMAGE_ROLE_ARGB
];
1028 pal
= &s
->image
[IMAGE_ROLE_COLOR_INDEXING
];
1030 if (pal
->size_reduction
> 0) {
1031 BitstreamContext bc_g
;
1033 int pixel_bits
= 8 >> pal
->size_reduction
;
1035 line
= av_malloc(img
->frame
->linesize
[0]);
1037 return AVERROR(ENOMEM
);
1039 for (y
= 0; y
< img
->frame
->height
; y
++) {
1040 p
= GET_PIXEL(img
->frame
, 0, y
);
1041 memcpy(line
, p
, img
->frame
->linesize
[0]);
1042 bitstream_init8(&bc_g
, line
, img
->frame
->linesize
[0]);
1043 bitstream_skip(&bc_g
, 16);
1045 for (x
= 0; x
< img
->frame
->width
; x
++) {
1046 p
= GET_PIXEL(img
->frame
, x
, y
);
1047 p
[2] = bitstream_read(&bc_g
, pixel_bits
);
1049 if (i
== 1 << pal
->size_reduction
) {
1050 bitstream_skip(&bc_g
, 24);
1058 for (y
= 0; y
< img
->frame
->height
; y
++) {
1059 for (x
= 0; x
< img
->frame
->width
; x
++) {
1060 p
= GET_PIXEL(img
->frame
, x
, y
);
1062 if (i
>= pal
->frame
->width
) {
1063 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid palette index %d\n", i
);
1064 return AVERROR_INVALIDDATA
;
1066 pi
= GET_PIXEL(pal
->frame
, i
, 0);
1074 static int vp8_lossless_decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
1075 int *got_frame
, uint8_t *data_start
,
1076 unsigned int data_size
, int is_alpha_chunk
)
1078 WebPContext
*s
= avctx
->priv_data
;
1079 int w
, h
, ret
, i
, used
;
1081 if (!is_alpha_chunk
) {
1083 avctx
->pix_fmt
= AV_PIX_FMT_ARGB
;
1086 ret
= bitstream_init8(&s
->bc
, data_start
, data_size
);
1090 if (!is_alpha_chunk
) {
1091 if (bitstream_read(&s
->bc
, 8) != 0x2F) {
1092 av_log(avctx
, AV_LOG_ERROR
, "Invalid WebP Lossless signature\n");
1093 return AVERROR_INVALIDDATA
;
1096 w
= bitstream_read(&s
->bc
, 14) + 1;
1097 h
= bitstream_read(&s
->bc
, 14) + 1;
1098 if (s
->width
&& s
->width
!= w
) {
1099 av_log(avctx
, AV_LOG_WARNING
, "Width mismatch. %d != %d\n",
1103 if (s
->height
&& s
->height
!= h
) {
1104 av_log(avctx
, AV_LOG_WARNING
, "Height mismatch. %d != %d\n",
1109 ret
= ff_set_dimensions(avctx
, s
->width
, s
->height
);
1113 s
->has_alpha
= bitstream_read_bit(&s
->bc
);
1115 if (bitstream_read(&s
->bc
, 3) != 0x0) {
1116 av_log(avctx
, AV_LOG_ERROR
, "Invalid WebP Lossless version\n");
1117 return AVERROR_INVALIDDATA
;
1120 if (!s
->width
|| !s
->height
)
1126 /* parse transformations */
1127 s
->nb_transforms
= 0;
1128 s
->reduced_width
= 0;
1130 while (bitstream_read_bit(&s
->bc
)) {
1131 enum TransformType transform
= bitstream_read(&s
->bc
, 2);
1132 s
->transforms
[s
->nb_transforms
++] = transform
;
1133 if (used
& (1 << transform
)) {
1134 av_log(avctx
, AV_LOG_ERROR
, "Transform %d used more than once\n",
1136 ret
= AVERROR_INVALIDDATA
;
1137 goto free_and_return
;
1139 used
|= (1 << transform
);
1140 switch (transform
) {
1141 case PREDICTOR_TRANSFORM
:
1142 ret
= parse_transform_predictor(s
);
1144 case COLOR_TRANSFORM
:
1145 ret
= parse_transform_color(s
);
1147 case COLOR_INDEXING_TRANSFORM
:
1148 ret
= parse_transform_color_indexing(s
);
1152 goto free_and_return
;
1155 /* decode primary image */
1156 s
->image
[IMAGE_ROLE_ARGB
].frame
= p
;
1158 s
->image
[IMAGE_ROLE_ARGB
].is_alpha_primary
= 1;
1159 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_ARGB
, w
, h
);
1161 goto free_and_return
;
1163 /* apply transformations */
1164 for (i
= s
->nb_transforms
- 1; i
>= 0; i
--) {
1165 switch (s
->transforms
[i
]) {
1166 case PREDICTOR_TRANSFORM
:
1167 ret
= apply_predictor_transform(s
);
1169 case COLOR_TRANSFORM
:
1170 ret
= apply_color_transform(s
);
1172 case SUBTRACT_GREEN
:
1173 ret
= apply_subtract_green_transform(s
);
1175 case COLOR_INDEXING_TRANSFORM
:
1176 ret
= apply_color_indexing_transform(s
);
1180 goto free_and_return
;
1184 p
->pict_type
= AV_PICTURE_TYPE_I
;
1189 for (i
= 0; i
< IMAGE_ROLE_NB
; i
++)
1190 image_ctx_free(&s
->image
[i
]);
1195 static void alpha_inverse_prediction(AVFrame
*frame
, enum AlphaFilter m
)
1200 ls
= frame
->linesize
[3];
1202 /* filter first row using horizontal filter */
1203 dec
= frame
->data
[3] + 1;
1204 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1207 /* filter first column using vertical filter */
1208 dec
= frame
->data
[3] + ls
;
1209 for (y
= 1; y
< frame
->height
; y
++, dec
+= ls
)
1210 *dec
+= *(dec
- ls
);
1212 /* filter the rest using the specified filter */
1214 case ALPHA_FILTER_HORIZONTAL
:
1215 for (y
= 1; y
< frame
->height
; y
++) {
1216 dec
= frame
->data
[3] + y
* ls
+ 1;
1217 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1221 case ALPHA_FILTER_VERTICAL
:
1222 for (y
= 1; y
< frame
->height
; y
++) {
1223 dec
= frame
->data
[3] + y
* ls
+ 1;
1224 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1225 *dec
+= *(dec
- ls
);
1228 case ALPHA_FILTER_GRADIENT
:
1229 for (y
= 1; y
< frame
->height
; y
++) {
1230 dec
= frame
->data
[3] + y
* ls
+ 1;
1231 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1232 dec
[0] += av_clip_uint8(*(dec
- 1) + *(dec
- ls
) - *(dec
- ls
- 1));
1238 static int vp8_lossy_decode_alpha(AVCodecContext
*avctx
, AVFrame
*p
,
1239 uint8_t *data_start
,
1240 unsigned int data_size
)
1242 WebPContext
*s
= avctx
->priv_data
;
1245 if (s
->alpha_compression
== ALPHA_COMPRESSION_NONE
) {
1248 bytestream2_init(&gb
, data_start
, data_size
);
1249 for (y
= 0; y
< s
->height
; y
++)
1250 bytestream2_get_buffer(&gb
, p
->data
[3] + p
->linesize
[3] * y
,
1252 } else if (s
->alpha_compression
== ALPHA_COMPRESSION_VP8L
) {
1254 int alpha_got_frame
= 0;
1256 s
->alpha_frame
= av_frame_alloc();
1257 if (!s
->alpha_frame
)
1258 return AVERROR(ENOMEM
);
1260 ret
= vp8_lossless_decode_frame(avctx
, s
->alpha_frame
, &alpha_got_frame
,
1261 data_start
, data_size
, 1);
1263 av_frame_free(&s
->alpha_frame
);
1266 if (!alpha_got_frame
) {
1267 av_frame_free(&s
->alpha_frame
);
1268 return AVERROR_INVALIDDATA
;
1271 /* copy green component of alpha image to alpha plane of primary image */
1272 for (y
= 0; y
< s
->height
; y
++) {
1273 ap
= GET_PIXEL(s
->alpha_frame
, 0, y
) + 2;
1274 pp
= p
->data
[3] + p
->linesize
[3] * y
;
1275 for (x
= 0; x
< s
->width
; x
++) {
1281 av_frame_free(&s
->alpha_frame
);
1284 /* apply alpha filtering */
1285 if (s
->alpha_filter
)
1286 alpha_inverse_prediction(p
, s
->alpha_filter
);
1291 static int vp8_lossy_decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
1292 int *got_frame
, uint8_t *data_start
,
1293 unsigned int data_size
)
1295 WebPContext
*s
= avctx
->priv_data
;
1299 if (!s
->initialized
) {
1300 ff_vp8_decode_init(avctx
);
1303 avctx
->pix_fmt
= AV_PIX_FMT_YUVA420P
;
1307 if (data_size
> INT_MAX
) {
1308 av_log(avctx
, AV_LOG_ERROR
, "unsupported chunk size\n");
1309 return AVERROR_PATCHWELCOME
;
1312 av_init_packet(&pkt
);
1313 pkt
.data
= data_start
;
1314 pkt
.size
= data_size
;
1316 ret
= ff_vp8_decode_frame(avctx
, p
, got_frame
, &pkt
);
1318 ret
= vp8_lossy_decode_alpha(avctx
, p
, s
->alpha_data
,
1319 s
->alpha_data_size
);
1326 static int webp_decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
1329 AVFrame
* const p
= data
;
1330 WebPContext
*s
= avctx
->priv_data
;
1333 uint32_t chunk_type
, chunk_size
;
1341 bytestream2_init(&gb
, avpkt
->data
, avpkt
->size
);
1343 if (bytestream2_get_bytes_left(&gb
) < 12)
1344 return AVERROR_INVALIDDATA
;
1346 if (bytestream2_get_le32(&gb
) != MKTAG('R', 'I', 'F', 'F')) {
1347 av_log(avctx
, AV_LOG_ERROR
, "missing RIFF tag\n");
1348 return AVERROR_INVALIDDATA
;
1351 chunk_size
= bytestream2_get_le32(&gb
);
1352 if (bytestream2_get_bytes_left(&gb
) < chunk_size
)
1353 return AVERROR_INVALIDDATA
;
1355 if (bytestream2_get_le32(&gb
) != MKTAG('W', 'E', 'B', 'P')) {
1356 av_log(avctx
, AV_LOG_ERROR
, "missing WEBP tag\n");
1357 return AVERROR_INVALIDDATA
;
1360 while (bytestream2_get_bytes_left(&gb
) > 8) {
1361 char chunk_str
[5] = { 0 };
1363 chunk_type
= bytestream2_get_le32(&gb
);
1364 chunk_size
= bytestream2_get_le32(&gb
);
1365 if (chunk_size
== UINT32_MAX
)
1366 return AVERROR_INVALIDDATA
;
1367 chunk_size
+= chunk_size
& 1;
1369 if (bytestream2_get_bytes_left(&gb
) < chunk_size
)
1370 return AVERROR_INVALIDDATA
;
1372 switch (chunk_type
) {
1373 case MKTAG('V', 'P', '8', ' '):
1375 ret
= vp8_lossy_decode_frame(avctx
, p
, got_frame
,
1376 avpkt
->data
+ bytestream2_tell(&gb
),
1381 bytestream2_skip(&gb
, chunk_size
);
1383 case MKTAG('V', 'P', '8', 'L'):
1385 ret
= vp8_lossless_decode_frame(avctx
, p
, got_frame
,
1386 avpkt
->data
+ bytestream2_tell(&gb
),
1391 bytestream2_skip(&gb
, chunk_size
);
1393 case MKTAG('V', 'P', '8', 'X'):
1394 vp8x_flags
= bytestream2_get_byte(&gb
);
1395 bytestream2_skip(&gb
, 3);
1396 s
->width
= bytestream2_get_le24(&gb
) + 1;
1397 s
->height
= bytestream2_get_le24(&gb
) + 1;
1398 ret
= av_image_check_size(s
->width
, s
->height
, 0, avctx
);
1402 case MKTAG('A', 'L', 'P', 'H'): {
1403 int alpha_header
, filter_m
, compression
;
1405 if (!(vp8x_flags
& VP8X_FLAG_ALPHA
)) {
1406 av_log(avctx
, AV_LOG_WARNING
,
1407 "ALPHA chunk present, but alpha bit not set in the "
1410 if (chunk_size
== 0) {
1411 av_log(avctx
, AV_LOG_ERROR
, "invalid ALPHA chunk size\n");
1412 return AVERROR_INVALIDDATA
;
1414 alpha_header
= bytestream2_get_byte(&gb
);
1415 s
->alpha_data
= avpkt
->data
+ bytestream2_tell(&gb
);
1416 s
->alpha_data_size
= chunk_size
- 1;
1417 bytestream2_skip(&gb
, s
->alpha_data_size
);
1419 filter_m
= (alpha_header
>> 2) & 0x03;
1420 compression
= alpha_header
& 0x03;
1422 if (compression
> ALPHA_COMPRESSION_VP8L
) {
1423 av_log(avctx
, AV_LOG_VERBOSE
,
1424 "skipping unsupported ALPHA chunk\n");
1427 s
->alpha_compression
= compression
;
1428 s
->alpha_filter
= filter_m
;
1433 case MKTAG('I', 'C', 'C', 'P'):
1434 case MKTAG('A', 'N', 'I', 'M'):
1435 case MKTAG('A', 'N', 'M', 'F'):
1436 case MKTAG('E', 'X', 'I', 'F'):
1437 case MKTAG('X', 'M', 'P', ' '):
1438 AV_WL32(chunk_str
, chunk_type
);
1439 av_log(avctx
, AV_LOG_VERBOSE
, "skipping unsupported chunk: %s\n",
1441 bytestream2_skip(&gb
, chunk_size
);
1444 AV_WL32(chunk_str
, chunk_type
);
1445 av_log(avctx
, AV_LOG_VERBOSE
, "skipping unknown chunk: %s\n",
1447 bytestream2_skip(&gb
, chunk_size
);
1453 av_log(avctx
, AV_LOG_ERROR
, "image data not found\n");
1454 return AVERROR_INVALIDDATA
;
1460 static av_cold
int webp_decode_close(AVCodecContext
*avctx
)
1462 WebPContext
*s
= avctx
->priv_data
;
1465 return ff_vp8_decode_free(avctx
);
1470 AVCodec ff_webp_decoder
= {
1472 .long_name
= NULL_IF_CONFIG_SMALL("WebP image"),
1473 .type
= AVMEDIA_TYPE_VIDEO
,
1474 .id
= AV_CODEC_ID_WEBP
,
1475 .priv_data_size
= sizeof(WebPContext
),
1476 .decode
= webp_decode_frame
,
1477 .close
= webp_decode_close
,
1478 .capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_FRAME_THREADS
,