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 #if FF_API_CODEC_PROPS
1415 #endif
1416  }
1417  bytestream2_skip(&gb, chunk_size);
1418  break;
1419  case MKTAG('V', 'P', '8', 'X'):
1420  if (s->width || s->height || *got_frame) {
1421  av_log(avctx, AV_LOG_ERROR, "Canvas dimensions are already set\n");
1422  return AVERROR_INVALIDDATA;
1423  }
1424  vp8x_flags = bytestream2_get_byte(&gb);
1425  bytestream2_skip(&gb, 3);
1426  s->width = bytestream2_get_le24(&gb) + 1;
1427  s->height = bytestream2_get_le24(&gb) + 1;
1428  ret = av_image_check_size(s->width, s->height, 0, avctx);
1429  if (ret < 0)
1430  return ret;
1431  break;
1432  case MKTAG('A', 'L', 'P', 'H'): {
1433  int alpha_header, filter_m, compression;
1434 
1435  if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
1436  av_log(avctx, AV_LOG_WARNING,
1437  "ALPHA chunk present, but alpha bit not set in the "
1438  "VP8X header\n");
1439  }
1440  if (chunk_size == 0) {
1441  av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
1442  return AVERROR_INVALIDDATA;
1443  }
1444  alpha_header = bytestream2_get_byte(&gb);
1445  s->alpha_data = avpkt->data + bytestream2_tell(&gb);
1446  s->alpha_data_size = chunk_size - 1;
1447  bytestream2_skip(&gb, s->alpha_data_size);
1448 
1449  filter_m = (alpha_header >> 2) & 0x03;
1450  compression = alpha_header & 0x03;
1451 
1452  if (compression > ALPHA_COMPRESSION_VP8L) {
1453  av_log(avctx, AV_LOG_VERBOSE,
1454  "skipping unsupported ALPHA chunk\n");
1455  } else {
1456  s->has_alpha = 1;
1457  s->alpha_compression = compression;
1458  s->alpha_filter = filter_m;
1459  }
1460 
1461  break;
1462  }
1463  case MKTAG('E', 'X', 'I', 'F'): {
1464  AVBufferRef *exif_buf = NULL;
1465 
1466  if (s->has_exif) {
1467  av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n");
1468  goto exif_end;
1469  }
1470 
1471  if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA))
1472  av_log(avctx, AV_LOG_WARNING,
1473  "EXIF chunk present, but Exif bit not set in the "
1474  "VP8X header\n");
1475 
1476  exif_buf = av_buffer_alloc(chunk_size);
1477  if (!exif_buf) {
1478  av_log(avctx, AV_LOG_WARNING, "unable to allocate EXIF buffer\n");
1479  goto exif_end;
1480  }
1481  s->has_exif = 1;
1482  memcpy(exif_buf->data, gb.buffer, chunk_size);
1483 
1484  ret = ff_decode_exif_attach_buffer(avctx, p, &exif_buf, AV_EXIF_TIFF_HEADER);
1485  if (ret < 0)
1486  av_log(avctx, AV_LOG_WARNING, "unable to attach EXIF buffer\n");
1487 
1488 exif_end:
1489  bytestream2_skip(&gb, chunk_size);
1490  break;
1491  }
1492  case MKTAG('I', 'C', 'C', 'P'): {
1493  AVFrameSideData *sd;
1494 
1495  if (s->has_iccp) {
1496  av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra ICCP chunk\n");
1497  bytestream2_skip(&gb, chunk_size);
1498  break;
1499  }
1500  if (!(vp8x_flags & VP8X_FLAG_ICC))
1501  av_log(avctx, AV_LOG_WARNING,
1502  "ICCP chunk present, but ICC Profile bit not set in the "
1503  "VP8X header\n");
1504 
1505  s->has_iccp = 1;
1506 
1507  ret = ff_frame_new_side_data(avctx, p, AV_FRAME_DATA_ICC_PROFILE, chunk_size, &sd);
1508  if (ret < 0)
1509  return ret;
1510 
1511  if (sd) {
1512  bytestream2_get_buffer(&gb, sd->data, chunk_size);
1513  } else {
1514  bytestream2_skip(&gb, chunk_size);
1515  }
1516  break;
1517  }
1518  case MKTAG('A', 'N', 'I', 'M'):
1519  case MKTAG('A', 'N', 'M', 'F'):
1520  av_log(avctx, AV_LOG_WARNING, "skipping unsupported chunk: %s\n",
1521  av_fourcc2str(chunk_type));
1522  bytestream2_skip(&gb, chunk_size);
1523  break;
1524  case MKTAG('X', 'M', 'P', ' '): {
1525  if (s->has_xmp) {
1526  av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra XMP chunk\n");
1527  bytestream2_skip(&gb, chunk_size);
1528  break;
1529  }
1530  if (!(vp8x_flags & VP8X_FLAG_XMP_METADATA))
1531  av_log(avctx, AV_LOG_WARNING,
1532  "XMP chunk present, but XMP bit not set in the "
1533  "VP8X header\n");
1534 
1535  s->has_xmp = 1;
1536 
1537  // there are at least chunk_size bytes left to read
1538  uint8_t *buffer = av_malloc(chunk_size + 1);
1539  if (!buffer)
1540  return AVERROR(ENOMEM);
1541 
1542  bytestream2_get_buffer(&gb, buffer, chunk_size);
1543  buffer[chunk_size] = '\0';
1544 
1545  av_dict_set(&p->metadata, "xmp", buffer, AV_DICT_DONT_STRDUP_VAL);
1546  break;
1547  }
1548  default:
1549  av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
1550  av_fourcc2str(chunk_type));
1551  bytestream2_skip(&gb, chunk_size);
1552  break;
1553  }
1554  }
1555 
1556  if (!*got_frame) {
1557  av_log(avctx, AV_LOG_ERROR, "image data not found\n");
1558  return AVERROR_INVALIDDATA;
1559  }
1560 
1561  return avpkt->size;
1562 }
1563 
1565 {
1566  WebPContext *s = avctx->priv_data;
1567 
1568  s->pkt = av_packet_alloc();
1569  if (!s->pkt)
1570  return AVERROR(ENOMEM);
1571 
1572  return 0;
1573 }
1574 
1576 {
1577  WebPContext *s = avctx->priv_data;
1578 
1579  av_packet_free(&s->pkt);
1580 
1581  if (s->initialized)
1582  return ff_vp8_decode_free(avctx);
1583 
1584  return 0;
1585 }
1586 
1588  .p.name = "webp",
1589  CODEC_LONG_NAME("WebP image"),
1590  .p.type = AVMEDIA_TYPE_VIDEO,
1591  .p.id = AV_CODEC_ID_WEBP,
1592  .priv_data_size = sizeof(WebPContext),
1595  .close = webp_decode_close,
1596  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
1597  .caps_internal = FF_CODEC_CAP_ICC_PROFILES |
1599 };
1600 
1601 #if CONFIG_WEBP_ANIM_DECODER
1602 
1603 #define ANMF_FLAG_DISPOSE (1 << 0)
1604 #define ANMF_FLAG_NO_BLEND (1 << 1)
1605 
1606 typedef struct AnimatedWebPContext {
1607  WebPContext w;
1608 
1609  AVFrame *canvas; /* AVFrame for canvas */
1610  AVFrame *subframe; /* AVFrame for subframe */
1611  int canvas_width; /* canvas width */
1612  int canvas_height; /* canvas height */
1613  int anmf_flags; /* frame flags from ANMF chunk */
1614  int pos_x; /* frame position X */
1615  int pos_y; /* frame position Y */
1616  int duration; /* frame duration */
1617  int prev_anmf_flags; /* previous frame flags from ANMF chunk */
1618  int prev_width; /* previous frame width */
1619  int prev_height; /* previous frame height */
1620  int prev_pos_x; /* previous frame position X */
1621  int prev_pos_y; /* previous frame position Y */
1622  uint8_t background_argb[4]; /* background color in ARGB format */
1623  uint8_t background_yuva[4]; /* background color in YUVA format */
1624 } AnimatedWebPContext;
1625 
1626 /*
1627  * Blend src (foreground) into dst (background), in ARGB format.
1628  * pos_x, pos_y is the position in dst.
1629  */
1630 static void blend_alpha_argb(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1631 {
1632  for (int y = 0; y < src->height; y++) {
1633  const uint8_t *src_argb = src->data[0] + y * src->linesize[0];
1634  uint8_t *dst_argb = dst->data[0] + (pos_y + y) * dst->linesize[0] + pos_x * sizeof(uint32_t);
1635  for (int x = 0; x < src->width; x++) {
1636  int src_alpha = src_argb[0];
1637  int dst_alpha = dst_argb[0];
1638 
1639  if (src_alpha == 255) {
1640  memcpy(dst_argb, src_argb, sizeof(uint32_t));
1641  } else if (src_alpha == 0) {
1642  // no-op
1643  } else {
1644  int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1645  int blend_alpha = src_alpha + tmp_alpha;
1646  int scale = (1UL << 24) / blend_alpha;
1647 
1648  dst_argb[0] = blend_alpha;
1649  dst_argb[1] = (((uint32_t) (src_argb[1] * src_alpha + dst_argb[1] * tmp_alpha)) * scale) >> 24;
1650  dst_argb[2] = (((uint32_t) (src_argb[2] * src_alpha + dst_argb[2] * tmp_alpha)) * scale) >> 24;
1651  dst_argb[3] = (((uint32_t) (src_argb[3] * src_alpha + dst_argb[3] * tmp_alpha)) * scale) >> 24;
1652  }
1653  src_argb += sizeof(uint32_t);
1654  dst_argb += sizeof(uint32_t);
1655  }
1656  }
1657 }
1658 
1659 /*
1660  * Blend src (foreground) into dst (background), in YUVA format.
1661  * pos_x, pos_y is the position in dst.
1662  */
1663 static void blend_alpha_yuva(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1664 {
1665  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format);
1666 
1667  int plane_y = desc->comp[0].plane;
1668  int plane_u = desc->comp[1].plane;
1669  int plane_v = desc->comp[2].plane;
1670  int plane_a = desc->comp[3].plane;
1671 
1672  // blend U & V planes first, because the later step may modify alpha plane
1673  for (int y = 0; y < AV_CEIL_RSHIFT(src->height, 1); y++) {
1674  int tile_h = FFMIN(src->height - y * 2, 2);
1675  const uint8_t *src_u = src->data[plane_u] + y * src->linesize[plane_u];
1676  const uint8_t *src_v = src->data[plane_v] + y * src->linesize[plane_v];
1677  uint8_t *dst_u = dst->data[plane_u] + ((pos_y >> 1) + y) * dst->linesize[plane_u] + (pos_x >> 1);
1678  uint8_t *dst_v = dst->data[plane_v] + ((pos_y >> 1) + y) * dst->linesize[plane_v] + (pos_x >> 1);
1679  for (int x = 0; x < AV_CEIL_RSHIFT(src->width, 1); x++) {
1680  int tile_w = FFMIN(src->width - x * 2, 2);
1681  // calculate the average alpha of the tile
1682  int src_alpha = 0;
1683  int dst_alpha = 0;
1684  for (int yy = 0; yy < tile_h; yy++) {
1685  for (int xx = 0; xx < tile_w; xx++) {
1686  src_alpha += src->data[plane_a][(y * 2 + yy) * src->linesize[plane_a] +
1687  (x * 2 + xx)];
1688  dst_alpha += dst->data[plane_a][(((pos_y >> 1) + y) * 2 + yy) * dst->linesize[plane_a] +
1689  (((pos_x >> 1) + x) * 2 + xx)];
1690  }
1691  }
1692  int shift = (tile_h == 2) + (tile_w == 2);
1693  src_alpha = AV_CEIL_RSHIFT(src_alpha, shift);
1694  dst_alpha = AV_CEIL_RSHIFT(dst_alpha, shift);
1695 
1696  if (src_alpha == 255) {
1697  *dst_u = *src_u;
1698  *dst_v = *src_v;
1699  } else if (src_alpha == 0) {
1700  // no-op
1701  } else {
1702  int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1703  int blend_alpha = src_alpha + tmp_alpha;
1704  int scale = (1UL << 24) / blend_alpha;
1705  *dst_u = (((uint32_t) (*src_u * src_alpha + *dst_u * tmp_alpha)) * scale) >> 24;
1706  *dst_v = (((uint32_t) (*src_v * src_alpha + *dst_v * tmp_alpha)) * scale) >> 24;
1707  }
1708  src_u += 1;
1709  src_v += 1;
1710  dst_u += 1;
1711  dst_v += 1;
1712  }
1713  }
1714 
1715  // blend Y & A planes
1716  for (int y = 0; y < src->height; y++) {
1717  const uint8_t *src_y = src->data[plane_y] + y * src->linesize[plane_y];
1718  const uint8_t *src_a = src->data[plane_a] + y * src->linesize[plane_a];
1719  uint8_t *dst_y = dst->data[plane_y] + (pos_y + y) * dst->linesize[plane_y] + pos_x;
1720  uint8_t *dst_a = dst->data[plane_a] + (pos_y + y) * dst->linesize[plane_a] + pos_x;
1721  for (int x = 0; x < src->width; x++) {
1722  int src_alpha = *src_a;
1723  int dst_alpha = *dst_a;
1724 
1725  if (src_alpha == 255) {
1726  *dst_y = *src_y;
1727  *dst_a = 255;
1728  } else if (src_alpha == 0) {
1729  // no-op
1730  } else {
1731  int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1732  int blend_alpha = src_alpha + tmp_alpha;
1733  int scale = (1UL << 24) / blend_alpha;
1734  *dst_y = (((uint32_t) (*src_y * src_alpha + *dst_y * tmp_alpha)) * scale) >> 24;
1735  *dst_a = blend_alpha;
1736  }
1737  src_y += 1;
1738  src_a += 1;
1739  dst_y += 1;
1740  dst_a += 1;
1741  }
1742  }
1743 }
1744 
1745 static av_always_inline void webp_yuva2argb(uint8_t *out, int Y, int U, int V, int A)
1746 {
1747  // variables used in macros
1748  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
1749  uint8_t r, g, b;
1750  int y, cb, cr;
1751  int r_add, g_add, b_add;
1752 
1753  YUV_TO_RGB1_CCIR(U, V);
1754  YUV_TO_RGB2_CCIR(r, g, b, Y);
1755 
1756  out[0] = av_clip_uint8(A);
1757  out[1] = av_clip_uint8(r);
1758  out[2] = av_clip_uint8(g);
1759  out[3] = av_clip_uint8(b);
1760 }
1761 
1762 static void copy_yuva2argb(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1763 {
1764  const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src->format);
1765 
1766  int alpha = src_desc->nb_components > 3;
1767  int plane_y = src_desc->comp[0].plane;
1768  int plane_u = src_desc->comp[1].plane;
1769  int plane_v = src_desc->comp[2].plane;
1770  int plane_a = src_desc->comp[3].plane;
1771 
1772  for (int y = 0; y < src->height; y++) {
1773  const uint8_t *src_y = src->data[plane_y] + y * src->linesize[plane_y];
1774  const uint8_t *src_u = src->data[plane_u] + (y >> 1) * src->linesize[plane_u];
1775  const uint8_t *src_v = src->data[plane_v] + (y >> 1) * src->linesize[plane_v];
1776  const uint8_t *src_a = NULL;
1777  uint8_t *dst_argb = dst->data[0] + (pos_y + y) * dst->linesize[0] + pos_x * 4;
1778  if (alpha)
1779  src_a = src->data[plane_a] + y * src->linesize[plane_a];
1780 
1781  for (int x = 0; x < src->width; x++) {
1782  webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, (alpha ? *src_a : 255));
1783  src_y += 1;
1784  src_u += x & 1;
1785  src_v += x & 1;
1786  if (alpha)
1787  src_a += 1;
1788  dst_argb += sizeof(uint32_t);
1789  }
1790  }
1791 }
1792 
1793 static void blend_yuva2argb(AVFrame *dst, AVFrame *src, int pos_x, int pos_y)
1794 {
1795  const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src->format);
1796 
1797  int plane_y = src_desc->comp[0].plane;
1798  int plane_u = src_desc->comp[1].plane;
1799  int plane_v = src_desc->comp[2].plane;
1800  int plane_a = src_desc->comp[3].plane;
1801 
1802  for (int y = 0; y < src->height; y++) {
1803  const uint8_t *src_y = src->data[plane_y] + y * src->linesize[plane_y];
1804  const uint8_t *src_u = src->data[plane_u] + (y >> 1) * src->linesize[plane_u];
1805  const uint8_t *src_v = src->data[plane_v] + (y >> 1) * src->linesize[plane_v];
1806  const uint8_t *src_a = src->data[plane_a] + y * src->linesize[plane_a];
1807  uint8_t *dst_argb = dst->data[0] + (pos_y + y) * dst->linesize[0] + pos_x * 4;
1808 
1809  for (int x = 0; x < src->width; x++) {
1810  int src_alpha = *src_a;
1811  int dst_alpha = dst_argb[0];
1812 
1813  if (src_alpha == 255) {
1814  webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, src_alpha);
1815  } else if (src_alpha == 0) {
1816  // no-op
1817  } else {
1818  uint8_t tmp[4];
1819  int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1820  int blend_alpha = src_alpha + tmp_alpha;
1821  int scale = (1UL << 24) / blend_alpha;
1822 
1823  webp_yuva2argb(tmp, *src_y, *src_u, *src_v, src_alpha);
1824 
1825  dst_argb[0] = blend_alpha;
1826  dst_argb[1] = (((uint32_t) (tmp[1] * src_alpha + dst_argb[1] * tmp_alpha)) * scale) >> 24;
1827  dst_argb[2] = (((uint32_t) (tmp[2] * src_alpha + dst_argb[2] * tmp_alpha)) * scale) >> 24;
1828  dst_argb[3] = (((uint32_t) (tmp[3] * src_alpha + dst_argb[3] * tmp_alpha)) * scale) >> 24;
1829  }
1830 
1831  src_y += 1;
1832  src_u += x & 1;
1833  src_v += x & 1;
1834  src_a += 1;
1835  dst_argb += sizeof(uint32_t);
1836  }
1837  }
1838 }
1839 
1840 static int blend_subframe_into_canvas(AnimatedWebPContext *s)
1841 {
1842  AVFrame *canvas = s->canvas;
1843  AVFrame *frame = s->subframe;
1844 
1845  if ((s->anmf_flags & ANMF_FLAG_NO_BLEND)
1846  || frame->format == AV_PIX_FMT_YUV420P) {
1847  // do not blend, overwrite
1848 
1849  if (canvas->format == AV_PIX_FMT_ARGB) {
1850  if (canvas->format == frame->format) {
1851  const uint8_t *src = frame->data[0];
1852  uint8_t *dst = canvas->data[0] +
1853  s->pos_y * canvas->linesize[0] +
1854  s->pos_x * sizeof(uint32_t);
1855  for (int y = 0; y < s->w.height; y++) {
1856  memcpy(dst, src, s->w.width * sizeof(uint32_t));
1857  src += frame->linesize[0];
1858  dst += canvas->linesize[0];
1859  }
1860  } else {
1861  copy_yuva2argb(canvas, frame, s->pos_x, s->pos_y);
1862  }
1863  } else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ {
1865 
1866  for (int comp = 0; comp < desc->nb_components; comp++) {
1867  int plane = desc->comp[comp].plane;
1868  int shift = (comp == 1 || comp == 2) ? 1 : 0;
1869  const uint8_t *src = frame->data[plane];
1870  uint8_t *dst = canvas->data[plane] +
1871  (s->pos_y >> shift) * canvas->linesize[plane] +
1872  (s->pos_x >> shift);
1873  for (int y = 0; y < AV_CEIL_RSHIFT(s->w.height, shift); y++) {
1874  memcpy(dst, src, AV_CEIL_RSHIFT(s->w.width, shift));
1875  src += frame->linesize[plane];
1876  dst += canvas->linesize[plane];
1877  }
1878  }
1879 
1880  if (canvas->format == AV_PIX_FMT_YUVA420P && desc->nb_components < 4) {
1881  // frame does not have alpha, set alpha to 255
1882  const AVPixFmtDescriptor *canvas_desc = av_pix_fmt_desc_get(canvas->format);
1883  int plane = canvas_desc->comp[3].plane;
1884  uint8_t *dst = canvas->data[plane] + s->pos_y * canvas->linesize[plane] + s->pos_x;
1885  for (int y = 0; y < s->w.height; y++) {
1886  memset(dst, 255, s->w.width);
1887  dst += canvas->linesize[plane];
1888  }
1889  }
1890  }
1891  } else {
1892  // alpha blending
1893 
1894  if (canvas->format == AV_PIX_FMT_ARGB) {
1895  if (canvas->format == frame->format) {
1896  blend_alpha_argb(canvas, frame, s->pos_x, s->pos_y);
1897  } else {
1898  blend_yuva2argb(canvas, frame, s->pos_x, s->pos_y);
1899  }
1900  } else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ {
1901  blend_alpha_yuva(canvas, frame, s->pos_x, s->pos_y);
1902  }
1903  }
1904 
1905  return 0;
1906 }
1907 
1908 /**
1909  * Fill a rectangle on the canvas with the background color (transparent black
1910  * by default, or the color from the ANIM chunk if provided by the demuxer).
1911  */
1912 static void fill_canvas_rect(AnimatedWebPContext *s, int pos_x, int pos_y, int width, int height)
1913 {
1914  AVFrame *canvas = s->canvas;
1915 
1916  if (canvas->format == AV_PIX_FMT_ARGB) {
1917  uint32_t bg_color = AV_RN32(s->background_argb);
1918  int is_repeatable = (bg_color == ((bg_color & 0xff) * 0x01010101));
1919  for (int y = 0; y < height; y++) {
1920  uint32_t *dst = (uint32_t *) (canvas->data[0] + (pos_y + y) * canvas->linesize[0]) + pos_x;
1921  if (is_repeatable) {
1922  memset(dst, bg_color, width * sizeof(uint32_t));
1923  } else {
1924  for (int x = 0; x < width; x++)
1925  dst[x] = bg_color;
1926  }
1927  }
1928  } else /* if (canvas->format == AV_PIX_FMT_YUVA420P) */ {
1930  for (int comp = 0; comp < desc->nb_components; comp++) {
1931  int shift = (comp == 1 || comp == 2) ? 1 : 0;
1932  int plane = desc->comp[comp].plane;
1933  uint8_t *dst = canvas->data[plane] + (pos_y >> shift) * canvas->linesize[plane] + (pos_x >> shift);
1934  for (int y = 0; y < AV_CEIL_RSHIFT(height, shift); y++) {
1935  memset(dst, s->background_yuva[plane], AV_CEIL_RSHIFT(width, shift));
1936  dst += canvas->linesize[plane];
1937  }
1938  }
1939  }
1940 }
1941 
1942 static int allocate_canvas(AnimatedWebPContext *s, int format)
1943 {
1944  s->w.avctx->pix_fmt = format;
1945  int ret = ff_set_dimensions(s->w.avctx, s->canvas_width, s->canvas_height);
1946  if (ret < 0)
1947  return ret;
1948  return ff_reget_buffer(s->w.avctx, s->canvas, 0);
1949 }
1950 
1951 static int prepare_canvas(AnimatedWebPContext *s, int key_frame, int format)
1952 {
1953  int ret;
1954 
1955  /**
1956  * Clear the canvas on keyframes and frames that overwrite the entire
1957  * canvas.
1958  */
1959  if (key_frame ||
1960  ((s->anmf_flags & ANMF_FLAG_NO_BLEND) &&
1961  (s->pos_x == 0) && (s->pos_x + s->w.width == s->canvas_width) &&
1962  (s->pos_y == 0) && (s->pos_y + s->w.height == s->canvas_height)))
1963  av_frame_unref(s->canvas);
1964 
1965  if (!s->canvas->buf[0]) {
1966  /* Allocate new canvas frame */
1967  ret = allocate_canvas(s, format);
1968  if (ret < 0)
1969  return ret;
1970  /* ... and initialize it. */
1971  fill_canvas_rect(s, 0, 0, s->canvas->width, s->canvas->height);
1972  } else {
1973  if (format == AV_PIX_FMT_ARGB && s->canvas->format == AV_PIX_FMT_YUVA420P) {
1974  /**
1975  * If we have a lossless frame following a lossy frame, we upgrade
1976  * the canvas to ARGB, but we don't convert the canvas back to YUVA
1977  * if there is a lossy frame following a lossless frame.
1978  */
1979  AVFrame *yuva_canvas = av_frame_clone(s->canvas);
1980  if (!yuva_canvas)
1981  return AVERROR(ENOMEM);
1982  av_frame_unref(s->canvas);
1983  ret = allocate_canvas(s, AV_PIX_FMT_ARGB);
1984  if (ret < 0) {
1985  av_frame_free(&yuva_canvas);
1986  return ret;
1987  }
1988  copy_yuva2argb(s->canvas, yuva_canvas, 0, 0);
1989  av_frame_free(&yuva_canvas);
1990  } else {
1991  /**
1992  * The decode frame function returns a reference to the canvas,
1993  * therefore we have to ensure it is writable before using it
1994  * for a new frame.
1995  */
1996  ret = av_frame_make_writable(s->canvas);
1997  if (ret < 0)
1998  return ret;
1999  }
2000  /* Dispose of previous frame if needed. */
2001  if (s->prev_anmf_flags & ANMF_FLAG_DISPOSE)
2002  fill_canvas_rect(s, s->prev_pos_x, s->prev_pos_y, s->prev_width, s->prev_height);
2003  }
2004 
2005  return 0;
2006 }
2007 
2008 static int webp_anim_decode_frame(AVCodecContext *avctx, AVFrame *p,
2009  int *got_frame, AVPacket *avpkt)
2010 {
2011  AnimatedWebPContext *s = avctx->priv_data;
2012  int key_frame = (avpkt->flags & AV_PKT_FLAG_KEY);
2013  int ret;
2014 
2015  GetByteContext gb;
2016  bytestream2_init(&gb, avpkt->data, avpkt->size);
2017 
2018  /* Parse ANMF header. */
2019  s->pos_x = bytestream2_get_le24(&gb) * 2;
2020  s->pos_y = bytestream2_get_le24(&gb) * 2;
2021  s->w.width = bytestream2_get_le24(&gb) + 1;
2022  s->w.height = bytestream2_get_le24(&gb) + 1;
2023  s->duration = bytestream2_get_le24(&gb);
2024  s->anmf_flags = bytestream2_get_byte(&gb);
2025 
2026  av_log(avctx, AV_LOG_DEBUG,
2027  "ANMF frame pos: %dx%d size: %dx%d duration: %d\n",
2028  s->pos_x, s->pos_y, s->w.width, s->w.height, s->duration);
2029 
2030  /* Reset alpha field from previous frame. */
2031  s->w.has_alpha = 0;
2032 
2033  /* Parse ANMF subchunks. */
2034  while (bytestream2_get_bytes_left(&gb) > 8) {
2035  uint32_t chunk_type = bytestream2_get_le32(&gb);
2036  uint32_t chunk_size = bytestream2_get_le32(&gb);
2037 
2038  if (chunk_size == UINT32_MAX) {
2040  goto end;
2041  }
2042  chunk_size += chunk_size & 1;
2043 
2044  if (bytestream2_get_bytes_left(&gb) < chunk_size) {
2045  /* we seem to be running out of data, but it could also be that the
2046  * bitstream has trailing junk leading to bogus chunk_size. */
2047  break;
2048  }
2049 
2050  switch (chunk_type) {
2051  case MKTAG('A', 'L', 'P', 'H'): {
2052  if (chunk_size == 0) {
2053  av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
2055  goto end;
2056  }
2057  int alpha_header = bytestream2_get_byte(&gb);
2058  s->w.alpha_data = avpkt->data + bytestream2_tell(&gb);
2059  s->w.alpha_data_size = chunk_size - 1;
2060  bytestream2_skip(&gb, s->w.alpha_data_size);
2061 
2062  int filter_m = (alpha_header >> 2) & 0x03;
2063  int compression = alpha_header & 0x03;
2064 
2065  if (compression > ALPHA_COMPRESSION_VP8L) {
2066  av_log(avctx, AV_LOG_VERBOSE,
2067  "skipping unsupported ALPHA chunk\n");
2068  } else {
2069  s->w.has_alpha = 1;
2070  s->w.alpha_compression = compression;
2071  s->w.alpha_filter = filter_m;
2072  }
2073 
2074  break;
2075  }
2076  case MKTAG('V', 'P', '8', ' '):
2077  if (*got_frame) {
2078  av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra VP8 chunk\n");
2079  bytestream2_skip(&gb, chunk_size);
2080  break;
2081  }
2082  ret = vp8_lossy_decode_frame(avctx, s->subframe, got_frame,
2083  avpkt->data + bytestream2_tell(&gb),
2084  chunk_size);
2085  if (ret < 0)
2086  goto end;
2087  ret = prepare_canvas(s, key_frame, AV_PIX_FMT_YUVA420P);
2088  if (ret < 0)
2089  goto end;
2090  bytestream2_skip(&gb, chunk_size);
2091  break;
2092  case MKTAG('V', 'P', '8', 'L'):
2093  if (*got_frame) {
2094  av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra VP8L chunk\n");
2095  bytestream2_skip(&gb, chunk_size);
2096  break;
2097  }
2098  ret = vp8_lossless_decode_frame(avctx, s->subframe, got_frame,
2099  avpkt->data + bytestream2_tell(&gb),
2100  chunk_size, 0);
2101  if (ret < 0)
2102  goto end;
2103  ret = prepare_canvas(s, key_frame, AV_PIX_FMT_ARGB);
2104  if (ret < 0)
2105  goto end;
2106 #if FF_API_CODEC_PROPS
2110 #endif
2111  bytestream2_skip(&gb, chunk_size);
2112  break;
2113  default:
2114  av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
2115  av_fourcc2str(chunk_type));
2116  bytestream2_skip(&gb, chunk_size);
2117  break;
2118  }
2119  }
2120 
2121  if (!*got_frame) {
2122  av_log(avctx, AV_LOG_ERROR, "image data not found\n");
2124  goto end;
2125  }
2126 
2127  /* The subframe dimensions may have been modified by update_canvas_size() */
2128  if (s->pos_x + s->w.width > s->canvas_width ||
2129  s->pos_y + s->w.height > s->canvas_height) {
2130  av_log(avctx, AV_LOG_ERROR,
2131  "Frame (%dx%d at pos %dx%d) does not fit into canvas (%dx%d)\n",
2132  s->w.width, s->w.height, s->pos_x, s->pos_y,
2133  s->canvas_width, s->canvas_height);
2135  goto end;
2136  }
2137 
2138  ret = blend_subframe_into_canvas(s);
2139  if (ret < 0)
2140  goto end;
2141 
2142  ret = av_frame_ref(p, s->canvas);
2143  if (ret < 0)
2144  goto end;
2145 
2146  p->pict_type = key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
2147  p->pts = avpkt->pts;
2148  p->duration = s->duration;
2149 
2150  s->prev_anmf_flags = s->anmf_flags;
2151  s->prev_width = s->w.width;
2152  s->prev_height = s->w.height;
2153  s->prev_pos_x = s->pos_x;
2154  s->prev_pos_y = s->pos_y;
2155 
2156  ret = avpkt->size;
2157 
2158 end:
2159  av_frame_unref(s->subframe);
2160  return ret;
2161 }
2162 
2163 static av_cold int webp_anim_decode_init(AVCodecContext *avctx)
2164 {
2165  AnimatedWebPContext *s = avctx->priv_data;
2166 
2167  s->w.avctx = avctx;
2168  s->canvas_width = avctx->width;
2169  s->canvas_height = avctx->height;
2170 
2171  s->canvas = av_frame_alloc();
2172  if (!s->canvas)
2173  return AVERROR(ENOMEM);
2174 
2175  s->subframe = av_frame_alloc();
2176  if (!s->subframe)
2177  return AVERROR(ENOMEM);
2178 
2179  /**
2180  * Use background color if it was provided by the demuxer. Otherwise, the
2181  * background color will be 0x00000000 (transparent black).
2182  */
2183  if (avctx->extradata_size >= 4) {
2184  s->background_argb[0] = avctx->extradata[3];
2185  s->background_argb[1] = avctx->extradata[2];
2186  s->background_argb[2] = avctx->extradata[1];
2187  s->background_argb[3] = avctx->extradata[0];
2188  }
2189 
2190  /* Convert background color to YUVA. */
2191  const uint8_t *argb = s->background_argb;
2192  s->background_yuva[0] = RGB_TO_Y_CCIR(argb[1], argb[2], argb[3]);
2193  s->background_yuva[1] = RGB_TO_U_CCIR(argb[1], argb[2], argb[3], 0);
2194  s->background_yuva[2] = RGB_TO_V_CCIR(argb[1], argb[2], argb[3], 0);
2195  s->background_yuva[3] = argb[0];
2196 
2197  return webp_decode_init(avctx);
2198 }
2199 
2200 static av_cold int webp_anim_decode_close(AVCodecContext *avctx)
2201 {
2202  AnimatedWebPContext *s = avctx->priv_data;
2203 
2204  av_frame_free(&s->canvas);
2205  av_frame_free(&s->subframe);
2206 
2207  return webp_decode_close(avctx);
2208 }
2209 
2210 const FFCodec ff_webp_anim_decoder = {
2211  .p.name = "webp_anim",
2212  CODEC_LONG_NAME("Animated WebP image"),
2213  .p.type = AVMEDIA_TYPE_VIDEO,
2214  .p.id = AV_CODEC_ID_WEBP_ANIM,
2215  .priv_data_size = sizeof(AnimatedWebPContext),
2216  .init = webp_anim_decode_init,
2217  FF_CODEC_DECODE_CB(webp_anim_decode_frame),
2218  .close = webp_anim_decode_close,
2219  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
2220  .caps_internal = FF_CODEC_CAP_USES_PROGRESSFRAMES,
2221 };
2222 #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:433
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
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
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:459
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:531
GET_PIXEL_COMP
#define GET_PIXEL_COMP(frame, x, y, c)
Definition: webp.c:230
AVPacket::data
uint8_t * data
Definition: packet.h:595
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:480
HuffReader::simple
int simple
Definition: webp.c:181
PRED_MODE_TL
@ PRED_MODE_TL
Definition: webp.c:131
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:1587
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
av_cold
#define av_cold
Definition: attributes.h:119
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
FF_CODEC_PROPERTY_LOSSLESS
#define FF_CODEC_PROPERTY_LOSSLESS
Definition: avcodec.h:1656
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:674
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:347
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:1044
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:1575
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:332
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:95
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:63
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:1564
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:551
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:52
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:596
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:2487
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:2175
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:316
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:546
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:99
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:335
line
Definition: graph2dot.c:48
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:601
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:588
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
av_always_inline
#define av_always_inline
Definition: attributes.h:76
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:179
AV_CODEC_ID_WEBP
@ AV_CODEC_ID_WEBP
Definition: codec_id.h:226
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:1897
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
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
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:314
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:572
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
AVCodecContext::properties
attribute_deprecated unsigned properties
Properties of the stream that gets decoded.
Definition: avcodec.h:1655
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:504
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:695
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:347
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