Add wuffs_base__pixel_blend type
diff --git a/example/gifplayer/gifplayer.c b/example/gifplayer/gifplayer.c
index 8658bf3..3cd5bab 100644
--- a/example/gifplayer/gifplayer.c
+++ b/example/gifplayer/gifplayer.c
@@ -370,8 +370,8 @@
}
}
- wuffs_base__status decode_frame_status =
- wuffs_gif__decoder__decode_frame(&dec, &pb, &src, workbuf, NULL);
+ wuffs_base__status decode_frame_status = wuffs_gif__decoder__decode_frame(
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
if (decode_frame_status.repr == wuffs_base__note__end_of_data) {
break;
}
diff --git a/fuzz/c/std/gif_fuzzer.c b/fuzz/c/std/gif_fuzzer.c
index 3dbc2e2..d9460c6 100644
--- a/fuzz/c/std/gif_fuzzer.c
+++ b/fuzz/c/std/gif_fuzzer.c
@@ -123,7 +123,8 @@
goto exit;
}
- status = wuffs_gif__decoder__decode_frame(&dec, &pb, src, workbuf, NULL);
+ status = wuffs_gif__decoder__decode_frame(
+ &dec, &pb, src, WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL);
wuffs_base__rect_ie_u32 frame_rect =
wuffs_base__frame_config__bounds(&fc);
diff --git a/internal/cgen/base/image-impl.c b/internal/cgen/base/image-impl.c
index 540f05e..5bff8ea 100644
--- a/internal/cgen/base/image-impl.c
+++ b/internal/cgen/base/image-impl.c
@@ -159,7 +159,8 @@
wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette) {
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
if (!p) {
return wuffs_base__make_status(wuffs_base__error__bad_receiver);
}
diff --git a/internal/cgen/base/image-public.h b/internal/cgen/base/image-public.h
index 40d8f3e..1c308e2 100644
--- a/internal/cgen/base/image-public.h
+++ b/internal/cgen/base/image-public.h
@@ -23,6 +23,17 @@
// --------
+typedef uint8_t wuffs_base__pixel_blend;
+
+// wuffs_base__pixel_blend encodes how to blend source and destination pixels,
+// accounting for transparency. It encompasses the Porter-Duff compositing
+// operators as well as the other blending modes defined by PDF.
+//
+// TODO: implement the other modes.
+#define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
+
+// --------
+
// wuffs_base__pixel_format encodes the format of the bytes that constitute an
// image frame's pixel data.
//
@@ -601,6 +612,8 @@
// --------
+// Deprecated: use wuffs_base__pixel_blend instead.
+//
// wuffs_base__animation_blend encodes, for an animated image, how to blend the
// transparent pixels of this frame with the existing canvas. In Porter-Duff
// compositing operator terminology:
@@ -1072,7 +1085,8 @@
inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette);
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend);
inline uint64_t swizzle_interleaved(wuffs_base__slice_u8 dst,
wuffs_base__slice_u8 dst_palette,
wuffs_base__slice_u8 src) const;
@@ -1085,7 +1099,8 @@
wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette);
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend);
uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved(
@@ -1100,9 +1115,10 @@
wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette) {
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette,
- src_format, src_palette);
+ src_format, src_palette, blend);
}
uint64_t //
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index aac99ff..a1f8eab 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -30,9 +30,9 @@
"cause with \">=\",\n // the last 4-byte store could write past the end of the dst slice.\n //\n // Each 4-byte store writes one too many bytes, but a subsequent store will\n // overwrite that with the correct byte. There is always another store,\n // whether a 4-byte store in this loop or a 1-byte store in the next loop.\n while (n > N) {\n wuffs_base__store_u32le(\n d + (0 * 3),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n wuffs_base__store_u32le(\n d + (1 * 3),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));\n wuffs_base__store_u32le(\n d + (2 * 3),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));\n wuffs_base__store_u32le(\n d + (3 * 3),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));\n\n s += 1 * N;\n d += 3 * N;\n n -= (size_t)(1 * N);\n }\n\n while (n >= 1) {\n uint32_t color =\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4));\n d[0" +
"] = (uint8_t)(color >> 0);\n d[1] = (uint8_t)(color >> 8);\n d[2] = (uint8_t)(color >> 16);\n\n s += 1 * 1;\n d += 3 * 1;\n n -= (size_t)(1 * 1);\n }\n\n return len;\n}\nstatic uint64_t //\nwuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) {\n if (dst_palette.len != 1024) {\n return 0;\n }\n size_t dst_len4 = dst.len / 4;\n size_t len = dst_len4 < src.len ? dst_len4 : src.len;\n uint8_t* d = dst.ptr;\n uint8_t* s = src.ptr;\n size_t n = len;\n\n // N is the loop unroll count.\n const int N = 4;\n\n while (n >= N) {\n wuffs_base__store_u32le(\n d + (0 * 4),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n wuffs_base__store_u32le(\n d + (1 * 4),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));\n wuffs_base__store_u32le(\n d + (2 * 4),\n wuffs_base__load_u32le(dst_palette.ptr + (" +
"(uint32_t)(s[2]) * 4)));\n wuffs_base__store_u32le(\n d + (3 * 4),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));\n\n s += 1 * N;\n d += 4 * N;\n n -= (size_t)(1 * N);\n }\n\n while (n >= 1) {\n wuffs_base__store_u32le(\n d + (0 * 4),\n wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n\n s += 1 * 1;\n d += 4 * 1;\n n -= (size_t)(1 * 1);\n }\n\n return len;\n}\n\nstatic uint64_t //\nwuffs_base__pixel_swizzler__swap_rgbx_bgrx(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 src) {\n size_t len4 = (dst.len < src.len ? dst.len : src.len) / 4;\n uint8_t* d = dst.ptr;\n uint8_t* s = src.ptr;\n\n size_t n = len4;\n while (n--) {\n uint8_t b0 = s[0];\n uint8_t b1 = s[1];\n uint8_t b2 = s[2];\n uint8_t b3 = s[3];\n d[0] = b2;\n d[1] = b1;\n d[2] = b0;\n d[3] = b3;\n s += 4;\n d += 4;\n }\n return len4 * 4;\n}\n\nwuffs_base__status //\nwuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_s" +
- "wizzler* p,\n wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette) {\n if (!p) {\n return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n }\n\n // TODO: support many more formats.\n\n uint64_t (*func)(wuffs_base__slice_u8 dst, wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) = NULL;\n\n switch (src_format.repr) {\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n switch (dst_format.repr) {\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n 1024) {\n break;\n }\n func = wuffs_base" +
- "__pixel_swizzler__copy_1_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__BGR:\n if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_3_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:\n if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_4_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__RGB:\n if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n src_palette) != 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_3_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:\n cas" +
- "e WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:\n if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n src_palette) != 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_4_1;\n break;\n default:\n break;\n }\n break;\n\n default:\n break;\n }\n\n p->private_impl.func = func;\n return wuffs_base__make_status(func ? NULL\n : wuffs_base__error__unsupported_option);\n}\n\nuint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) {\n if (p && p->private_impl.func) {\n return (*(p->private_impl.func))(dst, dst_palette, src);\n }\n return 0;\n}\n" +
+ "wizzler* p,\n wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette,\n wuffs_base__pixel_blend blend) {\n if (!p) {\n return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n }\n\n // TODO: support many more formats.\n\n uint64_t (*func)(wuffs_base__slice_u8 dst, wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) = NULL;\n\n switch (src_format.repr) {\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n switch (dst_format.repr) {\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n " +
+ " 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_1_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__BGR:\n if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_3_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:\n if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_4_1;\n break;\n case WUFFS_BASE__PIXEL_FORMAT__RGB:\n if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n src_palette) != 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_3_1;\n break;" +
+ "\n case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:\n case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:\n if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n src_palette) != 1024) {\n break;\n }\n func = wuffs_base__pixel_swizzler__copy_4_1;\n break;\n default:\n break;\n }\n break;\n\n default:\n break;\n }\n\n p->private_impl.func = func;\n return wuffs_base__make_status(func ? NULL\n : wuffs_base__error__unsupported_option);\n}\n\nuint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) {\n if (p && p->private_impl.func) {\n return (*(p->private_impl.func))(dst, dst_palette, src);\n }\n return 0;\n}\n" +
""
const baseCorePrivateH = "" +
@@ -110,6 +110,8 @@
const baseImagePublicH = "" +
"// ---------------- Images\n\n// wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied\n// Alpha, Red, Green, Blue color, as a uint32_t value. It is in word order, not\n// byte order: its value is always 0xAARRGGBB, regardless of endianness.\ntypedef uint32_t wuffs_base__color_u32_argb_premul;\n\n" +
"" +
+ "// --------\n\ntypedef uint8_t wuffs_base__pixel_blend;\n\n// wuffs_base__pixel_blend encodes how to blend source and destination pixels,\n// accounting for transparency. It encompasses the Porter-Duff compositing\n// operators as well as the other blending modes defined by PDF.\n//\n// TODO: implement the other modes.\n#define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)\n\n" +
+ "" +
"// --------\n\n// wuffs_base__pixel_format encodes the format of the bytes that constitute an\n// image frame's pixel data.\n//\n// See https://github.com/google/wuffs/blob/master/doc/note/pixel-formats.md\n//\n// Do not manipulate its bits directly; they are private implementation\n// details. Use methods such as wuffs_base__pixel_format__num_planes instead.\ntypedef struct {\n uint32_t repr;\n\n#ifdef __cplusplus\n inline bool is_valid() const;\n inline uint32_t bits_per_pixel() const;\n inline bool is_indexed() const;\n inline bool is_interleaved() const;\n inline bool is_planar() const;\n inline uint32_t num_planes() const;\n#endif // __cplusplus\n\n} wuffs_base__pixel_format;\n\nstatic inline wuffs_base__pixel_format //\nwuffs_base__make_pixel_format(uint32_t repr) {\n wuffs_base__pixel_format f;\n f.repr = repr;\n return f;\n}\n\n // Common 8-bit-depth pixel formats. This list is not exhaustive; not all\n // valid wuffs_base__pixel_format values are present.\n\n#define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000\n\n#define" +
" WUFFS_BASE__PIXEL_FORMAT__A 0x02000008\n\n#define WUFFS_BASE__PIXEL_FORMAT__Y 0x10000008\n#define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x15000008\n#define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x16000008\n\n#define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x20020888\n#define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x21038888\n#define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x25038888\n\n#define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x30020888\n#define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x31038888\n#define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x35038888\n\n#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x45040008\n#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x46040008\n#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x47040008\n\n#define WUFFS_BASE__PIXEL_FORMAT__BGR 0x40000888\n#define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x41008888\n#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x45008888\n#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x46008888\n#define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x47008888\n\n#define WUFFS_" +
"BASE__PIXEL_FORMAT__RGB 0x50000888\n#define WUFFS_BASE__PIXEL_FORMAT__RGBX 0x51008888\n#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0x55008888\n#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0x56008888\n#define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0x57008888\n\n#define WUFFS_BASE__PIXEL_FORMAT__CMY 0x60020888\n#define WUFFS_BASE__PIXEL_FORMAT__CMYK 0x61038888\n\nextern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];\n\nstatic inline bool //\nwuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {\n return f->repr != 0;\n}\n\n// wuffs_base__pixel_format__bits_per_pixel returns the number of bits per\n// pixel for interleaved pixel formats, and returns 0 for planar pixel formats.\nstatic inline uint32_t //\nwuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {\n if (((f->repr >> 16) & 0x03) != 0) {\n return 0;\n }\n return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +\n wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +\n " +
@@ -132,7 +134,7 @@
"ight = 0;\n c->private_impl.first_frame_io_position = 0;\n c->private_impl.first_frame_is_opaque = 0;\n}\n\nstatic inline void //\nwuffs_base__image_config__invalidate(wuffs_base__image_config* c) {\n if (c) {\n c->pixcfg.private_impl.pixfmt.repr = 0;\n c->pixcfg.private_impl.pixsub.repr = 0;\n c->pixcfg.private_impl.width = 0;\n c->pixcfg.private_impl.height = 0;\n c->private_impl.first_frame_io_position = 0;\n c->private_impl.first_frame_is_opaque = 0;\n }\n}\n\nstatic inline bool //\nwuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {\n return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));\n}\n\nstatic inline uint64_t //\nwuffs_base__image_config__first_frame_io_position(\n const wuffs_base__image_config* c) {\n return c ? c->private_impl.first_frame_io_position : 0;\n}\n\nstatic inline bool //\nwuffs_base__image_config__first_frame_is_opaque(\n const wuffs_base__image_config* c) {\n return c ? c->private_impl.first_frame_is_opaque : false;\n}\n\n#ifdef __cplusplus\n\ninline void" +
" //\nwuffs_base__image_config::set(uint32_t pixfmt_repr,\n uint32_t pixsub_repr,\n uint32_t width,\n uint32_t height,\n uint64_t first_frame_io_position,\n bool first_frame_is_opaque) {\n wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,\n first_frame_io_position, first_frame_is_opaque);\n}\n\ninline void //\nwuffs_base__image_config::invalidate() {\n wuffs_base__image_config__invalidate(this);\n}\n\ninline bool //\nwuffs_base__image_config::is_valid() const {\n return wuffs_base__image_config__is_valid(this);\n}\n\ninline uint64_t //\nwuffs_base__image_config::first_frame_io_position() const {\n return wuffs_base__image_config__first_frame_io_position(this);\n}\n\ninline bool //\nwuffs_base__image_config::first_frame_is_opaque() const {\n return wuffs_base__image_config__first_frame_is_opaque(this);\n}\n\n#endif // __cplusplus\n\n" +
"" +
- "// --------\n\n// wuffs_base__animation_blend encodes, for an animated image, how to blend the\n// transparent pixels of this frame with the existing canvas. In Porter-Duff\n// compositing operator terminology:\n// - 0 means the frame may be transparent, and should be blended \"src over\n// dst\", also known as just \"over\".\n// - 1 means the frame may be transparent, and should be blended \"src\".\n// - 2 means the frame is completely opaque, so that \"src over dst\" and \"src\"\n// are equivalent.\n//\n// These semantics are conservative. It is valid for a completely opaque frame\n// to have a blend value other than 2.\ntypedef uint8_t wuffs_base__animation_blend;\n\n#define WUFFS_BASE__ANIMATION_BLEND__SRC_OVER_DST \\\n ((wuffs_base__animation_blend)0)\n#define WUFFS_BASE__ANIMATION_BLEND__SRC ((wuffs_base__animation_blend)1)\n#define WUFFS_BASE__ANIMATION_BLEND__OPAQUE ((wuffs_base__animation_blend)2)\n\n" +
+ "// --------\n\n// Deprecated: use wuffs_base__pixel_blend instead.\n//\n// wuffs_base__animation_blend encodes, for an animated image, how to blend the\n// transparent pixels of this frame with the existing canvas. In Porter-Duff\n// compositing operator terminology:\n// - 0 means the frame may be transparent, and should be blended \"src over\n// dst\", also known as just \"over\".\n// - 1 means the frame may be transparent, and should be blended \"src\".\n// - 2 means the frame is completely opaque, so that \"src over dst\" and \"src\"\n// are equivalent.\n//\n// These semantics are conservative. It is valid for a completely opaque frame\n// to have a blend value other than 2.\ntypedef uint8_t wuffs_base__animation_blend;\n\n#define WUFFS_BASE__ANIMATION_BLEND__SRC_OVER_DST \\\n ((wuffs_base__animation_blend)0)\n#define WUFFS_BASE__ANIMATION_BLEND__SRC ((wuffs_base__animation_blend)1)\n#define WUFFS_BASE__ANIMATION_BLEND__OPAQUE ((wuffs_base__animation_blend)2)\n\n" +
"" +
"// --------\n\n// wuffs_base__animation_disposal encodes, for an animated image, how to\n// dispose of a frame after displaying it:\n// - None means to draw the next frame on top of this one.\n// - Restore Background means to clear the frame's dirty rectangle to \"the\n// background color\" (in practice, this means transparent black) before\n// drawing the next frame.\n// - Restore Previous means to undo the current frame, so that the next frame\n// is drawn on top of the previous one.\ntypedef uint8_t wuffs_base__animation_disposal;\n\n#define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)\n#define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \\\n ((wuffs_base__animation_disposal)1)\n#define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \\\n ((wuffs_base__animation_disposal)2)\n\n" +
"" +
@@ -155,9 +157,9 @@
"" +
"// --------\n\ntypedef struct {\n // Do not access the private_impl's fields directly. There is no API/ABI\n // compatibility or safety guarantee if you do so.\n struct {\n uint8_t TODO;\n } private_impl;\n\n#ifdef __cplusplus\n#endif // __cplusplus\n\n} wuffs_base__decode_frame_options;\n\n#ifdef __cplusplus\n\n#endif // __cplusplus\n\n" +
"" +
- "// --------\n\ntypedef struct {\n // Do not access the private_impl's fields directly. There is no API/ABI\n // compatibility or safety guarantee if you do so.\n struct {\n // TODO: should the func type take restrict pointers?\n uint64_t (*func)(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src);\n } private_impl;\n\n#ifdef __cplusplus\n inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette);\n inline uint64_t swizzle_interleaved(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) const;\n#endif // __cplusplus\n\n} wuffs_base__pixel_swizzler;\n\nwuffs_base__status //\nwuffs_base__pixel_swizzler__prepare(w" +
- "uffs_base__pixel_swizzler* p,\n wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette);\n\nuint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src);\n\n#ifdef __cplusplus\n\ninline wuffs_base__status //\nwuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette) {\n return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette,\n src_format, src_palette);\n}\n\nuint64_t //\nwu" +
- "ffs_base__pixel_swizzler::swizzle_interleaved(\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) const {\n return wuffs_base__pixel_swizzler__swizzle_interleaved(this, dst, dst_palette,\n src);\n}\n\n#endif // __cplusplus\n" +
+ "// --------\n\ntypedef struct {\n // Do not access the private_impl's fields directly. There is no API/ABI\n // compatibility or safety guarantee if you do so.\n struct {\n // TODO: should the func type take restrict pointers?\n uint64_t (*func)(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src);\n } private_impl;\n\n#ifdef __cplusplus\n inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette,\n wuffs_base__pixel_blend blend);\n inline uint64_t swizzle_interleaved(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) const;\n#endif // __cplusplus\n\n} wuffs_base__pixel_swiz" +
+ "zler;\n\nwuffs_base__status //\nwuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,\n wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette,\n wuffs_base__pixel_blend blend);\n\nuint64_t //\nwuffs_base__pixel_swizzler__swizzle_interleaved(\n const wuffs_base__pixel_swizzler* p,\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src);\n\n#ifdef __cplusplus\n\ninline wuffs_base__status //\nwuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__pixel_format src_format,\n wuffs_base__slice_u8 src_palette,\n " +
+ " wuffs_base__pixel_blend blend) {\n return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette,\n src_format, src_palette, blend);\n}\n\nuint64_t //\nwuffs_base__pixel_swizzler::swizzle_interleaved(\n wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 dst_palette,\n wuffs_base__slice_u8 src) const {\n return wuffs_base__pixel_swizzler__swizzle_interleaved(this, dst, dst_palette,\n src);\n}\n\n#endif // __cplusplus\n" +
""
const baseIOPrivateH = "" +
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index 3fbcb14..4421bfe 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -87,6 +87,7 @@
"frame_config",
"image_config",
+ "pixel_blend",
"pixel_buffer",
"pixel_config",
"pixel_format",
@@ -339,7 +340,7 @@
"pixel_swizzler.prepare!(" +
"dst_pixfmt: pixel_format, dst_palette: slice u8, " +
- "src_pixfmt: pixel_format, src_palette: slice u8) status",
+ "src_pixfmt: pixel_format, src_palette: slice u8, blend: pixel_blend) status",
"pixel_swizzler.swizzle_interleaved!(" +
"dst: slice u8, dst_palette: slice u8, src: slice u8) u64",
}
@@ -365,8 +366,8 @@
"image_decoder.ack_metadata_chunk?(src: io_reader)",
"image_decoder.decode_frame?(" +
- "dst: ptr pixel_buffer, src: io_reader, workbuf: slice u8," +
- "opts: nptr decode_frame_options)",
+ "dst: ptr pixel_buffer, src: io_reader, blend: pixel_blend," +
+ "workbuf: slice u8, opts: nptr decode_frame_options)",
"image_decoder.decode_frame_config?(dst: nptr frame_config, src: io_reader)",
"image_decoder.decode_image_config?(dst: nptr image_config, src: io_reader)",
"image_decoder.frame_dirty_rect() rect_ie_u32",
diff --git a/lang/check/resolve.go b/lang/check/resolve.go
index 3893ef8..c193f99 100644
--- a/lang/check/resolve.go
+++ b/lang/check/resolve.go
@@ -60,6 +60,7 @@
typeExprFrameConfig = a.NewTypeExpr(0, t.IDBase, t.IDFrameConfig, nil, nil, nil)
typeExprImageConfig = a.NewTypeExpr(0, t.IDBase, t.IDImageConfig, nil, nil, nil)
+ typeExprPixelBlend = a.NewTypeExpr(0, t.IDBase, t.IDPixelBlend, nil, nil, nil)
typeExprPixelBuffer = a.NewTypeExpr(0, t.IDBase, t.IDPixelBuffer, nil, nil, nil)
typeExprPixelConfig = a.NewTypeExpr(0, t.IDBase, t.IDPixelConfig, nil, nil, nil)
typeExprPixelFormat = a.NewTypeExpr(0, t.IDBase, t.IDPixelFormat, nil, nil, nil)
@@ -102,6 +103,7 @@
t.IDFrameConfig: typeExprFrameConfig,
t.IDImageConfig: typeExprImageConfig,
+ t.IDPixelBlend: typeExprPixelBlend,
t.IDPixelBuffer: typeExprPixelBuffer,
t.IDPixelConfig: typeExprPixelConfig,
t.IDPixelFormat: typeExprPixelFormat,
diff --git a/lang/token/list.go b/lang/token/list.go
index 10c1c84..5cc3943 100644
--- a/lang/token/list.go
+++ b/lang/token/list.go
@@ -478,10 +478,11 @@
IDFrameConfig = ID(0x150)
IDImageConfig = ID(0x151)
- IDPixelBuffer = ID(0x152)
- IDPixelConfig = ID(0x153)
- IDPixelFormat = ID(0x154)
- IDPixelSwizzler = ID(0x155)
+ IDPixelBlend = ID(0x152)
+ IDPixelBuffer = ID(0x153)
+ IDPixelConfig = ID(0x154)
+ IDPixelFormat = ID(0x155)
+ IDPixelSwizzler = ID(0x156)
IDDecodeFrameOptions = ID(0x158)
@@ -819,6 +820,7 @@
IDFrameConfig: "frame_config",
IDImageConfig: "image_config",
+ IDPixelBlend: "pixel_blend",
IDPixelBuffer: "pixel_buffer",
IDPixelConfig: "pixel_config",
IDPixelFormat: "pixel_format",
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 4bc6939..6419478 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -1475,6 +1475,17 @@
// --------
+typedef uint8_t wuffs_base__pixel_blend;
+
+// wuffs_base__pixel_blend encodes how to blend source and destination pixels,
+// accounting for transparency. It encompasses the Porter-Duff compositing
+// operators as well as the other blending modes defined by PDF.
+//
+// TODO: implement the other modes.
+#define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
+
+// --------
+
// wuffs_base__pixel_format encodes the format of the bytes that constitute an
// image frame's pixel data.
//
@@ -2053,6 +2064,8 @@
// --------
+// Deprecated: use wuffs_base__pixel_blend instead.
+//
// wuffs_base__animation_blend encodes, for an animated image, how to blend the
// transparent pixels of this frame with the existing canvas. In Porter-Duff
// compositing operator terminology:
@@ -2524,7 +2537,8 @@
inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette);
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend);
inline uint64_t swizzle_interleaved(wuffs_base__slice_u8 dst,
wuffs_base__slice_u8 dst_palette,
wuffs_base__slice_u8 src) const;
@@ -2537,7 +2551,8 @@
wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette);
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend);
uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved(
@@ -2552,9 +2567,10 @@
wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette) {
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette,
- src_format, src_palette);
+ src_format, src_palette, blend);
}
uint64_t //
@@ -2614,6 +2630,7 @@
wuffs_base__status (*decode_frame)(void* self,
wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts);
wuffs_base__status (*decode_frame_config)(void* self,
@@ -2648,6 +2665,7 @@
wuffs_base__image_decoder* self,
wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts);
@@ -2717,9 +2735,10 @@
inline wuffs_base__status //
decode_frame(wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts) {
- return wuffs_base__image_decoder__decode_frame(this, a_dst, a_src,
+ return wuffs_base__image_decoder__decode_frame(this, a_dst, a_src, a_blend,
a_workbuf, a_opts);
}
@@ -3620,6 +3639,7 @@
wuffs_gif__decoder__decode_frame(wuffs_gif__decoder* self,
wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts);
@@ -3874,10 +3894,11 @@
inline wuffs_base__status //
decode_frame(wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts) {
- return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_workbuf,
- a_opts);
+ return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend,
+ a_workbuf, a_opts);
}
#endif // __cplusplus
@@ -5076,6 +5097,7 @@
wuffs_base__image_decoder* self,
wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts) {
if (!self) {
@@ -5094,7 +5116,8 @@
if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
const wuffs_base__image_decoder__func_ptrs* func_ptrs =
(const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
- return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_workbuf, a_opts);
+ return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf,
+ a_opts);
} else if (v->vtable_name == NULL) {
break;
}
@@ -5617,7 +5640,8 @@
wuffs_base__pixel_format dst_format,
wuffs_base__slice_u8 dst_palette,
wuffs_base__pixel_format src_format,
- wuffs_base__slice_u8 src_palette) {
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
if (!p) {
return wuffs_base__make_status(wuffs_base__error__bad_receiver);
}
@@ -9481,7 +9505,8 @@
static wuffs_base__status //
wuffs_gif__decoder__decode_id_part1(wuffs_gif__decoder* self,
wuffs_base__pixel_buffer* a_dst,
- wuffs_base__io_buffer* a_src);
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend);
static wuffs_base__status //
wuffs_gif__decoder__decode_id_part2(wuffs_gif__decoder* self,
@@ -9503,6 +9528,7 @@
(wuffs_base__status(*)(void*,
wuffs_base__pixel_buffer*,
wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
wuffs_base__slice_u8,
wuffs_base__decode_frame_options*))(
&wuffs_gif__decoder__decode_frame),
@@ -10275,6 +10301,7 @@
wuffs_gif__decoder__decode_frame(wuffs_gif__decoder* self,
wuffs_base__pixel_buffer* a_dst,
wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
wuffs_base__slice_u8 a_workbuf,
wuffs_base__decode_frame_options* a_opts) {
if (!self) {
@@ -10322,7 +10349,7 @@
goto exit;
}
WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
- status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src);
+ status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
if (status.repr) {
goto suspend;
}
@@ -11516,7 +11543,8 @@
static wuffs_base__status //
wuffs_gif__decoder__decode_id_part1(wuffs_gif__decoder* self,
wuffs_base__pixel_buffer* a_dst,
- wuffs_base__io_buffer* a_src) {
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend) {
wuffs_base__status status = wuffs_base__make_status(NULL);
uint8_t v_flags = 0;
@@ -11652,7 +11680,8 @@
wuffs_base__pixel_buffer__pixel_format(a_dst), v_dst_palette,
wuffs_base__utility__make_pixel_format(1191444488),
wuffs_base__make_slice_u8(
- self->private_data.f_palettes[v_which_palette], 1024));
+ self->private_data.f_palettes[v_which_palette], 1024),
+ a_blend);
if (!wuffs_base__status__is_ok(&v_status)) {
status = v_status;
if (wuffs_base__status__is_error(&status)) {
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index e4606a1..5a442c3 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -422,7 +422,7 @@
}
// TODO: honor args.opts.
-pub func decoder.decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
+pub func decoder.decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend, workbuf: slice base.u8, opts: nptr base.decode_frame_options) {
this.ignore_metadata = true
if this.call_sequence <> 4 {
this.decode_frame_config?(dst: nullptr, src: args.src)
@@ -431,7 +431,7 @@
((this.frame_rect_x0 == this.frame_rect_x1) or (this.frame_rect_y0 == this.frame_rect_y1)) {
return "#bad frame size"
}
- this.decode_id_part1?(dst: args.dst, src: args.src)
+ this.decode_id_part1?(dst: args.dst, src: args.src, blend: args.blend)
this.decode_id_part2?(dst: args.dst, src: args.src, workbuf: args.workbuf)
this.num_decoded_frames_value ~sat+= 1
@@ -813,7 +813,7 @@
}
}
-pri func decoder.decode_id_part1?(dst: ptr base.pixel_buffer, src: base.io_reader) {
+pri func decoder.decode_id_part1?(dst: ptr base.pixel_buffer, src: base.io_reader, blend: base.pixel_blend) {
var flags : base.u8
var which_palette : base.u8[..= 1]
var num_palette_entries : base.u32[..= 256]
@@ -882,7 +882,8 @@
dst_pixfmt: args.dst.pixel_format(),
dst_palette: dst_palette,
src_pixfmt: this.util.make_pixel_format(repr: 0x47040008),
- src_palette: this.palettes[which_palette][..])
+ src_palette: this.palettes[which_palette][..],
+ blend: args.blend)
if not status.is_ok() {
return status
}
diff --git a/test/c/std/gif.c b/test/c/std/gif.c
index a3fa11f..5093bd6 100644
--- a/test/c/std/gif.c
+++ b/test/c/std/gif.c
@@ -238,8 +238,10 @@
}
CHECK_STATUS("decode_frame_config", status);
- CHECK_STATUS("decode_frame", wuffs_gif__decoder__decode_frame(
- &dec, &pb, src, global_work_slice, NULL));
+ CHECK_STATUS("decode_frame",
+ wuffs_gif__decoder__decode_frame(&dec, &pb, src,
+ WUFFS_BASE__PIXEL_BLEND__SRC,
+ global_work_slice, NULL));
CHECK_STRING(copy_to_io_buffer_from_pixel_buffer(
dst, &pb, wuffs_base__frame_config__bounds(&fc)));
@@ -343,7 +345,8 @@
size_t old_ri = src.meta.ri;
wuffs_base__status status = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &limited_src, global_work_slice, NULL);
+ &dec, &pb, &limited_src, WUFFS_BASE__PIXEL_BLEND__SRC,
+ global_work_slice, NULL);
src.meta.ri += limited_src.meta.ri;
if (wuffs_base__status__is_ok(&status)) {
@@ -455,7 +458,7 @@
RETURN_FAIL("decode_frame returned \"ok\" but src was exhausted");
}
wuffs_base__status status = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &src, global_work_slice, NULL);
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, global_work_slice, NULL);
if (status.repr != wuffs_base__note__end_of_data) {
RETURN_FAIL("decode_frame: got \"%s\", want \"%s\"", status.repr,
wuffs_base__note__end_of_data);
@@ -491,7 +494,7 @@
&pb, &ic.pixcfg, global_pixel_slice));
wuffs_base__status status = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &src, global_work_slice, NULL);
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, global_work_slice, NULL);
if (status.repr != want_status) {
RETURN_FAIL("decode_frame: got \"%s\", want \"%s\"", status.repr,
want_status);
@@ -625,8 +628,8 @@
}
}
- status = wuffs_gif__decoder__decode_frame(&dec, &pb, &src,
- global_work_slice, NULL);
+ status = wuffs_gif__decoder__decode_frame(
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, global_work_slice, NULL);
if (!wuffs_base__status__is_ok(&status)) {
RETURN_FAIL("decode_frame #%" PRIu32 ": \"%s\"", i, status.repr);
}
@@ -643,7 +646,7 @@
// decode_frame.
for (i = 0; i < 3; i++) {
wuffs_base__status status = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &src, global_work_slice, NULL);
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, global_work_slice, NULL);
if (status.repr != wuffs_base__note__end_of_data) {
RETURN_FAIL("decode_frame: got \"%s\", want \"%s\"", status.repr,
wuffs_base__note__end_of_data);
@@ -773,6 +776,7 @@
int i;
for (i = 0; i < 2; i++) {
status = wuffs_gif__decoder__decode_frame(&dec, &pb, &src,
+ WUFFS_BASE__PIXEL_BLEND__SRC,
global_work_slice, NULL);
if ((q == 1) && (i == 1)) {
if (status.repr != wuffs_gif__error__bad_palette) {
@@ -995,6 +999,7 @@
}
status = wuffs_gif__decoder__decode_frame(&dec, &pb, &src,
+ WUFFS_BASE__PIXEL_BLEND__SRC,
global_work_slice, NULL);
if (!wuffs_base__status__is_ok(&status)) {
RETURN_FAIL("q=%d: decode_frame #%" PRIu32 ": \"%s\"", q, i,
@@ -1095,7 +1100,7 @@
}
wuffs_base__status got = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &src, global_work_slice, NULL);
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, global_work_slice, NULL);
if (got.repr != want) {
RETURN_FAIL("q=%d: decode_frame: got \"%s\", want \"%s\"", q, got.repr,
want);
@@ -1244,7 +1249,7 @@
}
wuffs_base__status status = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &src, global_work_slice, NULL);
+ &dec, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC, global_work_slice, NULL);
if (status.repr != wuffs_base__suspension__short_read) {
RETURN_FAIL("decode_frame: got \"%s\", want \"%s\"", status.repr,
wuffs_base__suspension__short_read);
@@ -1614,7 +1619,8 @@
wuffs_base__io_buffer limited_src = make_limited_reader(src, 1);
wuffs_base__status status = wuffs_gif__decoder__decode_frame(
- &dec, &pb, &limited_src, global_work_slice, NULL);
+ &dec, &pb, &limited_src, WUFFS_BASE__PIXEL_BLEND__SRC,
+ global_work_slice, NULL);
src.meta.ri += limited_src.meta.ri;
wuffs_base__rect_ie_u32 r = wuffs_gif__decoder__frame_dirty_rect(&dec);
@@ -1680,6 +1686,7 @@
status = wuffs_gif__decoder__decode_frame_config(&dec, NULL, &src);
} else {
status = wuffs_gif__decoder__decode_frame(&dec, &pb, &src,
+ WUFFS_BASE__PIXEL_BLEND__SRC,
global_work_slice, NULL);
}
@@ -1910,8 +1917,10 @@
fr.max_excl_y);
}
- CHECK_STATUS("decode_frame", wuffs_gif__decoder__decode_frame(
- &dec, &pb, &src, global_work_slice, NULL));
+ CHECK_STATUS("decode_frame",
+ wuffs_gif__decoder__decode_frame(&dec, &pb, &src,
+ WUFFS_BASE__PIXEL_BLEND__SRC,
+ global_work_slice, NULL));
wuffs_base__rect_ie_u32 dr = wuffs_gif__decoder__frame_dirty_rect(&dec);
if (dr.max_excl_y != 3) {
diff --git a/test/c/testlib/testlib.c b/test/c/testlib/testlib.c
index dda75ec..cc9b1ee 100644
--- a/test/c/testlib/testlib.c
+++ b/test/c/testlib/testlib.c
@@ -822,7 +822,8 @@
CHECK_STATUS("set_from_slice", wuffs_base__pixel_buffer__set_from_slice(
&pb, &ic.pixcfg, global_pixel_slice));
CHECK_STATUS("decode_frame", wuffs_base__image_decoder__decode_frame(
- b, &pb, &src, global_work_slice, NULL));
+ b, &pb, &src, WUFFS_BASE__PIXEL_BLEND__SRC,
+ global_work_slice, NULL));
uint64_t n = wuffs_base__pixel_config__pixbuf_len(&ic.pixcfg);
if (n < 4) {