Add wuffs_base__pixel_buffer__set_interleaved
diff --git a/internal/cgen/base/image-public.h b/internal/cgen/base/image-public.h
index 7e3a83c..b16460d 100644
--- a/internal/cgen/base/image-public.h
+++ b/internal/cgen/base/image-public.h
@@ -1105,12 +1105,16 @@
   } private_impl;
 
 #ifdef __cplusplus
+  inline wuffs_base__status set_interleaved(
+      const wuffs_base__pixel_config* pixcfg,
+      wuffs_base__table_u8 primary_memory,
+      wuffs_base__slice_u8 palette_memory);
   inline wuffs_base__status set_from_slice(
       const wuffs_base__pixel_config* pixcfg,
       wuffs_base__slice_u8 pixbuf_memory);
   inline wuffs_base__status set_from_table(
       const wuffs_base__pixel_config* pixcfg,
-      wuffs_base__table_u8 pixbuf_memory);
+      wuffs_base__table_u8 primary_memory);
   inline wuffs_base__slice_u8 palette();
   inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
   inline wuffs_base__pixel_format pixel_format() const;
@@ -1140,6 +1144,55 @@
 }
 
 static inline wuffs_base__status  //
+wuffs_base__pixel_buffer__set_interleaved(
+    wuffs_base__pixel_buffer* pb,
+    const wuffs_base__pixel_config* pixcfg,
+    wuffs_base__table_u8 primary_memory,
+    wuffs_base__slice_u8 palette_memory) {
+  if (!pb) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  memset(pb, 0, sizeof(*pb));
+  if (!pixcfg ||
+      wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
+    return wuffs_base__make_status(wuffs_base__error__bad_argument);
+  }
+  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
+      (palette_memory.len <
+       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
+    return wuffs_base__make_status(
+        wuffs_base__error__bad_argument_length_too_short);
+  }
+  uint32_t bits_per_pixel =
+      wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
+  if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
+    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
+    return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+  }
+  uint64_t bytes_per_pixel = bits_per_pixel / 8;
+
+  uint64_t width_in_bytes =
+      ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
+  if ((width_in_bytes > primary_memory.width) ||
+      (pixcfg->private_impl.height > primary_memory.height)) {
+    return wuffs_base__make_status(wuffs_base__error__bad_argument);
+  }
+
+  pb->pixcfg = *pixcfg;
+  pb->private_impl.planes[0] = primary_memory;
+  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
+    wuffs_base__table_u8* tab =
+        &pb->private_impl
+             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
+    tab->ptr = palette_memory.ptr;
+    tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+    tab->height = 1;
+    tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+  }
+  return wuffs_base__make_status(NULL);
+}
+
+static inline wuffs_base__status  //
 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
                                          const wuffs_base__pixel_config* pixcfg,
                                          wuffs_base__slice_u8 pixbuf_memory) {
@@ -1208,15 +1261,18 @@
   return wuffs_base__make_status(NULL);
 }
 
+// Deprecated: does not handle indexed pixel configurations. Use
+// wuffs_base__pixel_buffer__set_interleaved instead.
 static inline wuffs_base__status  //
 wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,
                                          const wuffs_base__pixel_config* pixcfg,
-                                         wuffs_base__table_u8 pixbuf_memory) {
+                                         wuffs_base__table_u8 primary_memory) {
   if (!pb) {
     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
   }
   memset(pb, 0, sizeof(*pb));
   if (!pixcfg ||
+      wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) ||
       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
     return wuffs_base__make_status(wuffs_base__error__bad_argument);
   }
@@ -1230,13 +1286,13 @@
 
   uint64_t width_in_bytes =
       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
-  if ((width_in_bytes > pixbuf_memory.width) ||
-      (pixcfg->private_impl.height > pixbuf_memory.height)) {
+  if ((width_in_bytes > primary_memory.width) ||
+      (pixcfg->private_impl.height > primary_memory.height)) {
     return wuffs_base__make_status(wuffs_base__error__bad_argument);
   }
 
   pb->pixcfg = *pixcfg;
-  pb->private_impl.planes[0] = pixbuf_memory;
+  pb->private_impl.planes[0] = primary_memory;
   return wuffs_base__make_status(NULL);
 }
 
@@ -1321,6 +1377,15 @@
 #ifdef __cplusplus
 
 inline wuffs_base__status  //
+wuffs_base__pixel_buffer::set_interleaved(
+    const wuffs_base__pixel_config* pixcfg_arg,
+    wuffs_base__table_u8 primary_memory,
+    wuffs_base__slice_u8 palette_memory) {
+  return wuffs_base__pixel_buffer__set_interleaved(
+      this, pixcfg_arg, primary_memory, palette_memory);
+}
+
+inline wuffs_base__status  //
 wuffs_base__pixel_buffer::set_from_slice(
     const wuffs_base__pixel_config* pixcfg_arg,
     wuffs_base__slice_u8 pixbuf_memory) {
@@ -1331,9 +1396,9 @@
 inline wuffs_base__status  //
 wuffs_base__pixel_buffer::set_from_table(
     const wuffs_base__pixel_config* pixcfg_arg,
-    wuffs_base__table_u8 pixbuf_memory) {
+    wuffs_base__table_u8 primary_memory) {
   return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,
-                                                  pixbuf_memory);
+                                                  primary_memory);
 }
 
 inline wuffs_base__slice_u8  //
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index fd6bce6..2fcf9e3 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -185,17 +185,20 @@
 	"(\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__set(this, bounds, duration, index, io_position,\n                                disposal, opaque_within_bounds,\n                                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_b" +
 	"ase__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_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 wuffs_base__pixel_buffer__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__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);\n  inline wuffs_base__pixel_format pixel_format() const;\n  inline wuffs_base__table_u8 plane(uint32_t p);\n  inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,\n                                                        uint32_t y) const;\n  inline wuff" +
-	"s_base__status set_color_u32_at(\n      uint32_t x,\n      uint32_t y,\n      wuffs_base__color_u32_argb_premul color);\n  inline wuffs_base__status set_color_u32_fill_rect(\n      wuffs_base__rect_ie_u32 rect,\n      wuffs_base__color_u32_argb_premul color);\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* pb,\n                                         const wuffs_base__pixel_config* pixcfg,\n                                         wuffs_base__slice_u8 pixbuf_memory) {\n  if (!pb) {\n    return wuffs_b" +
-	"ase__make_status(wuffs_base__error__bad_receiver);\n  }\n  memset(pb, 0, sizeof(*pb));\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_pixel == 0) || ((bits_per_pixel % 8) != 0)) {\n    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?\n    return wuffs_base__make_status(wuffs_base__error__unsupported_option);\n  }\n  uint64_t bytes_per_pixel = bits_per_pixel / 8;\n\n  uint8_t* ptr = pixbuf_memory.ptr;\n  uint64_t len = pixbuf_memory.len;\n  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {\n    // Split a WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte\n    // chunk (1024 bytes = 256 pa" +
-	"lette entries × 4 bytes per entry) from the\n    // start of pixbuf_memory. We split from the start, not the end, so that\n    // the both chunks' pointers have the same alignment as the original\n    // pointer, up to an alignment of 1024.\n    if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {\n      return wuffs_base__make_status(\n          wuffs_base__error__bad_argument_length_too_short);\n    }\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];\n    tab->ptr = ptr;\n    tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    tab->height = 1;\n    tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n  }\n\n  uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *\n                ((uint64_t)pixcfg->private_impl.height);\n  size_t width = (size_t)(pixcfg->priva" +
-	"te_impl.width);\n  if ((wh > (UINT64_MAX / bytes_per_pixel)) ||\n      (width > (SIZE_MAX / bytes_per_pixel))) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n  wh *= bytes_per_pixel;\n  width = ((size_t)(width * bytes_per_pixel));\n  if (wh > len) {\n    return wuffs_base__make_status(\n        wuffs_base__error__bad_argument_length_too_short);\n  }\n\n  pb->pixcfg = *pixcfg;\n  wuffs_base__table_u8* tab = &pb->private_impl.planes[0];\n  tab->ptr = ptr;\n  tab->width = width;\n  tab->height = pixcfg->private_impl.height;\n  tab->stride = width;\n  return wuffs_base__make_status(NULL);\n}\n\nstatic inline wuffs_base__status  //\nwuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,\n                                         const wuffs_base__pixel_config* pixcfg,\n                                         wuffs_base__table_u8 pixbuf_memory) {\n  if (!pb) {\n    return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n  }\n  memset(pb, 0, sizeof(*pb));\n  if (!pixcfg ||\n      wuffs_bas" +
-	"e__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n  uint32_t bits_per_pixel =\n      wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);\n  if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {\n    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?\n    return wuffs_base__make_status(wuffs_base__error__unsupported_option);\n  }\n  uint64_t bytes_per_pixel = bits_per_pixel / 8;\n\n  uint64_t width_in_bytes =\n      ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;\n  if ((width_in_bytes > pixbuf_memory.width) ||\n      (pixcfg->private_impl.height > pixbuf_memory.height)) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n\n  pb->pixcfg = *pixcfg;\n  pb->private_impl.planes[0] = pixbuf_memory;\n  return wuffs_base__make_status(NULL);\n}\n\n// wuffs_base__pixel_buffer__palette returns the palette color data. If\n// non-empty, it will have length\n// WUFFS_BASE__PIXEL_FORMAT__IN" +
-	"DEXED__PALETTE_BYTE_LENGTH.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {\n  if (pb &&\n      wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];\n    if ((tab->width ==\n         WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&\n        (tab->height == 1)) {\n      return wuffs_base__make_slice_u8(\n          tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);\n    }\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,\n                                          wuffs_base__slice_u8 fallback) {\n  if (pb &&\n      wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FO" +
-	"RMAT__INDEXED__COLOR_PLANE];\n    if ((tab->width ==\n         WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&\n        (tab->height == 1)) {\n      return wuffs_base__make_slice_u8(\n          tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);\n    }\n  }\n  return fallback;\n}\n\nstatic inline wuffs_base__pixel_format  //\nwuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {\n  if (pb) {\n    return pb->pixcfg.private_impl.pixfmt;\n  }\n  return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);\n}\n\nstatic inline wuffs_base__table_u8  //\nwuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {\n  if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {\n    return pb->private_impl.planes[p];\n  }\n\n  wuffs_base__table_u8 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul  //\nwuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffe" +
-	"r* pb,\n                                       uint32_t x,\n                                       uint32_t y);\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status  //\nwuffs_base__pixel_buffer__set_color_u32_at(\n    wuffs_base__pixel_buffer* pb,\n    uint32_t x,\n    uint32_t y,\n    wuffs_base__color_u32_argb_premul color);\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status  //\nwuffs_base__pixel_buffer__set_color_u32_fill_rect(\n    wuffs_base__pixel_buffer* pb,\n    wuffs_base__rect_ie_u32 rect,\n    wuffs_base__color_u32_argb_premul color);\n\n#ifdef __cplusplus\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_from_slice(\n    const wuffs_base__pixel_config* pixcfg_arg,\n    wuffs_base__slice_u8 pixbuf_memory) {\n  return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,\n                                                  pixbuf_memory);\n}\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_from_table(\n    const wuffs_base__pixel_config* pixcfg_arg,\n    wuffs_base__table_u8 pixbuf_memory) {\n  return wuff" +
-	"s_base__pixel_buffer__set_from_table(this, pixcfg_arg,\n                                                  pixbuf_memory);\n}\n\ninline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer::palette() {\n  return wuffs_base__pixel_buffer__palette(this);\n}\n\ninline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {\n  return wuffs_base__pixel_buffer__palette_or_else(this, fallback);\n}\n\ninline wuffs_base__pixel_format  //\nwuffs_base__pixel_buffer::pixel_format() const {\n  return wuffs_base__pixel_buffer__pixel_format(this);\n}\n\ninline wuffs_base__table_u8  //\nwuffs_base__pixel_buffer::plane(uint32_t p) {\n  return wuffs_base__pixel_buffer__plane(this, p);\n}\n\ninline wuffs_base__color_u32_argb_premul  //\nwuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {\n  return wuffs_base__pixel_buffer__color_u32_at(this, x, y);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status  //\nwuffs_base__pixel_buffer__set_color_u32_fill_rect(\n    wuffs_base__pixel_buffer* pb,\n    wuffs_b" +
-	"ase__rect_ie_u32 rect,\n    wuffs_base__color_u32_argb_premul color);\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_color_u32_at(\n    uint32_t x,\n    uint32_t y,\n    wuffs_base__color_u32_argb_premul color) {\n  return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);\n}\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_color_u32_fill_rect(\n    wuffs_base__rect_ie_u32 rect,\n    wuffs_base__color_u32_argb_premul color) {\n  return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);\n}\n\n#endif  // __cplusplus\n\n" +
+	"// --------\n\ntypedef struct wuffs_base__pixel_buffer__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_interleaved(\n      const wuffs_base__pixel_config* pixcfg,\n      wuffs_base__table_u8 primary_memory,\n      wuffs_base__slice_u8 palette_memory);\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 primary_memory);\n  inline wuffs_base__slice_u8 palette();\n  inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);\n  inline wuffs_base__pixel_format pixel_format() const;\n  inline wuffs_base__table" +
+	"_u8 plane(uint32_t p);\n  inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,\n                                                        uint32_t y) const;\n  inline wuffs_base__status set_color_u32_at(\n      uint32_t x,\n      uint32_t y,\n      wuffs_base__color_u32_argb_premul color);\n  inline wuffs_base__status set_color_u32_fill_rect(\n      wuffs_base__rect_ie_u32 rect,\n      wuffs_base__color_u32_argb_premul color);\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_interleaved(\n    wuffs_base__pixel_buffer* pb,\n    co" +
+	"nst wuffs_base__pixel_config* pixcfg,\n    wuffs_base__table_u8 primary_memory,\n    wuffs_base__slice_u8 palette_memory) {\n  if (!pb) {\n    return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n  }\n  memset(pb, 0, sizeof(*pb));\n  if (!pixcfg ||\n      wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&\n      (palette_memory.len <\n       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {\n    return wuffs_base__make_status(\n        wuffs_base__error__bad_argument_length_too_short);\n  }\n  uint32_t bits_per_pixel =\n      wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);\n  if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {\n    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?\n    return wuffs_base__make_status(wuffs_base__error__unsupported_option);\n  }\n  uint64_t bytes_per_pixel = bits_per" +
+	"_pixel / 8;\n\n  uint64_t width_in_bytes =\n      ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;\n  if ((width_in_bytes > primary_memory.width) ||\n      (pixcfg->private_impl.height > primary_memory.height)) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n\n  pb->pixcfg = *pixcfg;\n  pb->private_impl.planes[0] = primary_memory;\n  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];\n    tab->ptr = palette_memory.ptr;\n    tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    tab->height = 1;\n    tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n  }\n  return wuffs_base__make_status(NULL);\n}\n\nstatic inline wuffs_base__status  //\nwuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,\n                                         const wuffs_base__pixel_config* pixcfg,\n                   " +
+	"                      wuffs_base__slice_u8 pixbuf_memory) {\n  if (!pb) {\n    return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n  }\n  memset(pb, 0, sizeof(*pb));\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_pixel == 0) || ((bits_per_pixel % 8) != 0)) {\n    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?\n    return wuffs_base__make_status(wuffs_base__error__unsupported_option);\n  }\n  uint64_t bytes_per_pixel = bits_per_pixel / 8;\n\n  uint8_t* ptr = pixbuf_memory.ptr;\n  uint64_t len = pixbuf_memory.len;\n  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {\n    // Split a WU" +
+	"FFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte\n    // chunk (1024 bytes = 256 palette entries × 4 bytes per entry) from the\n    // start of pixbuf_memory. We split from the start, not the end, so that\n    // the both chunks' pointers have the same alignment as the original\n    // pointer, up to an alignment of 1024.\n    if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {\n      return wuffs_base__make_status(\n          wuffs_base__error__bad_argument_length_too_short);\n    }\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];\n    tab->ptr = ptr;\n    tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    tab->height = 1;\n    tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n    len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;\n  }\n\n  uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *\n     " +
+	"           ((uint64_t)pixcfg->private_impl.height);\n  size_t width = (size_t)(pixcfg->private_impl.width);\n  if ((wh > (UINT64_MAX / bytes_per_pixel)) ||\n      (width > (SIZE_MAX / bytes_per_pixel))) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n  wh *= bytes_per_pixel;\n  width = ((size_t)(width * bytes_per_pixel));\n  if (wh > len) {\n    return wuffs_base__make_status(\n        wuffs_base__error__bad_argument_length_too_short);\n  }\n\n  pb->pixcfg = *pixcfg;\n  wuffs_base__table_u8* tab = &pb->private_impl.planes[0];\n  tab->ptr = ptr;\n  tab->width = width;\n  tab->height = pixcfg->private_impl.height;\n  tab->stride = width;\n  return wuffs_base__make_status(NULL);\n}\n\n// Deprecated: does not handle indexed pixel configurations. Use\n// wuffs_base__pixel_buffer__set_interleaved instead.\nstatic inline wuffs_base__status  //\nwuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,\n                                         const wuffs_base__pixel_config* pixcfg,\n                 " +
+	"                        wuffs_base__table_u8 primary_memory) {\n  if (!pb) {\n    return wuffs_base__make_status(wuffs_base__error__bad_receiver);\n  }\n  memset(pb, 0, sizeof(*pb));\n  if (!pixcfg ||\n      wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) ||\n      wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {\n    return wuffs_base__make_status(wuffs_base__error__bad_argument);\n  }\n  uint32_t bits_per_pixel =\n      wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);\n  if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {\n    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?\n    return wuffs_base__make_status(wuffs_base__error__unsupported_option);\n  }\n  uint64_t bytes_per_pixel = bits_per_pixel / 8;\n\n  uint64_t width_in_bytes =\n      ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;\n  if ((width_in_bytes > primary_memory.width) ||\n      (pixcfg->private_impl.height > primary_memory.height)) {\n    return wuffs_base__make_status(" +
+	"wuffs_base__error__bad_argument);\n  }\n\n  pb->pixcfg = *pixcfg;\n  pb->private_impl.planes[0] = primary_memory;\n  return wuffs_base__make_status(NULL);\n}\n\n// wuffs_base__pixel_buffer__palette returns the palette color data. If\n// non-empty, it will have length\n// WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {\n  if (pb &&\n      wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];\n    if ((tab->width ==\n         WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&\n        (tab->height == 1)) {\n      return wuffs_base__make_slice_u8(\n          tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);\n    }\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer__palette_or_else(wuffs" +
+	"_base__pixel_buffer* pb,\n                                          wuffs_base__slice_u8 fallback) {\n  if (pb &&\n      wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {\n    wuffs_base__table_u8* tab =\n        &pb->private_impl\n             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];\n    if ((tab->width ==\n         WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&\n        (tab->height == 1)) {\n      return wuffs_base__make_slice_u8(\n          tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);\n    }\n  }\n  return fallback;\n}\n\nstatic inline wuffs_base__pixel_format  //\nwuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {\n  if (pb) {\n    return pb->pixcfg.private_impl.pixfmt;\n  }\n  return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);\n}\n\nstatic inline wuffs_base__table_u8  //\nwuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {\n  if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {\n " +
+	"   return pb->private_impl.planes[p];\n  }\n\n  wuffs_base__table_u8 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul  //\nwuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,\n                                       uint32_t x,\n                                       uint32_t y);\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status  //\nwuffs_base__pixel_buffer__set_color_u32_at(\n    wuffs_base__pixel_buffer* pb,\n    uint32_t x,\n    uint32_t y,\n    wuffs_base__color_u32_argb_premul color);\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status  //\nwuffs_base__pixel_buffer__set_color_u32_fill_rect(\n    wuffs_base__pixel_buffer* pb,\n    wuffs_base__rect_ie_u32 rect,\n    wuffs_base__color_u32_argb_premul color);\n\n#ifdef __cplusplus\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_interleaved(\n    const wuffs_base__pixel_config* pixcfg_arg,\n    wuffs_base__table_u8 primary_memory,\n    wuffs_base__slice_" +
+	"u8 palette_memory) {\n  return wuffs_base__pixel_buffer__set_interleaved(\n      this, pixcfg_arg, primary_memory, palette_memory);\n}\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_from_slice(\n    const wuffs_base__pixel_config* pixcfg_arg,\n    wuffs_base__slice_u8 pixbuf_memory) {\n  return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,\n                                                  pixbuf_memory);\n}\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_from_table(\n    const wuffs_base__pixel_config* pixcfg_arg,\n    wuffs_base__table_u8 primary_memory) {\n  return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,\n                                                  primary_memory);\n}\n\ninline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer::palette() {\n  return wuffs_base__pixel_buffer__palette(this);\n}\n\ninline wuffs_base__slice_u8  //\nwuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {\n  return wuffs_base__pixel_buffer__palette_or_else(this, fall" +
+	"back);\n}\n\ninline wuffs_base__pixel_format  //\nwuffs_base__pixel_buffer::pixel_format() const {\n  return wuffs_base__pixel_buffer__pixel_format(this);\n}\n\ninline wuffs_base__table_u8  //\nwuffs_base__pixel_buffer::plane(uint32_t p) {\n  return wuffs_base__pixel_buffer__plane(this, p);\n}\n\ninline wuffs_base__color_u32_argb_premul  //\nwuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {\n  return wuffs_base__pixel_buffer__color_u32_at(this, x, y);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__status  //\nwuffs_base__pixel_buffer__set_color_u32_fill_rect(\n    wuffs_base__pixel_buffer* pb,\n    wuffs_base__rect_ie_u32 rect,\n    wuffs_base__color_u32_argb_premul color);\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_color_u32_at(\n    uint32_t x,\n    uint32_t y,\n    wuffs_base__color_u32_argb_premul color) {\n  return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);\n}\n\ninline wuffs_base__status  //\nwuffs_base__pixel_buffer::set_color_u32_fill_rect(\n    wuffs_base__rect_ie_u32 rect,\n  " +
+	"  wuffs_base__color_u32_argb_premul color) {\n  return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);\n}\n\n#endif  // __cplusplus\n\n" +
 	"" +
 	"// --------\n\ntypedef struct wuffs_base__decode_frame_options__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" +
 	"" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index b8945bb..0ac8a62 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -4271,12 +4271,16 @@
   } private_impl;
 
 #ifdef __cplusplus
+  inline wuffs_base__status set_interleaved(
+      const wuffs_base__pixel_config* pixcfg,
+      wuffs_base__table_u8 primary_memory,
+      wuffs_base__slice_u8 palette_memory);
   inline wuffs_base__status set_from_slice(
       const wuffs_base__pixel_config* pixcfg,
       wuffs_base__slice_u8 pixbuf_memory);
   inline wuffs_base__status set_from_table(
       const wuffs_base__pixel_config* pixcfg,
-      wuffs_base__table_u8 pixbuf_memory);
+      wuffs_base__table_u8 primary_memory);
   inline wuffs_base__slice_u8 palette();
   inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
   inline wuffs_base__pixel_format pixel_format() const;
@@ -4306,6 +4310,55 @@
 }
 
 static inline wuffs_base__status  //
+wuffs_base__pixel_buffer__set_interleaved(
+    wuffs_base__pixel_buffer* pb,
+    const wuffs_base__pixel_config* pixcfg,
+    wuffs_base__table_u8 primary_memory,
+    wuffs_base__slice_u8 palette_memory) {
+  if (!pb) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  memset(pb, 0, sizeof(*pb));
+  if (!pixcfg ||
+      wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
+    return wuffs_base__make_status(wuffs_base__error__bad_argument);
+  }
+  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
+      (palette_memory.len <
+       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
+    return wuffs_base__make_status(
+        wuffs_base__error__bad_argument_length_too_short);
+  }
+  uint32_t bits_per_pixel =
+      wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
+  if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
+    // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
+    return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+  }
+  uint64_t bytes_per_pixel = bits_per_pixel / 8;
+
+  uint64_t width_in_bytes =
+      ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
+  if ((width_in_bytes > primary_memory.width) ||
+      (pixcfg->private_impl.height > primary_memory.height)) {
+    return wuffs_base__make_status(wuffs_base__error__bad_argument);
+  }
+
+  pb->pixcfg = *pixcfg;
+  pb->private_impl.planes[0] = primary_memory;
+  if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
+    wuffs_base__table_u8* tab =
+        &pb->private_impl
+             .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
+    tab->ptr = palette_memory.ptr;
+    tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+    tab->height = 1;
+    tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+  }
+  return wuffs_base__make_status(NULL);
+}
+
+static inline wuffs_base__status  //
 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
                                          const wuffs_base__pixel_config* pixcfg,
                                          wuffs_base__slice_u8 pixbuf_memory) {
@@ -4374,15 +4427,18 @@
   return wuffs_base__make_status(NULL);
 }
 
+// Deprecated: does not handle indexed pixel configurations. Use
+// wuffs_base__pixel_buffer__set_interleaved instead.
 static inline wuffs_base__status  //
 wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,
                                          const wuffs_base__pixel_config* pixcfg,
-                                         wuffs_base__table_u8 pixbuf_memory) {
+                                         wuffs_base__table_u8 primary_memory) {
   if (!pb) {
     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
   }
   memset(pb, 0, sizeof(*pb));
   if (!pixcfg ||
+      wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) ||
       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
     return wuffs_base__make_status(wuffs_base__error__bad_argument);
   }
@@ -4396,13 +4452,13 @@
 
   uint64_t width_in_bytes =
       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
-  if ((width_in_bytes > pixbuf_memory.width) ||
-      (pixcfg->private_impl.height > pixbuf_memory.height)) {
+  if ((width_in_bytes > primary_memory.width) ||
+      (pixcfg->private_impl.height > primary_memory.height)) {
     return wuffs_base__make_status(wuffs_base__error__bad_argument);
   }
 
   pb->pixcfg = *pixcfg;
-  pb->private_impl.planes[0] = pixbuf_memory;
+  pb->private_impl.planes[0] = primary_memory;
   return wuffs_base__make_status(NULL);
 }
 
@@ -4487,6 +4543,15 @@
 #ifdef __cplusplus
 
 inline wuffs_base__status  //
+wuffs_base__pixel_buffer::set_interleaved(
+    const wuffs_base__pixel_config* pixcfg_arg,
+    wuffs_base__table_u8 primary_memory,
+    wuffs_base__slice_u8 palette_memory) {
+  return wuffs_base__pixel_buffer__set_interleaved(
+      this, pixcfg_arg, primary_memory, palette_memory);
+}
+
+inline wuffs_base__status  //
 wuffs_base__pixel_buffer::set_from_slice(
     const wuffs_base__pixel_config* pixcfg_arg,
     wuffs_base__slice_u8 pixbuf_memory) {
@@ -4497,9 +4562,9 @@
 inline wuffs_base__status  //
 wuffs_base__pixel_buffer::set_from_table(
     const wuffs_base__pixel_config* pixcfg_arg,
-    wuffs_base__table_u8 pixbuf_memory) {
+    wuffs_base__table_u8 primary_memory) {
   return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,
-                                                  pixbuf_memory);
+                                                  primary_memory);
 }
 
 inline wuffs_base__slice_u8  //