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'):
1411 #if FF_API_CODEC_PROPS
1419 case MKTAG(
'V',
'P',
'8',
'X'):
1420 if (
s->width ||
s->height || *got_frame) {
1424 vp8x_flags = bytestream2_get_byte(&gb);
1426 s->width = bytestream2_get_le24(&gb) + 1;
1427 s->height = bytestream2_get_le24(&gb) + 1;
1432 case MKTAG(
'A',
'L',
'P',
'H'): {
1433 int alpha_header, filter_m, compression;
1437 "ALPHA chunk present, but alpha bit not set in the "
1440 if (chunk_size == 0) {
1444 alpha_header = bytestream2_get_byte(&gb);
1446 s->alpha_data_size = chunk_size - 1;
1449 filter_m = (alpha_header >> 2) & 0x03;
1450 compression = alpha_header & 0x03;
1454 "skipping unsupported ALPHA chunk\n");
1457 s->alpha_compression = compression;
1458 s->alpha_filter = filter_m;
1463 case MKTAG(
'E',
'X',
'I',
'F'): {
1473 "EXIF chunk present, but Exif bit not set in the "
1482 memcpy(exif_buf->
data, gb.
buffer, chunk_size);
1492 case MKTAG(
'I',
'C',
'C',
'P'): {
1502 "ICCP chunk present, but ICC Profile bit not set in the "
1518 case MKTAG(
'A',
'N',
'I',
'M'):
1519 case MKTAG(
'A',
'N',
'M',
'F'):
1524 case MKTAG(
'X',
'M',
'P',
' '): {
1532 "XMP chunk present, but XMP bit not set in the "
1543 buffer[chunk_size] =
'\0';
1601 #if CONFIG_WEBP_ANIM_DECODER
1603 #define ANMF_FLAG_DISPOSE (1 << 0)
1604 #define ANMF_FLAG_NO_BLEND (1 << 1)
1606 typedef struct AnimatedWebPContext {
1617 int prev_anmf_flags;
1622 uint8_t background_argb[4];
1623 uint8_t background_yuva[4];
1624 } AnimatedWebPContext;
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];
1639 if (src_alpha == 255) {
1640 memcpy(dst_argb, src_argb,
sizeof(uint32_t));
1641 }
else if (src_alpha == 0) {
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;
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;
1653 src_argb +=
sizeof(uint32_t);
1654 dst_argb +=
sizeof(uint32_t);
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;
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);
1680 int tile_w =
FFMIN(
src->width - x * 2, 2);
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] +
1688 dst_alpha +=
dst->data[plane_a][(((pos_y >> 1) + y) * 2 + yy) *
dst->linesize[plane_a] +
1689 (((pos_x >> 1) + x) * 2 + xx)];
1692 int shift = (tile_h == 2) + (tile_w == 2);
1696 if (src_alpha == 255) {
1699 }
else if (src_alpha == 0) {
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;
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;
1725 if (src_alpha == 255) {
1728 }
else if (src_alpha == 0) {
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;
1751 int r_add, g_add, b_add;
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;
1779 src_a =
src->data[plane_a] + y *
src->linesize[plane_a];
1781 for (
int x = 0; x <
src->width; x++) {
1782 webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, (
alpha ? *src_a : 255));
1788 dst_argb +=
sizeof(uint32_t);
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;
1809 for (
int x = 0; x <
src->width; x++) {
1810 int src_alpha = *src_a;
1811 int dst_alpha = dst_argb[0];
1813 if (src_alpha == 255) {
1814 webp_yuva2argb(dst_argb, *src_y, *src_u, *src_v, src_alpha);
1815 }
else if (src_alpha == 0) {
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;
1823 webp_yuva2argb(
tmp, *src_y, *src_u, *src_v, src_alpha);
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;
1835 dst_argb +=
sizeof(uint32_t);
1840 static int blend_subframe_into_canvas(AnimatedWebPContext *
s)
1845 if ((
s->anmf_flags & ANMF_FLAG_NO_BLEND)
1851 const uint8_t *
src =
frame->data[0];
1852 uint8_t *
dst = canvas->
data[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));
1861 copy_yuva2argb(canvas,
frame,
s->pos_x,
s->pos_y);
1867 int plane =
desc->comp[
comp].plane;
1869 const uint8_t *
src =
frame->data[plane];
1870 uint8_t *
dst = canvas->
data[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);
1896 blend_alpha_argb(canvas,
frame,
s->pos_x,
s->pos_y);
1898 blend_yuva2argb(canvas,
frame,
s->pos_x,
s->pos_y);
1901 blend_alpha_yuva(canvas,
frame,
s->pos_x,
s->pos_y);
1912 static void fill_canvas_rect(AnimatedWebPContext *
s,
int pos_x,
int pos_y,
int width,
int height)
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));
1924 for (
int x = 0; x <
width; x++)
1932 int plane =
desc->comp[
comp].plane;
1942 static int allocate_canvas(AnimatedWebPContext *
s,
int format)
1951 static int prepare_canvas(AnimatedWebPContext *
s,
int key_frame,
int format)
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)))
1965 if (!
s->canvas->buf[0]) {
1971 fill_canvas_rect(
s, 0, 0,
s->canvas->width,
s->canvas->height);
1988 copy_yuva2argb(
s->canvas, yuva_canvas, 0, 0);
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);
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);
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);
2035 uint32_t chunk_type = bytestream2_get_le32(&gb);
2036 uint32_t chunk_size = bytestream2_get_le32(&gb);
2038 if (chunk_size == UINT32_MAX) {
2042 chunk_size += chunk_size & 1;
2050 switch (chunk_type) {
2051 case MKTAG(
'A',
'L',
'P',
'H'): {
2052 if (chunk_size == 0) {
2057 int alpha_header = bytestream2_get_byte(&gb);
2059 s->w.alpha_data_size = chunk_size - 1;
2062 int filter_m = (alpha_header >> 2) & 0x03;
2063 int compression = alpha_header & 0x03;
2067 "skipping unsupported ALPHA chunk\n");
2070 s->w.alpha_compression = compression;
2071 s->w.alpha_filter = filter_m;
2076 case MKTAG(
'V',
'P',
'8',
' '):
2092 case MKTAG(
'V',
'P',
'8',
'L'):
2106 #if FF_API_CODEC_PROPS
2128 if (
s->pos_x +
s->w.width >
s->canvas_width ||
2129 s->pos_y +
s->w.height >
s->canvas_height) {
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);
2138 ret = blend_subframe_into_canvas(
s);
2147 p->pts = avpkt->
pts;
2148 p->duration =
s->duration;
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;
2168 s->canvas_width = avctx->
width;
2169 s->canvas_height = avctx->
height;
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];
2211 .
p.
name =
"webp_anim",
2215 .priv_data_size =
sizeof(AnimatedWebPContext),
2216 .
init = webp_anim_decode_init,
2218 .close = webp_anim_decode_close,