FFmpeg
Loading...
Searching...
No Matches
webp.c
Go to the documentation of this file.
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 * Copyright (c) 2020 Pexeso Inc.
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24/**
25 * @file
26 * WebP image decoder
27 *
28 * @author Aneesh Dogra <aneesh@sugarlabs.org>
29 * Container and Lossy decoding
30 *
31 * @author Justin Ruggles <justin.ruggles@gmail.com>
32 * Lossless decoder
33 * Compressed alpha for lossy
34 *
35 * @author James Almer <jamrial@gmail.com>
36 * Exif metadata
37 * ICC profile
38 *
39 * @author Thilo Borgmann <thilo.borgmann _at_ mail.de>
40 * XMP metadata
41 *
42 * @author Josef Zlomek, Pexeso Inc. <josef@pex.com>
43 * Animation
44 */
45
46#include "config_components.h"
47
49#include "libavutil/imgutils.h"
50#include "libavutil/mem.h"
51
52#define BITSTREAM_READER_LE
53#include "avcodec.h"
54#include "bytestream.h"
55#include "codec_internal.h"
56#include "decode.h"
57#include "exif_internal.h"
58#include "get_bits.h"
59#include "thread.h"
60#include "tiff_common.h"
61#include "vp8.h"
62
63#define VP8X_FLAG_ANIMATION 0x02
64#define VP8X_FLAG_XMP_METADATA 0x04
65#define VP8X_FLAG_EXIF_METADATA 0x08
66#define VP8X_FLAG_ALPHA 0x10
67#define VP8X_FLAG_ICC 0x20
68
69#define MAX_PALETTE_SIZE 256
70#define MAX_CACHE_BITS 11
71#define NUM_CODE_LENGTH_CODES 19
72#define HUFFMAN_CODES_PER_META_CODE 5
73#define NUM_LITERAL_CODES 256
74#define NUM_LENGTH_CODES 24
75#define NUM_DISTANCE_CODES 40
76#define NUM_SHORT_DISTANCES 120
77#define MAX_HUFFMAN_CODE_LENGTH 15
78
84
86 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
87};
88
89static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2] = {
90 { 0, 1 }, { 1, 0 }, { 1, 1 }, { -1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { -1, 2 },
91 { 2, 1 }, { -2, 1 }, { 2, 2 }, { -2, 2 }, { 0, 3 }, { 3, 0 }, { 1, 3 }, { -1, 3 },
92 { 3, 1 }, { -3, 1 }, { 2, 3 }, { -2, 3 }, { 3, 2 }, { -3, 2 }, { 0, 4 }, { 4, 0 },
93 { 1, 4 }, { -1, 4 }, { 4, 1 }, { -4, 1 }, { 3, 3 }, { -3, 3 }, { 2, 4 }, { -2, 4 },
94 { 4, 2 }, { -4, 2 }, { 0, 5 }, { 3, 4 }, { -3, 4 }, { 4, 3 }, { -4, 3 }, { 5, 0 },
95 { 1, 5 }, { -1, 5 }, { 5, 1 }, { -5, 1 }, { 2, 5 }, { -2, 5 }, { 5, 2 }, { -5, 2 },
96 { 4, 4 }, { -4, 4 }, { 3, 5 }, { -3, 5 }, { 5, 3 }, { -5, 3 }, { 0, 6 }, { 6, 0 },
97 { 1, 6 }, { -1, 6 }, { 6, 1 }, { -6, 1 }, { 2, 6 }, { -2, 6 }, { 6, 2 }, { -6, 2 },
98 { 4, 5 }, { -4, 5 }, { 5, 4 }, { -5, 4 }, { 3, 6 }, { -3, 6 }, { 6, 3 }, { -6, 3 },
99 { 0, 7 }, { 7, 0 }, { 1, 7 }, { -1, 7 }, { 5, 5 }, { -5, 5 }, { 7, 1 }, { -7, 1 },
100 { 4, 6 }, { -4, 6 }, { 6, 4 }, { -6, 4 }, { 2, 7 }, { -2, 7 }, { 7, 2 }, { -7, 2 },
101 { 3, 7 }, { -3, 7 }, { 7, 3 }, { -7, 3 }, { 5, 6 }, { -5, 6 }, { 6, 5 }, { -6, 5 },
102 { 8, 0 }, { 4, 7 }, { -4, 7 }, { 7, 4 }, { -7, 4 }, { 8, 1 }, { 8, 2 }, { 6, 6 },
103 { -6, 6 }, { 8, 3 }, { 5, 7 }, { -5, 7 }, { 7, 5 }, { -7, 5 }, { 8, 4 }, { 6, 7 },
104 { -6, 7 }, { 7, 6 }, { -7, 6 }, { 8, 5 }, { 7, 7 }, { -7, 7 }, { 8, 6 }, { 8, 7 }
105};
106
111
118
125
142
150
151/* The structure of WebP lossless is an optional series of transformation data,
152 * followed by the primary image. The primary image also optionally contains
153 * an entropy group mapping if there are multiple entropy groups. There is a
154 * basic image type called an "entropy coded image" that is used for all of
155 * these. The type of each entropy coded image is referred to by the
156 * specification as its role. */
158 /* Primary Image: Stores the actual pixels of the image. */
160
161 /* Entropy Image: Defines which Huffman group to use for different areas of
162 * the primary image. */
164
165 /* Predictors: Defines which predictor type to use for different areas of
166 * the primary image. */
168
169 /* Color Transform Data: Defines the color transformation for different
170 * areas of the primary image. */
172
173 /* Color Index: Stored as an image of height == 1. */
175
177};
178
179typedef struct HuffReader {
180 VLC vlc; /* Huffman decoder context */
181 int simple; /* whether to use simple mode */
182 int nb_symbols; /* number of coded symbols */
183 uint16_t simple_symbols[2]; /* symbols for simple mode */
184} HuffReader;
185
186typedef struct ImageContext {
187 enum ImageRole role; /* role of this image */
188 AVFrame *frame; /* AVFrame for data */
189 int color_cache_bits; /* color cache size, log2 */
190 uint32_t *color_cache; /* color cache data */
191 int nb_huffman_groups; /* number of huffman groups */
192 HuffReader *huffman_groups; /* reader for each huffman group */
193 /* relative size compared to primary image, log2.
194 * for IMAGE_ROLE_COLOR_INDEXING with <= 16 colors, this is log2 of the
195 * number of pixels per byte in the primary image (pixel packing) */
199
200typedef struct WebPContext {
201 VP8Context v; /* VP8 Context used for lossy decoding */
202 GetBitContext gb; /* bitstream reader for main image chunk */
203 AVFrame *alpha_frame; /* AVFrame for alpha data decompressed from VP8L */
204 AVPacket *pkt; /* AVPacket to be passed to the underlying VP8 decoder */
205 AVCodecContext *avctx; /* parent AVCodecContext */
206 int initialized; /* set once the VP8 context is initialized */
207 int has_alpha; /* has a separate alpha chunk */
208 enum AlphaCompression alpha_compression; /* compression type for alpha chunk */
209 enum AlphaFilter alpha_filter; /* filtering method for alpha chunk */
210 const uint8_t *alpha_data; /* alpha chunk data */
211 int alpha_data_size; /* alpha chunk data size */
212 int has_exif; /* set after an EXIF chunk has been processed */
213 int has_iccp; /* set after an ICCP chunk has been processed */
214 int has_xmp; /* set after an XMP chunk has been processed */
215 int width; /* image width */
216 int height; /* image height */
217
218 int nb_transforms; /* number of transforms */
219 enum TransformType transforms[4]; /* transformations used in the image, in order */
220 /* reduced width when using a color indexing transform with <= 16 colors (pixel packing)
221 * before pixels are unpacked, or same as width otherwise. */
223 int nb_huffman_groups; /* number of huffman groups in the primary image */
224 ImageContext image[IMAGE_ROLE_NB]; /* image context for each role */
226
227#define GET_PIXEL(frame, x, y) \
228 ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
229
230#define GET_PIXEL_COMP(frame, x, y, c) \
231 (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
232
234{
235 int i, j;
236
237 av_free(img->color_cache);
238 if (img->role != IMAGE_ROLE_ARGB && !img->is_alpha_primary)
239 av_frame_free(&img->frame);
240 if (img->huffman_groups) {
241 for (i = 0; i < img->nb_huffman_groups; i++) {
242 for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++)
243 ff_vlc_free(&img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE + j].vlc);
244 }
245 av_free(img->huffman_groups);
246 }
247 memset(img, 0, sizeof(*img));
248}
249
251{
252 if (r->simple) {
253 if (r->nb_symbols == 1)
254 return r->simple_symbols[0];
255 else
256 return r->simple_symbols[get_bits1(gb)];
257 } else
258 return get_vlc2(gb, r->vlc.table, 8, 2);
259}
260
261static int huff_reader_build_canonical(HuffReader *r, const uint8_t *code_lengths,
262 uint16_t len_counts[MAX_HUFFMAN_CODE_LENGTH + 1],
263 uint8_t lens[], uint16_t syms[],
264 int alphabet_size, void *logctx)
265{
266 unsigned nb_codes = 0;
267 int ret;
268
269 // Count the number of symbols of each length and transform len_counts
270 // into an array of offsets.
271 for (int len = 1; len <= MAX_HUFFMAN_CODE_LENGTH; ++len) {
272 unsigned cnt = len_counts[len];
273 len_counts[len] = nb_codes;
274 nb_codes += cnt;
275 }
276
277 for (int sym = 0; sym < alphabet_size; ++sym) {
278 if (code_lengths[sym]) {
279 unsigned idx = len_counts[code_lengths[sym]]++;
280 syms[idx] = sym;
281 lens[idx] = code_lengths[sym];
282 }
283 }
284
285 if (nb_codes == 0) {
286 // No symbols
287 return AVERROR_INVALIDDATA;
288 }
289 if (nb_codes == 1) {
290 // Special-case 1 symbol since the VLC reader cannot handle it
291 r->nb_symbols = 1;
292 r->simple = 1;
293 r->simple_symbols[0] = syms[0];
294 return 0;
295 }
296
297 ret = ff_vlc_init_from_lengths(&r->vlc, 8, nb_codes, lens, 1,
298 syms, 2, 2, 0, VLC_INIT_OUTPUT_LE, logctx);
299 if (ret < 0)
300 return ret;
301 r->simple = 0;
302
303 return 0;
304}
305
307{
308 hc->nb_symbols = get_bits1(&s->gb) + 1;
309
310 if (get_bits1(&s->gb))
311 hc->simple_symbols[0] = get_bits(&s->gb, 8);
312 else
313 hc->simple_symbols[0] = get_bits1(&s->gb);
314
315 if (hc->nb_symbols == 2)
316 hc->simple_symbols[1] = get_bits(&s->gb, 8);
317
318 hc->simple = 1;
319}
320
322 int alphabet_size)
323{
324 HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } };
325 uint8_t *code_lengths;
326 uint8_t code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
327 uint8_t reordered_code_length_code_lengths[NUM_CODE_LENGTH_CODES];
328 uint16_t reordered_code_length_syms[NUM_CODE_LENGTH_CODES];
329 uint16_t len_counts[MAX_HUFFMAN_CODE_LENGTH + 1] = { 0 };
330 int symbol, max_symbol, prev_code_len, ret;
331 int num_codes = 4 + get_bits(&s->gb, 4);
332
333 av_assert1(num_codes <= NUM_CODE_LENGTH_CODES);
334
335 for (int i = 0; i < num_codes; i++) {
336 unsigned len = get_bits(&s->gb, 3);
337 code_length_code_lengths[code_length_code_order[i]] = len;
338 len_counts[len]++;
339 }
340
341 if (get_bits1(&s->gb)) {
342 int bits = 2 + 2 * get_bits(&s->gb, 3);
343 max_symbol = 2 + get_bits(&s->gb, bits);
344 if (max_symbol > alphabet_size) {
345 av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n",
346 max_symbol, alphabet_size);
347 return AVERROR_INVALIDDATA;
348 }
349 } else {
350 max_symbol = alphabet_size;
351 }
352
353 ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths, len_counts,
354 reordered_code_length_code_lengths,
355 reordered_code_length_syms,
356 NUM_CODE_LENGTH_CODES, s->avctx);
357 if (ret < 0)
358 return ret;
359
360 code_lengths = av_malloc_array(alphabet_size, 2 * sizeof(uint8_t) + sizeof(uint16_t));
361 if (!code_lengths) {
362 ret = AVERROR(ENOMEM);
363 goto finish;
364 }
365
366 prev_code_len = 8;
367 symbol = 0;
368 memset(len_counts, 0, sizeof(len_counts));
369 while (symbol < alphabet_size) {
370 int code_len;
371
372 if (!max_symbol--)
373 break;
374 code_len = huff_reader_get_symbol(&code_len_hc, &s->gb);
375 if (code_len < 16U) {
376 /* Code length code [0..15] indicates literal code lengths. */
377 code_lengths[symbol++] = code_len;
378 len_counts[code_len]++;
379 if (code_len)
380 prev_code_len = code_len;
381 } else {
382 int repeat = 0, length = 0;
383 switch (code_len) {
384 default:
386 goto finish;
387 case 16:
388 /* Code 16 repeats the previous non-zero value [3..6] times,
389 * i.e., 3 + ReadBits(2) times. If code 16 is used before a
390 * non-zero value has been emitted, a value of 8 is repeated. */
391 repeat = 3 + get_bits(&s->gb, 2);
392 length = prev_code_len;
393 len_counts[length] += repeat;
394 break;
395 case 17:
396 /* Code 17 emits a streak of zeros [3..10], i.e.,
397 * 3 + ReadBits(3) times. */
398 repeat = 3 + get_bits(&s->gb, 3);
399 break;
400 case 18:
401 /* Code 18 emits a streak of zeros of length [11..138], i.e.,
402 * 11 + ReadBits(7) times. */
403 repeat = 11 + get_bits(&s->gb, 7);
404 break;
405 }
406 if (symbol + repeat > alphabet_size) {
407 av_log(s->avctx, AV_LOG_ERROR,
408 "invalid symbol %d + repeat %d > alphabet size %d\n",
409 symbol, repeat, alphabet_size);
411 goto finish;
412 }
413 while (repeat-- > 0)
414 code_lengths[symbol++] = length;
415 }
416 }
417
418 ret = huff_reader_build_canonical(hc, code_lengths, len_counts,
419 code_lengths + symbol,
420 (uint16_t*)(code_lengths + 2 * symbol),
421 symbol, s->avctx);
422
423finish:
424 ff_vlc_free(&code_len_hc.vlc);
425 av_free(code_lengths);
426 return ret;
427}
428
430 int w, int h);
431
432#define PARSE_BLOCK_SIZE(w, h) do { \
433 block_bits = get_bits(&s->gb, 3) + 2; \
434 blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \
435 blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \
436} while (0)
437
439{
441 int ret, block_bits, blocks_w, blocks_h, x, y, max;
442
443 PARSE_BLOCK_SIZE(s->reduced_width, s->height);
444
445 ret = decode_entropy_coded_image(s, IMAGE_ROLE_ENTROPY, blocks_w, blocks_h);
446 if (ret < 0)
447 return ret;
448
449 img = &s->image[IMAGE_ROLE_ENTROPY];
450 img->size_reduction = block_bits;
451
452 /* the number of huffman groups is determined by the maximum group number
453 * coded in the entropy image */
454 max = 0;
455 for (y = 0; y < img->frame->height; y++) {
456 for (x = 0; x < img->frame->width; x++) {
457 int p0 = GET_PIXEL_COMP(img->frame, x, y, 1);
458 int p1 = GET_PIXEL_COMP(img->frame, x, y, 2);
459 int p = p0 << 8 | p1;
460 max = FFMAX(max, p);
461 }
462 }
463 s->nb_huffman_groups = max + 1;
464
465 return 0;
466}
467
469{
470 int block_bits, blocks_w, blocks_h, ret;
471
472 PARSE_BLOCK_SIZE(s->reduced_width, s->height);
473
475 blocks_h);
476 if (ret < 0)
477 return ret;
478
479 s->image[IMAGE_ROLE_PREDICTOR].size_reduction = block_bits;
480
481 return 0;
482}
483
485{
486 int block_bits, blocks_w, blocks_h, ret;
487
488 PARSE_BLOCK_SIZE(s->reduced_width, s->height);
489
491 blocks_h);
492 if (ret < 0)
493 return ret;
494
495 s->image[IMAGE_ROLE_COLOR_TRANSFORM].size_reduction = block_bits;
496
497 return 0;
498}
499
501{
503 int width_bits, index_size, ret, x;
504 uint8_t *ct;
505
506 index_size = get_bits(&s->gb, 8) + 1;
507
508 if (index_size <= 2)
509 width_bits = 3;
510 else if (index_size <= 4)
511 width_bits = 2;
512 else if (index_size <= 16)
513 width_bits = 1;
514 else
515 width_bits = 0;
516
518 index_size, 1);
519 if (ret < 0)
520 return ret;
521
523 img->size_reduction = width_bits;
524 if (width_bits > 0)
525 s->reduced_width = (s->width + ((1 << width_bits) - 1)) >> width_bits;
526
527 /* color index values are delta-coded */
528 ct = img->frame->data[0] + 4;
529 for (x = 4; x < img->frame->width * 4; x++, ct++)
530 ct[0] += ct[-4];
531
532 return 0;
533}
534
536 int x, int y)
537{
538 ImageContext *gimg = &s->image[IMAGE_ROLE_ENTROPY];
539 int group = 0;
540
541 if (gimg->size_reduction > 0) {
542 int group_x = x >> gimg->size_reduction;
543 int group_y = y >> gimg->size_reduction;
544 int g0 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 1);
545 int g1 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
546 group = g0 << 8 | g1;
547 }
548
549 return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE];
550}
551
553{
554 uint32_t cache_idx = (0x1E35A7BD * c) >> (32 - img->color_cache_bits);
555 img->color_cache[cache_idx] = c;
556}
557
559 int w, int h)
560{
562 HuffReader *hg;
563 int i, j, ret, x, y, width;
564
565 img = &s->image[role];
566 img->role = role;
567
568 if (!img->frame) {
569 img->frame = av_frame_alloc();
570 if (!img->frame)
571 return AVERROR(ENOMEM);
572 }
573
574 img->frame->format = AV_PIX_FMT_ARGB;
575 img->frame->width = w;
576 img->frame->height = h;
577
578 if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) {
579 ret = ff_thread_get_buffer(s->avctx, img->frame, 0);
580 } else
581 ret = av_frame_get_buffer(img->frame, 1);
582 if (ret < 0)
583 return ret;
584
585 if (get_bits1(&s->gb)) {
586 img->color_cache_bits = get_bits(&s->gb, 4);
587 if (img->color_cache_bits < 1 || img->color_cache_bits > 11) {
588 av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n",
589 img->color_cache_bits);
590 return AVERROR_INVALIDDATA;
591 }
592 img->color_cache = av_calloc(1 << img->color_cache_bits,
593 sizeof(*img->color_cache));
594 if (!img->color_cache)
595 return AVERROR(ENOMEM);
596 } else {
597 img->color_cache_bits = 0;
598 }
599
600 img->nb_huffman_groups = 1;
601 if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) {
602 ret = decode_entropy_image(s);
603 if (ret < 0)
604 return ret;
605 img->nb_huffman_groups = s->nb_huffman_groups;
606 }
607 img->huffman_groups = av_calloc(img->nb_huffman_groups,
609 sizeof(*img->huffman_groups));
610 if (!img->huffman_groups)
611 return AVERROR(ENOMEM);
612
613 for (i = 0; i < img->nb_huffman_groups; i++) {
614 hg = &img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE];
615 for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) {
616 int alphabet_size = alphabet_sizes[j];
617 if (!j && img->color_cache_bits > 0)
618 alphabet_size += 1 << img->color_cache_bits;
619
620 if (get_bits1(&s->gb)) {
622 } else {
623 ret = read_huffman_code_normal(s, &hg[j], alphabet_size);
624 if (ret < 0)
625 return ret;
626 }
627 }
628 }
629
630 width = img->frame->width;
631 if (role == IMAGE_ROLE_ARGB)
632 width = s->reduced_width;
633
634 x = 0; y = 0;
635 while (y < img->frame->height) {
636 int v;
637
638 if (get_bits_left(&s->gb) < 0)
639 return AVERROR_INVALIDDATA;
640
641 hg = get_huffman_group(s, img, x, y);
643 if (v < NUM_LITERAL_CODES) {
644 /* literal pixel values */
645 uint8_t *p = GET_PIXEL(img->frame, x, y);
646 p[2] = v;
647 p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED], &s->gb);
648 p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE], &s->gb);
649 p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb);
650 if (img->color_cache_bits)
652 x++;
653 if (x == width) {
654 x = 0;
655 y++;
656 }
657 } else if (v < NUM_LITERAL_CODES + NUM_LENGTH_CODES) {
658 /* LZ77 backwards mapping */
659 int prefix_code, length, distance, ref_x, ref_y;
660
661 /* parse length and distance */
662 prefix_code = v - NUM_LITERAL_CODES;
663 if (prefix_code < 4) {
664 length = prefix_code + 1;
665 } else {
666 int extra_bits = (prefix_code - 2) >> 1;
667 int offset = 2 + (prefix_code & 1) << extra_bits;
668 length = offset + get_bits(&s->gb, extra_bits) + 1;
669 }
670 prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb);
671 if (prefix_code > 39U) {
672 av_log(s->avctx, AV_LOG_ERROR,
673 "distance prefix code too large: %d\n", prefix_code);
674 return AVERROR_INVALIDDATA;
675 }
676 if (prefix_code < 4) {
677 distance = prefix_code + 1;
678 } else {
679 int extra_bits = prefix_code - 2 >> 1;
680 int offset = 2 + (prefix_code & 1) << extra_bits;
681 distance = offset + get_bits(&s->gb, extra_bits) + 1;
682 }
683
684 /* find reference location */
686 int xi = lz77_distance_offsets[distance - 1][0];
687 int yi = lz77_distance_offsets[distance - 1][1];
688 distance = FFMAX(1, xi + yi * width);
689 } else {
691 }
692 ref_x = x;
693 ref_y = y;
694 if (distance <= x) {
695 ref_x -= distance;
696 distance = 0;
697 } else {
698 ref_x = 0;
699 distance -= x;
700 }
701 while (distance >= width) {
702 ref_y--;
703 distance -= width;
704 }
705 if (distance > 0) {
706 ref_x = width - distance;
707 ref_y--;
708 }
709 ref_x = FFMAX(0, ref_x);
710 ref_y = FFMAX(0, ref_y);
711
712 if (ref_y == y && ref_x >= x)
713 return AVERROR_INVALIDDATA;
714
715 /* copy pixels
716 * source and dest regions can overlap and wrap lines, so just
717 * copy per-pixel */
718 for (i = 0; i < length; i++) {
719 uint8_t *p_ref = GET_PIXEL(img->frame, ref_x, ref_y);
720 uint8_t *p = GET_PIXEL(img->frame, x, y);
721
722 AV_COPY32(p, p_ref);
723 if (img->color_cache_bits)
725 x++;
726 ref_x++;
727 if (x == width) {
728 x = 0;
729 y++;
730 }
731 if (ref_x == width) {
732 ref_x = 0;
733 ref_y++;
734 }
735 if (y == img->frame->height || ref_y == img->frame->height)
736 break;
737 }
738 } else {
739 /* read from color cache */
740 uint8_t *p = GET_PIXEL(img->frame, x, y);
741 int cache_idx = v - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
742
743 if (!img->color_cache_bits) {
744 av_log(s->avctx, AV_LOG_ERROR, "color cache not found\n");
745 return AVERROR_INVALIDDATA;
746 }
747 if (cache_idx >= 1 << img->color_cache_bits) {
748 av_log(s->avctx, AV_LOG_ERROR,
749 "color cache index out-of-bounds\n");
750 return AVERROR_INVALIDDATA;
751 }
752 AV_WB32(p, img->color_cache[cache_idx]);
753 x++;
754 if (x == width) {
755 x = 0;
756 y++;
757 }
758 }
759 }
760
761 return 0;
762}
763
764/* PRED_MODE_BLACK */
765static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
766 const uint8_t *p_t, const uint8_t *p_tr)
767{
768 AV_WB32(p, 0xFF000000);
769}
770
771/* PRED_MODE_L */
772static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
773 const uint8_t *p_t, const uint8_t *p_tr)
774{
775 AV_COPY32(p, p_l);
776}
777
778/* PRED_MODE_T */
779static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
780 const uint8_t *p_t, const uint8_t *p_tr)
781{
782 AV_COPY32(p, p_t);
783}
784
785/* PRED_MODE_TR */
786static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
787 const uint8_t *p_t, const uint8_t *p_tr)
788{
789 AV_COPY32(p, p_tr);
790}
791
792/* PRED_MODE_TL */
793static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
794 const uint8_t *p_t, const uint8_t *p_tr)
795{
796 AV_COPY32(p, p_tl);
797}
798
799/* PRED_MODE_AVG_T_AVG_L_TR */
800static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
801 const uint8_t *p_t, const uint8_t *p_tr)
802{
803 p[0] = p_t[0] + (p_l[0] + p_tr[0] >> 1) >> 1;
804 p[1] = p_t[1] + (p_l[1] + p_tr[1] >> 1) >> 1;
805 p[2] = p_t[2] + (p_l[2] + p_tr[2] >> 1) >> 1;
806 p[3] = p_t[3] + (p_l[3] + p_tr[3] >> 1) >> 1;
807}
808
809/* PRED_MODE_AVG_L_TL */
810static void inv_predict_6(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 p[0] = p_l[0] + p_tl[0] >> 1;
814 p[1] = p_l[1] + p_tl[1] >> 1;
815 p[2] = p_l[2] + p_tl[2] >> 1;
816 p[3] = p_l[3] + p_tl[3] >> 1;
817}
818
819/* PRED_MODE_AVG_L_T */
820static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
821 const uint8_t *p_t, const uint8_t *p_tr)
822{
823 p[0] = p_l[0] + p_t[0] >> 1;
824 p[1] = p_l[1] + p_t[1] >> 1;
825 p[2] = p_l[2] + p_t[2] >> 1;
826 p[3] = p_l[3] + p_t[3] >> 1;
827}
828
829/* PRED_MODE_AVG_TL_T */
830static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
831 const uint8_t *p_t, const uint8_t *p_tr)
832{
833 p[0] = p_tl[0] + p_t[0] >> 1;
834 p[1] = p_tl[1] + p_t[1] >> 1;
835 p[2] = p_tl[2] + p_t[2] >> 1;
836 p[3] = p_tl[3] + p_t[3] >> 1;
837}
838
839/* PRED_MODE_AVG_T_TR */
840static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
841 const uint8_t *p_t, const uint8_t *p_tr)
842{
843 p[0] = p_t[0] + p_tr[0] >> 1;
844 p[1] = p_t[1] + p_tr[1] >> 1;
845 p[2] = p_t[2] + p_tr[2] >> 1;
846 p[3] = p_t[3] + p_tr[3] >> 1;
847}
848
849/* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
850static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
851 const uint8_t *p_t, const uint8_t *p_tr)
852{
853 p[0] = (p_l[0] + p_tl[0] >> 1) + (p_t[0] + p_tr[0] >> 1) >> 1;
854 p[1] = (p_l[1] + p_tl[1] >> 1) + (p_t[1] + p_tr[1] >> 1) >> 1;
855 p[2] = (p_l[2] + p_tl[2] >> 1) + (p_t[2] + p_tr[2] >> 1) >> 1;
856 p[3] = (p_l[3] + p_tl[3] >> 1) + (p_t[3] + p_tr[3] >> 1) >> 1;
857}
858
859/* PRED_MODE_SELECT */
860static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
861 const uint8_t *p_t, const uint8_t *p_tr)
862{
863 int diff = (FFABS(p_l[0] - p_tl[0]) - FFABS(p_t[0] - p_tl[0])) +
864 (FFABS(p_l[1] - p_tl[1]) - FFABS(p_t[1] - p_tl[1])) +
865 (FFABS(p_l[2] - p_tl[2]) - FFABS(p_t[2] - p_tl[2])) +
866 (FFABS(p_l[3] - p_tl[3]) - FFABS(p_t[3] - p_tl[3]));
867 if (diff <= 0)
868 AV_COPY32(p, p_t);
869 else
870 AV_COPY32(p, p_l);
871}
872
873/* PRED_MODE_ADD_SUBTRACT_FULL */
874static void inv_predict_12(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 p[0] = av_clip_uint8(p_l[0] + p_t[0] - p_tl[0]);
878 p[1] = av_clip_uint8(p_l[1] + p_t[1] - p_tl[1]);
879 p[2] = av_clip_uint8(p_l[2] + p_t[2] - p_tl[2]);
880 p[3] = av_clip_uint8(p_l[3] + p_t[3] - p_tl[3]);
881}
882
883static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
884{
885 int d = a + b >> 1;
886 return av_clip_uint8(d + (d - c) / 2);
887}
888
889/* PRED_MODE_ADD_SUBTRACT_HALF */
890static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
891 const uint8_t *p_t, const uint8_t *p_tr)
892{
893 p[0] = clamp_add_subtract_half(p_l[0], p_t[0], p_tl[0]);
894 p[1] = clamp_add_subtract_half(p_l[1], p_t[1], p_tl[1]);
895 p[2] = clamp_add_subtract_half(p_l[2], p_t[2], p_tl[2]);
896 p[3] = clamp_add_subtract_half(p_l[3], p_t[3], p_tl[3]);
897}
898
899typedef void (*inv_predict_func)(uint8_t *p, const uint8_t *p_l,
900 const uint8_t *p_tl, const uint8_t *p_t,
901 const uint8_t *p_tr);
902
909
910static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
911{
912 uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr;
913 uint8_t p[4];
914
915 dec = GET_PIXEL(frame, x, y);
916 p_l = GET_PIXEL(frame, x - 1, y);
917 p_tl = GET_PIXEL(frame, x - 1, y - 1);
918 p_t = GET_PIXEL(frame, x, y - 1);
919 if (x == frame->width - 1)
920 p_tr = GET_PIXEL(frame, 0, y);
921 else
922 p_tr = GET_PIXEL(frame, x + 1, y - 1);
923
924 inverse_predict[m](p, p_l, p_tl, p_t, p_tr);
925
926 dec[0] += p[0];
927 dec[1] += p[1];
928 dec[2] += p[2];
929 dec[3] += p[3];
930}
931
933{
934 ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
935 ImageContext *pimg = &s->image[IMAGE_ROLE_PREDICTOR];
936 int x, y;
937
938 for (y = 0; y < img->frame->height; y++) {
939 for (x = 0; x < s->reduced_width; x++) {
940 int tx = x >> pimg->size_reduction;
941 int ty = y >> pimg->size_reduction;
942 enum PredictionMode m = GET_PIXEL_COMP(pimg->frame, tx, ty, 2);
943
944 if (x == 0) {
945 if (y == 0)
946 m = PRED_MODE_BLACK;
947 else
948 m = PRED_MODE_T;
949 } else if (y == 0)
950 m = PRED_MODE_L;
951
952 if (m > 13) {
953 av_log(s->avctx, AV_LOG_ERROR,
954 "invalid predictor mode: %d\n", m);
955 return AVERROR_INVALIDDATA;
956 }
957 inverse_prediction(img->frame, m, x, y);
958 }
959 }
960 return 0;
961}
962
963static av_always_inline uint8_t color_transform_delta(uint8_t color_pred,
964 uint8_t color)
965{
966 return (int)ff_u8_to_s8(color_pred) * ff_u8_to_s8(color) >> 5;
967}
968
970{
971 ImageContext *img, *cimg;
972 int x, y, cx, cy;
973 uint8_t *p, *cp;
974
975 img = &s->image[IMAGE_ROLE_ARGB];
976 cimg = &s->image[IMAGE_ROLE_COLOR_TRANSFORM];
977
978 for (y = 0; y < img->frame->height; y++) {
979 for (x = 0; x < s->reduced_width; x++) {
980 cx = x >> cimg->size_reduction;
981 cy = y >> cimg->size_reduction;
982 cp = GET_PIXEL(cimg->frame, cx, cy);
983 p = GET_PIXEL(img->frame, x, y);
984
985 p[1] += color_transform_delta(cp[3], p[2]);
986 p[3] += color_transform_delta(cp[2], p[2]) +
987 color_transform_delta(cp[1], p[1]);
988 }
989 }
990 return 0;
991}
992
994{
995 int x, y;
996 ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
997
998 for (y = 0; y < img->frame->height; y++) {
999 for (x = 0; x < s->reduced_width; x++) {
1000 uint8_t *p = GET_PIXEL(img->frame, x, y);
1001 p[1] += p[2];
1002 p[3] += p[2];
1003 }
1004 }
1005 return 0;
1006}
1007
1009{
1011 ImageContext *pal;
1012 int i, x, y;
1013 uint8_t *p;
1014
1015 img = &s->image[IMAGE_ROLE_ARGB];
1016 pal = &s->image[IMAGE_ROLE_COLOR_INDEXING];
1017
1018 if (pal->size_reduction > 0) { // undo pixel packing
1019 GetBitContext gb_g;
1020 uint8_t *line;
1021 int pixel_bits = 8 >> pal->size_reduction;
1022
1023 line = av_malloc(img->frame->linesize[0] + AV_INPUT_BUFFER_PADDING_SIZE);
1024 if (!line)
1025 return AVERROR(ENOMEM);
1026
1027 for (y = 0; y < img->frame->height; y++) {
1028 p = GET_PIXEL(img->frame, 0, y);
1029 memcpy(line, p, img->frame->linesize[0]);
1030 init_get_bits(&gb_g, line, img->frame->linesize[0] * 8);
1031 skip_bits(&gb_g, 16);
1032 i = 0;
1033 for (x = 0; x < img->frame->width; x++) {
1034 p = GET_PIXEL(img->frame, x, y);
1035 p[2] = get_bits(&gb_g, pixel_bits);
1036 i++;
1037 if (i == 1 << pal->size_reduction) {
1038 skip_bits(&gb_g, 24);
1039 i = 0;
1040 }
1041 }
1042 }
1043 av_free(line);
1044 s->reduced_width = s->width; // we are back to full size
1045 }
1046
1047 // switch to local palette if it's worth initializing it
1048 if (img->frame->height * img->frame->width > 300) {
1049 uint8_t palette[256 * 4];
1050 const int size = pal->frame->width * 4;
1051 av_assert0(size <= 1024U);
1052 memcpy(palette, GET_PIXEL(pal->frame, 0, 0), size); // copy palette
1053 // set extra entries to transparent black
1054 memset(palette + size, 0, 256 * 4 - size);
1055 for (y = 0; y < img->frame->height; y++) {
1056 for (x = 0; x < img->frame->width; x++) {
1057 p = GET_PIXEL(img->frame, x, y);
1058 i = p[2];
1059 AV_COPY32(p, &palette[i * 4]);
1060 }
1061 }
1062 } else {
1063 for (y = 0; y < img->frame->height; y++) {
1064 for (x = 0; x < img->frame->width; x++) {
1065 p = GET_PIXEL(img->frame, x, y);
1066 i = p[2];
1067 if (i >= pal->frame->width) {
1068 AV_WB32(p, 0x00000000);
1069 } else {
1070 const uint8_t *pi = GET_PIXEL(pal->frame, i, 0);
1071 AV_COPY32(p, pi);
1072 }
1073 }
1074 }
1075 }
1076
1077 return 0;
1078}
1079
1080static void update_canvas_size(AVCodecContext *avctx, int w, int h)
1081{
1082 WebPContext *s = avctx->priv_data;
1083 if (s->width && s->width != w) {
1084 av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n",
1085 s->width, w);
1086 }
1087 s->width = w;
1088 if (s->height && s->height != h) {
1089 av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n",
1090 s->height, h);
1091 }
1092 s->height = h;
1093}
1094
1096 int *got_frame, const uint8_t *data_start,
1097 unsigned int data_size, int is_alpha_chunk)
1098{
1099 WebPContext *s = avctx->priv_data;
1100 int w, h, ret, i, used;
1101
1102 if (!is_alpha_chunk)
1103 avctx->pix_fmt = AV_PIX_FMT_ARGB;
1104
1105 ret = init_get_bits8(&s->gb, data_start, data_size);
1106 if (ret < 0)
1107 return ret;
1108
1109 if (!is_alpha_chunk) {
1110 if (get_bits(&s->gb, 8) != 0x2F) {
1111 av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n");
1112 return AVERROR_INVALIDDATA;
1113 }
1114
1115 w = get_bits(&s->gb, 14) + 1;
1116 h = get_bits(&s->gb, 14) + 1;
1117
1118 update_canvas_size(avctx, w, h);
1119
1120 ret = ff_set_dimensions(avctx, s->width, s->height);
1121 if (ret < 0)
1122 return ret;
1123
1124 s->has_alpha = get_bits1(&s->gb);
1125
1126 if (get_bits(&s->gb, 3) != 0x0) {
1127 av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n");
1128 return AVERROR_INVALIDDATA;
1129 }
1130 } else {
1131 if (!s->width || !s->height)
1132 return AVERROR_BUG;
1133 w = s->width;
1134 h = s->height;
1135 }
1136
1137 /* parse transformations */
1138 s->nb_transforms = 0;
1139 s->reduced_width = s->width;
1140 used = 0;
1141 while (get_bits1(&s->gb)) {
1142 enum TransformType transform = get_bits(&s->gb, 2);
1143 if (used & (1 << transform)) {
1144 av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n",
1145 transform);
1146 ret = AVERROR_INVALIDDATA;
1147 goto free_and_return;
1148 }
1149 used |= (1 << transform);
1150 s->transforms[s->nb_transforms++] = transform;
1151 switch (transform) {
1154 break;
1155 case COLOR_TRANSFORM:
1156 ret = parse_transform_color(s);
1157 break;
1160 break;
1161 }
1162 if (ret < 0)
1163 goto free_and_return;
1164 }
1165
1166 /* decode primary image */
1167 s->image[IMAGE_ROLE_ARGB].frame = p;
1168 if (is_alpha_chunk)
1169 s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
1171 if (ret < 0)
1172 goto free_and_return;
1173
1174 /* apply transformations */
1175 for (i = s->nb_transforms - 1; i >= 0; i--) {
1176 switch (s->transforms[i]) {
1179 break;
1180 case COLOR_TRANSFORM:
1181 ret = apply_color_transform(s);
1182 break;
1183 case SUBTRACT_GREEN:
1185 break;
1188 break;
1189 }
1190 if (ret < 0)
1191 goto free_and_return;
1192 }
1193
1194 *got_frame = 1;
1195 p->pict_type = AV_PICTURE_TYPE_I;
1196 p->flags |= AV_FRAME_FLAG_KEY;
1197 p->flags |= AV_FRAME_FLAG_LOSSLESS;
1198 ret = data_size;
1199
1200free_and_return:
1201 for (i = 0; i < IMAGE_ROLE_NB; i++)
1202 image_ctx_free(&s->image[i]);
1203
1204 return ret;
1205}
1206
1208{
1209 int x, y, ls;
1210 uint8_t *dec;
1211
1212 ls = frame->linesize[3];
1213
1214 /* filter first row using horizontal filter */
1215 dec = frame->data[3] + 1;
1216 for (x = 1; x < frame->width; x++, dec++)
1217 *dec += *(dec - 1);
1218
1219 /* filter first column using vertical filter */
1220 dec = frame->data[3] + ls;
1221 for (y = 1; y < frame->height; y++, dec += ls)
1222 *dec += *(dec - ls);
1223
1224 /* filter the rest using the specified filter */
1225 switch (m) {
1227 for (y = 1; y < frame->height; y++) {
1228 dec = frame->data[3] + y * ls + 1;
1229 for (x = 1; x < frame->width; x++, dec++)
1230 *dec += *(dec - 1);
1231 }
1232 break;
1234 for (y = 1; y < frame->height; y++) {
1235 dec = frame->data[3] + y * ls + 1;
1236 for (x = 1; x < frame->width; x++, dec++)
1237 *dec += *(dec - ls);
1238 }
1239 break;
1241 for (y = 1; y < frame->height; y++) {
1242 dec = frame->data[3] + y * ls + 1;
1243 for (x = 1; x < frame->width; x++, dec++)
1244 dec[0] += av_clip_uint8(*(dec - 1) + *(dec - ls) - *(dec - ls - 1));
1245 }
1246 break;
1247 }
1248}
1249
1251 const uint8_t *data_start,
1252 unsigned int data_size)
1253{
1254 WebPContext *s = avctx->priv_data;
1255 int x, y, ret;
1256
1257 if (s->alpha_compression == ALPHA_COMPRESSION_NONE) {
1258 GetByteContext gb;
1259
1260 bytestream2_init(&gb, data_start, data_size);
1261 for (y = 0; y < s->height; y++)
1262 bytestream2_get_buffer(&gb, p->data[3] + p->linesize[3] * y,
1263 s->width);
1264 } else if (s->alpha_compression == ALPHA_COMPRESSION_VP8L) {
1265 uint8_t *ap, *pp;
1266 int alpha_got_frame = 0;
1267
1268 s->alpha_frame = av_frame_alloc();
1269 if (!s->alpha_frame)
1270 return AVERROR(ENOMEM);
1271
1272 ret = vp8_lossless_decode_frame(avctx, s->alpha_frame, &alpha_got_frame,
1273 data_start, data_size, 1);
1274 if (ret < 0) {
1275 av_frame_free(&s->alpha_frame);
1276 return ret;
1277 }
1278 if (!alpha_got_frame) {
1279 av_frame_free(&s->alpha_frame);
1280 return AVERROR_INVALIDDATA;
1281 }
1282
1283 /* copy green component of alpha image to alpha plane of primary image */
1284 for (y = 0; y < s->height; y++) {
1285 ap = GET_PIXEL(s->alpha_frame, 0, y) + 2;
1286 pp = p->data[3] + p->linesize[3] * y;
1287 for (x = 0; x < s->width; x++) {
1288 *pp = *ap;
1289 pp++;
1290 ap += 4;
1291 }
1292 }
1293 av_frame_free(&s->alpha_frame);
1294 }
1295
1296 /* apply alpha filtering */
1297 if (s->alpha_filter)
1298 alpha_inverse_prediction(p, s->alpha_filter);
1299
1300 return 0;
1301}
1302
1304 int *got_frame, uint8_t *data_start,
1305 unsigned int data_size)
1306{
1307 WebPContext *s = avctx->priv_data;
1308 int ret;
1309
1310 if (!s->initialized) {
1311 ff_vp8_decode_init(avctx);
1312 s->initialized = 1;
1313 s->v.actually_webp = 1;
1314 }
1315 avctx->pix_fmt = s->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
1316
1317 if (data_size > INT_MAX) {
1318 av_log(avctx, AV_LOG_ERROR, "unsupported chunk size\n");
1319 return AVERROR_PATCHWELCOME;
1320 }
1321
1322 av_packet_unref(s->pkt);
1323 s->pkt->data = data_start;
1324 s->pkt->size = data_size;
1325
1326 ret = ff_vp8_decode_frame(avctx, p, got_frame, s->pkt);
1327 if (ret < 0)
1328 return ret;
1329
1330 if (!*got_frame)
1331 return AVERROR_INVALIDDATA;
1332
1333 update_canvas_size(avctx, avctx->width, avctx->height);
1334
1335 if (s->has_alpha) {
1336 ret = vp8_lossy_decode_alpha(avctx, p, s->alpha_data,
1337 s->alpha_data_size);
1338 if (ret < 0)
1339 return ret;
1340 }
1341 return ret;
1342}
1343
1345 int *got_frame, AVPacket *avpkt)
1346{
1347 WebPContext *s = avctx->priv_data;
1348 GetByteContext gb;
1349 int ret;
1350 uint32_t chunk_type, chunk_size;
1351 int vp8x_flags = 0;
1352
1353 s->avctx = avctx;
1354 s->width = 0;
1355 s->height = 0;
1356 *got_frame = 0;
1357 s->has_alpha = 0;
1358 s->has_exif = 0;
1359 s->has_iccp = 0;
1360 s->has_xmp = 0;
1361 bytestream2_init(&gb, avpkt->data, avpkt->size);
1362
1363 if (bytestream2_get_bytes_left(&gb) < 12)
1364 return AVERROR_INVALIDDATA;
1365
1366 if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
1367 av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
1368 return AVERROR_INVALIDDATA;
1369 }
1370
1371 chunk_size = bytestream2_get_le32(&gb);
1372 if (bytestream2_get_bytes_left(&gb) < chunk_size)
1373 return AVERROR_INVALIDDATA;
1374
1375 if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) {
1376 av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n");
1377 return AVERROR_INVALIDDATA;
1378 }
1379
1380 while (bytestream2_get_bytes_left(&gb) > 8) {
1381 chunk_type = bytestream2_get_le32(&gb);
1382 chunk_size = bytestream2_get_le32(&gb);
1383 if (chunk_size == UINT32_MAX)
1384 return AVERROR_INVALIDDATA;
1385 chunk_size += chunk_size & 1;
1386
1387 if (bytestream2_get_bytes_left(&gb) < chunk_size) {
1388 /* we seem to be running out of data, but it could also be that the
1389 bitstream has trailing junk leading to bogus chunk_size. */
1390 break;
1391 }
1392
1393 switch (chunk_type) {
1394 case MKTAG('V', 'P', '8', ' '):
1395 if (!*got_frame) {
1396 ret = vp8_lossy_decode_frame(avctx, p, got_frame,
1397 avpkt->data + bytestream2_tell(&gb),
1398 chunk_size);
1399 if (ret < 0)
1400 return ret;
1401 }
1402 bytestream2_skip(&gb, chunk_size);
1403 break;
1404 case MKTAG('V', 'P', '8', 'L'):
1405 if (!*got_frame) {
1406 ret = vp8_lossless_decode_frame(avctx, p, got_frame,
1407 avpkt->data + bytestream2_tell(&gb),
1408 chunk_size, 0);
1409 if (ret < 0)
1410 return ret;
1411 }
1412 bytestream2_skip(&gb, chunk_size);
1413 break;
1414 case MKTAG('V', 'P', '8', 'X'):
1415 if (s->width || s->height || *got_frame) {
1416 av_log(avctx, AV_LOG_ERROR, "Canvas dimensions are already set\n");
1417 return AVERROR_INVALIDDATA;
1418 }
1419 vp8x_flags = bytestream2_get_byte(&gb);
1420 bytestream2_skip(&gb, 3);
1421 s->width = bytestream2_get_le24(&gb) + 1;
1422 s->height = bytestream2_get_le24(&gb) + 1;
1423 ret = av_image_check_size(s->width, s->height, 0, avctx);
1424 if (ret < 0)
1425 return ret;
1426 break;
1427 case MKTAG('A', 'L', 'P', 'H'): {
1428 int alpha_header, filter_m, compression;
1429
1430 if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
1431 av_log(avctx, AV_LOG_WARNING,
1432 "ALPHA chunk present, but alpha bit not set in the "
1433 "VP8X header\n");
1434 }
1435 if (chunk_size == 0) {
1436 av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
1437 return AVERROR_INVALIDDATA;
1438 }
1439 alpha_header = bytestream2_get_byte(&gb);
1440 s->alpha_data = avpkt->data + bytestream2_tell(&gb);
1441 s->alpha_data_size = chunk_size - 1;
1442 bytestream2_skip(&gb, s->alpha_data_size);
1443
1444 filter_m = (alpha_header >> 2) & 0x03;
1445 compression = alpha_header & 0x03;
1446
1447 if (compression > ALPHA_COMPRESSION_VP8L) {
1448 av_log(avctx, AV_LOG_VERBOSE,
1449 "skipping unsupported ALPHA chunk\n");
1450 } else {
1451 s->has_alpha = 1;
1452 s->alpha_compression = compression;
1453 s->alpha_filter = filter_m;
1454 }
1455
1456 break;
1457 }
1458 case MKTAG('E', 'X', 'I', 'F'): {
1459 AVBufferRef *exif_buf = NULL;
1460
1461 if (s->has_exif) {
1462 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n");
1463 goto exif_end;
1464 }
1465
1466 if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA))
1467 av_log(avctx, AV_LOG_WARNING,
1468 "EXIF chunk present, but Exif bit not set in the "
1469 "VP8X header\n");
1470
1471 exif_buf = av_buffer_alloc(chunk_size);
1472 if (!exif_buf) {
1473 av_log(avctx, AV_LOG_WARNING, "unable to allocate EXIF buffer\n");
1474 goto exif_end;
1475 }
1476 s->has_exif = 1;
1477 memcpy(exif_buf->data, gb.buffer, chunk_size);
1478
1479 ret = ff_decode_exif_attach_buffer(avctx, p, &exif_buf, AV_EXIF_TIFF_HEADER);
1480 if (ret < 0)
1481 av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n");
1482
1483exif_end:
1484 bytestream2_skip(&gb, chunk_size);
1485 break;
1486 }
1487 case MKTAG('I', 'C', 'C', 'P'): {
1488 AVFrameSideData *sd;
1489
1490 if (s->has_iccp) {
1491 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra ICCP chunk\n");
1492 bytestream2_skip(&gb, chunk_size);
1493 break;
1494 }
1495 if (!(vp8x_flags & VP8X_FLAG_ICC))
1496 av_log(avctx, AV_LOG_WARNING,
1497 "ICCP chunk present, but ICC Profile bit not set in the "
1498 "VP8X header\n");
1499
1500 s->has_iccp = 1;
1501
1502 ret = ff_frame_new_side_data(avctx, p, AV_FRAME_DATA_ICC_PROFILE, chunk_size, &sd);
1503 if (ret < 0)
1504 return ret;
1505
1506 if (sd) {
1507 bytestream2_get_buffer(&gb, sd->data, chunk_size);
1508 } else {
1509 bytestream2_skip(&gb, chunk_size);
1510 }
1511 break;
1512 }
1513 case MKTAG('A', 'N', 'I', 'M'):
1514 case MKTAG('A', 'N', 'M', 'F'):
1515 av_log(avctx, AV_LOG_WARNING, "skipping unsupported chunk: %s\n",
1516 av_fourcc2str(chunk_type));
1517 bytestream2_skip(&gb, chunk_size);
1518 break;
1519 case MKTAG('X', 'M', 'P', ' '): {
1520 if (s->has_xmp) {
1521 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra XMP chunk\n");
1522 bytestream2_skip(&gb, chunk_size);
1523 break;
1524 }
1525 if (!(vp8x_flags & VP8X_FLAG_XMP_METADATA))
1526 av_log(avctx, AV_LOG_WARNING,
1527 "XMP chunk present, but XMP bit not set in the "
1528 "VP8X header\n");
1529
1530 s->has_xmp = 1;
1531
1532 // there are at least chunk_size bytes left to read
1533 uint8_t *buffer = av_malloc(chunk_size + 1);
1534 if (!buffer)
1535 return AVERROR(ENOMEM);
1536
1537 bytestream2_get_buffer(&gb, buffer, chunk_size);
1538 buffer[chunk_size] = '\0';
1539
1540 av_dict_set(&p->metadata, "xmp", buffer, AV_DICT_DONT_STRDUP_VAL);
1541 break;
1542 }
1543 default:
1544 av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
1545 av_fourcc2str(chunk_type));
1546 bytestream2_skip(&gb, chunk_size);
1547 break;
1548 }
1549 }
1550
1551 if (!*got_frame) {
1552 av_log(avctx, AV_LOG_ERROR, "image data not found\n");
1553 return AVERROR_INVALIDDATA;
1554 }
1555
1556 return avpkt->size;
1557}
1558
1560{
1561 WebPContext *s = avctx->priv_data;
1562
1563 s->pkt = av_packet_alloc();
1564 if (!s->pkt)
1565 return AVERROR(ENOMEM);
1566
1567 return 0;
1568}
1569
1571{
1572 WebPContext *s = avctx->priv_data;
1573
1574 av_packet_free(&s->pkt);
1575
1576 if (s->initialized)
1577 return ff_vp8_decode_free(avctx);
1578
1579 return 0;
1580}
1581
1583 .p.name = "webp",
1584 CODEC_LONG_NAME("WebP image"),
1585 .p.type = AVMEDIA_TYPE_VIDEO,
1586 .p.id = AV_CODEC_ID_WEBP,
1587 .priv_data_size = sizeof(WebPContext),
1590 .close = webp_decode_close,
1591 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
1592 .caps_internal = FF_CODEC_CAP_ICC_PROFILES |
1594};
1595
1596#if CONFIG_WEBP_ANIM_DECODER
1597
1598#define ANMF_FLAG_DISPOSE (1 << 0)
1599#define ANMF_FLAG_NO_BLEND (1 << 1)
1600
1601typedef struct AnimatedWebPContext {
1602 WebPContext w;
1603
1604 AVFrame *canvas; /* AVFrame for canvas */
1605 AVFrame *subframe; /* AVFrame for subframe */
1606 int canvas_width; /* canvas width */
1607 int canvas_height; /* canvas height */
1608 int anmf_flags; /* frame flags from ANMF chunk */
1609 int pos_x; /* frame position X */
1610 int pos_y; /* frame position Y */
1611 int duration; /* frame duration */
1612 int prev_anmf_flags; /* previous frame flags from ANMF chunk */
1613 int prev_width; /* previous frame width */
1614 int prev_height; /* previous frame height */
1615 int prev_pos_x; /* previous frame position X */
1616 int prev_pos_y; /* previous frame position Y */
1617 uint8_t background_argb[4]; /* background color in ARGB format */
1618 uint8_t background_yuva[4]; /* background color in YUVA format */
1619} AnimatedWebPContext;
1620
1621/*
1622 * Blend src (foreground) into dst (background), in ARGB format.
1623 * pos_x, pos_y is the position in dst.
1624 */
1625static void blend_alpha_argb(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1626{
1627 for (int y = 0; y < src->height; y++) {
1628 const uint8_t *src_argb = src->data[0] + y * src->linesize[0];
1629 uint8_t *dst_argb = dst->data[0] + (pos_y + y) * dst->linesize[0] + pos_x * sizeof(uint32_t);
1630 for (int x = 0; x < src->width; x++) {
1631 int src_alpha = src_argb[0];
1632 int dst_alpha = dst_argb[0];
1633
1634 if (src_alpha == 255) {
1635 memcpy(dst_argb, src_argb, sizeof(uint32_t));
1636 } else if (src_alpha == 0) {
1637 // no-op
1638 } else {
1639 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1640 int blend_alpha = src_alpha + tmp_alpha;
1641 int scale = (1UL << 24) / blend_alpha;
1642
1643 dst_argb[0] = blend_alpha;
1644 dst_argb[1] = (((uint32_t) (src_argb[1] * src_alpha + dst_argb[1] * tmp_alpha)) * scale) >> 24;
1645 dst_argb[2] = (((uint32_t) (src_argb[2] * src_alpha + dst_argb[2] * tmp_alpha)) * scale) >> 24;
1646 dst_argb[3] = (((uint32_t) (src_argb[3] * src_alpha + dst_argb[3] * tmp_alpha)) * scale) >> 24;
1647 }
1648 src_argb += sizeof(uint32_t);
1649 dst_argb += sizeof(uint32_t);
1650 }
1651 }
1652}
1653
1654/*
1655 * Blend src (foreground) into dst (background), in YUVA format.
1656 * pos_x, pos_y is the position in dst.
1657 */
1658static void blend_alpha_yuva(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1659{
1661
1662 int plane_y = desc->comp[0].plane;
1663 int plane_u = desc->comp[1].plane;
1664 int plane_v = desc->comp[2].plane;
1665 int plane_a = desc->comp[3].plane;
1666
1667 // blend U & V planes first, because the later step may modify alpha plane
1668 for (int y = 0; y < AV_CEIL_RSHIFT(src->height, 1); y++) {
1669 int tile_h = FFMIN(src->height - y * 2, 2);
1670 const uint8_t *src_u = src->data[plane_u] + y * src->linesize[plane_u];
1671 const uint8_t *src_v = src->data[plane_v] + y * src->linesize[plane_v];
1672 uint8_t *dst_u = dst->data[plane_u] + ((pos_y >> 1) + y) * dst->linesize[plane_u] + (pos_x >> 1);
1673 uint8_t *dst_v = dst->data[plane_v] + ((pos_y >> 1) + y) * dst->linesize[plane_v] + (pos_x >> 1);
1674 for (int x = 0; x < AV_CEIL_RSHIFT(src->width, 1); x++) {
1675 int tile_w = FFMIN(src->width - x * 2, 2);
1676 // calculate the average alpha of the tile
1677 int src_alpha = 0;
1678 int dst_alpha = 0;
1679 for (int yy = 0; yy < tile_h; yy++) {
1680 for (int xx = 0; xx < tile_w; xx++) {
1681 src_alpha += src->data[plane_a][(y * 2 + yy) * src->linesize[plane_a] +
1682 (x * 2 + xx)];
1683 dst_alpha += dst->data[plane_a][(((pos_y >> 1) + y) * 2 + yy) * dst->linesize[plane_a] +
1684 (((pos_x >> 1) + x) * 2 + xx)];
1685 }
1686 }
1687 int shift = (tile_h == 2) + (tile_w == 2);
1688 src_alpha = AV_CEIL_RSHIFT(src_alpha, shift);
1689 dst_alpha = AV_CEIL_RSHIFT(dst_alpha, shift);
1690
1691 if (src_alpha == 255) {
1692 *dst_u = *src_u;
1693 *dst_v = *src_v;
1694 } else if (src_alpha == 0) {
1695 // no-op
1696 } else {
1697 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1698 int blend_alpha = src_alpha + tmp_alpha;
1699 int scale = (1UL << 24) / blend_alpha;
1700 *dst_u = (((uint32_t) (*src_u * src_alpha + *dst_u * tmp_alpha)) * scale) >> 24;
1701 *dst_v = (((uint32_t) (*src_v * src_alpha + *dst_v * tmp_alpha)) * scale) >> 24;
1702 }
1703 src_u += 1;
1704 src_v += 1;
1705 dst_u += 1;
1706 dst_v += 1;
1707 }
1708 }
1709
1710 // blend Y & A planes
1711 for (int y = 0; y < src->height; y++) {
1712 const uint8_t *src_y = src->data[plane_y] + y * src->linesize[plane_y];
1713 const uint8_t *src_a = src->data[plane_a] + y * src->linesize[plane_a];
1714 uint8_t *dst_y = dst->data[plane_y] + (pos_y + y) * dst->linesize[plane_y] + pos_x;
1715 uint8_t *dst_a = dst->data[plane_a] + (pos_y + y) * dst->linesize[plane_a] + pos_x;
1716 for (int x = 0; x < src->width; x++) {
1717 int src_alpha = *src_a;
1718 int dst_alpha = *dst_a;
1719
1720 if (src_alpha == 255) {
1721 *dst_y = *src_y;
1722 *dst_a = 255;
1723 } else if (src_alpha == 0) {
1724 // no-op
1725 } else {
1726 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1727 int blend_alpha = src_alpha + tmp_alpha;
1728 int scale = (1UL << 24) / blend_alpha;
1729 *dst_y = (((uint32_t) (*src_y * src_alpha + *dst_y * tmp_alpha)) * scale) >> 24;
1730 *dst_a = blend_alpha;
1731 }
1732 src_y += 1;
1733 src_a += 1;
1734 dst_y += 1;
1735 dst_a += 1;
1736 }
1737 }
1738}
1739
1740static av_always_inline void webp_yuva2argb(uint8_t *out, int Y, int U, int V, int A)
1741{
1742 // variables used in macros
1743 const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
1744 uint8_t r, g, b;
1745 int y, cb, cr;
1746 int r_add, g_add, b_add;
1747
1749 YUV_TO_RGB2_CCIR(r, g, b, Y);
1750
1751 out[0] = av_clip_uint8(A);
1752 out[1] = av_clip_uint8(r);
1753 out[2] = av_clip_uint8(g);
1754 out[3] = av_clip_uint8(b);
1755}
1756
1757static void copy_yuva2argb(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1758{
1759 const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src->format);
1760
1761 int alpha = src_desc->nb_components > 3;
1762 int plane_y = src_desc->comp[0].plane;
1763 int plane_u = src_desc->comp[1].plane;
1764 int plane_v = src_desc->comp[2].plane;
1765 int plane_a = src_desc->comp[3].plane;
1766
1767 for (int y = 0; y < src->height; y++) {
1768 const uint8_t *src_y = src->data[plane_y] + y * src->linesize[plane_y];
1769 const uint8_t *src_u = src->data[plane_u] + (y >> 1) * src->linesize[plane_u];
1770 const uint8_t *src_v = src->data[plane_v] + (y >> 1) * src->linesize[plane_v];
1771 const uint8_t *src_a = NULL;
1772 uint8_t *dst_argb = dst->data[0] + (pos_y + y) * dst->linesize[0] + pos_x * 4;
1773 if (alpha)
1774 src_a = src->data[plane_a] + y * src->linesize[plane_a];
1775
1776 for (int x = 0; x < src->width; x++) {
1777 webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, (alpha ? *src_a : 255));
1778 src_y += 1;
1779 src_u += x & 1;
1780 src_v += x & 1;
1781 if (alpha)
1782 src_a += 1;
1783 dst_argb += sizeof(uint32_t);
1784 }
1785 }
1786}
1787
1788static void blend_yuva2argb(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1789{
1790 const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src->format);
1791
1792 int plane_y = src_desc->comp[0].plane;
1793 int plane_u = src_desc->comp[1].plane;
1794 int plane_v = src_desc->comp[2].plane;
1795 int plane_a = src_desc->comp[3].plane;
1796
1797 for (int y = 0; y < src->height; y++) {
1798 const uint8_t *src_y = src->data[plane_y] + y * src->linesize[plane_y];
1799 const uint8_t *src_u = src->data[plane_u] + (y >> 1) * src->linesize[plane_u];
1800 const uint8_t *src_v = src->data[plane_v] + (y >> 1) * src->linesize[plane_v];
1801 const uint8_t *src_a = src->data[plane_a] + y * src->linesize[plane_a];
1802 uint8_t *dst_argb = dst->data[0] + (pos_y + y) * dst->linesize[0] + pos_x * 4;
1803
1804 for (int x = 0; x < src->width; x++) {
1805 int src_alpha = *src_a;
1806 int dst_alpha = dst_argb[0];
1807
1808 if (src_alpha == 255) {
1809 webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, src_alpha);
1810 } else if (src_alpha == 0) {
1811 // no-op
1812 } else {
1813 uint8_t tmp[4];
1814 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1815 int blend_alpha = src_alpha + tmp_alpha;
1816 int scale = (1UL << 24) / blend_alpha;
1817
1818 webp_yuva2argb(tmp, *src_y, *src_u, *src_v, src_alpha);
1819
1820 dst_argb[0] = blend_alpha;
1821 dst_argb[1] = (((uint32_t) (tmp[1] * src_alpha + dst_argb[1] * tmp_alpha)) * scale) >> 24;
1822 dst_argb[2] = (((uint32_t) (tmp[2] * src_alpha + dst_argb[2] * tmp_alpha)) * scale) >> 24;
1823 dst_argb[3] = (((uint32_t) (tmp[3] * src_alpha + dst_argb[3] * tmp_alpha)) * scale) >> 24;
1824 }
1825
1826 src_y += 1;
1827 src_u += x & 1;
1828 src_v += x & 1;
1829 src_a += 1;
1830 dst_argb += sizeof(uint32_t);
1831 }
1832 }
1833}
1834
1835static int blend_subframe_into_canvas(AnimatedWebPContext *s)
1836{
1837 AVFrame *canvas = s->canvas;
1838 AVFrame *frame = s->subframe;
1839
1840 if ((s->anmf_flags & ANMF_FLAG_NO_BLEND)
1841 || frame->format == AV_PIX_FMT_YUV420P) {
1842 // do not blend, overwrite
1843
1844 if (canvas->format == AV_PIX_FMT_ARGB) {
1845 if (canvas->format == frame->format) {
1846 const uint8_t *src = frame->data[0];
1847 uint8_t *dst = canvas->data[0] +
1848 s->pos_y * canvas->linesize[0] +
1849 s->pos_x * sizeof(uint32_t);
1850 for (int y = 0; y < s->w.height; y++) {
1851 memcpy(dst, src, s->w.width * sizeof(uint32_t));
1852 src += frame->linesize[0];
1853 dst += canvas->linesize[0];
1854 }
1855 } else {
1856 copy_yuva2argb(canvas, frame, s->pos_x, s->pos_y);
1857 }
1858 } else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ {
1860
1861 for (int comp = 0; comp < desc->nb_components; comp++) {
1862 int plane = desc->comp[comp].plane;
1863 int shift = (comp == 1 || comp == 2) ? 1 : 0;
1864 const uint8_t *src = frame->data[plane];
1865 uint8_t *dst = canvas->data[plane] +
1866 (s->pos_y >> shift) * canvas->linesize[plane] +
1867 (s->pos_x >> shift);
1868 for (int y = 0; y < AV_CEIL_RSHIFT(s->w.height, shift); y++) {
1869 memcpy(dst, src, AV_CEIL_RSHIFT(s->w.width, shift));
1870 src += frame->linesize[plane];
1871 dst += canvas->linesize[plane];
1872 }
1873 }
1874
1875 if (canvas->format == AV_PIX_FMT_YUVA420P && desc->nb_components < 4) {
1876 // frame does not have alpha, set alpha to 255
1877 const AVPixFmtDescriptor *canvas_desc = av_pix_fmt_desc_get(canvas->format);
1878 int plane = canvas_desc->comp[3].plane;
1879 uint8_t *dst = canvas->data[plane] + s->pos_y * canvas->linesize[plane] + s->pos_x;
1880 for (int y = 0; y < s->w.height; y++) {
1881 memset(dst, 255, s->w.width);
1882 dst += canvas->linesize[plane];
1883 }
1884 }
1885 }
1886 } else {
1887 // alpha blending
1888
1889 if (canvas->format == AV_PIX_FMT_ARGB) {
1890 if (canvas->format == frame->format) {
1891 blend_alpha_argb(canvas, frame, s->pos_x, s->pos_y);
1892 } else {
1893 blend_yuva2argb(canvas, frame, s->pos_x, s->pos_y);
1894 }
1895 } else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ {
1896 blend_alpha_yuva(canvas, frame, s->pos_x, s->pos_y);
1897 }
1898 }
1899
1900 return 0;
1901}
1902
1903/**
1904 * Fill a rectangle on the canvas with the background color (transparent black
1905 * by default, or the color from the ANIM chunk if provided by the demuxer).
1906 */
1907static void fill_canvas_rect(AnimatedWebPContext *s, int pos_x, int pos_y, int width, int height)
1908{
1909 AVFrame *canvas = s->canvas;
1910
1911 if (canvas->format == AV_PIX_FMT_ARGB) {
1912 uint32_t bg_color = AV_RN32(s->background_argb);
1913 int is_repeatable = (bg_color == ((bg_color & 0xff) * 0x01010101));
1914 for (int y = 0; y < height; y++) {
1915 uint32_t *dst = (uint32_t *) (canvas->data[0] + (pos_y + y) * canvas->linesize[0]) + pos_x;
1916 if (is_repeatable) {
1917 memset(dst, bg_color, width * sizeof(uint32_t));
1918 } else {
1919 for (int x = 0; x < width; x++)
1920 dst[x] = bg_color;
1921 }
1922 }
1923 } else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ {
1925 for (int comp = 0; comp < desc->nb_components; comp++) {
1926 int shift = (comp == 1 || comp == 2) ? 1 : 0;
1927 int plane = desc->comp[comp].plane;
1928 uint8_t *dst = canvas->data[plane] + (pos_y >> shift) * canvas->linesize[plane] + (pos_x >> shift);
1929 for (int y = 0; y < AV_CEIL_RSHIFT(height, shift); y++) {
1930 memset(dst, s->background_yuva[plane], AV_CEIL_RSHIFT(width, shift));
1931 dst += canvas->linesize[plane];
1932 }
1933 }
1934 }
1935}
1936
1937static int allocate_canvas(AnimatedWebPContext *s, int format)
1938{
1939 s->w.avctx->pix_fmt = format;
1940 int ret = ff_set_dimensions(s->w.avctx, s->canvas_width, s->canvas_height);
1941 if (ret < 0)
1942 return ret;
1943 return ff_reget_buffer(s->w.avctx, s->canvas, 0);
1944}
1945
1946static int prepare_canvas(AnimatedWebPContext *s, int key_frame, int format)
1947{
1948 int ret;
1949
1950 /**
1951 * Clear the canvas on keyframes and frames that overwrite the entire
1952 * canvas.
1953 */
1954 if (key_frame ||
1955 ((s->anmf_flags & ANMF_FLAG_NO_BLEND) &&
1956 (s->pos_x == 0) && (s->pos_x + s->w.width == s->canvas_width) &&
1957 (s->pos_y == 0) && (s->pos_y + s->w.height == s->canvas_height)))
1958 av_frame_unref(s->canvas);
1959
1960 if (!s->canvas->buf[0]) {
1961 /* Allocate new canvas frame */
1962 ret = allocate_canvas(s, format);
1963 if (ret < 0)
1964 return ret;
1965 /* ... and initialize it. */
1966 fill_canvas_rect(s, 0, 0, s->canvas->width, s->canvas->height);
1967 } else {
1968 if (format == AV_PIX_FMT_ARGB && s->canvas->format == AV_PIX_FMT_YUVA420P) {
1969 /**
1970 * If we have a lossless frame following a lossy frame, we upgrade
1971 * the canvas to ARGB, but we don't convert the canvas back to YUVA
1972 * if there is a lossy frame following a lossless frame.
1973 */
1974 AVFrame *yuva_canvas = av_frame_clone(s->canvas);
1975 if (!yuva_canvas)
1976 return AVERROR(ENOMEM);
1977 av_frame_unref(s->canvas);
1978 ret = allocate_canvas(s, AV_PIX_FMT_ARGB);
1979 if (ret < 0) {
1980 av_frame_free(&yuva_canvas);
1981 return ret;
1982 }
1983 copy_yuva2argb(s->canvas, yuva_canvas, 0, 0);
1984 av_frame_free(&yuva_canvas);
1985 } else {
1986 /**
1987 * The decode frame function returns a reference to the canvas,
1988 * therefore we have to ensure it is writable before using it
1989 * for a new frame.
1990 */
1991 ret = av_frame_make_writable(s->canvas);
1992 if (ret < 0)
1993 return ret;
1994 }
1995 /* Dispose of previous frame if needed. */
1996 if (s->prev_anmf_flags & ANMF_FLAG_DISPOSE)
1997 fill_canvas_rect(s, s->prev_pos_x, s->prev_pos_y, s->prev_width, s->prev_height);
1998 }
1999
2000 return 0;
2001}
2002
2003static int webp_anim_decode_frame(AVCodecContext *avctx, AVFrame *p,
2004 int *got_frame, AVPacket *avpkt)
2005{
2006 AnimatedWebPContext *s = avctx->priv_data;
2007 int key_frame = (avpkt->flags & AV_PKT_FLAG_KEY);
2008 int ret;
2009
2010 GetByteContext gb;
2011 bytestream2_init(&gb, avpkt->data, avpkt->size);
2012
2013 /* Parse ANMF header. */
2014 s->pos_x = bytestream2_get_le24(&gb) * 2;
2015 s->pos_y = bytestream2_get_le24(&gb) * 2;
2016 s->w.width = bytestream2_get_le24(&gb) + 1;
2017 s->w.height = bytestream2_get_le24(&gb) + 1;
2018 s->duration = bytestream2_get_le24(&gb);
2019 s->anmf_flags = bytestream2_get_byte(&gb);
2020
2021 av_log(avctx, AV_LOG_DEBUG,
2022 "ANMF frame pos: %dx%d size: %dx%d duration: %d\n",
2023 s->pos_x, s->pos_y, s->w.width, s->w.height, s->duration);
2024
2025 /* Reset alpha field from previous frame. */
2026 s->w.has_alpha = 0;
2027
2028 /* Parse ANMF subchunks. */
2029 while (bytestream2_get_bytes_left(&gb) > 8) {
2030 uint32_t chunk_type = bytestream2_get_le32(&gb);
2031 uint32_t chunk_size = bytestream2_get_le32(&gb);
2032
2033 if (chunk_size == UINT32_MAX) {
2034 ret = AVERROR_INVALIDDATA;
2035 goto end;
2036 }
2037 chunk_size += chunk_size & 1;
2038
2039 if (bytestream2_get_bytes_left(&gb) < chunk_size) {
2040 /* we seem to be running out of data, but it could also be that the
2041 * bitstream has trailing junk leading to bogus chunk_size. */
2042 break;
2043 }
2044
2045 switch (chunk_type) {
2046 case MKTAG('A', 'L', 'P', 'H'): {
2047 if (chunk_size == 0) {
2048 av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
2049 ret = AVERROR_INVALIDDATA;
2050 goto end;
2051 }
2052 int alpha_header = bytestream2_get_byte(&gb);
2053 s->w.alpha_data = avpkt->data + bytestream2_tell(&gb);
2054 s->w.alpha_data_size = chunk_size - 1;
2055 bytestream2_skip(&gb, s->w.alpha_data_size);
2056
2057 int filter_m = (alpha_header >> 2) & 0x03;
2058 int compression = alpha_header & 0x03;
2059
2060 if (compression > ALPHA_COMPRESSION_VP8L) {
2061 av_log(avctx, AV_LOG_VERBOSE,
2062 "skipping unsupported ALPHA chunk\n");
2063 } else {
2064 s->w.has_alpha = 1;
2065 s->w.alpha_compression = compression;
2066 s->w.alpha_filter = filter_m;
2067 }
2068
2069 break;
2070 }
2071 case MKTAG('V', 'P', '8', ' '):
2072 if (*got_frame) {
2073 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra VP8 chunk\n");
2074 bytestream2_skip(&gb, chunk_size);
2075 break;
2076 }
2077 ret = vp8_lossy_decode_frame(avctx, s->subframe, got_frame,
2078 avpkt->data + bytestream2_tell(&gb),
2079 chunk_size);
2080 if (ret < 0)
2081 goto end;
2082 ret = prepare_canvas(s, key_frame, AV_PIX_FMT_YUVA420P);
2083 if (ret < 0)
2084 goto end;
2085 bytestream2_skip(&gb, chunk_size);
2086 break;
2087 case MKTAG('V', 'P', '8', 'L'):
2088 if (*got_frame) {
2089 av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra VP8L chunk\n");
2090 bytestream2_skip(&gb, chunk_size);
2091 break;
2092 }
2093 ret = vp8_lossless_decode_frame(avctx, s->subframe, got_frame,
2094 avpkt->data + bytestream2_tell(&gb),
2095 chunk_size, 0);
2096 if (ret < 0)
2097 goto end;
2098 ret = prepare_canvas(s, key_frame, AV_PIX_FMT_ARGB);
2099 if (ret < 0)
2100 goto end;
2101 bytestream2_skip(&gb, chunk_size);
2102 break;
2103 default:
2104 av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
2105 av_fourcc2str(chunk_type));
2106 bytestream2_skip(&gb, chunk_size);
2107 break;
2108 }
2109 }
2110
2111 if (!*got_frame) {
2112 av_log(avctx, AV_LOG_ERROR, "image data not found\n");
2113 ret = AVERROR_INVALIDDATA;
2114 goto end;
2115 }
2116
2117 /* The subframe dimensions may have been modified by update_canvas_size() */
2118 if (s->pos_x + s->w.width > s->canvas_width ||
2119 s->pos_y + s->w.height > s->canvas_height) {
2120 av_log(avctx, AV_LOG_ERROR,
2121 "Frame (%dx%d at pos %dx%d) does not fit into canvas (%dx%d)\n",
2122 s->w.width, s->w.height, s->pos_x, s->pos_y,
2123 s->canvas_width, s->canvas_height);
2124 ret = AVERROR_INVALIDDATA;
2125 goto end;
2126 }
2127
2128 ret = blend_subframe_into_canvas(s);
2129 if (ret < 0)
2130 goto end;
2131
2132 ret = av_frame_ref(p, s->canvas);
2133 if (ret < 0)
2134 goto end;
2135
2136 p->pict_type = key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
2137 p->pts = avpkt->pts;
2138 p->duration = s->duration;
2139
2140 s->prev_anmf_flags = s->anmf_flags;
2141 s->prev_width = s->w.width;
2142 s->prev_height = s->w.height;
2143 s->prev_pos_x = s->pos_x;
2144 s->prev_pos_y = s->pos_y;
2145
2146 ret = avpkt->size;
2147
2148end:
2149 av_frame_unref(s->subframe);
2150 return ret;
2151}
2152
2153static av_cold int webp_anim_decode_init(AVCodecContext *avctx)
2154{
2155 AnimatedWebPContext *s = avctx->priv_data;
2156
2157 s->w.avctx = avctx;
2158 s->canvas_width = avctx->width;
2159 s->canvas_height = avctx->height;
2160
2161 s->canvas = av_frame_alloc();
2162 if (!s->canvas)
2163 return AVERROR(ENOMEM);
2164
2165 s->subframe = av_frame_alloc();
2166 if (!s->subframe)
2167 return AVERROR(ENOMEM);
2168
2169 /**
2170 * Use background color if it was provided by the demuxer. Otherwise, the
2171 * background color will be 0x00000000 (transparent black).
2172 */
2173 if (avctx->extradata_size >= 4) {
2174 s->background_argb[0] = avctx->extradata[3];
2175 s->background_argb[1] = avctx->extradata[2];
2176 s->background_argb[2] = avctx->extradata[1];
2177 s->background_argb[3] = avctx->extradata[0];
2178 }
2179
2180 /* Convert background color to YUVA. */
2181 const uint8_t *argb = s->background_argb;
2182 s->background_yuva[0] = RGB_TO_Y_CCIR(argb[1], argb[2], argb[3]);
2183 s->background_yuva[1] = RGB_TO_U_CCIR(argb[1], argb[2], argb[3], 0);
2184 s->background_yuva[2] = RGB_TO_V_CCIR(argb[1], argb[2], argb[3], 0);
2185 s->background_yuva[3] = argb[0];
2186
2187 return webp_decode_init(avctx);
2188}
2189
2190static av_cold int webp_anim_decode_close(AVCodecContext *avctx)
2191{
2192 AnimatedWebPContext *s = avctx->priv_data;
2193
2194 av_frame_free(&s->canvas);
2195 av_frame_free(&s->subframe);
2196
2197 return webp_decode_close(avctx);
2198}
2199
2201 .p.name = "webp_anim",
2202 CODEC_LONG_NAME("Animated WebP image"),
2203 .p.type = AVMEDIA_TYPE_VIDEO,
2204 .p.id = AV_CODEC_ID_WEBP_ANIM,
2205 .priv_data_size = sizeof(AnimatedWebPContext),
2206 .init = webp_anim_decode_init,
2207 FF_CODEC_DECODE_CB(webp_anim_decode_frame),
2208 .close = webp_anim_decode_close,
2209 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
2210 .caps_internal = FF_CODEC_CAP_USES_PROGRESSFRAMES,
2211};
2212#endif /* CONFIG_WEBP_ANIM_DECODER */
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static const char *const format[]
Definition af_aiir.c:444
const FFCodec ff_webp_decoder
Definition webp.c:1582
const FFCodec ff_webp_anim_decoder
#define U(x)
Definition vpx_arith.h:37
#define A(x)
Definition vpx_arith.h:28
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
#define V
Definition avdct.c:32
#define Y
Definition boxblur.h:37
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition bytestream.h:192
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define xi(width, name, var, range_min, range_max, subs,...)
Definition cbs_h264.c:115
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_CAP_USES_PROGRESSFRAMES
The decoder might make use of the ProgressFrame API.
#define FF_CODEC_CAP_ICC_PROFILES
Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define av_clip_uint8
Definition common.h:106
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
#define max(a, b)
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition decode.c:1906
int ff_decode_exif_attach_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferRef **pbuf, enum AVExifHeaderMode header_mode)
Attach the data buffer to the frame.
Definition decode.c:2498
int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame, enum AVFrameSideDataType type, size_t size, AVFrameSideData **psd)
Wrapper around av_frame_new_side_data, which rejects side data overridden by the demuxer.
Definition decode.c:2184
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition utils.c:91
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define cm
Definition dvbsubdec.c:40
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition eamad.c:79
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
Definition exif.h:62
EXIF metadata parser - internal functions.
static const uint8_t bits[8]
Definition fastaudio.c:100
static int64_t duration
Definition ffplay.c:330
bitstream reader API header.
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth)
Parse a vlc code.
Definition get_bits.h:645
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition codec.h:102
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition codec.h:98
@ AV_CODEC_ID_WEBP_ANIM
Definition codec_id.h:326
@ AV_CODEC_ID_WEBP
Definition codec_id.h:221
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition buffer.c:77
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_LOSSLESS
A decoder can use this flag to mark frames which were originally encoded losslessly.
Definition frame.h:708
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition frame.c:206
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition frame.c:483
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
Definition frame.c:552
@ AV_FRAME_DATA_ICC_PROFILE
The data contains an ICC profile as an opaque octet buffer following the format described by ISO 1507...
Definition frame.h:144
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define av_fourcc2str(fourcc)
Definition avutil.h:323
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition imgutils.c:318
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
@ AV_PICTURE_TYPE_P
Predicted.
Definition avutil.h:279
int a
if(svq3)
static const int8_t transform[32][32]
Definition dsp.c:27
static const int16_t alpha[]
Definition ilbcdata.h:55
misc image utilities
static const uint8_t block_bits[]
Definition imm4.c:104
#define r
Definition input.c:42
#define b
Definition input.c:43
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition intra.c:278
#define extra_bits(eb)
Definition intrax8.c:120
#define AV_WB32(p, v)
#define AV_RN32(p)
#define AV_RB32(p)
#define AV_COPY32(d, s)
unsigned offset
Definition libaomenc.c:763
static int shift(int a, int b)
Definition bonk.c:261
Multithreading API for decoders.
#define av_always_inline
Definition attributes.h:72
#define av_cold
Definition attributes.h:117
Various defines for YUV<->RGB conversion.
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
Definition colorspace.h:102
#define RGB_TO_Y_CCIR(r, g, b)
Definition colorspace.h:98
#define YUV_TO_RGB1_CCIR(cb1, cr1)
Definition colorspace.h:34
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
Definition colorspace.h:55
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
Definition colorspace.h:106
const char * desc
Definition libsvtav1.c:83
uint8_t w
Definition llvidencdsp.c:39
#define FFMIN(a, b)
Definition macros.h:49
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define FFMAX(a, b)
Definition macros.h:47
static int8_t ff_u8_to_s8(uint8_t a)
Definition mathops.h:247
#define MAX_NEG_CROP
Definition mathops.h:31
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
#define ff_crop_tab
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
static float distance(float x, float y, int band)
#define av_malloc(s)
Definition ops_static.c:52
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
int plane
Which of the 4 planes contains the component.
Definition pixdesc.h:34
Structure to hold side data for an AVFrame.
Definition frame.h:327
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int width
Definition frame.h:544
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition frame.h:559
This structure stores compressed data.
Definition packet.h:580
int flags
A combination of AV_PKT_FLAG values.
Definition packet.h:609
int size
Definition packet.h:604
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
uint8_t * data
Definition packet.h:603
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition pixdesc.h:105
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition pixdesc.h:71
const uint8_t * buffer
Definition bytestream.h:34
uint16_t simple_symbols[2]
Definition webp.c:183
VLC vlc
Definition webp.c:180
int nb_symbols
Definition webp.c:182
int simple
Definition webp.c:181
int is_alpha_primary
Definition webp.c:197
enum ImageRole role
Definition webp.c:187
AVFrame * frame
Definition webp.c:188
int size_reduction
Definition webp.c:196
int nb_huffman_groups
Definition webp.c:191
HuffReader * huffman_groups
Definition webp.c:192
int color_cache_bits
Definition webp.c:189
uint32_t * color_cache
Definition webp.c:190
Definition vlc.h:50
int initialized
Definition webp.c:206
enum AlphaFilter alpha_filter
Definition webp.c:209
enum TransformType transforms[4]
Definition webp.c:219
int width
Definition webp.c:215
GetBitContext gb
Definition webp.c:202
int nb_transforms
Definition webp.c:218
int nb_huffman_groups
Definition webp.c:223
AVFrame * alpha_frame
Definition webp.c:203
int has_exif
Definition webp.c:212
int has_alpha
Definition webp.c:207
const uint8_t * alpha_data
Definition webp.c:210
int has_iccp
Definition webp.c:213
AVCodecContext * avctx
Definition webp.c:205
int alpha_data_size
Definition webp.c:211
VP8Context v
Definition webp.c:201
enum AlphaCompression alpha_compression
Definition webp.c:208
AVPacket * pkt
Definition webp.c:204
int has_xmp
Definition webp.c:214
int reduced_width
Definition webp.c:222
int height
Definition webp.c:216
ImageContext image[IMAGE_ROLE_NB]
Definition webp.c:224
#define av_free(p)
#define av_malloc_array(a, b)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static void finish(void)
Definition movenc.c:374
static char buffer[20]
Definition seek.c:32
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
TIFF Common Routines.
int size
#define img
const char * g
Definition vf_curves.c:128
static double cr(void *priv, double x, double y)
Definition vf_geq.c:248
static double cb(void *priv, double x, double y)
Definition vf_geq.c:247
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
int ff_vlc_init_from_lengths(VLC *vlc, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
Definition vlc.c:306
void ff_vlc_free(VLC *vlc)
Definition vlc.c:580
#define VLC_INIT_OUTPUT_LE
Definition vlc.h:196
int len
av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
Definition vp8.c:2818
int ff_vp8_decode_init(AVCodecContext *avctx)
int ff_vp8_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
static double c[64]
static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, int alphabet_size)
Definition webp.c:321
static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:850
static void image_ctx_free(ImageContext *img)
Definition webp.c:233
static int apply_color_transform(WebPContext *s)
Definition webp.c:969
AlphaCompression
Definition webp.c:107
@ ALPHA_COMPRESSION_NONE
Definition webp.c:108
@ ALPHA_COMPRESSION_VP8L
Definition webp.c:109
static int webp_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, AVPacket *avpkt)
Definition webp.c:1344
static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:830
static av_always_inline uint8_t color_transform_delta(uint8_t color_pred, uint8_t color)
Definition webp.c:963
#define NUM_CODE_LENGTH_CODES
Definition webp.c:71
static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:820
static av_cold int webp_decode_close(AVCodecContext *avctx)
Definition webp.c:1570
PredictionMode
Definition webp.c:126
@ PRED_MODE_ADD_SUBTRACT_FULL
Definition webp.c:139
@ PRED_MODE_TR
Definition webp.c:130
@ PRED_MODE_AVG_L_T
Definition webp.c:134
@ PRED_MODE_AVG_TL_T
Definition webp.c:135
@ PRED_MODE_T
Definition webp.c:129
@ PRED_MODE_AVG_T_TR
Definition webp.c:136
@ PRED_MODE_AVG_AVG_L_TL_AVG_T_TR
Definition webp.c:137
@ PRED_MODE_TL
Definition webp.c:131
@ PRED_MODE_AVG_L_TL
Definition webp.c:133
@ PRED_MODE_SELECT
Definition webp.c:138
@ PRED_MODE_ADD_SUBTRACT_HALF
Definition webp.c:140
@ PRED_MODE_BLACK
Definition webp.c:127
@ PRED_MODE_L
Definition webp.c:128
@ PRED_MODE_AVG_T_AVG_L_TR
Definition webp.c:132
static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
Definition webp.c:1207
#define VP8X_FLAG_ICC
Definition webp.c:67
static int parse_transform_color(WebPContext *s)
Definition webp.c:484
static int huff_reader_build_canonical(HuffReader *r, const uint8_t *code_lengths, uint16_t len_counts[MAX_HUFFMAN_CODE_LENGTH+1], uint8_t lens[], uint16_t syms[], int alphabet_size, void *logctx)
Definition webp.c:261
static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:793
#define GET_PIXEL(frame, x, y)
Definition webp.c:227
static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES]
Definition webp.c:85
HuffmanIndex
Definition webp.c:143
@ HUFF_IDX_RED
Definition webp.c:145
@ HUFF_IDX_GREEN
Definition webp.c:144
@ HUFF_IDX_BLUE
Definition webp.c:146
@ HUFF_IDX_ALPHA
Definition webp.c:147
@ HUFF_IDX_DIST
Definition webp.c:148
static HuffReader * get_huffman_group(WebPContext *s, ImageContext *img, int x, int y)
Definition webp.c:535
static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
Definition webp.c:910
static av_cold int webp_decode_init(AVCodecContext *avctx)
Definition webp.c:1559
static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2]
Definition webp.c:89
static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
Definition webp.c:552
static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:765
#define VP8X_FLAG_ALPHA
Definition webp.c:66
static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
Definition webp.c:883
static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:860
static int apply_subtract_green_transform(WebPContext *s)
Definition webp.c:993
static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, uint8_t *data_start, unsigned int data_size)
Definition webp.c:1303
static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:840
static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, const uint8_t *data_start, unsigned int data_size, int is_alpha_chunk)
Definition webp.c:1095
AlphaFilter
Definition webp.c:112
@ ALPHA_FILTER_NONE
Definition webp.c:113
@ ALPHA_FILTER_GRADIENT
Definition webp.c:116
@ ALPHA_FILTER_VERTICAL
Definition webp.c:115
@ ALPHA_FILTER_HORIZONTAL
Definition webp.c:114
#define NUM_LITERAL_CODES
Definition webp.c:73
#define VP8X_FLAG_EXIF_METADATA
Definition webp.c:65
static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:786
#define MAX_HUFFMAN_CODE_LENGTH
Definition webp.c:77
void(* inv_predict_func)(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:899
static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
Definition webp.c:306
static int apply_predictor_transform(WebPContext *s)
Definition webp.c:932
static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, int w, int h)
Definition webp.c:558
static void inv_predict_6(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:810
TransformType
Definition webp.c:119
@ COLOR_TRANSFORM
Definition webp.c:121
@ COLOR_INDEXING_TRANSFORM
Definition webp.c:123
@ PREDICTOR_TRANSFORM
Definition webp.c:120
@ SUBTRACT_GREEN
Definition webp.c:122
#define NUM_LENGTH_CODES
Definition webp.c:74
static int apply_color_indexing_transform(WebPContext *s)
Definition webp.c:1008
#define HUFFMAN_CODES_PER_META_CODE
Definition webp.c:72
static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:779
static int parse_transform_color_indexing(WebPContext *s)
Definition webp.c:500
ImageRole
Definition webp.c:157
@ IMAGE_ROLE_PREDICTOR
Definition webp.c:167
@ IMAGE_ROLE_COLOR_TRANSFORM
Definition webp.c:171
@ IMAGE_ROLE_ENTROPY
Definition webp.c:163
@ IMAGE_ROLE_NB
Definition webp.c:176
@ IMAGE_ROLE_COLOR_INDEXING
Definition webp.c:174
@ IMAGE_ROLE_ARGB
Definition webp.c:159
#define PARSE_BLOCK_SIZE(w, h)
Definition webp.c:432
static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:890
#define GET_PIXEL_COMP(frame, x, y, c)
Definition webp.c:230
#define NUM_DISTANCE_CODES
Definition webp.c:75
static int decode_entropy_image(WebPContext *s)
Definition webp.c:438
static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE]
Definition webp.c:79
static void update_canvas_size(AVCodecContext *avctx, int w, int h)
Definition webp.c:1080
#define VP8X_FLAG_XMP_METADATA
Definition webp.c:64
static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:772
static const inv_predict_func inverse_predict[14]
Definition webp.c:903
#define NUM_SHORT_DISTANCES
Definition webp.c:76
static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p, const uint8_t *data_start, unsigned int data_size)
Definition webp.c:1250
static void inv_predict_12(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:874
static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb)
Definition webp.c:250
static int parse_transform_predictor(WebPContext *s)
Definition webp.c:468
static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl, const uint8_t *p_t, const uint8_t *p_tr)
Definition webp.c:800