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) {