FFmpeg
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 
48 #include "libavutil/colorspace.h"
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 
79 static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE] = {
83 };
84 
86  17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
87 };
88 
89 static 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 
110 };
111 
117 };
118 
124 };
125 
141 };
142 
149 };
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. */
157 enum ImageRole {
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 
179 typedef 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 
186 typedef 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) */
198 } ImageContext;
199 
200 typedef 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 */
225 } WebPContext;
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 
261 static 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 
423 finish:
424  ff_vlc_free(&code_len_hc.vlc);
425  av_free(code_lengths);
426  return ret;
427 }
428 
429 static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
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 {
440  ImageContext *img;
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 {
502  ImageContext *img;
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 
522  img = &s->image[IMAGE_ROLE_COLOR_INDEXING];
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 {
561  ImageContext *img;
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)) {
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)) {
621  read_huffman_code_simple(s, &hg[j]);
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);
642  v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb);
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 */
685  if (distance <= NUM_SHORT_DISTANCES) {
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 */
765 static 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 */
772 static 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 */
779 static 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 */
786 static 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 */
793 static 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 */
800 static 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 */
810 static 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 */
820 static 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 */
830 static 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 */
840 static 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 */
850 static 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 */
860 static 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 */
874 static 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 
883 static 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 */
890 static 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 
899 typedef 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 
903 static const inv_predict_func inverse_predict[14] = {
908 };
909 
910 static 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 
963 static 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 {
1010  ImageContext *img;
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 
1080 static 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);
1147  goto free_and_return;
1148  }
1149  used |= (1 << transform);
1150  s->transforms[s->nb_transforms++] = transform;
1151  switch (transform) {
1152  case PREDICTOR_TRANSFORM:
1154  break;
1155  case COLOR_TRANSFORM:
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]) {
1177  case PREDICTOR_TRANSFORM:
1179  break;
1180  case COLOR_TRANSFORM:
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 
1200 free_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;
1233  case ALPHA_FILTER_VERTICAL:
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;
1240  case ALPHA_FILTER_GRADIENT:
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 
1483 exif_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 
1601 typedef 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  */
1625 static 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  */
1658 static void blend_alpha_yuva(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1659 {
1660  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format);
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 
1740 static 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 
1748  YUV_TO_RGB1_CCIR(U, V);
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 
1757 static 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 
1788 static 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 
1835 static 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  */
1907 static 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 
1937 static 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 
1946 static 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 
2003 static 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) {
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");
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");
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);
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 
2148 end:
2149  av_frame_unref(s->subframe);
2150  return ret;
2151 }
2152 
2153 static 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 
2190 static 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 
2200 const FFCodec ff_webp_anim_decoder = {
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 */
WebPContext::width
int width
Definition: webp.c:215
WebPContext::alpha_frame
AVFrame * alpha_frame
Definition: webp.c:203
A
#define A(x)
Definition: vpx_arith.h:28
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
ff_vp8_decode_free
av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
Definition: vp8.c:2814
HuffReader::vlc
VLC vlc
Definition: webp.c:180
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
inv_predict_12
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
ff_vlc_init_from_lengths
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
extra_bits
#define extra_bits(eb)
Definition: intrax8.c:120
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:688
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
NUM_SHORT_DISTANCES
#define NUM_SHORT_DISTANCES
Definition: webp.c:76
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
vp8_lossy_decode_frame
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
out
static FILE * out
Definition: movenc.c:55
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:206
color
Definition: vf_paletteuse.c:513
PRED_MODE_AVG_T_AVG_L_TR
@ PRED_MODE_AVG_T_AVG_L_TR
Definition: webp.c:132
ALPHA_FILTER_HORIZONTAL
@ ALPHA_FILTER_HORIZONTAL
Definition: webp.c:114
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
HuffReader::simple_symbols
uint16_t simple_symbols[2]
Definition: webp.c:183
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:79
GetByteContext
Definition: bytestream.h:33
bytestream2_tell
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition: bytestream.h:192
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
ff_u8_to_s8
static int8_t ff_u8_to_s8(uint8_t a)
Definition: mathops.h:247
block_bits
static const uint8_t block_bits[]
Definition: imm4.c:104
RGB_TO_U_CCIR
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:102
av_cold
#define av_cold
Definition: attributes.h:119
PRED_MODE_BLACK
@ PRED_MODE_BLACK
Definition: webp.c:127
inv_predict_4
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
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
inv_predict_2
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
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:466
av_frame_make_writable
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
Definition: frame.c:552
AVFrame::width
int width
Definition: frame.h:538
GET_PIXEL_COMP
#define GET_PIXEL_COMP(frame, x, y, c)
Definition: webp.c:230
AVPacket::data
uint8_t * data
Definition: packet.h:603
PRED_MODE_ADD_SUBTRACT_FULL
@ PRED_MODE_ADD_SUBTRACT_FULL
Definition: webp.c:139
COLOR_INDEXING_TRANSFORM
@ COLOR_INDEXING_TRANSFORM
Definition: webp.c:123
b
#define b
Definition: input.c:43
SUBTRACT_GREEN
@ SUBTRACT_GREEN
Definition: webp.c:122
ImageContext::nb_huffman_groups
int nb_huffman_groups
Definition: webp.c:191
parse_transform_color
static int parse_transform_color(WebPContext *s)
Definition: webp.c:484
FFCodec
Definition: codec_internal.h:127
PRED_MODE_AVG_TL_T
@ PRED_MODE_AVG_TL_T
Definition: webp.c:135
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
YUV_TO_RGB1_CCIR
#define YUV_TO_RGB1_CCIR(cb1, cr1)
Definition: colorspace.h:34
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition: utils.c:91
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:517
thread.h
WebPContext::transforms
enum TransformType transforms[4]
Definition: webp.c:219
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
ff_crop_tab
#define ff_crop_tab
Definition: motionpixels_tablegen.c:26
PRED_MODE_TR
@ PRED_MODE_TR
Definition: webp.c:130
PRED_MODE_AVG_L_T
@ PRED_MODE_AVG_L_T
Definition: webp.c:134
vp8_lossless_decode_frame
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
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:487
HuffReader::simple
int simple
Definition: webp.c:181
PRED_MODE_TL
@ PRED_MODE_TL
Definition: webp.c:131
av_always_inline
#define av_always_inline
Definition: attributes.h:76
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:383
WebPContext::alpha_compression
enum AlphaCompression alpha_compression
Definition: webp.c:208
inv_predict_10
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
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
inv_predict_8
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
WebPContext::avctx
AVCodecContext * avctx
Definition: webp.c:205
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
finish
static void finish(void)
Definition: movenc.c:374
ALPHA_COMPRESSION_NONE
@ ALPHA_COMPRESSION_NONE
Definition: webp.c:108
WebPContext::nb_transforms
int nb_transforms
Definition: webp.c:218
GetBitContext
Definition: get_bits.h:109
update_canvas_size
static void update_canvas_size(AVCodecContext *avctx, int w, int h)
Definition: webp.c:1080
WebPContext::alpha_data_size
int alpha_data_size
Definition: webp.c:211
inv_predict_func
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
COLOR_TRANSFORM
@ COLOR_TRANSFORM
Definition: webp.c:121
VP8X_FLAG_EXIF_METADATA
#define VP8X_FLAG_EXIF_METADATA
Definition: webp.c:65
inv_predict_3
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
ff_webp_decoder
const FFCodec ff_webp_decoder
Definition: webp.c:1582
color_transform_delta
static av_always_inline uint8_t color_transform_delta(uint8_t color_pred, uint8_t color)
Definition: webp.c:963
decode_entropy_coded_image
static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, int w, int h)
Definition: webp.c:558
AV_DICT_DONT_STRDUP_VAL
#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
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
HUFF_IDX_GREEN
@ HUFF_IDX_GREEN
Definition: webp.c:144
WebPContext::has_exif
int has_exif
Definition: webp.c:212
read_huffman_code_normal
static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, int alphabet_size)
Definition: webp.c:321
WebPContext::has_alpha
int has_alpha
Definition: webp.c:207
PredictionMode
PredictionMode
Definition: webp.c:126
FF_CODEC_CAP_USES_PROGRESSFRAMES
#define FF_CODEC_CAP_USES_PROGRESSFRAMES
The decoder might make use of the ProgressFrame API.
Definition: codec_internal.h:69
colorspace.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
ImageContext::frame
AVFrame * frame
Definition: webp.c:188
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:544
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:681
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:527
inverse_prediction
static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
Definition: webp.c:910
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:364
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
TransformType
TransformType
Definition: webp.c:119
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
RGB_TO_Y_CCIR
#define RGB_TO_Y_CCIR(r, g, b)
Definition: colorspace.h:98
g
const char * g
Definition: vf_curves.c:128
PRED_MODE_AVG_T_TR
@ PRED_MODE_AVG_T_TR
Definition: webp.c:136
transform
static const int8_t transform[32][32]
Definition: dsp.c:27
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1036
HUFFMAN_CODES_PER_META_CODE
#define HUFFMAN_CODES_PER_META_CODE
Definition: webp.c:72
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
code_length_code_order
static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES]
Definition: webp.c:85
color_cache_put
static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
Definition: webp.c:552
bits
uint8_t bits
Definition: vp3data.h:128
NUM_DISTANCE_CODES
#define NUM_DISTANCE_CODES
Definition: webp.c:75
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
inv_predict_11
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
NUM_CODE_LENGTH_CODES
#define NUM_CODE_LENGTH_CODES
Definition: webp.c:71
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ImageContext
Definition: webp.c:186
decode.h
get_bits.h
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:483
ImageContext::color_cache
uint32_t * color_cache
Definition: webp.c:190
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
GET_PIXEL
#define GET_PIXEL(frame, x, y)
Definition: webp.c:227
ImageContext::is_alpha_primary
int is_alpha_primary
Definition: webp.c:197
PRED_MODE_AVG_L_TL
@ PRED_MODE_AVG_L_TL
Definition: webp.c:133
webp_decode_close
static av_cold int webp_decode_close(AVCodecContext *avctx)
Definition: webp.c:1570
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:349
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
ImageContext::huffman_groups
HuffReader * huffman_groups
Definition: webp.c:192
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
if
if(ret)
Definition: filter_design.txt:179
ff_vp8_decode_init
int ff_vp8_decode_init(AVCodecContext *avctx)
apply_subtract_green_transform
static int apply_subtract_green_transform(WebPContext *s)
Definition: webp.c:993
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:92
HuffReader::nb_symbols
int nb_symbols
Definition: webp.c:182
WebPContext::height
int height
Definition: webp.c:216
ALPHA_FILTER_NONE
@ ALPHA_FILTER_NONE
Definition: webp.c:113
clamp_add_subtract_half
static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
Definition: webp.c:883
HUFF_IDX_DIST
@ HUFF_IDX_DIST
Definition: webp.c:148
NULL
#define NULL
Definition: coverity.c:32
exif_internal.h
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
inverse_predict
static const inv_predict_func inverse_predict[14]
Definition: webp.c:903
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
AV_EXIF_TIFF_HEADER
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
Definition: exif.h:62
AVPixFmtDescriptor::nb_components
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:71
tiff_common.h
AVComponentDescriptor::plane
int plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:34
RGB_TO_V_CCIR
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
Definition: colorspace.h:106
V
#define V
Definition: avdct.c:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:360
ImageContext::color_cache_bits
int color_cache_bits
Definition: webp.c:189
parse_transform_color_indexing
static int parse_transform_color_indexing(WebPContext *s)
Definition: webp.c:500
AV_FRAME_DATA_ICC_PROFILE
@ 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
webp_decode_init
static av_cold int webp_decode_init(AVCodecContext *avctx)
Definition: webp.c:1559
WebPContext::v
VP8Context v
Definition: webp.c:201
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
YUV_TO_RGB2_CCIR
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
Definition: colorspace.h:55
alphabet_sizes
static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE]
Definition: webp.c:79
NUM_LITERAL_CODES
#define NUM_LITERAL_CODES
Definition: webp.c:73
IMAGE_ROLE_PREDICTOR
@ IMAGE_ROLE_PREDICTOR
Definition: webp.c:167
get_vlc2
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
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
vp8.h
alpha_inverse_prediction
static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
Definition: webp.c:1207
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
IMAGE_ROLE_COLOR_INDEXING
@ IMAGE_ROLE_COLOR_INDEXING
Definition: webp.c:174
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:579
inv_predict_0
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
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:49
IMAGE_ROLE_NB
@ IMAGE_ROLE_NB
Definition: webp.c:176
VP8X_FLAG_ICC
#define VP8X_FLAG_ICC
Definition: webp.c:67
AVPacket::size
int size
Definition: packet.h:604
ff_decode_exif_attach_buffer
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:2492
height
#define height
Definition: dsp.h:89
av_frame_ref
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
codec_internal.h
AlphaCompression
AlphaCompression
Definition: webp.c:107
shift
static int shift(int a, int b)
Definition: bonk.c:261
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
PREDICTOR_TRANSFORM
@ PREDICTOR_TRANSFORM
Definition: webp.c:120
ImageContext::size_reduction
int size_reduction
Definition: webp.c:196
size
int size
Definition: twinvq_data.h:10344
ff_frame_new_side_data
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:2178
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
AVFrameSideData::data
uint8_t * data
Definition: frame.h:323
ImageContext::role
enum ImageRole role
Definition: webp.c:187
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:553
decode_entropy_image
static int decode_entropy_image(WebPContext *s)
Definition: webp.c:438
apply_color_transform
static int apply_color_transform(WebPContext *s)
Definition: webp.c:969
VP8X_FLAG_ALPHA
#define VP8X_FLAG_ALPHA
Definition: webp.c:66
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:166
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
img
#define img
Definition: vf_colormatrix.c:114
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: codec.h:96
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AV_CODEC_ID_WEBP_ANIM
@ AV_CODEC_ID_WEBP_ANIM
Definition: codec_id.h:326
line
Definition: graph2dot.c:48
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
HuffReader
Definition: webp.c:179
parse_transform_predictor
static int parse_transform_predictor(WebPContext *s)
Definition: webp.c:468
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
Y
#define Y
Definition: boxblur.h:37
PRED_MODE_AVG_AVG_L_TL_AVG_T_TR
@ PRED_MODE_AVG_AVG_L_TL_AVG_T_TR
Definition: webp.c:137
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
ALPHA_FILTER_GRADIENT
@ ALPHA_FILTER_GRADIENT
Definition: webp.c:116
WebPContext::nb_huffman_groups
int nb_huffman_groups
Definition: webp.c:223
inv_predict_5
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
WebPContext::reduced_width
int reduced_width
Definition: webp.c:222
NUM_LENGTH_CODES
#define NUM_LENGTH_CODES
Definition: webp.c:74
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
WebPContext::pkt
AVPacket * pkt
Definition: webp.c:204
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:526
AlphaFilter
AlphaFilter
Definition: webp.c:112
PRED_MODE_SELECT
@ PRED_MODE_SELECT
Definition: webp.c:138
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
lz77_distance_offsets
static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2]
Definition: webp.c:89
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
WebPContext::gb
GetBitContext gb
Definition: webp.c:202
apply_predictor_transform
static int apply_predictor_transform(WebPContext *s)
Definition: webp.c:932
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
HuffmanIndex
HuffmanIndex
Definition: webp.c:143
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
AV_COPY32
#define AV_COPY32(d, s)
Definition: intreadwrite.h:634
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:176
AV_CODEC_ID_WEBP
@ AV_CODEC_ID_WEBP
Definition: codec_id.h:221
len
int len
Definition: vorbis_enc_data.h:426
AVCodecContext::height
int height
Definition: avcodec.h:604
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:643
inv_predict_7
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
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
huff_reader_get_symbol
static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb)
Definition: webp.c:250
VP8X_FLAG_XMP_METADATA
#define VP8X_FLAG_XMP_METADATA
Definition: webp.c:64
FF_CODEC_CAP_ICC_PROFILES
#define FF_CODEC_CAP_ICC_PROFILES
Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
Definition: codec_internal.h:82
avcodec.h
inv_predict_13
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
ff_vlc_free
void ff_vlc_free(VLC *vlc)
Definition: vlc.c:580
ff_reget_buffer
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:1900
ret
ret
Definition: filter_design.txt:187
WebPContext::image
ImageContext image[IMAGE_ROLE_NB]
Definition: webp.c:224
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
ff_vp8_decode_frame
int ff_vp8_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
inv_predict_6
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
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
U
#define U(x)
Definition: vpx_arith.h:37
vp8_lossy_decode_alpha
static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p, const uint8_t *data_start, unsigned int data_size)
Definition: webp.c:1250
AVCodecContext
main external API structure.
Definition: avcodec.h:443
HUFF_IDX_BLUE
@ HUFF_IDX_BLUE
Definition: webp.c:146
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
IMAGE_ROLE_ENTROPY
@ IMAGE_ROLE_ENTROPY
Definition: webp.c:163
VLC
Definition: vlc.h:50
webp_decode_frame
static int webp_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, AVPacket *avpkt)
Definition: webp.c:1344
cm
#define cm
Definition: dvbsubdec.c:40
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
image_ctx_free
static void image_ctx_free(ImageContext *img)
Definition: webp.c:233
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
WebPContext::has_xmp
int has_xmp
Definition: webp.c:214
WebPContext::initialized
int initialized
Definition: webp.c:206
desc
const char * desc
Definition: libsvtav1.c:83
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:279
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
apply_color_indexing_transform
static int apply_color_indexing_transform(WebPContext *s)
Definition: webp.c:1008
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
WebPContext::alpha_data
const uint8_t * alpha_data
Definition: webp.c:210
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:321
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
VLC_INIT_OUTPUT_LE
#define VLC_INIT_OUTPUT_LE
Definition: vlc.h:196
MAX_HUFFMAN_CODE_LENGTH
#define MAX_HUFFMAN_CODE_LENGTH
Definition: webp.c:77
ALPHA_FILTER_VERTICAL
@ ALPHA_FILTER_VERTICAL
Definition: webp.c:115
w
uint8_t w
Definition: llvidencdsp.c:39
PARSE_BLOCK_SIZE
#define PARSE_BLOCK_SIZE(w, h)
Definition: webp.c:432
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
PRED_MODE_L
@ PRED_MODE_L
Definition: webp.c:128
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
WebPContext
Definition: webp.c:200
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
AVPacket
This structure stores compressed data.
Definition: packet.h:580
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
av_dict_set
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
VP8Context
Definition: vp8.h:161
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
ImageRole
ImageRole
Definition: webp.c:157
bytestream.h
distance
static float distance(float x, float y, int band)
Definition: nellymoserenc.c:231
imgutils.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AVFrame::linesize
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:511
read_huffman_code_simple
static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
Definition: webp.c:306
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
HUFF_IDX_ALPHA
@ HUFF_IDX_ALPHA
Definition: webp.c:147
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
huff_reader_build_canonical
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
h
h
Definition: vp9dsp_template.c:2070
av_image_check_size
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
WebPContext::has_iccp
int has_iccp
Definition: webp.c:213
get_huffman_group
static HuffReader * get_huffman_group(WebPContext *s, ImageContext *img, int x, int y)
Definition: webp.c:535
width
#define width
Definition: dsp.h:89
xi
#define xi(width, name, var, range_min, range_max, subs,...)
Definition: cbs_h264.c:190
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:31
AV_FRAME_FLAG_LOSSLESS
#define AV_FRAME_FLAG_LOSSLESS
A decoder can use this flag to mark frames which were originally encoded losslessly.
Definition: frame.h:702
inv_predict_9
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
ALPHA_COMPRESSION_VP8L
@ ALPHA_COMPRESSION_VP8L
Definition: webp.c:109
inv_predict_1
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
PRED_MODE_T
@ PRED_MODE_T
Definition: webp.c:129
ff_webp_anim_decoder
const FFCodec ff_webp_anim_decoder
src
#define src
Definition: vp8dsp.c:248
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
duration
static int64_t duration
Definition: ffplay.c:329
WebPContext::alpha_filter
enum AlphaFilter alpha_filter
Definition: webp.c:209
HUFF_IDX_RED
@ HUFF_IDX_RED
Definition: webp.c:145
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:323
IMAGE_ROLE_ARGB
@ IMAGE_ROLE_ARGB
Definition: webp.c:159
PRED_MODE_ADD_SUBTRACT_HALF
@ PRED_MODE_ADD_SUBTRACT_HALF
Definition: webp.c:140
IMAGE_ROLE_COLOR_TRANSFORM
@ IMAGE_ROLE_COLOR_TRANSFORM
Definition: webp.c:171