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 < 16
U) {
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;
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 > 39
U) {
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");
766 const uint8_t *p_t,
const uint8_t *p_tr)
773 const uint8_t *p_t,
const uint8_t *p_tr)
780 const uint8_t *p_t,
const uint8_t *p_tr)
787 const uint8_t *p_t,
const uint8_t *p_tr)
794 const uint8_t *p_t,
const uint8_t *p_tr)
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;
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;
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;
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;
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++) {
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)
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)
1601 typedef 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);
1835 static 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);
1907 static 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;
1937 static int allocate_canvas(AnimatedWebPContext *
s,
int format)
1946 static 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]) {
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,