46#include "config_components.h"
52#define BITSTREAM_READER_LE
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
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
86 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
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 }
227#define GET_PIXEL(frame, x, y) \
228 ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
230#define GET_PIXEL_COMP(frame, x, y, c) \
231 (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
240 if (
img->huffman_groups) {
241 for (
i = 0;
i <
img->nb_huffman_groups;
i++) {
247 memset(
img, 0,
sizeof(*
img));
253 if (
r->nb_symbols == 1)
254 return r->simple_symbols[0];
263 uint8_t lens[], uint16_t syms[],
264 int alphabet_size,
void *logctx)
266 unsigned nb_codes = 0;
272 unsigned cnt = len_counts[
len];
273 len_counts[
len] = nb_codes;
277 for (
int sym = 0; sym < alphabet_size; ++sym) {
278 if (code_lengths[sym]) {
279 unsigned idx = len_counts[code_lengths[sym]]++;
281 lens[idx] = code_lengths[sym];
293 r->simple_symbols[0] = syms[0];
324 HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } };
325 uint8_t *code_lengths;
330 int symbol, max_symbol, prev_code_len, ret;
335 for (
int i = 0;
i < num_codes;
i++) {
344 if (max_symbol > alphabet_size) {
346 max_symbol, alphabet_size);
350 max_symbol = alphabet_size;
354 reordered_code_length_code_lengths,
355 reordered_code_length_syms,
360 code_lengths =
av_malloc_array(alphabet_size, 2 *
sizeof(uint8_t) +
sizeof(uint16_t));
368 memset(len_counts, 0,
sizeof(len_counts));
369 while (symbol < alphabet_size) {
375 if (code_len < 16U) {
377 code_lengths[symbol++] = code_len;
378 len_counts[code_len]++;
380 prev_code_len = code_len;
382 int repeat = 0, length = 0;
392 length = prev_code_len;
393 len_counts[length] += repeat;
406 if (symbol + repeat > alphabet_size) {
408 "invalid symbol %d + repeat %d > alphabet size %d\n",
409 symbol, repeat, alphabet_size);
414 code_lengths[symbol++] = length;
419 code_lengths + symbol,
420 (uint16_t*)(code_lengths + 2 * symbol),
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; \
455 for (y = 0; y <
img->frame->height; y++) {
456 for (x = 0; x <
img->frame->width; x++) {
459 int p = p0 << 8 | p1;
463 s->nb_huffman_groups =
max + 1;
503 int width_bits, index_size, ret, x;
510 else if (index_size <= 4)
512 else if (index_size <= 16)
523 img->size_reduction = width_bits;
525 s->reduced_width = (
s->width + ((1 << width_bits) - 1)) >> width_bits;
528 ct =
img->frame->data[0] + 4;
529 for (x = 4; x <
img->frame->width * 4; x++, ct++)
546 group = g0 << 8 | g1;
554 uint32_t cache_idx = (0x1E35A7BD *
c) >> (32 -
img->color_cache_bits);
555 img->color_cache[cache_idx] =
c;
563 int i, j, ret, x, y,
width;
565 img = &
s->image[role];
575 img->frame->width =
w;
576 img->frame->height =
h;
587 if (
img->color_cache_bits < 1 ||
img->color_cache_bits > 11) {
589 img->color_cache_bits);
593 sizeof(*
img->color_cache));
594 if (!
img->color_cache)
597 img->color_cache_bits = 0;
600 img->nb_huffman_groups = 1;
605 img->nb_huffman_groups =
s->nb_huffman_groups;
609 sizeof(*
img->huffman_groups));
610 if (!
img->huffman_groups)
613 for (
i = 0;
i <
img->nb_huffman_groups;
i++) {
617 if (!j &&
img->color_cache_bits > 0)
618 alphabet_size += 1 <<
img->color_cache_bits;
635 while (y < img->
frame->height) {
650 if (
img->color_cache_bits)
659 int prefix_code, length,
distance, ref_x, ref_y;
663 if (prefix_code < 4) {
664 length = prefix_code + 1;
671 if (prefix_code > 39U) {
673 "distance prefix code too large: %d\n", prefix_code);
676 if (prefix_code < 4) {
709 ref_x =
FFMAX(0, ref_x);
710 ref_y =
FFMAX(0, ref_y);
712 if (ref_y == y && ref_x >= x)
718 for (
i = 0;
i < length;
i++) {
723 if (
img->color_cache_bits)
731 if (ref_x ==
width) {
735 if (y ==
img->frame->height || ref_y ==
img->frame->height)
743 if (!
img->color_cache_bits) {
747 if (cache_idx >= 1 <<
img->color_cache_bits) {
749 "color cache index out-of-bounds\n");
765static void inv_predict_0(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
766 const uint8_t *p_t,
const uint8_t *p_tr)
772static void inv_predict_1(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
773 const uint8_t *p_t,
const uint8_t *p_tr)
779static void inv_predict_2(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
780 const uint8_t *p_t,
const uint8_t *p_tr)
786static void inv_predict_3(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
787 const uint8_t *p_t,
const uint8_t *p_tr)
793static void inv_predict_4(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
794 const uint8_t *p_t,
const uint8_t *p_tr)
800static void inv_predict_5(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
801 const uint8_t *p_t,
const uint8_t *p_tr)
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;
810static void inv_predict_6(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
811 const uint8_t *p_t,
const uint8_t *p_tr)
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;
820static void inv_predict_7(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
821 const uint8_t *p_t,
const uint8_t *p_tr)
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;
830static void inv_predict_8(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
831 const uint8_t *p_t,
const uint8_t *p_tr)
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;
840static void inv_predict_9(uint8_t *p,
const uint8_t *p_l,
const uint8_t *p_tl,
841 const uint8_t *p_t,
const uint8_t *p_tr)
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;
851 const uint8_t *p_t,
const uint8_t *p_tr)
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;
861 const uint8_t *p_t,
const uint8_t *p_tr)
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]));
875 const uint8_t *p_t,
const uint8_t *p_tr)
891 const uint8_t *p_t,
const uint8_t *p_tr)
900 const uint8_t *p_tl,
const uint8_t *p_t,
901 const uint8_t *p_tr);
912 uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr;
919 if (x ==
frame->width - 1)
938 for (y = 0; y <
img->frame->height; y++) {
939 for (x = 0; x <
s->reduced_width; x++) {
954 "invalid predictor mode: %d\n", m);
978 for (y = 0; y <
img->frame->height; y++) {
979 for (x = 0; x <
s->reduced_width; x++) {
998 for (y = 0; y <
img->frame->height; y++) {
999 for (x = 0; x <
s->reduced_width; x++) {
1027 for (y = 0; y <
img->frame->height; y++) {
1029 memcpy(
line, p,
img->frame->linesize[0]);
1033 for (x = 0; x <
img->frame->width; x++) {
1035 p[2] =
get_bits(&gb_g, pixel_bits);
1044 s->reduced_width =
s->width;
1048 if (
img->frame->height *
img->frame->width > 300) {
1049 uint8_t palette[256 * 4];
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++) {
1063 for (y = 0; y <
img->frame->height; y++) {
1064 for (x = 0; x <
img->frame->width; x++) {
1083 if (
s->width &&
s->width !=
w) {
1088 if (
s->height &&
s->height !=
h) {
1096 int *got_frame,
const uint8_t *data_start,
1097 unsigned int data_size,
int is_alpha_chunk)
1100 int w,
h, ret,
i, used;
1102 if (!is_alpha_chunk)
1109 if (!is_alpha_chunk) {
1131 if (!
s->width || !
s->height)
1138 s->nb_transforms = 0;
1139 s->reduced_width =
s->width;
1147 goto free_and_return;
1163 goto free_and_return;
1172 goto free_and_return;
1175 for (
i =
s->nb_transforms - 1;
i >= 0;
i--) {
1176 switch (
s->transforms[
i]) {
1191 goto free_and_return;
1212 ls =
frame->linesize[3];
1215 dec =
frame->data[3] + 1;
1216 for (x = 1; x <
frame->width; x++, dec++)
1220 dec =
frame->data[3] + ls;
1221 for (y = 1; y <
frame->height; y++, dec += ls)
1222 *dec += *(dec - ls);
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++)
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);
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));
1251 const uint8_t *data_start,
1252 unsigned int data_size)
1261 for (y = 0; y <
s->height; y++)
1266 int alpha_got_frame = 0;
1269 if (!
s->alpha_frame)
1273 data_start, data_size, 1);
1278 if (!alpha_got_frame) {
1284 for (y = 0; y <
s->height; y++) {
1286 pp = p->data[3] + p->linesize[3] * y;
1287 for (x = 0; x <
s->width; x++) {
1297 if (
s->alpha_filter)
1304 int *got_frame, uint8_t *data_start,
1305 unsigned int data_size)
1310 if (!
s->initialized) {
1313 s->v.actually_webp = 1;
1317 if (data_size > INT_MAX) {
1323 s->pkt->data = data_start;
1324 s->pkt->size = data_size;
1337 s->alpha_data_size);
1350 uint32_t chunk_type, chunk_size;
1366 if (bytestream2_get_le32(&gb) !=
MKTAG(
'R',
'I',
'F',
'F')) {
1371 chunk_size = bytestream2_get_le32(&gb);
1375 if (bytestream2_get_le32(&gb) !=
MKTAG(
'W',
'E',
'B',
'P')) {
1381 chunk_type = bytestream2_get_le32(&gb);
1382 chunk_size = bytestream2_get_le32(&gb);
1383 if (chunk_size == UINT32_MAX)
1385 chunk_size += chunk_size & 1;
1393 switch (chunk_type) {
1394 case MKTAG(
'V',
'P',
'8',
' '):
1404 case MKTAG(
'V',
'P',
'8',
'L'):
1414 case MKTAG(
'V',
'P',
'8',
'X'):
1415 if (
s->width ||
s->height || *got_frame) {
1419 vp8x_flags = bytestream2_get_byte(&gb);
1421 s->width = bytestream2_get_le24(&gb) + 1;
1422 s->height = bytestream2_get_le24(&gb) + 1;
1427 case MKTAG(
'A',
'L',
'P',
'H'): {
1428 int alpha_header, filter_m, compression;
1432 "ALPHA chunk present, but alpha bit not set in the "
1435 if (chunk_size == 0) {
1439 alpha_header = bytestream2_get_byte(&gb);
1441 s->alpha_data_size = chunk_size - 1;
1444 filter_m = (alpha_header >> 2) & 0x03;
1445 compression = alpha_header & 0x03;
1449 "skipping unsupported ALPHA chunk\n");
1452 s->alpha_compression = compression;
1453 s->alpha_filter = filter_m;
1458 case MKTAG(
'E',
'X',
'I',
'F'): {
1468 "EXIF chunk present, but Exif bit not set in the "
1477 memcpy(exif_buf->
data, gb.
buffer, chunk_size);
1487 case MKTAG(
'I',
'C',
'C',
'P'): {
1497 "ICCP chunk present, but ICC Profile bit not set in the "
1513 case MKTAG(
'A',
'N',
'I',
'M'):
1514 case MKTAG(
'A',
'N',
'M',
'F'):
1519 case MKTAG(
'X',
'M',
'P',
' '): {
1527 "XMP chunk present, but XMP bit not set in the "
1538 buffer[chunk_size] =
'\0';
1596#if CONFIG_WEBP_ANIM_DECODER
1598#define ANMF_FLAG_DISPOSE (1 << 0)
1599#define ANMF_FLAG_NO_BLEND (1 << 1)
1601typedef struct AnimatedWebPContext {
1612 int prev_anmf_flags;
1617 uint8_t background_argb[4];
1618 uint8_t background_yuva[4];
1619} AnimatedWebPContext;
1627 for (
int y = 0; y <
src->height; y++) {
1628 const uint8_t *src_argb =
src->data[0] + y *
src->linesize[0];
1629 uint8_t *dst_argb =
dst->data[0] + (pos_y + y) *
dst->linesize[0] + pos_x *
sizeof(uint32_t);
1630 for (
int x = 0; x <
src->width; x++) {
1631 int src_alpha = src_argb[0];
1632 int dst_alpha = dst_argb[0];
1634 if (src_alpha == 255) {
1635 memcpy(dst_argb, src_argb,
sizeof(uint32_t));
1636 }
else if (src_alpha == 0) {
1639 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1640 int blend_alpha = src_alpha + tmp_alpha;
1641 int scale = (1UL << 24) / blend_alpha;
1643 dst_argb[0] = blend_alpha;
1644 dst_argb[1] = (((uint32_t) (src_argb[1] * src_alpha + dst_argb[1] * tmp_alpha)) *
scale) >> 24;
1645 dst_argb[2] = (((uint32_t) (src_argb[2] * src_alpha + dst_argb[2] * tmp_alpha)) *
scale) >> 24;
1646 dst_argb[3] = (((uint32_t) (src_argb[3] * src_alpha + dst_argb[3] * tmp_alpha)) *
scale) >> 24;
1648 src_argb +=
sizeof(uint32_t);
1649 dst_argb +=
sizeof(uint32_t);
1662 int plane_y =
desc->comp[0].plane;
1663 int plane_u =
desc->comp[1].plane;
1664 int plane_v =
desc->comp[2].plane;
1665 int plane_a =
desc->comp[3].plane;
1669 int tile_h =
FFMIN(
src->height - y * 2, 2);
1670 const uint8_t *src_u =
src->data[plane_u] + y *
src->linesize[plane_u];
1671 const uint8_t *src_v =
src->data[plane_v] + y *
src->linesize[plane_v];
1672 uint8_t *dst_u =
dst->data[plane_u] + ((pos_y >> 1) + y) *
dst->linesize[plane_u] + (pos_x >> 1);
1673 uint8_t *dst_v =
dst->data[plane_v] + ((pos_y >> 1) + y) *
dst->linesize[plane_v] + (pos_x >> 1);
1675 int tile_w =
FFMIN(
src->width - x * 2, 2);
1679 for (
int yy = 0; yy < tile_h; yy++) {
1680 for (
int xx = 0; xx < tile_w; xx++) {
1681 src_alpha +=
src->data[plane_a][(y * 2 + yy) *
src->linesize[plane_a] +
1683 dst_alpha +=
dst->data[plane_a][(((pos_y >> 1) + y) * 2 + yy) *
dst->linesize[plane_a] +
1684 (((pos_x >> 1) + x) * 2 + xx)];
1687 int shift = (tile_h == 2) + (tile_w == 2);
1691 if (src_alpha == 255) {
1694 }
else if (src_alpha == 0) {
1697 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1698 int blend_alpha = src_alpha + tmp_alpha;
1699 int scale = (1UL << 24) / blend_alpha;
1700 *dst_u = (((uint32_t) (*src_u * src_alpha + *dst_u * tmp_alpha)) *
scale) >> 24;
1701 *dst_v = (((uint32_t) (*src_v * src_alpha + *dst_v * tmp_alpha)) *
scale) >> 24;
1711 for (
int y = 0; y <
src->height; y++) {
1712 const uint8_t *src_y =
src->data[plane_y] + y *
src->linesize[plane_y];
1713 const uint8_t *src_a =
src->data[plane_a] + y *
src->linesize[plane_a];
1714 uint8_t *dst_y =
dst->data[plane_y] + (pos_y + y) *
dst->linesize[plane_y] + pos_x;
1715 uint8_t *dst_a =
dst->data[plane_a] + (pos_y + y) *
dst->linesize[plane_a] + pos_x;
1716 for (
int x = 0; x <
src->width; x++) {
1717 int src_alpha = *src_a;
1718 int dst_alpha = *dst_a;
1720 if (src_alpha == 255) {
1723 }
else if (src_alpha == 0) {
1726 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1727 int blend_alpha = src_alpha + tmp_alpha;
1728 int scale = (1UL << 24) / blend_alpha;
1729 *dst_y = (((uint32_t) (*src_y * src_alpha + *dst_y * tmp_alpha)) *
scale) >> 24;
1730 *dst_a = blend_alpha;
1746 int r_add, g_add, b_add;
1767 for (
int y = 0; y <
src->height; y++) {
1768 const uint8_t *src_y =
src->data[plane_y] + y *
src->linesize[plane_y];
1769 const uint8_t *src_u =
src->data[plane_u] + (y >> 1) *
src->linesize[plane_u];
1770 const uint8_t *src_v =
src->data[plane_v] + (y >> 1) *
src->linesize[plane_v];
1771 const uint8_t *src_a =
NULL;
1772 uint8_t *dst_argb =
dst->data[0] + (pos_y + y) *
dst->linesize[0] + pos_x * 4;
1774 src_a =
src->data[plane_a] + y *
src->linesize[plane_a];
1776 for (
int x = 0; x <
src->width; x++) {
1777 webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, (
alpha ? *src_a : 255));
1783 dst_argb +=
sizeof(uint32_t);
1797 for (
int y = 0; y <
src->height; y++) {
1798 const uint8_t *src_y =
src->data[plane_y] + y *
src->linesize[plane_y];
1799 const uint8_t *src_u =
src->data[plane_u] + (y >> 1) *
src->linesize[plane_u];
1800 const uint8_t *src_v =
src->data[plane_v] + (y >> 1) *
src->linesize[plane_v];
1801 const uint8_t *src_a =
src->data[plane_a] + y *
src->linesize[plane_a];
1802 uint8_t *dst_argb =
dst->data[0] + (pos_y + y) *
dst->linesize[0] + pos_x * 4;
1804 for (
int x = 0; x <
src->width; x++) {
1805 int src_alpha = *src_a;
1806 int dst_alpha = dst_argb[0];
1808 if (src_alpha == 255) {
1809 webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, src_alpha);
1810 }
else if (src_alpha == 0) {
1814 int tmp_alpha = (dst_alpha * (256 - src_alpha)) >> 8;
1815 int blend_alpha = src_alpha + tmp_alpha;
1816 int scale = (1UL << 24) / blend_alpha;
1818 webp_yuva2argb(
tmp, *src_y, *src_u, *src_v, src_alpha);
1820 dst_argb[0] = blend_alpha;
1821 dst_argb[1] = (((uint32_t) (
tmp[1] * src_alpha + dst_argb[1] * tmp_alpha)) *
scale) >> 24;
1822 dst_argb[2] = (((uint32_t) (
tmp[2] * src_alpha + dst_argb[2] * tmp_alpha)) *
scale) >> 24;
1823 dst_argb[3] = (((uint32_t) (
tmp[3] * src_alpha + dst_argb[3] * tmp_alpha)) *
scale) >> 24;
1830 dst_argb +=
sizeof(uint32_t);
1835static int blend_subframe_into_canvas(AnimatedWebPContext *
s)
1840 if ((
s->anmf_flags & ANMF_FLAG_NO_BLEND)
1846 const uint8_t *
src =
frame->data[0];
1847 uint8_t *
dst = canvas->
data[0] +
1849 s->pos_x *
sizeof(uint32_t);
1850 for (
int y = 0; y <
s->w.height; y++) {
1851 memcpy(
dst,
src,
s->w.width *
sizeof(uint32_t));
1856 copy_yuva2argb(canvas,
frame,
s->pos_x,
s->pos_y);
1862 int plane =
desc->comp[
comp].plane;
1864 const uint8_t *
src =
frame->data[plane];
1865 uint8_t *
dst = canvas->
data[plane] +
1879 uint8_t *
dst = canvas->
data[plane] +
s->pos_y * canvas->
linesize[plane] +
s->pos_x;
1880 for (
int y = 0; y <
s->w.height; y++) {
1881 memset(
dst, 255,
s->w.width);
1891 blend_alpha_argb(canvas,
frame,
s->pos_x,
s->pos_y);
1893 blend_yuva2argb(canvas,
frame,
s->pos_x,
s->pos_y);
1896 blend_alpha_yuva(canvas,
frame,
s->pos_x,
s->pos_y);
1907static void fill_canvas_rect(AnimatedWebPContext *
s,
int pos_x,
int pos_y,
int width,
int height)
1912 uint32_t bg_color =
AV_RN32(
s->background_argb);
1913 int is_repeatable = (bg_color == ((bg_color & 0xff) * 0x01010101));
1914 for (
int y = 0; y <
height; y++) {
1915 uint32_t *
dst = (uint32_t *) (canvas->
data[0] + (pos_y + y) * canvas->
linesize[0]) + pos_x;
1916 if (is_repeatable) {
1917 memset(
dst, bg_color,
width *
sizeof(uint32_t));
1919 for (
int x = 0; x <
width; x++)
1927 int plane =
desc->comp[
comp].plane;
1937static int allocate_canvas(AnimatedWebPContext *
s,
int format)
1946static int prepare_canvas(AnimatedWebPContext *
s,
int key_frame,
int format)
1955 ((
s->anmf_flags & ANMF_FLAG_NO_BLEND) &&
1956 (
s->pos_x == 0) && (
s->pos_x +
s->w.width ==
s->canvas_width) &&
1957 (
s->pos_y == 0) && (
s->pos_y +
s->w.height ==
s->canvas_height)))
1960 if (!
s->canvas->buf[0]) {
1962 ret = allocate_canvas(
s,
format);
1966 fill_canvas_rect(
s, 0, 0,
s->canvas->width,
s->canvas->height);
1983 copy_yuva2argb(
s->canvas, yuva_canvas, 0, 0);
1996 if (
s->prev_anmf_flags & ANMF_FLAG_DISPOSE)
1997 fill_canvas_rect(
s,
s->prev_pos_x,
s->prev_pos_y,
s->prev_width,
s->prev_height);
2014 s->pos_x = bytestream2_get_le24(&gb) * 2;
2015 s->pos_y = bytestream2_get_le24(&gb) * 2;
2016 s->w.width = bytestream2_get_le24(&gb) + 1;
2017 s->w.height = bytestream2_get_le24(&gb) + 1;
2018 s->duration = bytestream2_get_le24(&gb);
2019 s->anmf_flags = bytestream2_get_byte(&gb);
2022 "ANMF frame pos: %dx%d size: %dx%d duration: %d\n",
2023 s->pos_x,
s->pos_y,
s->w.width,
s->w.height,
s->duration);
2030 uint32_t chunk_type = bytestream2_get_le32(&gb);
2031 uint32_t chunk_size = bytestream2_get_le32(&gb);
2033 if (chunk_size == UINT32_MAX) {
2037 chunk_size += chunk_size & 1;
2045 switch (chunk_type) {
2046 case MKTAG(
'A',
'L',
'P',
'H'): {
2047 if (chunk_size == 0) {
2052 int alpha_header = bytestream2_get_byte(&gb);
2054 s->w.alpha_data_size = chunk_size - 1;
2057 int filter_m = (alpha_header >> 2) & 0x03;
2058 int compression = alpha_header & 0x03;
2062 "skipping unsupported ALPHA chunk\n");
2065 s->w.alpha_compression = compression;
2066 s->w.alpha_filter = filter_m;
2071 case MKTAG(
'V',
'P',
'8',
' '):
2087 case MKTAG(
'V',
'P',
'8',
'L'):
2118 if (
s->pos_x +
s->w.width >
s->canvas_width ||
2119 s->pos_y +
s->w.height >
s->canvas_height) {
2121 "Frame (%dx%d at pos %dx%d) does not fit into canvas (%dx%d)\n",
2122 s->w.width,
s->w.height,
s->pos_x,
s->pos_y,
2123 s->canvas_width,
s->canvas_height);
2128 ret = blend_subframe_into_canvas(
s);
2137 p->pts = avpkt->
pts;
2138 p->duration =
s->duration;
2140 s->prev_anmf_flags =
s->anmf_flags;
2141 s->prev_width =
s->w.width;
2142 s->prev_height =
s->w.height;
2143 s->prev_pos_x =
s->pos_x;
2144 s->prev_pos_y =
s->pos_y;
2158 s->canvas_width = avctx->
width;
2159 s->canvas_height = avctx->
height;
2181 const uint8_t *argb =
s->background_argb;
2182 s->background_yuva[0] =
RGB_TO_Y_CCIR(argb[1], argb[2], argb[3]);
2183 s->background_yuva[1] =
RGB_TO_U_CCIR(argb[1], argb[2], argb[3], 0);
2184 s->background_yuva[2] =
RGB_TO_V_CCIR(argb[1], argb[2], argb[3], 0);
2185 s->background_yuva[3] = argb[0];
2201 .p.name =
"webp_anim",
2205 .priv_data_size =
sizeof(AnimatedWebPContext),
2206 .
init = webp_anim_decode_init,
2208 .close = webp_anim_decode_close,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static const char *const format[]
const FFCodec ff_webp_decoder
const FFCodec ff_webp_anim_decoder
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
static av_always_inline int bytestream2_tell(const GetByteContext *g)
#define i(width, name, range_min, range_max)
#define xi(width, name, var, range_min, range_max, subs,...)
#define FF_CODEC_CAP_USES_PROGRESSFRAMES
The decoder might make use of the ProgressFrame API.
#define FF_CODEC_CAP_ICC_PROFILES
Codec supports embedded ICC profiles (AV_FRAME_DATA_ICC_PROFILE).
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define AV_CEIL_RSHIFT(a, b)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
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.
int ff_decode_exif_attach_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferRef **pbuf, enum AVExifHeaderMode header_mode)
Attach the data buffer to the frame.
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.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
int(* init)(AVBSFContext *ctx)
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
@ AV_EXIF_TIFF_HEADER
The TIFF header starts with 0x49492a00, or 0x4d4d002a.
EXIF metadata parser - internal functions.
static const uint8_t bits[8]
bitstream reader API header.
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth)
Parse a vlc code.
static int get_bits_left(GetBitContext *gb)
static unsigned int get_bits1(GetBitContext *s)
static void skip_bits(GetBitContext *s, int n)
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_FRAME_FLAG_LOSSLESS
A decoder can use this flag to mark frames which were originally encoded losslessly.
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
@ AV_FRAME_DATA_ICC_PROFILE
The data contains an ICC profile as an opaque octet buffer following the format described by ISO 1507...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define av_fourcc2str(fourcc)
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...
@ AV_PICTURE_TYPE_I
Intra.
@ AV_PICTURE_TYPE_P
Predicted.
static const int8_t transform[32][32]
static const int16_t alpha[]
static const uint8_t block_bits[]
static void scale(int *out, const int *in, const int w, const int h, const int shift)
static int shift(int a, int b)
Multithreading API for decoders.
Various defines for YUV<->RGB conversion.
#define RGB_TO_U_CCIR(r1, g1, b1, shift)
#define RGB_TO_Y_CCIR(r, g, b)
#define YUV_TO_RGB1_CCIR(cb1, cr1)
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
#define RGB_TO_V_CCIR(r1, g1, b1, shift)
#define MKTAG(a, b, c, d)
static int8_t ff_u8_to_s8(uint8_t a)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
static float distance(float x, float y, int band)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
A reference to a data buffer.
uint8_t * data
The data buffer.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
int plane
Which of the 4 planes contains the component.
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
This structure stores compressed data.
int flags
A combination of AV_PKT_FLAG values.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
uint8_t nb_components
The number of components each pixel has, (1-4)
uint16_t simple_symbols[2]
HuffReader * huffman_groups
enum AlphaFilter alpha_filter
enum TransformType transforms[4]
const uint8_t * alpha_data
enum AlphaCompression alpha_compression
ImageContext image[IMAGE_ROLE_NB]
#define av_malloc_array(a, b)
static double cr(void *priv, double x, double y)
static double cb(void *priv, double x, double y)
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
int ff_vlc_init_from_lengths(VLC *vlc, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
void ff_vlc_free(VLC *vlc)
#define VLC_INIT_OUTPUT_LE
av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
int ff_vp8_decode_init(AVCodecContext *avctx)
int ff_vp8_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
static int read_huffman_code_normal(WebPContext *s, HuffReader *hc, int alphabet_size)
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)
static void image_ctx_free(ImageContext *img)
static int apply_color_transform(WebPContext *s)
static int webp_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, AVPacket *avpkt)
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)
static av_always_inline uint8_t color_transform_delta(uint8_t color_pred, uint8_t color)
#define NUM_CODE_LENGTH_CODES
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)
static av_cold int webp_decode_close(AVCodecContext *avctx)
@ PRED_MODE_ADD_SUBTRACT_FULL
@ PRED_MODE_AVG_AVG_L_TL_AVG_T_TR
@ PRED_MODE_ADD_SUBTRACT_HALF
@ PRED_MODE_AVG_T_AVG_L_TR
static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
static int parse_transform_color(WebPContext *s)
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)
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)
#define GET_PIXEL(frame, x, y)
static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES]
static HuffReader * get_huffman_group(WebPContext *s, ImageContext *img, int x, int y)
static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
static av_cold int webp_decode_init(AVCodecContext *avctx)
static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2]
static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
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)
static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
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)
static int apply_subtract_green_transform(WebPContext *s)
static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, uint8_t *data_start, unsigned int data_size)
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)
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)
@ ALPHA_FILTER_HORIZONTAL
#define NUM_LITERAL_CODES
#define VP8X_FLAG_EXIF_METADATA
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)
#define MAX_HUFFMAN_CODE_LENGTH
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)
static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
static int apply_predictor_transform(WebPContext *s)
static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, int w, int h)
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)
@ COLOR_INDEXING_TRANSFORM
static int apply_color_indexing_transform(WebPContext *s)
#define HUFFMAN_CODES_PER_META_CODE
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)
static int parse_transform_color_indexing(WebPContext *s)
@ IMAGE_ROLE_COLOR_TRANSFORM
@ IMAGE_ROLE_COLOR_INDEXING
#define PARSE_BLOCK_SIZE(w, h)
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)
#define GET_PIXEL_COMP(frame, x, y, c)
#define NUM_DISTANCE_CODES
static int decode_entropy_image(WebPContext *s)
static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE]
static void update_canvas_size(AVCodecContext *avctx, int w, int h)
#define VP8X_FLAG_XMP_METADATA
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)
static const inv_predict_func inverse_predict[14]
#define NUM_SHORT_DISTANCES
static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p, const uint8_t *data_start, unsigned int data_size)
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)
static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb)
static int parse_transform_predictor(WebPContext *s)
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)