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 FFmpeg.
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.
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.
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
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
34 * @author James Almer <jamrial@gmail.com>
43 #include "libavutil/imgutils.h"
44 #include "libavutil/mem.h"
46 #define BITSTREAM_READER_LE
48 #include "bytestream.h"
49 #include "codec_internal.h"
54 #include "tiff_common.h"
57 #define VP8X_FLAG_ANIMATION 0x02
58 #define VP8X_FLAG_XMP_METADATA 0x04
59 #define VP8X_FLAG_EXIF_METADATA 0x08
60 #define VP8X_FLAG_ALPHA 0x10
61 #define VP8X_FLAG_ICC 0x20
63 #define MAX_PALETTE_SIZE 256
64 #define MAX_CACHE_BITS 11
65 #define NUM_CODE_LENGTH_CODES 19
66 #define HUFFMAN_CODES_PER_META_CODE 5
67 #define NUM_LITERAL_CODES 256
68 #define NUM_LENGTH_CODES 24
69 #define NUM_DISTANCE_CODES 40
70 #define NUM_SHORT_DISTANCES 120
71 #define MAX_HUFFMAN_CODE_LENGTH 15
73 static const uint16_t alphabet_sizes
[HUFFMAN_CODES_PER_META_CODE
] = {
74 NUM_LITERAL_CODES
+ NUM_LENGTH_CODES
,
75 NUM_LITERAL_CODES
, NUM_LITERAL_CODES
, NUM_LITERAL_CODES
,
79 static const uint8_t code_length_code_order
[NUM_CODE_LENGTH_CODES
] = {
80 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
83 static const int8_t lz77_distance_offsets
[NUM_SHORT_DISTANCES
][2] = {
84 { 0, 1 }, { 1, 0 }, { 1, 1 }, { -1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { -1, 2 },
85 { 2, 1 }, { -2, 1 }, { 2, 2 }, { -2, 2 }, { 0, 3 }, { 3, 0 }, { 1, 3 }, { -1, 3 },
86 { 3, 1 }, { -3, 1 }, { 2, 3 }, { -2, 3 }, { 3, 2 }, { -3, 2 }, { 0, 4 }, { 4, 0 },
87 { 1, 4 }, { -1, 4 }, { 4, 1 }, { -4, 1 }, { 3, 3 }, { -3, 3 }, { 2, 4 }, { -2, 4 },
88 { 4, 2 }, { -4, 2 }, { 0, 5 }, { 3, 4 }, { -3, 4 }, { 4, 3 }, { -4, 3 }, { 5, 0 },
89 { 1, 5 }, { -1, 5 }, { 5, 1 }, { -5, 1 }, { 2, 5 }, { -2, 5 }, { 5, 2 }, { -5, 2 },
90 { 4, 4 }, { -4, 4 }, { 3, 5 }, { -3, 5 }, { 5, 3 }, { -5, 3 }, { 0, 6 }, { 6, 0 },
91 { 1, 6 }, { -1, 6 }, { 6, 1 }, { -6, 1 }, { 2, 6 }, { -2, 6 }, { 6, 2 }, { -6, 2 },
92 { 4, 5 }, { -4, 5 }, { 5, 4 }, { -5, 4 }, { 3, 6 }, { -3, 6 }, { 6, 3 }, { -6, 3 },
93 { 0, 7 }, { 7, 0 }, { 1, 7 }, { -1, 7 }, { 5, 5 }, { -5, 5 }, { 7, 1 }, { -7, 1 },
94 { 4, 6 }, { -4, 6 }, { 6, 4 }, { -6, 4 }, { 2, 7 }, { -2, 7 }, { 7, 2 }, { -7, 2 },
95 { 3, 7 }, { -3, 7 }, { 7, 3 }, { -7, 3 }, { 5, 6 }, { -5, 6 }, { 6, 5 }, { -6, 5 },
96 { 8, 0 }, { 4, 7 }, { -4, 7 }, { 7, 4 }, { -7, 4 }, { 8, 1 }, { 8, 2 }, { 6, 6 },
97 { -6, 6 }, { 8, 3 }, { 5, 7 }, { -5, 7 }, { 7, 5 }, { -7, 5 }, { 8, 4 }, { 6, 7 },
98 { -6, 7 }, { 7, 6 }, { -7, 6 }, { 8, 5 }, { 7, 7 }, { -7, 7 }, { 8, 6 }, { 8, 7 }
101 enum AlphaCompression
{
102 ALPHA_COMPRESSION_NONE
,
103 ALPHA_COMPRESSION_VP8L
,
108 ALPHA_FILTER_HORIZONTAL
,
109 ALPHA_FILTER_VERTICAL
,
110 ALPHA_FILTER_GRADIENT
,
114 PREDICTOR_TRANSFORM
= 0,
117 COLOR_INDEXING_TRANSFORM
= 3,
120 enum PredictionMode
{
126 PRED_MODE_AVG_T_AVG_L_TR
,
131 PRED_MODE_AVG_AVG_L_TL_AVG_T_TR
,
133 PRED_MODE_ADD_SUBTRACT_FULL
,
134 PRED_MODE_ADD_SUBTRACT_HALF
,
145 /* The structure of WebP lossless is an optional series of transformation data,
146 * followed by the primary image. The primary image also optionally contains
147 * an entropy group mapping if there are multiple entropy groups. There is a
148 * basic image type called an "entropy coded image" that is used for all of
149 * these. The type of each entropy coded image is referred to by the
150 * specification as its role. */
152 /* Primary Image: Stores the actual pixels of the image. */
155 /* Entropy Image: Defines which Huffman group to use for different areas of
156 * the primary image. */
159 /* Predictors: Defines which predictor type to use for different areas of
160 * the primary image. */
161 IMAGE_ROLE_PREDICTOR
,
163 /* Color Transform Data: Defines the color transformation for different
164 * areas of the primary image. */
165 IMAGE_ROLE_COLOR_TRANSFORM
,
167 /* Color Index: Stored as an image of height == 1. */
168 IMAGE_ROLE_COLOR_INDEXING
,
173 typedef struct HuffReader
{
174 VLC vlc
; /* Huffman decoder context */
175 int simple
; /* whether to use simple mode */
176 int nb_symbols
; /* number of coded symbols */
177 uint16_t simple_symbols
[2]; /* symbols for simple mode */
180 typedef struct ImageContext
{
181 enum ImageRole role
; /* role of this image */
182 AVFrame
*frame
; /* AVFrame for data */
183 int color_cache_bits
; /* color cache size, log2 */
184 uint32_t *color_cache
; /* color cache data */
185 int nb_huffman_groups
; /* number of huffman groups */
186 HuffReader
*huffman_groups
; /* reader for each huffman group */
187 /* relative size compared to primary image, log2.
188 * for IMAGE_ROLE_COLOR_INDEXING with <= 16 colors, this is log2 of the
189 * number of pixels per byte in the primary image (pixel packing) */
191 int is_alpha_primary
;
194 typedef struct WebPContext
{
195 VP8Context v
; /* VP8 Context used for lossy decoding */
196 GetBitContext gb
; /* bitstream reader for main image chunk */
197 AVFrame
*alpha_frame
; /* AVFrame for alpha data decompressed from VP8L */
198 AVPacket
*pkt
; /* AVPacket to be passed to the underlying VP8 decoder */
199 AVCodecContext
*avctx
; /* parent AVCodecContext */
200 int initialized
; /* set once the VP8 context is initialized */
201 int has_alpha
; /* has a separate alpha chunk */
202 enum AlphaCompression alpha_compression
; /* compression type for alpha chunk */
203 enum AlphaFilter alpha_filter
; /* filtering method for alpha chunk */
204 const uint8_t *alpha_data
; /* alpha chunk data */
205 int alpha_data_size
; /* alpha chunk data size */
206 int has_exif
; /* set after an EXIF chunk has been processed */
207 int has_iccp
; /* set after an ICCP chunk has been processed */
208 int width
; /* image width */
209 int height
; /* image height */
210 int lossless
; /* indicates lossless or lossy */
212 int nb_transforms
; /* number of transforms */
213 enum TransformType transforms
[4]; /* transformations used in the image, in order */
214 /* reduced width when using a color indexing transform with <= 16 colors (pixel packing)
215 * before pixels are unpacked, or same as width otherwise. */
217 int nb_huffman_groups
; /* number of huffman groups in the primary image */
218 ImageContext image
[IMAGE_ROLE_NB
]; /* image context for each role */
221 #define GET_PIXEL(frame, x, y) \
222 ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
224 #define GET_PIXEL_COMP(frame, x, y, c) \
225 (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
227 static void image_ctx_free(ImageContext
*img
)
231 av_free(img
->color_cache
);
232 if (img
->role
!= IMAGE_ROLE_ARGB
&& !img
->is_alpha_primary
)
233 av_frame_free(&img
->frame
);
234 if (img
->huffman_groups
) {
235 for (i
= 0; i
< img
->nb_huffman_groups
; i
++) {
236 for (j
= 0; j
< HUFFMAN_CODES_PER_META_CODE
; j
++)
237 ff_vlc_free(&img
->huffman_groups
[i
* HUFFMAN_CODES_PER_META_CODE
+ j
].vlc
);
239 av_free(img
->huffman_groups
);
241 memset(img
, 0, sizeof(*img
));
244 static int huff_reader_get_symbol(HuffReader
*r
, GetBitContext
*gb
)
247 if (r
->nb_symbols
== 1)
248 return r
->simple_symbols
[0];
250 return r
->simple_symbols
[get_bits1(gb
)];
252 return get_vlc2(gb
, r
->vlc
.table
, 8, 2);
255 static int huff_reader_build_canonical(HuffReader
*r
, const uint8_t *code_lengths
,
258 int len
= 0, sym
, code
= 0, ret
;
259 int max_code_length
= 0;
262 /* special-case 1 symbol since the vlc reader cannot handle it */
263 for (sym
= 0; sym
< alphabet_size
; sym
++) {
264 if (code_lengths
[sym
] > 0) {
273 r
->simple_symbols
[0] = code
;
278 for (sym
= 0; sym
< alphabet_size
; sym
++)
279 max_code_length
= FFMAX(max_code_length
, code_lengths
[sym
]);
281 if (max_code_length
== 0 || max_code_length
> MAX_HUFFMAN_CODE_LENGTH
)
282 return AVERROR(EINVAL
);
284 codes
= av_malloc_array(alphabet_size
, sizeof(*codes
));
286 return AVERROR(ENOMEM
);
290 for (len
= 1; len
<= max_code_length
; len
++) {
291 for (sym
= 0; sym
< alphabet_size
; sym
++) {
292 if (code_lengths
[sym
] != len
)
299 if (!r
->nb_symbols
) {
301 return AVERROR_INVALIDDATA
;
304 ret
= vlc_init(&r
->vlc
, 8, alphabet_size
,
305 code_lengths
, sizeof(*code_lengths
), sizeof(*code_lengths
),
306 codes
, sizeof(*codes
), sizeof(*codes
), VLC_INIT_OUTPUT_LE
);
317 static void read_huffman_code_simple(WebPContext
*s
, HuffReader
*hc
)
319 hc
->nb_symbols
= get_bits1(&s
->gb
) + 1;
321 if (get_bits1(&s
->gb
))
322 hc
->simple_symbols
[0] = get_bits(&s
->gb
, 8);
324 hc
->simple_symbols
[0] = get_bits1(&s
->gb
);
326 if (hc
->nb_symbols
== 2)
327 hc
->simple_symbols
[1] = get_bits(&s
->gb
, 8);
332 static int read_huffman_code_normal(WebPContext
*s
, HuffReader
*hc
,
335 HuffReader code_len_hc
= { { 0 }, 0, 0, { 0 } };
336 uint8_t *code_lengths
;
337 uint8_t code_length_code_lengths
[NUM_CODE_LENGTH_CODES
] = { 0 };
338 int i
, symbol
, max_symbol
, prev_code_len
, ret
;
339 int num_codes
= 4 + get_bits(&s
->gb
, 4);
341 av_assert1(num_codes
<= NUM_CODE_LENGTH_CODES
);
343 for (i
= 0; i
< num_codes
; i
++)
344 code_length_code_lengths
[code_length_code_order
[i
]] = get_bits(&s
->gb
, 3);
346 ret
= huff_reader_build_canonical(&code_len_hc
, code_length_code_lengths
,
347 NUM_CODE_LENGTH_CODES
);
351 code_lengths
= av_mallocz(alphabet_size
);
353 ret
= AVERROR(ENOMEM
);
357 if (get_bits1(&s
->gb
)) {
358 int bits
= 2 + 2 * get_bits(&s
->gb
, 3);
359 max_symbol
= 2 + get_bits(&s
->gb
, bits
);
360 if (max_symbol
> alphabet_size
) {
361 av_log(s
->avctx
, AV_LOG_ERROR
, "max symbol %d > alphabet size %d\n",
362 max_symbol
, alphabet_size
);
363 ret
= AVERROR_INVALIDDATA
;
367 max_symbol
= alphabet_size
;
372 while (symbol
< alphabet_size
) {
377 code_len
= huff_reader_get_symbol(&code_len_hc
, &s
->gb
);
379 /* Code length code [0..15] indicates literal code lengths. */
380 code_lengths
[symbol
++] = code_len
;
382 prev_code_len
= code_len
;
384 int repeat
= 0, length
= 0;
387 /* Code 16 repeats the previous non-zero value [3..6] times,
388 * i.e., 3 + ReadBits(2) times. If code 16 is used before a
389 * non-zero value has been emitted, a value of 8 is repeated. */
390 repeat
= 3 + get_bits(&s
->gb
, 2);
391 length
= prev_code_len
;
394 /* Code 17 emits a streak of zeros [3..10], i.e.,
395 * 3 + ReadBits(3) times. */
396 repeat
= 3 + get_bits(&s
->gb
, 3);
399 /* Code 18 emits a streak of zeros of length [11..138], i.e.,
400 * 11 + ReadBits(7) times. */
401 repeat
= 11 + get_bits(&s
->gb
, 7);
404 if (symbol
+ repeat
> alphabet_size
) {
405 av_log(s
->avctx
, AV_LOG_ERROR
,
406 "invalid symbol %d + repeat %d > alphabet size %d\n",
407 symbol
, repeat
, alphabet_size
);
408 ret
= AVERROR_INVALIDDATA
;
412 code_lengths
[symbol
++] = length
;
416 ret
= huff_reader_build_canonical(hc
, code_lengths
, alphabet_size
);
419 ff_vlc_free(&code_len_hc
.vlc
);
420 av_free(code_lengths
);
424 static int decode_entropy_coded_image(WebPContext
*s
, enum ImageRole role
,
427 #define PARSE_BLOCK_SIZE(w, h) do { \
428 block_bits = get_bits(&s->gb, 3) + 2; \
429 blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \
430 blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \
433 static int decode_entropy_image(WebPContext
*s
)
436 int ret
, block_bits
, blocks_w
, blocks_h
, x
, y
, max
;
438 PARSE_BLOCK_SIZE(s
->reduced_width
, s
->height
);
440 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_ENTROPY
, blocks_w
, blocks_h
);
444 img
= &s
->image
[IMAGE_ROLE_ENTROPY
];
445 img
->size_reduction
= block_bits
;
447 /* the number of huffman groups is determined by the maximum group number
448 * coded in the entropy image */
450 for (y
= 0; y
< img
->frame
->height
; y
++) {
451 for (x
= 0; x
< img
->frame
->width
; x
++) {
452 int p0
= GET_PIXEL_COMP(img
->frame
, x
, y
, 1);
453 int p1
= GET_PIXEL_COMP(img
->frame
, x
, y
, 2);
454 int p
= p0
<< 8 | p1
;
458 s
->nb_huffman_groups
= max
+ 1;
463 static int parse_transform_predictor(WebPContext
*s
)
465 int block_bits
, blocks_w
, blocks_h
, ret
;
467 PARSE_BLOCK_SIZE(s
->reduced_width
, s
->height
);
469 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_PREDICTOR
, blocks_w
,
474 s
->image
[IMAGE_ROLE_PREDICTOR
].size_reduction
= block_bits
;
479 static int parse_transform_color(WebPContext
*s
)
481 int block_bits
, blocks_w
, blocks_h
, ret
;
483 PARSE_BLOCK_SIZE(s
->reduced_width
, s
->height
);
485 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_COLOR_TRANSFORM
, blocks_w
,
490 s
->image
[IMAGE_ROLE_COLOR_TRANSFORM
].size_reduction
= block_bits
;
495 static int parse_transform_color_indexing(WebPContext
*s
)
498 int width_bits
, index_size
, ret
, x
;
501 index_size
= get_bits(&s
->gb
, 8) + 1;
505 else if (index_size
<= 4)
507 else if (index_size
<= 16)
512 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_COLOR_INDEXING
,
517 img
= &s
->image
[IMAGE_ROLE_COLOR_INDEXING
];
518 img
->size_reduction
= width_bits
;
520 s
->reduced_width
= (s
->width
+ ((1 << width_bits
) - 1)) >> width_bits
;
522 /* color index values are delta-coded */
523 ct
= img
->frame
->data
[0] + 4;
524 for (x
= 4; x
< img
->frame
->width
* 4; x
++, ct
++)
530 static HuffReader
*get_huffman_group(WebPContext
*s
, ImageContext
*img
,
533 ImageContext
*gimg
= &s
->image
[IMAGE_ROLE_ENTROPY
];
536 if (gimg
->size_reduction
> 0) {
537 int group_x
= x
>> gimg
->size_reduction
;
538 int group_y
= y
>> gimg
->size_reduction
;
539 int g0
= GET_PIXEL_COMP(gimg
->frame
, group_x
, group_y
, 1);
540 int g1
= GET_PIXEL_COMP(gimg
->frame
, group_x
, group_y
, 2);
541 group
= g0
<< 8 | g1
;
544 return &img
->huffman_groups
[group
* HUFFMAN_CODES_PER_META_CODE
];
547 static av_always_inline
void color_cache_put(ImageContext
*img
, uint32_t c
)
549 uint32_t cache_idx
= (0x1E35A7BD * c
) >> (32 - img
->color_cache_bits
);
550 img
->color_cache
[cache_idx
] = c
;
553 static int decode_entropy_coded_image(WebPContext
*s
, enum ImageRole role
,
558 int i
, j
, ret
, x
, y
, width
;
560 img
= &s
->image
[role
];
564 img
->frame
= av_frame_alloc();
566 return AVERROR(ENOMEM
);
569 img
->frame
->format
= AV_PIX_FMT_ARGB
;
570 img
->frame
->width
= w
;
571 img
->frame
->height
= h
;
573 if (role
== IMAGE_ROLE_ARGB
&& !img
->is_alpha_primary
) {
574 ret
= ff_thread_get_buffer(s
->avctx
, img
->frame
, 0);
576 ret
= av_frame_get_buffer(img
->frame
, 1);
580 if (get_bits1(&s
->gb
)) {
581 img
->color_cache_bits
= get_bits(&s
->gb
, 4);
582 if (img
->color_cache_bits
< 1 || img
->color_cache_bits
> 11) {
583 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid color cache bits: %d\n",
584 img
->color_cache_bits
);
585 return AVERROR_INVALIDDATA
;
587 img
->color_cache
= av_calloc(1 << img
->color_cache_bits
,
588 sizeof(*img
->color_cache
));
589 if (!img
->color_cache
)
590 return AVERROR(ENOMEM
);
592 img
->color_cache_bits
= 0;
595 img
->nb_huffman_groups
= 1;
596 if (role
== IMAGE_ROLE_ARGB
&& get_bits1(&s
->gb
)) {
597 ret
= decode_entropy_image(s
);
600 img
->nb_huffman_groups
= s
->nb_huffman_groups
;
602 img
->huffman_groups
= av_calloc(img
->nb_huffman_groups
,
603 HUFFMAN_CODES_PER_META_CODE
*
604 sizeof(*img
->huffman_groups
));
605 if (!img
->huffman_groups
)
606 return AVERROR(ENOMEM
);
608 for (i
= 0; i
< img
->nb_huffman_groups
; i
++) {
609 hg
= &img
->huffman_groups
[i
* HUFFMAN_CODES_PER_META_CODE
];
610 for (j
= 0; j
< HUFFMAN_CODES_PER_META_CODE
; j
++) {
611 int alphabet_size
= alphabet_sizes
[j
];
612 if (!j
&& img
->color_cache_bits
> 0)
613 alphabet_size
+= 1 << img
->color_cache_bits
;
615 if (get_bits1(&s
->gb
)) {
616 read_huffman_code_simple(s
, &hg
[j
]);
618 ret
= read_huffman_code_normal(s
, &hg
[j
], alphabet_size
);
625 width
= img
->frame
->width
;
626 if (role
== IMAGE_ROLE_ARGB
)
627 width
= s
->reduced_width
;
630 while (y
< img
->frame
->height
) {
633 if (get_bits_left(&s
->gb
) < 0)
634 return AVERROR_INVALIDDATA
;
636 hg
= get_huffman_group(s
, img
, x
, y
);
637 v
= huff_reader_get_symbol(&hg
[HUFF_IDX_GREEN
], &s
->gb
);
638 if (v
< NUM_LITERAL_CODES
) {
639 /* literal pixel values */
640 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
642 p
[1] = huff_reader_get_symbol(&hg
[HUFF_IDX_RED
], &s
->gb
);
643 p
[3] = huff_reader_get_symbol(&hg
[HUFF_IDX_BLUE
], &s
->gb
);
644 p
[0] = huff_reader_get_symbol(&hg
[HUFF_IDX_ALPHA
], &s
->gb
);
645 if (img
->color_cache_bits
)
646 color_cache_put(img
, AV_RB32(p
));
652 } else if (v
< NUM_LITERAL_CODES
+ NUM_LENGTH_CODES
) {
653 /* LZ77 backwards mapping */
654 int prefix_code
, length
, distance
, ref_x
, ref_y
;
656 /* parse length and distance */
657 prefix_code
= v
- NUM_LITERAL_CODES
;
658 if (prefix_code
< 4) {
659 length
= prefix_code
+ 1;
661 int extra_bits
= (prefix_code
- 2) >> 1;
662 int offset
= 2 + (prefix_code
& 1) << extra_bits
;
663 length
= offset
+ get_bits(&s
->gb
, extra_bits
) + 1;
665 prefix_code
= huff_reader_get_symbol(&hg
[HUFF_IDX_DIST
], &s
->gb
);
666 if (prefix_code
> 39U) {
667 av_log(s
->avctx
, AV_LOG_ERROR
,
668 "distance prefix code too large: %d\n", prefix_code
);
669 return AVERROR_INVALIDDATA
;
671 if (prefix_code
< 4) {
672 distance
= prefix_code
+ 1;
674 int extra_bits
= prefix_code
- 2 >> 1;
675 int offset
= 2 + (prefix_code
& 1) << extra_bits
;
676 distance
= offset
+ get_bits(&s
->gb
, extra_bits
) + 1;
679 /* find reference location */
680 if (distance
<= NUM_SHORT_DISTANCES
) {
681 int xi
= lz77_distance_offsets
[distance
- 1][0];
682 int yi
= lz77_distance_offsets
[distance
- 1][1];
683 distance
= FFMAX(1, xi
+ yi
* width
);
685 distance
-= NUM_SHORT_DISTANCES
;
696 while (distance
>= width
) {
701 ref_x
= width
- distance
;
704 ref_x
= FFMAX(0, ref_x
);
705 ref_y
= FFMAX(0, ref_y
);
707 if (ref_y
== y
&& ref_x
>= x
)
708 return AVERROR_INVALIDDATA
;
711 * source and dest regions can overlap and wrap lines, so just
713 for (i
= 0; i
< length
; i
++) {
714 uint8_t *p_ref
= GET_PIXEL(img
->frame
, ref_x
, ref_y
);
715 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
718 if (img
->color_cache_bits
)
719 color_cache_put(img
, AV_RB32(p
));
726 if (ref_x
== width
) {
730 if (y
== img
->frame
->height
|| ref_y
== img
->frame
->height
)
734 /* read from color cache */
735 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
736 int cache_idx
= v
- (NUM_LITERAL_CODES
+ NUM_LENGTH_CODES
);
738 if (!img
->color_cache_bits
) {
739 av_log(s
->avctx
, AV_LOG_ERROR
, "color cache not found\n");
740 return AVERROR_INVALIDDATA
;
742 if (cache_idx
>= 1 << img
->color_cache_bits
) {
743 av_log(s
->avctx
, AV_LOG_ERROR
,
744 "color cache index out-of-bounds\n");
745 return AVERROR_INVALIDDATA
;
747 AV_WB32(p
, img
->color_cache
[cache_idx
]);
759 /* PRED_MODE_BLACK */
760 static void inv_predict_0(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
761 const uint8_t *p_t
, const uint8_t *p_tr
)
763 AV_WB32(p
, 0xFF000000);
767 static void inv_predict_1(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
768 const uint8_t *p_t
, const uint8_t *p_tr
)
774 static void inv_predict_2(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
775 const uint8_t *p_t
, const uint8_t *p_tr
)
781 static void inv_predict_3(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
782 const uint8_t *p_t
, const uint8_t *p_tr
)
788 static void inv_predict_4(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
789 const uint8_t *p_t
, const uint8_t *p_tr
)
794 /* PRED_MODE_AVG_T_AVG_L_TR */
795 static void inv_predict_5(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
796 const uint8_t *p_t
, const uint8_t *p_tr
)
798 p
[0] = p_t
[0] + (p_l
[0] + p_tr
[0] >> 1) >> 1;
799 p
[1] = p_t
[1] + (p_l
[1] + p_tr
[1] >> 1) >> 1;
800 p
[2] = p_t
[2] + (p_l
[2] + p_tr
[2] >> 1) >> 1;
801 p
[3] = p_t
[3] + (p_l
[3] + p_tr
[3] >> 1) >> 1;
804 /* PRED_MODE_AVG_L_TL */
805 static void inv_predict_6(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
806 const uint8_t *p_t
, const uint8_t *p_tr
)
808 p
[0] = p_l
[0] + p_tl
[0] >> 1;
809 p
[1] = p_l
[1] + p_tl
[1] >> 1;
810 p
[2] = p_l
[2] + p_tl
[2] >> 1;
811 p
[3] = p_l
[3] + p_tl
[3] >> 1;
814 /* PRED_MODE_AVG_L_T */
815 static void inv_predict_7(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
816 const uint8_t *p_t
, const uint8_t *p_tr
)
818 p
[0] = p_l
[0] + p_t
[0] >> 1;
819 p
[1] = p_l
[1] + p_t
[1] >> 1;
820 p
[2] = p_l
[2] + p_t
[2] >> 1;
821 p
[3] = p_l
[3] + p_t
[3] >> 1;
824 /* PRED_MODE_AVG_TL_T */
825 static void inv_predict_8(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
826 const uint8_t *p_t
, const uint8_t *p_tr
)
828 p
[0] = p_tl
[0] + p_t
[0] >> 1;
829 p
[1] = p_tl
[1] + p_t
[1] >> 1;
830 p
[2] = p_tl
[2] + p_t
[2] >> 1;
831 p
[3] = p_tl
[3] + p_t
[3] >> 1;
834 /* PRED_MODE_AVG_T_TR */
835 static void inv_predict_9(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
836 const uint8_t *p_t
, const uint8_t *p_tr
)
838 p
[0] = p_t
[0] + p_tr
[0] >> 1;
839 p
[1] = p_t
[1] + p_tr
[1] >> 1;
840 p
[2] = p_t
[2] + p_tr
[2] >> 1;
841 p
[3] = p_t
[3] + p_tr
[3] >> 1;
844 /* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
845 static void inv_predict_10(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
846 const uint8_t *p_t
, const uint8_t *p_tr
)
848 p
[0] = (p_l
[0] + p_tl
[0] >> 1) + (p_t
[0] + p_tr
[0] >> 1) >> 1;
849 p
[1] = (p_l
[1] + p_tl
[1] >> 1) + (p_t
[1] + p_tr
[1] >> 1) >> 1;
850 p
[2] = (p_l
[2] + p_tl
[2] >> 1) + (p_t
[2] + p_tr
[2] >> 1) >> 1;
851 p
[3] = (p_l
[3] + p_tl
[3] >> 1) + (p_t
[3] + p_tr
[3] >> 1) >> 1;
854 /* PRED_MODE_SELECT */
855 static void inv_predict_11(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
856 const uint8_t *p_t
, const uint8_t *p_tr
)
858 int diff
= (FFABS(p_l
[0] - p_tl
[0]) - FFABS(p_t
[0] - p_tl
[0])) +
859 (FFABS(p_l
[1] - p_tl
[1]) - FFABS(p_t
[1] - p_tl
[1])) +
860 (FFABS(p_l
[2] - p_tl
[2]) - FFABS(p_t
[2] - p_tl
[2])) +
861 (FFABS(p_l
[3] - p_tl
[3]) - FFABS(p_t
[3] - p_tl
[3]));
868 /* PRED_MODE_ADD_SUBTRACT_FULL */
869 static void inv_predict_12(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
870 const uint8_t *p_t
, const uint8_t *p_tr
)
872 p
[0] = av_clip_uint8(p_l
[0] + p_t
[0] - p_tl
[0]);
873 p
[1] = av_clip_uint8(p_l
[1] + p_t
[1] - p_tl
[1]);
874 p
[2] = av_clip_uint8(p_l
[2] + p_t
[2] - p_tl
[2]);
875 p
[3] = av_clip_uint8(p_l
[3] + p_t
[3] - p_tl
[3]);
878 static av_always_inline
uint8_t clamp_add_subtract_half(int a
, int b
, int c
)
881 return av_clip_uint8(d
+ (d
- c
) / 2);
884 /* PRED_MODE_ADD_SUBTRACT_HALF */
885 static void inv_predict_13(uint8_t *p
, const uint8_t *p_l
, const uint8_t *p_tl
,
886 const uint8_t *p_t
, const uint8_t *p_tr
)
888 p
[0] = clamp_add_subtract_half(p_l
[0], p_t
[0], p_tl
[0]);
889 p
[1] = clamp_add_subtract_half(p_l
[1], p_t
[1], p_tl
[1]);
890 p
[2] = clamp_add_subtract_half(p_l
[2], p_t
[2], p_tl
[2]);
891 p
[3] = clamp_add_subtract_half(p_l
[3], p_t
[3], p_tl
[3]);
894 typedef void (*inv_predict_func
)(uint8_t *p
, const uint8_t *p_l
,
895 const uint8_t *p_tl
, const uint8_t *p_t
,
896 const uint8_t *p_tr
);
898 static const inv_predict_func inverse_predict
[14] = {
899 inv_predict_0
, inv_predict_1
, inv_predict_2
, inv_predict_3
,
900 inv_predict_4
, inv_predict_5
, inv_predict_6
, inv_predict_7
,
901 inv_predict_8
, inv_predict_9
, inv_predict_10
, inv_predict_11
,
902 inv_predict_12
, inv_predict_13
,
905 static void inverse_prediction(AVFrame
*frame
, enum PredictionMode m
, int x
, int y
)
907 uint8_t *dec
, *p_l
, *p_tl
, *p_t
, *p_tr
;
910 dec
= GET_PIXEL(frame
, x
, y
);
911 p_l
= GET_PIXEL(frame
, x
- 1, y
);
912 p_tl
= GET_PIXEL(frame
, x
- 1, y
- 1);
913 p_t
= GET_PIXEL(frame
, x
, y
- 1);
914 if (x
== frame
->width
- 1)
915 p_tr
= GET_PIXEL(frame
, 0, y
);
917 p_tr
= GET_PIXEL(frame
, x
+ 1, y
- 1);
919 inverse_predict
[m
](p
, p_l
, p_tl
, p_t
, p_tr
);
927 static int apply_predictor_transform(WebPContext
*s
)
929 ImageContext
*img
= &s
->image
[IMAGE_ROLE_ARGB
];
930 ImageContext
*pimg
= &s
->image
[IMAGE_ROLE_PREDICTOR
];
933 for (y
= 0; y
< img
->frame
->height
; y
++) {
934 for (x
= 0; x
< s
->reduced_width
; x
++) {
935 int tx
= x
>> pimg
->size_reduction
;
936 int ty
= y
>> pimg
->size_reduction
;
937 enum PredictionMode m
= GET_PIXEL_COMP(pimg
->frame
, tx
, ty
, 2);
948 av_log(s
->avctx
, AV_LOG_ERROR
,
949 "invalid predictor mode: %d\n", m
);
950 return AVERROR_INVALIDDATA
;
952 inverse_prediction(img
->frame
, m
, x
, y
);
958 static av_always_inline
uint8_t color_transform_delta(uint8_t color_pred
,
961 return (int)ff_u8_to_s8(color_pred
) * ff_u8_to_s8(color
) >> 5;
964 static int apply_color_transform(WebPContext
*s
)
966 ImageContext
*img
, *cimg
;
970 img
= &s
->image
[IMAGE_ROLE_ARGB
];
971 cimg
= &s
->image
[IMAGE_ROLE_COLOR_TRANSFORM
];
973 for (y
= 0; y
< img
->frame
->height
; y
++) {
974 for (x
= 0; x
< s
->reduced_width
; x
++) {
975 cx
= x
>> cimg
->size_reduction
;
976 cy
= y
>> cimg
->size_reduction
;
977 cp
= GET_PIXEL(cimg
->frame
, cx
, cy
);
978 p
= GET_PIXEL(img
->frame
, x
, y
);
980 p
[1] += color_transform_delta(cp
[3], p
[2]);
981 p
[3] += color_transform_delta(cp
[2], p
[2]) +
982 color_transform_delta(cp
[1], p
[1]);
988 static int apply_subtract_green_transform(WebPContext
*s
)
991 ImageContext
*img
= &s
->image
[IMAGE_ROLE_ARGB
];
993 for (y
= 0; y
< img
->frame
->height
; y
++) {
994 for (x
= 0; x
< s
->reduced_width
; x
++) {
995 uint8_t *p
= GET_PIXEL(img
->frame
, x
, y
);
1003 static int apply_color_indexing_transform(WebPContext
*s
)
1010 img
= &s
->image
[IMAGE_ROLE_ARGB
];
1011 pal
= &s
->image
[IMAGE_ROLE_COLOR_INDEXING
];
1013 if (pal
->size_reduction
> 0) { // undo pixel packing
1016 int pixel_bits
= 8 >> pal
->size_reduction
;
1018 line
= av_malloc(img
->frame
->linesize
[0] + AV_INPUT_BUFFER_PADDING_SIZE
);
1020 return AVERROR(ENOMEM
);
1022 for (y
= 0; y
< img
->frame
->height
; y
++) {
1023 p
= GET_PIXEL(img
->frame
, 0, y
);
1024 memcpy(line
, p
, img
->frame
->linesize
[0]);
1025 init_get_bits(&gb_g
, line
, img
->frame
->linesize
[0] * 8);
1026 skip_bits(&gb_g
, 16);
1028 for (x
= 0; x
< img
->frame
->width
; x
++) {
1029 p
= GET_PIXEL(img
->frame
, x
, y
);
1030 p
[2] = get_bits(&gb_g
, pixel_bits
);
1032 if (i
== 1 << pal
->size_reduction
) {
1033 skip_bits(&gb_g
, 24);
1039 s
->reduced_width
= s
->width
; // we are back to full size
1042 // switch to local palette if it's worth initializing it
1043 if (img
->frame
->height
* img
->frame
->width
> 300) {
1044 uint8_t palette
[256 * 4];
1045 const int size
= pal
->frame
->width
* 4;
1046 av_assert0(size
<= 1024U);
1047 memcpy(palette
, GET_PIXEL(pal
->frame
, 0, 0), size
); // copy palette
1048 // set extra entries to transparent black
1049 memset(palette
+ size
, 0, 256 * 4 - size
);
1050 for (y
= 0; y
< img
->frame
->height
; y
++) {
1051 for (x
= 0; x
< img
->frame
->width
; x
++) {
1052 p
= GET_PIXEL(img
->frame
, x
, y
);
1054 AV_COPY32(p
, &palette
[i
* 4]);
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_WB32(p
, 0x00000000);
1065 const uint8_t *pi
= GET_PIXEL(pal
->frame
, i
, 0);
1075 static void update_canvas_size(AVCodecContext
*avctx
, int w
, int h
)
1077 WebPContext
*s
= avctx
->priv_data
;
1078 if (s
->width
&& s
->width
!= w
) {
1079 av_log(avctx
, AV_LOG_WARNING
, "Width mismatch. %d != %d\n",
1083 if (s
->height
&& s
->height
!= h
) {
1084 av_log(avctx
, AV_LOG_WARNING
, "Height mismatch. %d != %d\n",
1090 static int vp8_lossless_decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
1091 int *got_frame
, const uint8_t *data_start
,
1092 unsigned int data_size
, int is_alpha_chunk
)
1094 WebPContext
*s
= avctx
->priv_data
;
1095 int w
, h
, ret
, i
, used
;
1097 if (!is_alpha_chunk
) {
1099 avctx
->pix_fmt
= AV_PIX_FMT_ARGB
;
1102 ret
= init_get_bits8(&s
->gb
, data_start
, data_size
);
1106 if (!is_alpha_chunk
) {
1107 if (get_bits(&s
->gb
, 8) != 0x2F) {
1108 av_log(avctx
, AV_LOG_ERROR
, "Invalid WebP Lossless signature\n");
1109 return AVERROR_INVALIDDATA
;
1112 w
= get_bits(&s
->gb
, 14) + 1;
1113 h
= get_bits(&s
->gb
, 14) + 1;
1115 update_canvas_size(avctx
, w
, h
);
1117 ret
= ff_set_dimensions(avctx
, s
->width
, s
->height
);
1121 s
->has_alpha
= get_bits1(&s
->gb
);
1123 if (get_bits(&s
->gb
, 3) != 0x0) {
1124 av_log(avctx
, AV_LOG_ERROR
, "Invalid WebP Lossless version\n");
1125 return AVERROR_INVALIDDATA
;
1128 if (!s
->width
|| !s
->height
)
1134 /* parse transformations */
1135 s
->nb_transforms
= 0;
1136 s
->reduced_width
= s
->width
;
1138 while (get_bits1(&s
->gb
)) {
1139 enum TransformType transform
= get_bits(&s
->gb
, 2);
1140 if (used
& (1 << transform
)) {
1141 av_log(avctx
, AV_LOG_ERROR
, "Transform %d used more than once\n",
1143 ret
= AVERROR_INVALIDDATA
;
1144 goto free_and_return
;
1146 used
|= (1 << transform
);
1147 s
->transforms
[s
->nb_transforms
++] = transform
;
1148 switch (transform
) {
1149 case PREDICTOR_TRANSFORM
:
1150 ret
= parse_transform_predictor(s
);
1152 case COLOR_TRANSFORM
:
1153 ret
= parse_transform_color(s
);
1155 case COLOR_INDEXING_TRANSFORM
:
1156 ret
= parse_transform_color_indexing(s
);
1160 goto free_and_return
;
1163 /* decode primary image */
1164 s
->image
[IMAGE_ROLE_ARGB
].frame
= p
;
1166 s
->image
[IMAGE_ROLE_ARGB
].is_alpha_primary
= 1;
1167 ret
= decode_entropy_coded_image(s
, IMAGE_ROLE_ARGB
, w
, h
);
1169 goto free_and_return
;
1171 /* apply transformations */
1172 for (i
= s
->nb_transforms
- 1; i
>= 0; i
--) {
1173 switch (s
->transforms
[i
]) {
1174 case PREDICTOR_TRANSFORM
:
1175 ret
= apply_predictor_transform(s
);
1177 case COLOR_TRANSFORM
:
1178 ret
= apply_color_transform(s
);
1180 case SUBTRACT_GREEN
:
1181 ret
= apply_subtract_green_transform(s
);
1183 case COLOR_INDEXING_TRANSFORM
:
1184 ret
= apply_color_indexing_transform(s
);
1188 goto free_and_return
;
1192 p
->pict_type
= AV_PICTURE_TYPE_I
;
1193 p
->flags
|= AV_FRAME_FLAG_KEY
;
1194 p
->flags
|= AV_FRAME_FLAG_LOSSLESS
;
1198 for (i
= 0; i
< IMAGE_ROLE_NB
; i
++)
1199 image_ctx_free(&s
->image
[i
]);
1204 static void alpha_inverse_prediction(AVFrame
*frame
, enum AlphaFilter m
)
1209 ls
= frame
->linesize
[3];
1211 /* filter first row using horizontal filter */
1212 dec
= frame
->data
[3] + 1;
1213 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1216 /* filter first column using vertical filter */
1217 dec
= frame
->data
[3] + ls
;
1218 for (y
= 1; y
< frame
->height
; y
++, dec
+= ls
)
1219 *dec
+= *(dec
- ls
);
1221 /* filter the rest using the specified filter */
1223 case ALPHA_FILTER_HORIZONTAL
:
1224 for (y
= 1; y
< frame
->height
; y
++) {
1225 dec
= frame
->data
[3] + y
* ls
+ 1;
1226 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1230 case ALPHA_FILTER_VERTICAL
:
1231 for (y
= 1; y
< frame
->height
; y
++) {
1232 dec
= frame
->data
[3] + y
* ls
+ 1;
1233 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1234 *dec
+= *(dec
- ls
);
1237 case ALPHA_FILTER_GRADIENT
:
1238 for (y
= 1; y
< frame
->height
; y
++) {
1239 dec
= frame
->data
[3] + y
* ls
+ 1;
1240 for (x
= 1; x
< frame
->width
; x
++, dec
++)
1241 dec
[0] += av_clip_uint8(*(dec
- 1) + *(dec
- ls
) - *(dec
- ls
- 1));
1247 static int vp8_lossy_decode_alpha(AVCodecContext
*avctx
, AVFrame
*p
,
1248 const uint8_t *data_start
,
1249 unsigned int data_size
)
1251 WebPContext
*s
= avctx
->priv_data
;
1254 if (s
->alpha_compression
== ALPHA_COMPRESSION_NONE
) {
1257 bytestream2_init(&gb
, data_start
, data_size
);
1258 for (y
= 0; y
< s
->height
; y
++)
1259 bytestream2_get_buffer(&gb
, p
->data
[3] + p
->linesize
[3] * y
,
1261 } else if (s
->alpha_compression
== ALPHA_COMPRESSION_VP8L
) {
1263 int alpha_got_frame
= 0;
1265 s
->alpha_frame
= av_frame_alloc();
1266 if (!s
->alpha_frame
)
1267 return AVERROR(ENOMEM
);
1269 ret
= vp8_lossless_decode_frame(avctx
, s
->alpha_frame
, &alpha_got_frame
,
1270 data_start
, data_size
, 1);
1272 av_frame_free(&s
->alpha_frame
);
1275 if (!alpha_got_frame
) {
1276 av_frame_free(&s
->alpha_frame
);
1277 return AVERROR_INVALIDDATA
;
1280 /* copy green component of alpha image to alpha plane of primary image */
1281 for (y
= 0; y
< s
->height
; y
++) {
1282 ap
= GET_PIXEL(s
->alpha_frame
, 0, y
) + 2;
1283 pp
= p
->data
[3] + p
->linesize
[3] * y
;
1284 for (x
= 0; x
< s
->width
; x
++) {
1290 av_frame_free(&s
->alpha_frame
);
1293 /* apply alpha filtering */
1294 if (s
->alpha_filter
)
1295 alpha_inverse_prediction(p
, s
->alpha_filter
);
1300 static int vp8_lossy_decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
1301 int *got_frame
, uint8_t *data_start
,
1302 unsigned int data_size
)
1304 WebPContext
*s
= avctx
->priv_data
;
1307 if (!s
->initialized
) {
1308 ff_vp8_decode_init(avctx
);
1310 s
->v
.actually_webp
= 1;
1312 avctx
->pix_fmt
= s
->has_alpha
? AV_PIX_FMT_YUVA420P
: AV_PIX_FMT_YUV420P
;
1315 if (data_size
> INT_MAX
) {
1316 av_log(avctx
, AV_LOG_ERROR
, "unsupported chunk size\n");
1317 return AVERROR_PATCHWELCOME
;
1320 av_packet_unref(s
->pkt
);
1321 s
->pkt
->data
= data_start
;
1322 s
->pkt
->size
= data_size
;
1324 ret
= ff_vp8_decode_frame(avctx
, p
, got_frame
, s
->pkt
);
1329 return AVERROR_INVALIDDATA
;
1331 update_canvas_size(avctx
, avctx
->width
, avctx
->height
);
1334 ret
= vp8_lossy_decode_alpha(avctx
, p
, s
->alpha_data
,
1335 s
->alpha_data_size
);
1342 static int webp_decode_frame(AVCodecContext
*avctx
, AVFrame
*p
,
1343 int *got_frame
, AVPacket
*avpkt
)
1345 WebPContext
*s
= avctx
->priv_data
;
1348 uint32_t chunk_type
, chunk_size
;
1358 bytestream2_init(&gb
, avpkt
->data
, avpkt
->size
);
1360 if (bytestream2_get_bytes_left(&gb
) < 12)
1361 return AVERROR_INVALIDDATA
;
1363 if (bytestream2_get_le32(&gb
) != MKTAG('R', 'I', 'F', 'F')) {
1364 av_log(avctx
, AV_LOG_ERROR
, "missing RIFF tag\n");
1365 return AVERROR_INVALIDDATA
;
1368 chunk_size
= bytestream2_get_le32(&gb
);
1369 if (bytestream2_get_bytes_left(&gb
) < chunk_size
)
1370 return AVERROR_INVALIDDATA
;
1372 if (bytestream2_get_le32(&gb
) != MKTAG('W', 'E', 'B', 'P')) {
1373 av_log(avctx
, AV_LOG_ERROR
, "missing WEBP tag\n");
1374 return AVERROR_INVALIDDATA
;
1377 while (bytestream2_get_bytes_left(&gb
) > 8) {
1378 char chunk_str
[5] = { 0 };
1380 chunk_type
= bytestream2_get_le32(&gb
);
1381 chunk_size
= bytestream2_get_le32(&gb
);
1382 if (chunk_size
== UINT32_MAX
)
1383 return AVERROR_INVALIDDATA
;
1384 chunk_size
+= chunk_size
& 1;
1386 if (bytestream2_get_bytes_left(&gb
) < chunk_size
) {
1387 /* we seem to be running out of data, but it could also be that the
1388 bitstream has trailing junk leading to bogus chunk_size. */
1392 switch (chunk_type
) {
1393 case MKTAG('V', 'P', '8', ' '):
1395 ret
= vp8_lossy_decode_frame(avctx
, p
, got_frame
,
1396 avpkt
->data
+ bytestream2_tell(&gb
),
1401 bytestream2_skip(&gb
, chunk_size
);
1403 case MKTAG('V', 'P', '8', 'L'):
1405 ret
= vp8_lossless_decode_frame(avctx
, p
, got_frame
,
1406 avpkt
->data
+ bytestream2_tell(&gb
),
1410 #if FF_API_CODEC_PROPS
1411 FF_DISABLE_DEPRECATION_WARNINGS
1412 avctx
->properties
|= FF_CODEC_PROPERTY_LOSSLESS
;
1413 FF_ENABLE_DEPRECATION_WARNINGS
1416 bytestream2_skip(&gb
, chunk_size
);
1418 case MKTAG('V', 'P', '8', 'X'):
1419 if (s
->width
|| s
->height
|| *got_frame
) {
1420 av_log(avctx
, AV_LOG_ERROR
, "Canvas dimensions are already set\n");
1421 return AVERROR_INVALIDDATA
;
1423 vp8x_flags
= bytestream2_get_byte(&gb
);
1424 bytestream2_skip(&gb
, 3);
1425 s
->width
= bytestream2_get_le24(&gb
) + 1;
1426 s
->height
= bytestream2_get_le24(&gb
) + 1;
1427 ret
= av_image_check_size(s
->width
, s
->height
, 0, avctx
);
1431 case MKTAG('A', 'L', 'P', 'H'): {
1432 int alpha_header
, filter_m
, compression
;
1434 if (!(vp8x_flags
& VP8X_FLAG_ALPHA
)) {
1435 av_log(avctx
, AV_LOG_WARNING
,
1436 "ALPHA chunk present, but alpha bit not set in the "
1439 if (chunk_size
== 0) {
1440 av_log(avctx
, AV_LOG_ERROR
, "invalid ALPHA chunk size\n");
1441 return AVERROR_INVALIDDATA
;
1443 alpha_header
= bytestream2_get_byte(&gb
);
1444 s
->alpha_data
= avpkt
->data
+ bytestream2_tell(&gb
);
1445 s
->alpha_data_size
= chunk_size
- 1;
1446 bytestream2_skip(&gb
, s
->alpha_data_size
);
1448 filter_m
= (alpha_header
>> 2) & 0x03;
1449 compression
= alpha_header
& 0x03;
1451 if (compression
> ALPHA_COMPRESSION_VP8L
) {
1452 av_log(avctx
, AV_LOG_VERBOSE
,
1453 "skipping unsupported ALPHA chunk\n");
1456 s
->alpha_compression
= compression
;
1457 s
->alpha_filter
= filter_m
;
1462 case MKTAG('E', 'X', 'I', 'F'): {
1463 int le
, ifd_offset
, exif_offset
= bytestream2_tell(&gb
);
1464 AVDictionary
*exif_metadata
= NULL
;
1465 GetByteContext exif_gb
;
1468 av_log(avctx
, AV_LOG_VERBOSE
, "Ignoring extra EXIF chunk\n");
1471 if (!(vp8x_flags
& VP8X_FLAG_EXIF_METADATA
))
1472 av_log(avctx
, AV_LOG_WARNING
,
1473 "EXIF chunk present, but Exif bit not set in the "
1477 bytestream2_init(&exif_gb
, avpkt
->data
+ exif_offset
,
1478 avpkt
->size
- exif_offset
);
1479 if (ff_tdecode_header(&exif_gb
, &le
, &ifd_offset
) < 0) {
1480 av_log(avctx
, AV_LOG_ERROR
, "invalid TIFF header "
1485 bytestream2_seek(&exif_gb
, ifd_offset
, SEEK_SET
);
1486 if (ff_exif_decode_ifd(avctx
, &exif_gb
, le
, 0, &exif_metadata
) < 0) {
1487 av_log(avctx
, AV_LOG_ERROR
, "error decoding Exif data\n");
1491 av_dict_copy(&p
->metadata
, exif_metadata
, 0);
1494 av_dict_free(&exif_metadata
);
1495 bytestream2_skip(&gb
, chunk_size
);
1498 case MKTAG('I', 'C', 'C', 'P'): {
1499 AVFrameSideData
*sd
;
1502 av_log(avctx
, AV_LOG_VERBOSE
, "Ignoring extra ICCP chunk\n");
1503 bytestream2_skip(&gb
, chunk_size
);
1506 if (!(vp8x_flags
& VP8X_FLAG_ICC
))
1507 av_log(avctx
, AV_LOG_WARNING
,
1508 "ICCP chunk present, but ICC Profile bit not set in the "
1513 ret
= ff_frame_new_side_data(avctx
, p
, AV_FRAME_DATA_ICC_PROFILE
, chunk_size
, &sd
);
1518 bytestream2_get_buffer(&gb
, sd
->data
, chunk_size
);
1520 bytestream2_skip(&gb
, chunk_size
);
1524 case MKTAG('A', 'N', 'I', 'M'):
1525 case MKTAG('A', 'N', 'M', 'F'):
1526 case MKTAG('X', 'M', 'P', ' '):
1527 AV_WL32(chunk_str
, chunk_type
);
1528 av_log(avctx
, AV_LOG_WARNING
, "skipping unsupported chunk: %s\n",
1530 bytestream2_skip(&gb
, chunk_size
);
1533 AV_WL32(chunk_str
, chunk_type
);
1534 av_log(avctx
, AV_LOG_VERBOSE
, "skipping unknown chunk: %s\n",
1536 bytestream2_skip(&gb
, chunk_size
);
1542 av_log(avctx
, AV_LOG_ERROR
, "image data not found\n");
1543 return AVERROR_INVALIDDATA
;
1549 static av_cold
int webp_decode_init(AVCodecContext
*avctx
)
1551 WebPContext
*s
= avctx
->priv_data
;
1553 s
->pkt
= av_packet_alloc();
1555 return AVERROR(ENOMEM
);
1560 static av_cold
int webp_decode_close(AVCodecContext
*avctx
)
1562 WebPContext
*s
= avctx
->priv_data
;
1564 av_packet_free(&s
->pkt
);
1567 return ff_vp8_decode_free(avctx
);
1572 const FFCodec ff_webp_decoder
= {
1574 CODEC_LONG_NAME("WebP image"),
1575 .p
.type
= AVMEDIA_TYPE_VIDEO
,
1576 .p
.id
= AV_CODEC_ID_WEBP
,
1577 .priv_data_size
= sizeof(WebPContext
),
1578 .init
= webp_decode_init
,
1579 FF_CODEC_DECODE_CB(webp_decode_frame
),
1580 .close
= webp_decode_close
,
1581 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_FRAME_THREADS
,
1582 .caps_internal
= FF_CODEC_CAP_ICC_PROFILES
|
1583 FF_CODEC_CAP_USES_PROGRESSFRAMES
,