Remove wuffs_base__frame_config__blend
diff --git a/doc/changelog.md b/doc/changelog.md
index 0f07ac9..e18c76d 100644
--- a/doc/changelog.md
+++ b/doc/changelog.md
@@ -9,6 +9,7 @@
 - Made `wuffs_base__pixel_format` a struct.
 - Made `wuffs_base__pixel_subsampling` a struct.
 - Made `wuffs_base__status` a struct.
+- Removed `wuffs_base__frame_config__blend`.
 
 
 ## 2019-12-19 version 0.2.0
diff --git a/internal/cgen/base/image-public.h b/internal/cgen/base/image-public.h
index 1c308e2..27700db 100644
--- a/internal/cgen/base/image-public.h
+++ b/internal/cgen/base/image-public.h
@@ -660,8 +660,9 @@
     wuffs_base__flicks duration;
     uint64_t index;
     uint64_t io_position;
-    wuffs_base__animation_blend blend;
     wuffs_base__animation_disposal disposal;
+    bool opaque_within_bounds;
+    bool overwrite_instead_of_blend;
     wuffs_base__color_u32_argb_premul background_color;
   } private_impl;
 
@@ -670,8 +671,9 @@
                      wuffs_base__flicks duration,
                      uint64_t index,
                      uint64_t io_position,
-                     wuffs_base__animation_blend blend,
                      wuffs_base__animation_disposal disposal,
+                     bool opaque_within_bounds,
+                     bool overwrite_instead_of_blend,
                      wuffs_base__color_u32_argb_premul background_color);
   inline wuffs_base__rect_ie_u32 bounds() const;
   inline uint32_t width() const;
@@ -679,8 +681,9 @@
   inline wuffs_base__flicks duration() const;
   inline uint64_t index() const;
   inline uint64_t io_position() const;
-  inline wuffs_base__animation_blend blend() const;
   inline wuffs_base__animation_disposal disposal() const;
+  inline bool opaque_within_bounds() const;
+  inline bool overwrite_instead_of_blend() const;
   inline wuffs_base__color_u32_argb_premul background_color() const;
 #endif  // __cplusplus
 
@@ -693,8 +696,9 @@
   ret.private_impl.duration = 0;
   ret.private_impl.index = 0;
   ret.private_impl.io_position = 0;
-  ret.private_impl.blend = 0;
   ret.private_impl.disposal = 0;
+  ret.private_impl.opaque_within_bounds = false;
+  ret.private_impl.overwrite_instead_of_blend = false;
   return ret;
 }
 
@@ -705,8 +709,9 @@
     wuffs_base__flicks duration,
     uint64_t index,
     uint64_t io_position,
-    wuffs_base__animation_blend blend,
     wuffs_base__animation_disposal disposal,
+    bool opaque_within_bounds,
+    bool overwrite_instead_of_blend,
     wuffs_base__color_u32_argb_premul background_color) {
   if (!c) {
     return;
@@ -716,8 +721,9 @@
   c->private_impl.duration = duration;
   c->private_impl.index = index;
   c->private_impl.io_position = io_position;
-  c->private_impl.blend = blend;
   c->private_impl.disposal = disposal;
+  c->private_impl.opaque_within_bounds = opaque_within_bounds;
+  c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
   c->private_impl.background_color = background_color;
 }
 
@@ -766,13 +772,6 @@
   return c ? c->private_impl.io_position : 0;
 }
 
-// wuffs_base__frame_config__blend returns, for an animated image, how to blend
-// the transparent pixels of this frame with the existing canvas.
-static inline wuffs_base__animation_blend  //
-wuffs_base__frame_config__blend(const wuffs_base__frame_config* c) {
-  return c ? c->private_impl.blend : 0;
-}
-
 // wuffs_base__frame_config__disposal returns, for an animated image, how to
 // dispose of this frame after displaying it.
 static inline wuffs_base__animation_disposal  //
@@ -780,6 +779,37 @@
   return c ? c->private_impl.disposal : 0;
 }
 
+// wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
+// within the frame's bounds are fully opaque. It makes no claim about pixels
+// outside the frame bounds but still inside the overall image. The two
+// bounding rectangles can differ for animated images.
+//
+// Its semantics are conservative. It is valid for a fully opaque frame to have
+// this value be false: a false negative.
+//
+// If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
+// WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
+// resultant pixels, but the former may be faster.
+static inline bool  //
+wuffs_base__frame_config__opaque_within_bounds(
+    const wuffs_base__frame_config* c) {
+  return c && c->private_impl.opaque_within_bounds;
+}
+
+// wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
+// animated image, whether to ignore the previous image state (within the frame
+// bounds) when drawing this incremental frame. Equivalently, whether to use
+// WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
+//
+// The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
+// calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
+// Wuffs' "overwrite_instead_of_blend".
+static inline bool  //
+wuffs_base__frame_config__overwrite_instead_of_blend(
+    const wuffs_base__frame_config* c) {
+  return c && c->private_impl.overwrite_instead_of_blend;
+}
+
 static inline wuffs_base__color_u32_argb_premul  //
 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
   return c ? c->private_impl.background_color : 0;
@@ -793,11 +823,13 @@
     wuffs_base__flicks duration,
     uint64_t index,
     uint64_t io_position,
-    wuffs_base__animation_blend blend,
     wuffs_base__animation_disposal disposal,
+    bool opaque_within_bounds,
+    bool overwrite_instead_of_blend,
     wuffs_base__color_u32_argb_premul background_color) {
-  wuffs_base__frame_config__update(this, bounds, duration, index, io_position,
-                                   blend, disposal, background_color);
+  wuffs_base__frame_config__update(
+      this, bounds, duration, index, io_position, disposal,
+      opaque_within_bounds, overwrite_instead_of_blend, background_color);
 }
 
 inline wuffs_base__rect_ie_u32  //
@@ -830,16 +862,21 @@
   return wuffs_base__frame_config__io_position(this);
 }
 
-inline wuffs_base__animation_blend  //
-wuffs_base__frame_config::blend() const {
-  return wuffs_base__frame_config__blend(this);
-}
-
 inline wuffs_base__animation_disposal  //
 wuffs_base__frame_config::disposal() const {
   return wuffs_base__frame_config__disposal(this);
 }
 
+inline bool  //
+wuffs_base__frame_config::opaque_within_bounds() const {
+  return wuffs_base__frame_config__opaque_within_bounds(this);
+}
+
+inline bool  //
+wuffs_base__frame_config::overwrite_instead_of_blend() const {
+  return wuffs_base__frame_config__overwrite_instead_of_blend(this);
+}
+
 inline wuffs_base__color_u32_argb_premul  //
 wuffs_base__frame_config::background_color() const {
   return wuffs_base__frame_config__background_color(this);
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index a1f8eab..7b9decb 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -138,13 +138,14 @@
 	"" +
 	"// --------\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" +
 	"" +
-	"// --------\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    wuffs_base__rect_ie_u32 bounds;\n    wuffs_base__flicks duration;\n    uint64_t index;\n    uint64_t io_position;\n    wuffs_base__animation_blend blend;\n    wuffs_base__animation_disposal disposal;\n    wuffs_base__color_u32_argb_premul background_color;\n  } private_impl;\n\n#ifdef __cplusplus\n  inline void update(wuffs_base__rect_ie_u32 bounds,\n                     wuffs_base__flicks duration,\n                     uint64_t index,\n                     uint64_t io_position,\n                     wuffs_base__animation_blend blend,\n                     wuffs_base__animation_disposal disposal,\n                     wuffs_base__color_u32_argb_premul background_color);\n  inline wuffs_base__rect_ie_u32 bounds() const;\n  inline uint32_t width() const;\n  inline uint32_t height() const;\n  inline wuffs_base__flicks duration() const;\n  inline uint64_t index()" +
-	" const;\n  inline uint64_t io_position() const;\n  inline wuffs_base__animation_blend blend() const;\n  inline wuffs_base__animation_disposal disposal() const;\n  inline wuffs_base__color_u32_argb_premul background_color() const;\n#endif  // __cplusplus\n\n} wuffs_base__frame_config;\n\nstatic inline wuffs_base__frame_config  //\nwuffs_base__null_frame_config() {\n  wuffs_base__frame_config ret;\n  ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);\n  ret.private_impl.duration = 0;\n  ret.private_impl.index = 0;\n  ret.private_impl.io_position = 0;\n  ret.private_impl.blend = 0;\n  ret.private_impl.disposal = 0;\n  return ret;\n}\n\nstatic inline void  //\nwuffs_base__frame_config__update(\n    wuffs_base__frame_config* c,\n    wuffs_base__rect_ie_u32 bounds,\n    wuffs_base__flicks duration,\n    uint64_t index,\n    uint64_t io_position,\n    wuffs_base__animation_blend blend,\n    wuffs_base__animation_disposal disposal,\n    wuffs_base__color_u32_argb_premul background_color) {\n  if (!c) {\n    return;\n  }\n\n  c->privat" +
-	"e_impl.bounds = bounds;\n  c->private_impl.duration = duration;\n  c->private_impl.index = index;\n  c->private_impl.io_position = io_position;\n  c->private_impl.blend = blend;\n  c->private_impl.disposal = disposal;\n  c->private_impl.background_color = background_color;\n}\n\nstatic inline wuffs_base__rect_ie_u32  //\nwuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {\n  if (c) {\n    return c->private_impl.bounds;\n  }\n\n  wuffs_base__rect_ie_u32 ret;\n  ret.min_incl_x = 0;\n  ret.min_incl_y = 0;\n  ret.max_excl_x = 0;\n  ret.max_excl_y = 0;\n  return ret;\n}\n\nstatic inline uint32_t  //\nwuffs_base__frame_config__width(const wuffs_base__frame_config* c) {\n  return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;\n}\n\nstatic inline uint32_t  //\nwuffs_base__frame_config__height(const wuffs_base__frame_config* c) {\n  return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;\n}\n\n// wuffs_base__frame_config__duration returns the amount of time to display\n// this frame. Zero means to d" +
-	"isplay forever - a still (non-animated) image.\nstatic inline wuffs_base__flicks  //\nwuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.duration : 0;\n}\n\n// wuffs_base__frame_config__index returns the index of this frame. The first\n// frame in an image has index 0, the second frame has index 1, and so on.\nstatic inline uint64_t  //\nwuffs_base__frame_config__index(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.index : 0;\n}\n\n// wuffs_base__frame_config__io_position returns the I/O stream position before\n// the frame config.\nstatic inline uint64_t  //\nwuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.io_position : 0;\n}\n\n// wuffs_base__frame_config__blend returns, for an animated image, how to blend\n// the transparent pixels of this frame with the existing canvas.\nstatic inline wuffs_base__animation_blend  //\nwuffs_base__frame_config__blend(const wuffs_base__frame_config* c) {\n  return c ? c->p" +
-	"rivate_impl.blend : 0;\n}\n\n// wuffs_base__frame_config__disposal returns, for an animated image, how to\n// dispose of this frame after displaying it.\nstatic inline wuffs_base__animation_disposal  //\nwuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.disposal : 0;\n}\n\nstatic inline wuffs_base__color_u32_argb_premul  //\nwuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.background_color : 0;\n}\n\n#ifdef __cplusplus\n\ninline void  //\nwuffs_base__frame_config::update(\n    wuffs_base__rect_ie_u32 bounds,\n    wuffs_base__flicks duration,\n    uint64_t index,\n    uint64_t io_position,\n    wuffs_base__animation_blend blend,\n    wuffs_base__animation_disposal disposal,\n    wuffs_base__color_u32_argb_premul background_color) {\n  wuffs_base__frame_config__update(this, bounds, duration, index, io_position,\n                                   blend, disposal, background_color);\n}\n\ninline wuffs_base__rect_ie_u32  //\nwuffs_b" +
-	"ase__frame_config::bounds() const {\n  return wuffs_base__frame_config__bounds(this);\n}\n\ninline uint32_t  //\nwuffs_base__frame_config::width() const {\n  return wuffs_base__frame_config__width(this);\n}\n\ninline uint32_t  //\nwuffs_base__frame_config::height() const {\n  return wuffs_base__frame_config__height(this);\n}\n\ninline wuffs_base__flicks  //\nwuffs_base__frame_config::duration() const {\n  return wuffs_base__frame_config__duration(this);\n}\n\ninline uint64_t  //\nwuffs_base__frame_config::index() const {\n  return wuffs_base__frame_config__index(this);\n}\n\ninline uint64_t  //\nwuffs_base__frame_config::io_position() const {\n  return wuffs_base__frame_config__io_position(this);\n}\n\ninline wuffs_base__animation_blend  //\nwuffs_base__frame_config::blend() const {\n  return wuffs_base__frame_config__blend(this);\n}\n\ninline wuffs_base__animation_disposal  //\nwuffs_base__frame_config::disposal() const {\n  return wuffs_base__frame_config__disposal(this);\n}\n\ninline wuffs_base__color_u32_argb_premul  //\nwuffs_base__frame_confi" +
-	"g::background_color() const {\n  return wuffs_base__frame_config__background_color(this);\n}\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    wuffs_base__rect_ie_u32 bounds;\n    wuffs_base__flicks duration;\n    uint64_t index;\n    uint64_t io_position;\n    wuffs_base__animation_disposal disposal;\n    bool opaque_within_bounds;\n    bool overwrite_instead_of_blend;\n    wuffs_base__color_u32_argb_premul background_color;\n  } private_impl;\n\n#ifdef __cplusplus\n  inline void update(wuffs_base__rect_ie_u32 bounds,\n                     wuffs_base__flicks duration,\n                     uint64_t index,\n                     uint64_t io_position,\n                     wuffs_base__animation_disposal disposal,\n                     bool opaque_within_bounds,\n                     bool overwrite_instead_of_blend,\n                     wuffs_base__color_u32_argb_premul background_color);\n  inline wuffs_base__rect_ie_u32 bounds() const;\n  inline uint32_t width() const;\n  inline uint32_t height() con" +
+	"st;\n  inline wuffs_base__flicks duration() const;\n  inline uint64_t index() const;\n  inline uint64_t io_position() const;\n  inline wuffs_base__animation_disposal disposal() const;\n  inline bool opaque_within_bounds() const;\n  inline bool overwrite_instead_of_blend() const;\n  inline wuffs_base__color_u32_argb_premul background_color() const;\n#endif  // __cplusplus\n\n} wuffs_base__frame_config;\n\nstatic inline wuffs_base__frame_config  //\nwuffs_base__null_frame_config() {\n  wuffs_base__frame_config ret;\n  ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);\n  ret.private_impl.duration = 0;\n  ret.private_impl.index = 0;\n  ret.private_impl.io_position = 0;\n  ret.private_impl.disposal = 0;\n  ret.private_impl.opaque_within_bounds = false;\n  ret.private_impl.overwrite_instead_of_blend = false;\n  return ret;\n}\n\nstatic inline void  //\nwuffs_base__frame_config__update(\n    wuffs_base__frame_config* c,\n    wuffs_base__rect_ie_u32 bounds,\n    wuffs_base__flicks duration,\n    uint64_t index,\n    uint64_t io_p" +
+	"osition,\n    wuffs_base__animation_disposal disposal,\n    bool opaque_within_bounds,\n    bool overwrite_instead_of_blend,\n    wuffs_base__color_u32_argb_premul background_color) {\n  if (!c) {\n    return;\n  }\n\n  c->private_impl.bounds = bounds;\n  c->private_impl.duration = duration;\n  c->private_impl.index = index;\n  c->private_impl.io_position = io_position;\n  c->private_impl.disposal = disposal;\n  c->private_impl.opaque_within_bounds = opaque_within_bounds;\n  c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;\n  c->private_impl.background_color = background_color;\n}\n\nstatic inline wuffs_base__rect_ie_u32  //\nwuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {\n  if (c) {\n    return c->private_impl.bounds;\n  }\n\n  wuffs_base__rect_ie_u32 ret;\n  ret.min_incl_x = 0;\n  ret.min_incl_y = 0;\n  ret.max_excl_x = 0;\n  ret.max_excl_y = 0;\n  return ret;\n}\n\nstatic inline uint32_t  //\nwuffs_base__frame_config__width(const wuffs_base__frame_config* c) {\n  return c ? wuffs_base__rect_ie_" +
+	"u32__width(&c->private_impl.bounds) : 0;\n}\n\nstatic inline uint32_t  //\nwuffs_base__frame_config__height(const wuffs_base__frame_config* c) {\n  return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;\n}\n\n// wuffs_base__frame_config__duration returns the amount of time to display\n// this frame. Zero means to display forever - a still (non-animated) image.\nstatic inline wuffs_base__flicks  //\nwuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.duration : 0;\n}\n\n// wuffs_base__frame_config__index returns the index of this frame. The first\n// frame in an image has index 0, the second frame has index 1, and so on.\nstatic inline uint64_t  //\nwuffs_base__frame_config__index(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.index : 0;\n}\n\n// wuffs_base__frame_config__io_position returns the I/O stream position before\n// the frame config.\nstatic inline uint64_t  //\nwuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {\n  " +
+	"return c ? c->private_impl.io_position : 0;\n}\n\n// wuffs_base__frame_config__disposal returns, for an animated image, how to\n// dispose of this frame after displaying it.\nstatic inline wuffs_base__animation_disposal  //\nwuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.disposal : 0;\n}\n\n// wuffs_base__frame_config__opaque_within_bounds returns whether all pixels\n// within the frame's bounds are fully opaque. It makes no claim about pixels\n// outside the frame bounds but still inside the overall image. The two\n// bounding rectangles can differ for animated images.\n//\n// Its semantics are conservative. It is valid for a fully opaque frame to have\n// this value be false: a false negative.\n//\n// If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and\n// WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of\n// resultant pixels, but the former may be faster.\nstatic inline bool  //\nwuffs_base__frame_config__opaque_within_bounds(\n    const wuffs_" +
+	"base__frame_config* c) {\n  return c && c->private_impl.opaque_within_bounds;\n}\n\n// wuffs_base__frame_config__overwrite_instead_of_blend returns, for an\n// animated image, whether to ignore the previous image state (within the frame\n// bounds) when drawing this incremental frame. Equivalently, whether to use\n// WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.\n//\n// The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)\n// calls this the \"Blending method\" bit. WebP's \"Do not blend\" corresponds to\n// Wuffs' \"overwrite_instead_of_blend\".\nstatic inline bool  //\nwuffs_base__frame_config__overwrite_instead_of_blend(\n    const wuffs_base__frame_config* c) {\n  return c && c->private_impl.overwrite_instead_of_blend;\n}\n\nstatic inline wuffs_base__color_u32_argb_premul  //\nwuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {\n  return c ? c->private_impl.background_color : 0;\n}\n\n#ifdef __cplusplus\n\ninline void  //\nwuffs_base__frame_config::update(\n " +
+	"   wuffs_base__rect_ie_u32 bounds,\n    wuffs_base__flicks duration,\n    uint64_t index,\n    uint64_t io_position,\n    wuffs_base__animation_disposal disposal,\n    bool opaque_within_bounds,\n    bool overwrite_instead_of_blend,\n    wuffs_base__color_u32_argb_premul background_color) {\n  wuffs_base__frame_config__update(\n      this, bounds, duration, index, io_position, disposal,\n      opaque_within_bounds, overwrite_instead_of_blend, background_color);\n}\n\ninline wuffs_base__rect_ie_u32  //\nwuffs_base__frame_config::bounds() const {\n  return wuffs_base__frame_config__bounds(this);\n}\n\ninline uint32_t  //\nwuffs_base__frame_config::width() const {\n  return wuffs_base__frame_config__width(this);\n}\n\ninline uint32_t  //\nwuffs_base__frame_config::height() const {\n  return wuffs_base__frame_config__height(this);\n}\n\ninline wuffs_base__flicks  //\nwuffs_base__frame_config::duration() const {\n  return wuffs_base__frame_config__duration(this);\n}\n\ninline uint64_t  //\nwuffs_base__frame_config::index() const {\n  return wuffs_b" +
+	"ase__frame_config__index(this);\n}\n\ninline uint64_t  //\nwuffs_base__frame_config::io_position() const {\n  return wuffs_base__frame_config__io_position(this);\n}\n\ninline wuffs_base__animation_disposal  //\nwuffs_base__frame_config::disposal() const {\n  return wuffs_base__frame_config__disposal(this);\n}\n\ninline bool  //\nwuffs_base__frame_config::opaque_within_bounds() const {\n  return wuffs_base__frame_config__opaque_within_bounds(this);\n}\n\ninline bool  //\nwuffs_base__frame_config::overwrite_instead_of_blend() const {\n  return wuffs_base__frame_config__overwrite_instead_of_blend(this);\n}\n\ninline wuffs_base__color_u32_argb_premul  //\nwuffs_base__frame_config::background_color() const {\n  return wuffs_base__frame_config__background_color(this);\n}\n\n#endif  // __cplusplus\n\n" +
 	"" +
 	"// --------\n\ntypedef struct {\n  wuffs_base__pixel_config pixcfg;\n\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    wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX];\n    // TODO: color spaces.\n  } private_impl;\n\n#ifdef __cplusplus\n  inline wuffs_base__status set_from_slice(\n      const wuffs_base__pixel_config* pixcfg,\n      wuffs_base__slice_u8 pixbuf_memory);\n  inline wuffs_base__status set_from_table(\n      const wuffs_base__pixel_config* pixcfg,\n      wuffs_base__table_u8 pixbuf_memory);\n  inline wuffs_base__slice_u8 palette();\n  inline wuffs_base__pixel_format pixel_format() const;\n  inline wuffs_base__table_u8 plane(uint32_t p);\n#endif  // __cplusplus\n\n} wuffs_base__pixel_buffer;\n\nstatic inline wuffs_base__pixel_buffer  //\nwuffs_base__null_pixel_buffer() {\n  wuffs_base__pixel_buffer ret;\n  ret.pixcfg = wuffs_base__null_pixel_config();\n  ret.private_impl.planes[0] = wuffs_base__empty_table_u8" +
 	"();\n  ret.private_impl.planes[1] = wuffs_base__empty_table_u8();\n  ret.private_impl.planes[2] = wuffs_base__empty_table_u8();\n  ret.private_impl.planes[3] = wuffs_base__empty_table_u8();\n  return ret;\n}\n\nstatic inline wuffs_base__status  //\nwuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* b,\n                                         const wuffs_base__pixel_config* pixcfg,\n                                         wuffs_base__slice_u8 pixbuf_memory) {\n  if (!b) {\n    return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n  }\n  memset(b, 0, sizeof(*b));\n  if (!pixcfg) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n  if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {\n    // TODO: support planar pixel formats, concious of pixel subsampling.\n    return wuffs_base__make_status(wuffs_base__error__unsupported_option);\n  }\n  uint32_t bits_per_pixel =\n      wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);\n  if ((bits_per_" +
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index 4421bfe..473863f 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -318,12 +318,13 @@
 	"frame_config.index() u64",
 	"frame_config.io_position() u64",
 
-	"frame_config.update!(bounds: rect_ie_u32, duration: u64[..= 0x7FFFFFFFFFFFFFFF], " +
-		"index: u64, io_position: u64, blend: u8, disposal: u8, background_color: u32)",
+	"frame_config.update!(bounds: rect_ie_u32, duration: u64[..= 0x7FFFFFFFFFFFFFFF]," +
+		"index: u64, io_position: u64, disposal: u8, opaque_within_bounds: bool," +
+		"overwrite_instead_of_blend: bool, background_color: u32)",
 
 	// ---- image_config
 
-	"image_config.set!(pixfmt: u32, pixsub: u32, width: u32, height: u32, " +
+	"image_config.set!(pixfmt: u32, pixsub: u32, width: u32, height: u32," +
 		"first_frame_io_position: u64, first_frame_is_opaque: bool)",
 
 	// ---- pixel_buffer
@@ -339,7 +340,7 @@
 	// ---- pixel_swizzler
 
 	"pixel_swizzler.prepare!(" +
-		"dst_pixfmt: pixel_format, dst_palette: slice u8, " +
+		"dst_pixfmt: pixel_format, dst_palette: slice u8," +
 		"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",
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 6419478..2149bef 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -2112,8 +2112,9 @@
     wuffs_base__flicks duration;
     uint64_t index;
     uint64_t io_position;
-    wuffs_base__animation_blend blend;
     wuffs_base__animation_disposal disposal;
+    bool opaque_within_bounds;
+    bool overwrite_instead_of_blend;
     wuffs_base__color_u32_argb_premul background_color;
   } private_impl;
 
@@ -2122,8 +2123,9 @@
                      wuffs_base__flicks duration,
                      uint64_t index,
                      uint64_t io_position,
-                     wuffs_base__animation_blend blend,
                      wuffs_base__animation_disposal disposal,
+                     bool opaque_within_bounds,
+                     bool overwrite_instead_of_blend,
                      wuffs_base__color_u32_argb_premul background_color);
   inline wuffs_base__rect_ie_u32 bounds() const;
   inline uint32_t width() const;
@@ -2131,8 +2133,9 @@
   inline wuffs_base__flicks duration() const;
   inline uint64_t index() const;
   inline uint64_t io_position() const;
-  inline wuffs_base__animation_blend blend() const;
   inline wuffs_base__animation_disposal disposal() const;
+  inline bool opaque_within_bounds() const;
+  inline bool overwrite_instead_of_blend() const;
   inline wuffs_base__color_u32_argb_premul background_color() const;
 #endif  // __cplusplus
 
@@ -2145,8 +2148,9 @@
   ret.private_impl.duration = 0;
   ret.private_impl.index = 0;
   ret.private_impl.io_position = 0;
-  ret.private_impl.blend = 0;
   ret.private_impl.disposal = 0;
+  ret.private_impl.opaque_within_bounds = false;
+  ret.private_impl.overwrite_instead_of_blend = false;
   return ret;
 }
 
@@ -2157,8 +2161,9 @@
     wuffs_base__flicks duration,
     uint64_t index,
     uint64_t io_position,
-    wuffs_base__animation_blend blend,
     wuffs_base__animation_disposal disposal,
+    bool opaque_within_bounds,
+    bool overwrite_instead_of_blend,
     wuffs_base__color_u32_argb_premul background_color) {
   if (!c) {
     return;
@@ -2168,8 +2173,9 @@
   c->private_impl.duration = duration;
   c->private_impl.index = index;
   c->private_impl.io_position = io_position;
-  c->private_impl.blend = blend;
   c->private_impl.disposal = disposal;
+  c->private_impl.opaque_within_bounds = opaque_within_bounds;
+  c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
   c->private_impl.background_color = background_color;
 }
 
@@ -2218,13 +2224,6 @@
   return c ? c->private_impl.io_position : 0;
 }
 
-// wuffs_base__frame_config__blend returns, for an animated image, how to blend
-// the transparent pixels of this frame with the existing canvas.
-static inline wuffs_base__animation_blend  //
-wuffs_base__frame_config__blend(const wuffs_base__frame_config* c) {
-  return c ? c->private_impl.blend : 0;
-}
-
 // wuffs_base__frame_config__disposal returns, for an animated image, how to
 // dispose of this frame after displaying it.
 static inline wuffs_base__animation_disposal  //
@@ -2232,6 +2231,37 @@
   return c ? c->private_impl.disposal : 0;
 }
 
+// wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
+// within the frame's bounds are fully opaque. It makes no claim about pixels
+// outside the frame bounds but still inside the overall image. The two
+// bounding rectangles can differ for animated images.
+//
+// Its semantics are conservative. It is valid for a fully opaque frame to have
+// this value be false: a false negative.
+//
+// If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
+// WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
+// resultant pixels, but the former may be faster.
+static inline bool  //
+wuffs_base__frame_config__opaque_within_bounds(
+    const wuffs_base__frame_config* c) {
+  return c && c->private_impl.opaque_within_bounds;
+}
+
+// wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
+// animated image, whether to ignore the previous image state (within the frame
+// bounds) when drawing this incremental frame. Equivalently, whether to use
+// WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
+//
+// The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
+// calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
+// Wuffs' "overwrite_instead_of_blend".
+static inline bool  //
+wuffs_base__frame_config__overwrite_instead_of_blend(
+    const wuffs_base__frame_config* c) {
+  return c && c->private_impl.overwrite_instead_of_blend;
+}
+
 static inline wuffs_base__color_u32_argb_premul  //
 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
   return c ? c->private_impl.background_color : 0;
@@ -2245,11 +2275,13 @@
     wuffs_base__flicks duration,
     uint64_t index,
     uint64_t io_position,
-    wuffs_base__animation_blend blend,
     wuffs_base__animation_disposal disposal,
+    bool opaque_within_bounds,
+    bool overwrite_instead_of_blend,
     wuffs_base__color_u32_argb_premul background_color) {
-  wuffs_base__frame_config__update(this, bounds, duration, index, io_position,
-                                   blend, disposal, background_color);
+  wuffs_base__frame_config__update(
+      this, bounds, duration, index, io_position, disposal,
+      opaque_within_bounds, overwrite_instead_of_blend, background_color);
 }
 
 inline wuffs_base__rect_ie_u32  //
@@ -2282,16 +2314,21 @@
   return wuffs_base__frame_config__io_position(this);
 }
 
-inline wuffs_base__animation_blend  //
-wuffs_base__frame_config::blend() const {
-  return wuffs_base__frame_config__blend(this);
-}
-
 inline wuffs_base__animation_disposal  //
 wuffs_base__frame_config::disposal() const {
   return wuffs_base__frame_config__disposal(this);
 }
 
+inline bool  //
+wuffs_base__frame_config::opaque_within_bounds() const {
+  return wuffs_base__frame_config__opaque_within_bounds(this);
+}
+
+inline bool  //
+wuffs_base__frame_config::overwrite_instead_of_blend() const {
+  return wuffs_base__frame_config__overwrite_instead_of_blend(this);
+}
+
 inline wuffs_base__color_u32_argb_premul  //
 wuffs_base__frame_config::background_color() const {
   return wuffs_base__frame_config__background_color(this);
@@ -3734,7 +3771,6 @@
     wuffs_lzw__decoder f_lzw;
 
     struct {
-      uint8_t v_blend;
       uint32_t v_background_color;
     } s_decode_frame_config[1];
     struct {
@@ -10055,7 +10091,6 @@
   self->private_impl.active_coroutine = 0;
   wuffs_base__status status = wuffs_base__make_status(NULL);
 
-  uint8_t v_blend = 0;
   uint32_t v_background_color = 0;
   uint8_t v_flags = 0;
 
@@ -10072,7 +10107,6 @@
 
   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
   if (coro_susp_point) {
-    v_blend = self->private_data.s_decode_frame_config[0].v_blend;
     v_background_color =
         self->private_data.s_decode_frame_config[0].v_background_color;
   }
@@ -10125,10 +10159,8 @@
       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
       goto ok;
     }
-    v_blend = 0;
     v_background_color = self->private_impl.f_black_color_u32_argb_premul;
     if (!self->private_impl.f_gc_has_transparent_index) {
-      v_blend = 2;
       v_background_color =
           self->private_impl.f_background_color_u32_argb_premul;
       if (self->private_impl
@@ -10158,8 +10190,10 @@
                                    self->private_impl.f_height)),
           ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
           self->private_impl.f_num_decoded_frame_configs_value,
-          self->private_impl.f_frame_config_io_position, v_blend,
-          self->private_impl.f_gc_disposal, v_background_color);
+          self->private_impl.f_frame_config_io_position,
+          self->private_impl.f_gc_disposal,
+          !self->private_impl.f_gc_has_transparent_index, false,
+          v_background_color);
     }
     wuffs_base__u64__sat_add_indirect(
         &self->private_impl.f_num_decoded_frame_configs_value, 1);
@@ -10177,7 +10211,6 @@
       wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
   self->private_impl.active_coroutine =
       wuffs_base__status__is_suspension(&status) ? 3 : 0;
-  self->private_data.s_decode_frame_config[0].v_blend = v_blend;
   self->private_data.s_decode_frame_config[0].v_background_color =
       v_background_color;
 
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index 5a442c3..a08c470 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -324,7 +324,6 @@
 }
 
 pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
-	var blend            : base.u8
 	var background_color : base.u32
 	var flags            : base.u8
 
@@ -348,10 +347,8 @@
 		return base."@end of data"
 	}
 
-	blend = 0
 	background_color = this.black_color_u32_argb_premul
 	if not this.gc_has_transparent_index {
-		blend = 2  // 2 is WUFFS_BASE__ANIMATION_BLEND__OPAQUE.
 		background_color = this.background_color_u32_argb_premul
 
 		// If the quirk is enabled and the first frame has a local color
@@ -385,8 +382,9 @@
 			duration: this.gc_duration,
 			index: this.num_decoded_frame_configs_value,
 			io_position: this.frame_config_io_position,
-			blend: blend,
 			disposal: this.gc_disposal,
+			opaque_within_bounds: not this.gc_has_transparent_index,
+			overwrite_instead_of_blend: false,
 			background_color: background_color)
 	}