Spin out wuffs_aux Alloc{Pixbuf,Workbuf}Result
diff --git a/example/imageviewer/imageviewer.cc b/example/imageviewer/imageviewer.cc
index 3b12f89..717711c 100644
--- a/example/imageviewer/imageviewer.cc
+++ b/example/imageviewer/imageviewer.cc
@@ -86,7 +86,7 @@
 uint32_t g_width = 0;
 uint32_t g_height = 0;
 wuffs_aux::MemOwner g_pixbuf_mem_owner(nullptr, &free);
-wuffs_base__slice_u8 g_pixbuf_mem_slice = {0};
+wuffs_base__pixel_buffer g_pixbuf = {0};
 uint32_t g_background_color_index = 0;
 
 bool  //
@@ -106,7 +106,7 @@
   g_width = 0;
   g_height = 0;
   g_pixbuf_mem_owner.reset();
-  g_pixbuf_mem_slice = wuffs_base__empty_slice_u8();
+  g_pixbuf = wuffs_base__null_pixel_buffer();
 
   wuffs_aux::DecodeImageCallbacks callbacks;
   wuffs_aux::sync_io::FileInput input(file);
@@ -123,7 +123,7 @@
   g_width = res.pixbuf.pixcfg.width();
   g_height = res.pixbuf.pixcfg.height();
   g_pixbuf_mem_owner = std::move(res.pixbuf_mem_owner);
-  g_pixbuf_mem_slice = res.pixbuf_mem_slice;
+  g_pixbuf = res.pixbuf;
 
   if (res.error_message.empty()) {
     printf("%s: ok (%" PRIu32 " x %" PRIu32 ")\n", adj_filename, g_width,
@@ -193,11 +193,12 @@
   if (!load_image(filename)) {
     return false;
   }
+  wuffs_base__table_u8 tab = g_pixbuf.plane(0);
 
   xcb_create_pixmap(c, s->root_depth, g_pixmap, w, g_width, g_height);
   xcb_image_t* image = xcb_image_create_native(
       c, g_width, g_height, XCB_IMAGE_FORMAT_Z_PIXMAP, s->root_depth, NULL,
-      g_pixbuf_mem_slice.len, g_pixbuf_mem_slice.ptr);
+      tab.height * tab.stride, tab.ptr);
   xcb_image_put(c, g_pixmap, g, image, 0, 0, 0);
   xcb_image_destroy(image);
   return true;
diff --git a/example/sdl-imageviewer/sdl-imageviewer.cc b/example/sdl-imageviewer/sdl-imageviewer.cc
index a0c7d0c..6d2b0fe 100644
--- a/example/sdl-imageviewer/sdl-imageviewer.cc
+++ b/example/sdl-imageviewer/sdl-imageviewer.cc
@@ -115,7 +115,7 @@
         WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL);
   }
 
-  AllocResult  //
+  AllocPixbufResult  //
   AllocPixbuf(const wuffs_base__image_config& image_config,
               bool allow_uninitialized_memory) override {
     if (m_surface) {
@@ -126,7 +126,7 @@
     uint32_t w = image_config.pixcfg.width();
     uint32_t h = image_config.pixcfg.height();
     if ((w > 0xFFFFFF) || (h > 0xFFFFFF)) {
-      return AllocResult("Wuffs_Load_RW_Callbacks: image is too large");
+      return AllocPixbufResult("Wuffs_Load_RW_Callbacks: image is too large");
     }
     uint32_t sdl_pixelformat = SDL_PIXELFORMAT_BGRA32;
 
@@ -140,14 +140,24 @@
     m_surface = SDL_CreateRGBSurfaceWithFormat(
         0, static_cast<int>(w), static_cast<int>(h), 32, sdl_pixelformat);
     if (!m_surface) {
-      return AllocResult(
+      return AllocPixbufResult(
           "Wuffs_Load_RW_Callbacks: SDL_CreateRGBSurface failed");
     }
     SDL_LockSurface(m_surface);
-    return AllocResult(
-        wuffs_aux::MemOwner(NULL, &free),
-        wuffs_base__make_slice_u8(static_cast<uint8_t*>(m_surface->pixels),
-                                  m_surface->h * m_surface->pitch));
+    wuffs_base__pixel_buffer pixbuf;
+    wuffs_base__status status = pixbuf.set_interleaved(
+        &image_config.pixcfg,
+        wuffs_base__make_table_u8(static_cast<uint8_t*>(m_surface->pixels),
+                                  m_surface->w * 4, m_surface->h,
+                                  m_surface->pitch),
+        wuffs_base__empty_slice_u8());
+    if (!status.is_ok()) {
+      SDL_UnlockSurface(m_surface);
+      SDL_FreeSurface(m_surface);
+      m_surface = NULL;
+      return AllocPixbufResult(status.message());
+    }
+    return AllocPixbufResult(wuffs_aux::MemOwner(NULL, &free), pixbuf);
   }
 
   SDL_Surface* m_surface;
diff --git a/internal/cgen/auxiliary/image.cc b/internal/cgen/auxiliary/image.cc
index 545bd55..d6f891d 100644
--- a/internal/cgen/auxiliary/image.cc
+++ b/internal/cgen/auxiliary/image.cc
@@ -23,31 +23,39 @@
 namespace wuffs_aux {
 
 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
-                                     wuffs_base__slice_u8 pixbuf_mem_slice0,
                                      wuffs_base__pixel_buffer pixbuf0,
                                      std::string&& error_message0)
     : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
-      pixbuf_mem_slice(pixbuf_mem_slice0),
       pixbuf(pixbuf0),
       error_message(std::move(error_message0)) {}
 
 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
     : pixbuf_mem_owner(nullptr, &free),
-      pixbuf_mem_slice(wuffs_base__empty_slice_u8()),
       pixbuf(wuffs_base__null_pixel_buffer()),
       error_message(std::move(error_message0)) {}
 
 DecodeImageCallbacks::~DecodeImageCallbacks() {}
 
-DecodeImageCallbacks::AllocResult::AllocResult(MemOwner&& mem_owner0,
-                                               wuffs_base__slice_u8 mem_slice0)
-    : mem_owner(std::move(mem_owner0)),
-      mem_slice(mem_slice0),
-      error_message("") {}
+DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
+    MemOwner&& mem_owner0,
+    wuffs_base__pixel_buffer pixbuf0)
+    : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
 
-DecodeImageCallbacks::AllocResult::AllocResult(std::string&& error_message0)
+DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
+    std::string&& error_message0)
     : mem_owner(nullptr, &free),
-      mem_slice(wuffs_base__empty_slice_u8()),
+      pixbuf(wuffs_base__null_pixel_buffer()),
+      error_message(std::move(error_message0)) {}
+
+DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
+    MemOwner&& mem_owner0,
+    wuffs_base__slice_u8 workbuf0)
+    : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
+
+DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
+    std::string&& error_message0)
+    : mem_owner(nullptr, &free),
+      workbuf(wuffs_base__empty_slice_u8()),
       error_message(std::move(error_message0)) {}
 
 wuffs_base__image_decoder::unique_ptr  //
@@ -93,41 +101,51 @@
   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
 }
 
-DecodeImageCallbacks::AllocResult  //
+DecodeImageCallbacks::AllocPixbufResult  //
 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
                                   bool allow_uninitialized_memory) {
   uint32_t w = image_config.pixcfg.width();
   uint32_t h = image_config.pixcfg.height();
   if ((w == 0) || (h == 0)) {
-    return AllocResult("");
+    return AllocPixbufResult("");
   }
   uint64_t len = image_config.pixcfg.pixbuf_len();
   if ((len == 0) || (SIZE_MAX < len)) {
-    return AllocResult(DecodeImage_UnsupportedPixelConfiguration);
+    return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
   }
   void* ptr =
       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
-  return ptr ? AllocResult(
-                   MemOwner(ptr, &free),
-                   wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len))
-             : AllocResult(DecodeImage_OutOfMemory);
+  if (!ptr) {
+    return AllocPixbufResult(DecodeImage_OutOfMemory);
+  }
+  wuffs_base__pixel_buffer pixbuf;
+  wuffs_base__status status = pixbuf.set_from_slice(
+      &image_config.pixcfg,
+      wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
+  if (!status.is_ok()) {
+    free(ptr);
+    return AllocPixbufResult(status.message());
+  }
+  return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
 }
 
-DecodeImageCallbacks::AllocResult  //
+DecodeImageCallbacks::AllocWorkbufResult  //
 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
                                    bool allow_uninitialized_memory) {
   uint64_t len = len_range.max_incl;
   if (len == 0) {
-    return AllocResult("");
+    return AllocWorkbufResult("");
   } else if (SIZE_MAX < len) {
-    return AllocResult(DecodeImage_OutOfMemory);
+    return AllocWorkbufResult(DecodeImage_OutOfMemory);
   }
   void* ptr =
       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
-  return ptr ? AllocResult(
-                   MemOwner(ptr, &free),
-                   wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len))
-             : AllocResult(DecodeImage_OutOfMemory);
+  if (!ptr) {
+    return AllocWorkbufResult(DecodeImage_OutOfMemory);
+  }
+  return AllocWorkbufResult(
+      MemOwner(ptr, &free),
+      wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
 }
 
 void  //
@@ -310,28 +328,14 @@
   }
 
   // Allocate the pixel buffer.
-  uint64_t pixbuf_len_min_incl = 0;
-  if ((w > 0) && (h > 0)) {
-    pixbuf_len_min_incl = image_config.pixcfg.pixbuf_len();
-    if (pixbuf_len_min_incl == 0) {
-      return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
-    }
-  }
   bool valid_background_color =
       wuffs_base__color_u32_argb_premul__is_valid(background_color);
-  DecodeImageCallbacks::AllocResult alloc_pixbuf_result =
+  DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
       callbacks.AllocPixbuf(image_config, valid_background_color);
   if (!alloc_pixbuf_result.error_message.empty()) {
     return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
-  } else if (alloc_pixbuf_result.mem_slice.len < pixbuf_len_min_incl) {
-    return DecodeImageResult(DecodeImage_BufferIsTooShort);
   }
-  wuffs_base__pixel_buffer pixel_buffer;
-  wuffs_base__status pb_sfs_status = pixel_buffer.set_from_slice(
-      &image_config.pixcfg, alloc_pixbuf_result.mem_slice);
-  if (!pb_sfs_status.is_ok()) {
-    return DecodeImageResult(pb_sfs_status.message());
-  }
+  wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
   if (valid_background_color) {
     wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
         pixel_buffer.pixcfg.bounds(), background_color);
@@ -343,11 +347,11 @@
   // Allocate the work buffer. Wuffs' decoders conventionally assume that this
   // can be uninitialized memory.
   wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
-  DecodeImageCallbacks::AllocResult alloc_workbuf_result =
+  DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
       callbacks.AllocWorkbuf(workbuf_len, true);
   if (!alloc_workbuf_result.error_message.empty()) {
     return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
-  } else if (alloc_workbuf_result.mem_slice.len < workbuf_len.min_incl) {
+  } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
     return DecodeImageResult(DecodeImage_BufferIsTooShort);
   }
 
@@ -382,7 +386,7 @@
   while (true) {
     wuffs_base__status id_df_status =
         image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
-                                    alloc_workbuf_result.mem_slice, nullptr);
+                                    alloc_workbuf_result.workbuf, nullptr);
     if (id_df_status.repr == nullptr) {
       break;
     } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
@@ -400,8 +404,7 @@
     }
   }
   return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
-                           alloc_pixbuf_result.mem_slice, pixel_buffer,
-                           std::move(message));
+                           pixel_buffer, std::move(message));
 }
 
 }  // namespace
diff --git a/internal/cgen/auxiliary/image.hh b/internal/cgen/auxiliary/image.hh
index db905ec..0aebab0 100644
--- a/internal/cgen/auxiliary/image.hh
+++ b/internal/cgen/auxiliary/image.hh
@@ -20,13 +20,11 @@
 
 struct DecodeImageResult {
   DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
-                    wuffs_base__slice_u8 pixbuf_mem_slice0,
                     wuffs_base__pixel_buffer pixbuf0,
                     std::string&& error_message0);
   DecodeImageResult(std::string&& error_message0);
 
   MemOwner pixbuf_mem_owner;
-  wuffs_base__slice_u8 pixbuf_mem_slice;
   wuffs_base__pixel_buffer pixbuf;
   std::string error_message;
 };
@@ -43,15 +41,27 @@
 // one fails - but the final callback (Done) is always invoked.
 class DecodeImageCallbacks {
  public:
-  // AllocResult holds a memory allocation (the result of malloc or new, a
-  // statically allocated pointer, etc), or an error message. The memory is
+  // AllocPixbufResult holds a memory allocation (the result of malloc or new,
+  // a statically allocated pointer, etc), or an error message. The memory is
   // de-allocated when mem_owner goes out of scope and is destroyed.
-  struct AllocResult {
-    AllocResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 mem_slice0);
-    AllocResult(std::string&& error_message0);
+  struct AllocPixbufResult {
+    AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
+    AllocPixbufResult(std::string&& error_message0);
 
     MemOwner mem_owner;
-    wuffs_base__slice_u8 mem_slice;
+    wuffs_base__pixel_buffer pixbuf;
+    std::string error_message;
+  };
+
+  // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
+  // a statically allocated pointer, etc), or an error message. The memory is
+  // de-allocated when mem_owner goes out of scope and is destroyed.
+  struct AllocWorkbufResult {
+    AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
+    AllocWorkbufResult(std::string&& error_message0);
+
+    MemOwner mem_owner;
+    wuffs_base__slice_u8 workbuf;
     std::string error_message;
   };
 
@@ -112,7 +122,7 @@
   // The default AllocPixbuf implementation allocates either uninitialized or
   // zeroed memory. Zeroed memory typically corresponds to filling with opaque
   // black or transparent black, depending on the pixel format.
-  virtual AllocResult  //
+  virtual AllocPixbufResult  //
   AllocPixbuf(const wuffs_base__image_config& image_config,
               bool allow_uninitialized_memory);
 
@@ -122,7 +132,7 @@
   //
   // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
   // of either uninitialized or zeroed memory.
-  virtual AllocResult  //
+  virtual AllocWorkbufResult  //
   AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
                bool allow_uninitialized_memory);
 
diff --git a/internal/cgen/base/fundamental-public.h b/internal/cgen/base/fundamental-public.h
index fb38c14..1087ec8 100644
--- a/internal/cgen/base/fundamental-public.h
+++ b/internal/cgen/base/fundamental-public.h
@@ -1076,6 +1076,58 @@
 }
 
 static inline wuffs_base__table_u8  //
+wuffs_base__make_table_u8(uint8_t* ptr,
+                          size_t width,
+                          size_t height,
+                          size_t stride) {
+  wuffs_base__table_u8 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u16  //
+wuffs_base__make_table_u16(uint16_t* ptr,
+                           size_t width,
+                           size_t height,
+                           size_t stride) {
+  wuffs_base__table_u16 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u32  //
+wuffs_base__make_table_u32(uint32_t* ptr,
+                           size_t width,
+                           size_t height,
+                           size_t stride) {
+  wuffs_base__table_u32 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u64  //
+wuffs_base__make_table_u64(uint64_t* ptr,
+                           size_t width,
+                           size_t height,
+                           size_t stride) {
+  wuffs_base__table_u64 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u8  //
 wuffs_base__empty_table_u8() {
   wuffs_base__table_u8 ret;
   ret.ptr = NULL;
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 2fcf9e3..40bfc69 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -112,9 +112,10 @@
 	"" +
 	"// ---------------- Slices and Tables\n\n// WUFFS_BASE__SLICE is a 1-dimensional buffer.\n//\n// len measures a number of elements, not necessarily a size in bytes.\n//\n// A value with all fields NULL or zero is a valid, empty slice.\n#define WUFFS_BASE__SLICE(T) \\\n  struct {                   \\\n    T* ptr;                  \\\n    size_t len;              \\\n  }\n\n// WUFFS_BASE__TABLE is a 2-dimensional buffer.\n//\n// width, height and stride measure a number of elements, not necessarily a\n// size in bytes.\n//\n// A value with all fields NULL or zero is a valid, empty table.\n#define WUFFS_BASE__TABLE(T) \\\n  struct {                   \\\n    T* ptr;                  \\\n    size_t width;            \\\n    size_t height;           \\\n    size_t stride;           \\\n  }\n\ntypedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;\ntypedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;\ntypedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;\ntypedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;\n\ntypedef WUFFS_BASE__TABLE(u" +
 	"int8_t) wuffs_base__table_u8;\ntypedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;\ntypedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;\ntypedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;\n\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {\n  wuffs_base__slice_u8 ret;\n  ret.ptr = ptr;\n  ret.len = len;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u16  //\nwuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {\n  wuffs_base__slice_u16 ret;\n  ret.ptr = ptr;\n  ret.len = len;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u32  //\nwuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {\n  wuffs_base__slice_u32 ret;\n  ret.ptr = ptr;\n  ret.len = len;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u64  //\nwuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {\n  wuffs_base__slice_u64 ret;\n  ret.ptr = ptr;\n  ret.len = len;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__empty_slice_u8() {\n  wuffs_base__slice_u8 ret;\n  ret.ptr = NULL;\n" +
-	"  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u16  //\nwuffs_base__empty_slice_u16() {\n  wuffs_base__slice_u16 ret;\n  ret.ptr = NULL;\n  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u32  //\nwuffs_base__empty_slice_u32() {\n  wuffs_base__slice_u32 ret;\n  ret.ptr = NULL;\n  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u64  //\nwuffs_base__empty_slice_u64() {\n  wuffs_base__slice_u64 ret;\n  ret.ptr = NULL;\n  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u8  //\nwuffs_base__empty_table_u8() {\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\nstatic inline wuffs_base__table_u16  //\nwuffs_base__empty_table_u16() {\n  wuffs_base__table_u16 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u32  //\nwuffs_base__empty_table_u32() {\n  wuffs_base__table_u32 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stri" +
-	"de = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u64  //\nwuffs_base__empty_table_u64() {\n  wuffs_base__table_u64 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nstatic inline bool  //\nwuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {\n  return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||\n         ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));\n}\n\n// wuffs_base__slice_u8__subslice_i returns s[i:].\n//\n// It returns an empty slice if i is out of bounds.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {\n  if ((i <= SIZE_MAX) && (i <= s.len)) {\n    return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_j returns s[:j].\n//\n// It returns an empty slice if j is out of bounds.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, ui" +
-	"nt64_t j) {\n  if ((j <= SIZE_MAX) && (j <= s.len)) {\n    return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_ij returns s[i:j].\n//\n// It returns an empty slice if i or j is out of bounds.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,\n                                  uint64_t i,\n                                  uint64_t j) {\n  if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {\n    return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n" +
+	"  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u16  //\nwuffs_base__empty_slice_u16() {\n  wuffs_base__slice_u16 ret;\n  ret.ptr = NULL;\n  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u32  //\nwuffs_base__empty_slice_u32() {\n  wuffs_base__slice_u32 ret;\n  ret.ptr = NULL;\n  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__slice_u64  //\nwuffs_base__empty_slice_u64() {\n  wuffs_base__slice_u64 ret;\n  ret.ptr = NULL;\n  ret.len = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u8  //\nwuffs_base__make_table_u8(uint8_t* ptr,\n                          size_t width,\n                          size_t height,\n                          size_t stride) {\n  wuffs_base__table_u8 ret;\n  ret.ptr = ptr;\n  ret.width = width;\n  ret.height = height;\n  ret.stride = stride;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u16  //\nwuffs_base__make_table_u16(uint16_t* ptr,\n                           size_t width,\n                           size_t height,\n                           size_t stride) " +
+	"{\n  wuffs_base__table_u16 ret;\n  ret.ptr = ptr;\n  ret.width = width;\n  ret.height = height;\n  ret.stride = stride;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u32  //\nwuffs_base__make_table_u32(uint32_t* ptr,\n                           size_t width,\n                           size_t height,\n                           size_t stride) {\n  wuffs_base__table_u32 ret;\n  ret.ptr = ptr;\n  ret.width = width;\n  ret.height = height;\n  ret.stride = stride;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u64  //\nwuffs_base__make_table_u64(uint64_t* ptr,\n                           size_t width,\n                           size_t height,\n                           size_t stride) {\n  wuffs_base__table_u64 ret;\n  ret.ptr = ptr;\n  ret.width = width;\n  ret.height = height;\n  ret.stride = stride;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u8  //\nwuffs_base__empty_table_u8() {\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\nstatic inline wuffs_base__ta" +
+	"ble_u16  //\nwuffs_base__empty_table_u16() {\n  wuffs_base__table_u16 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u32  //\nwuffs_base__empty_table_u32() {\n  wuffs_base__table_u32 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nstatic inline wuffs_base__table_u64  //\nwuffs_base__empty_table_u64() {\n  wuffs_base__table_u64 ret;\n  ret.ptr = NULL;\n  ret.width = 0;\n  ret.height = 0;\n  ret.stride = 0;\n  return ret;\n}\n\nstatic inline bool  //\nwuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {\n  return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||\n         ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));\n}\n\n// wuffs_base__slice_u8__subslice_i returns s[i:].\n//\n// It returns an empty slice if i is out of bounds.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {\n  if ((i <= SIZE_MAX) && (i <= s.len)) {\n   " +
+	" return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_j returns s[:j].\n//\n// It returns an empty slice if j is out of bounds.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {\n  if ((j <= SIZE_MAX) && (j <= s.len)) {\n    return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n// wuffs_base__slice_u8__subslice_ij returns s[i:j].\n//\n// It returns an empty slice if i or j is out of bounds.\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,\n                                  uint64_t i,\n                                  uint64_t j) {\n  if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {\n    return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n\n" +
 	"" +
 	"// ---------------- Magic Numbers\n\n// wuffs_base__magic_number_guess_fourcc guesses the file format of some data,\n// given its opening bytes. It returns a positive FourCC value on success.\n//\n// It returns zero if nothing matches its hard-coded list of 'magic numbers'.\n//\n// It returns a negative value if a longer prefix is required for a conclusive\n// result. For example, seeing a single 'B' byte is not enough to discriminate\n// the BMP and BPG image file formats.\n//\n// It does not do a full validity check. Like any guess made from a short\n// prefix of the data, it may return false positives. Data that starts with 99\n// bytes of valid JPEG followed by corruption or truncation is an invalid JPEG\n// image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.\n//\n// Another source of false positives is that some 'magic numbers' are valid\n// ASCII data. A file starting with \"GIF87a and GIF89a are the two versions of\n// GIF\" will match GIF's 'magic number' even if it's plain text, not an image.\n//" +
 	"\n// For modular builds that divide the base module into sub-modules, using this\n// function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just\n// WUFFS_CONFIG__MODULE__BASE__CORE.\nWUFFS_BASE__MAYBE_STATIC int32_t  //\nwuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix);\n" +
@@ -811,36 +812,36 @@
 	""
 
 const AuxImageCc = "" +
-	"// ---------------- Auxiliary - Image\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)\n\n#include <utility>\n\nnamespace wuffs_aux {\n\nDecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,\n                                     wuffs_base__slice_u8 pixbuf_mem_slice0,\n                                     wuffs_base__pixel_buffer pixbuf0,\n                                     std::string&& error_message0)\n    : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),\n      pixbuf_mem_slice(pixbuf_mem_slice0),\n      pixbuf(pixbuf0),\n      error_message(std::move(error_message0)) {}\n\nDecodeImageResult::DecodeImageResult(std::string&& error_message0)\n    : pixbuf_mem_owner(nullptr, &free),\n      pixbuf_mem_slice(wuffs_base__empty_slice_u8()),\n      pixbuf(wuffs_base__null_pixel_buffer()),\n      error_message(std::move(error_message0)) {}\n\nDecodeImageCallbacks::~DecodeImageCallbacks() {}\n\nDecodeImageCallbacks::AllocResult::AllocResult(MemOwner&& mem_owner0,\n                            " +
-	"                   wuffs_base__slice_u8 mem_slice0)\n    : mem_owner(std::move(mem_owner0)),\n      mem_slice(mem_slice0),\n      error_message(\"\") {}\n\nDecodeImageCallbacks::AllocResult::AllocResult(std::string&& error_message0)\n    : mem_owner(nullptr, &free),\n      mem_slice(wuffs_base__empty_slice_u8()),\n      error_message(std::move(error_message0)) {}\n\nwuffs_base__image_decoder::unique_ptr  //\nDecodeImageCallbacks::SelectDecoder(uint32_t fourcc,\n                                    wuffs_base__slice_u8 prefix) {\n  switch (fourcc) {\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)\n    case WUFFS_BASE__FOURCC__BMP:\n      return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)\n    case WUFFS_BASE__FOURCC__GIF:\n      return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)\n    case WUFFS_BASE__FOURCC__NIE:\n " +
-	"     return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)\n    case WUFFS_BASE__FOURCC__PNG: {\n      auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();\n      // Favor faster decodes over rejecting invalid checksums.\n      dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);\n      return dec;\n    }\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)\n    case WUFFS_BASE__FOURCC__WBMP:\n      return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n  }\n\n  return wuffs_base__image_decoder::unique_ptr(nullptr, &free);\n}\n\nwuffs_base__pixel_format  //\nDecodeImageCallbacks::SelectPixfmt(\n    const wuffs_base__image_config& image_config) {\n  return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);\n}\n\nDecodeImageCallbacks::AllocResult  //\nDecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,\n             " +
-	"                     bool allow_uninitialized_memory) {\n  uint32_t w = image_config.pixcfg.width();\n  uint32_t h = image_config.pixcfg.height();\n  if ((w == 0) || (h == 0)) {\n    return AllocResult(\"\");\n  }\n  uint64_t len = image_config.pixcfg.pixbuf_len();\n  if ((len == 0) || (SIZE_MAX < len)) {\n    return AllocResult(DecodeImage_UnsupportedPixelConfiguration);\n  }\n  void* ptr =\n      allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);\n  return ptr ? AllocResult(\n                   MemOwner(ptr, &free),\n                   wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len))\n             : AllocResult(DecodeImage_OutOfMemory);\n}\n\nDecodeImageCallbacks::AllocResult  //\nDecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,\n                                   bool allow_uninitialized_memory) {\n  uint64_t len = len_range.max_incl;\n  if (len == 0) {\n    return AllocResult(\"\");\n  } else if (SIZE_MAX < len) {\n    return AllocResult(DecodeImage_OutOfMemory);\n  }\n  void* ptr =\n " +
-	"     allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);\n  return ptr ? AllocResult(\n                   MemOwner(ptr, &free),\n                   wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len))\n             : AllocResult(DecodeImage_OutOfMemory);\n}\n\nvoid  //\nDecodeImageCallbacks::Done(\n    DecodeImageResult& result,\n    sync_io::Input& input,\n    IOBuffer& buffer,\n    wuffs_base__image_decoder::unique_ptr image_decoder) {}\n\nconst char DecodeImage_BufferIsTooShort[] =  //\n    \"wuffs_aux::DecodeImage: buffer is too short\";\nconst char DecodeImage_MaxInclDimensionExceeded[] =  //\n    \"wuffs_aux::DecodeImage: max_incl_dimension exceeded\";\nconst char DecodeImage_OutOfMemory[] =  //\n    \"wuffs_aux::DecodeImage: out of memory\";\nconst char DecodeImage_UnexpectedEndOfFile[] =  //\n    \"wuffs_aux::DecodeImage: unexpected end of file\";\nconst char DecodeImage_UnsupportedImageFormat[] =  //\n    \"wuffs_aux::DecodeImage: unsupported image format\";\nconst char DecodeImage_UnsupportedPixelBlend[] =  " +
-	"//\n    \"wuffs_aux::DecodeImage: unsupported pixel blend\";\nconst char DecodeImage_UnsupportedPixelConfiguration[] =  //\n    \"wuffs_aux::DecodeImage: unsupported pixel configuration\";\nconst char DecodeImage_UnsupportedPixelFormat[] =  //\n    \"wuffs_aux::DecodeImage: unsupported pixel format\";\n\n" +
+	"// ---------------- Auxiliary - Image\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)\n\n#include <utility>\n\nnamespace wuffs_aux {\n\nDecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,\n                                     wuffs_base__pixel_buffer pixbuf0,\n                                     std::string&& error_message0)\n    : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),\n      pixbuf(pixbuf0),\n      error_message(std::move(error_message0)) {}\n\nDecodeImageResult::DecodeImageResult(std::string&& error_message0)\n    : pixbuf_mem_owner(nullptr, &free),\n      pixbuf(wuffs_base__null_pixel_buffer()),\n      error_message(std::move(error_message0)) {}\n\nDecodeImageCallbacks::~DecodeImageCallbacks() {}\n\nDecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(\n    MemOwner&& mem_owner0,\n    wuffs_base__pixel_buffer pixbuf0)\n    : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message(\"\") {}\n\nDecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(\n    std:" +
+	":string&& error_message0)\n    : mem_owner(nullptr, &free),\n      pixbuf(wuffs_base__null_pixel_buffer()),\n      error_message(std::move(error_message0)) {}\n\nDecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(\n    MemOwner&& mem_owner0,\n    wuffs_base__slice_u8 workbuf0)\n    : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message(\"\") {}\n\nDecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(\n    std::string&& error_message0)\n    : mem_owner(nullptr, &free),\n      workbuf(wuffs_base__empty_slice_u8()),\n      error_message(std::move(error_message0)) {}\n\nwuffs_base__image_decoder::unique_ptr  //\nDecodeImageCallbacks::SelectDecoder(uint32_t fourcc,\n                                    wuffs_base__slice_u8 prefix) {\n  switch (fourcc) {\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)\n    case WUFFS_BASE__FOURCC__BMP:\n      return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE" +
+	"__GIF)\n    case WUFFS_BASE__FOURCC__GIF:\n      return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)\n    case WUFFS_BASE__FOURCC__NIE:\n      return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)\n    case WUFFS_BASE__FOURCC__PNG: {\n      auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();\n      // Favor faster decodes over rejecting invalid checksums.\n      dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);\n      return dec;\n    }\n#endif\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)\n    case WUFFS_BASE__FOURCC__WBMP:\n      return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();\n#endif\n  }\n\n  return wuffs_base__image_decoder::unique_ptr(nullptr, &free);\n}\n\nwuffs_base__pixel_format  //\nDecodeImageCallbacks::SelectPixfmt(\n    const wuffs_base__image_config&" +
+	" image_config) {\n  return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);\n}\n\nDecodeImageCallbacks::AllocPixbufResult  //\nDecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,\n                                  bool allow_uninitialized_memory) {\n  uint32_t w = image_config.pixcfg.width();\n  uint32_t h = image_config.pixcfg.height();\n  if ((w == 0) || (h == 0)) {\n    return AllocPixbufResult(\"\");\n  }\n  uint64_t len = image_config.pixcfg.pixbuf_len();\n  if ((len == 0) || (SIZE_MAX < len)) {\n    return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);\n  }\n  void* ptr =\n      allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);\n  if (!ptr) {\n    return AllocPixbufResult(DecodeImage_OutOfMemory);\n  }\n  wuffs_base__pixel_buffer pixbuf;\n  wuffs_base__status status = pixbuf.set_from_slice(\n      &image_config.pixcfg,\n      wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));\n  if (!status.is_ok()) {\n    free(ptr);\n    return AllocPixbu" +
+	"fResult(status.message());\n  }\n  return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);\n}\n\nDecodeImageCallbacks::AllocWorkbufResult  //\nDecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,\n                                   bool allow_uninitialized_memory) {\n  uint64_t len = len_range.max_incl;\n  if (len == 0) {\n    return AllocWorkbufResult(\"\");\n  } else if (SIZE_MAX < len) {\n    return AllocWorkbufResult(DecodeImage_OutOfMemory);\n  }\n  void* ptr =\n      allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);\n  if (!ptr) {\n    return AllocWorkbufResult(DecodeImage_OutOfMemory);\n  }\n  return AllocWorkbufResult(\n      MemOwner(ptr, &free),\n      wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));\n}\n\nvoid  //\nDecodeImageCallbacks::Done(\n    DecodeImageResult& result,\n    sync_io::Input& input,\n    IOBuffer& buffer,\n    wuffs_base__image_decoder::unique_ptr image_decoder) {}\n\nconst char DecodeImage_BufferIsTooShort[] =  //\n    \"wuffs_aux::DecodeImage: buffer is too short" +
+	"\";\nconst char DecodeImage_MaxInclDimensionExceeded[] =  //\n    \"wuffs_aux::DecodeImage: max_incl_dimension exceeded\";\nconst char DecodeImage_OutOfMemory[] =  //\n    \"wuffs_aux::DecodeImage: out of memory\";\nconst char DecodeImage_UnexpectedEndOfFile[] =  //\n    \"wuffs_aux::DecodeImage: unexpected end of file\";\nconst char DecodeImage_UnsupportedImageFormat[] =  //\n    \"wuffs_aux::DecodeImage: unsupported image format\";\nconst char DecodeImage_UnsupportedPixelBlend[] =  //\n    \"wuffs_aux::DecodeImage: unsupported pixel blend\";\nconst char DecodeImage_UnsupportedPixelConfiguration[] =  //\n    \"wuffs_aux::DecodeImage: unsupported pixel configuration\";\nconst char DecodeImage_UnsupportedPixelFormat[] =  //\n    \"wuffs_aux::DecodeImage: unsupported pixel format\";\n\n" +
 	"" +
 	"// --------\n\nnamespace {\n\nstd::string  //\nDecodeImageAdvanceIOBuf(sync_io::Input& input,\n                        wuffs_base__io_buffer& io_buf,\n                        bool compactable,\n                        uint64_t min_excl_pos,\n                        uint64_t pos) {\n  if ((pos <= min_excl_pos) || (pos < io_buf.reader_position())) {\n    // Redirects must go forward.\n    return DecodeImage_UnsupportedImageFormat;\n  }\n  while (true) {\n    uint64_t relative_pos = pos - io_buf.reader_position();\n    if (relative_pos <= io_buf.reader_length()) {\n      io_buf.meta.ri += (size_t)relative_pos;\n      break;\n    } else if (io_buf.meta.closed) {\n      return DecodeImage_UnexpectedEndOfFile;\n    }\n    io_buf.meta.ri = io_buf.meta.wi;\n    if (compactable) {\n      io_buf.compact();\n    }\n    std::string error_message = input.CopyIn(&io_buf);\n    if (!error_message.empty()) {\n      return error_message;\n    }\n  }\n  return \"\";\n}\n\nDecodeImageResult  //\nDecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,\n  " +
 	"           DecodeImageCallbacks& callbacks,\n             sync_io::Input& input,\n             wuffs_base__io_buffer& io_buf,\n             wuffs_base__pixel_blend pixel_blend,\n             wuffs_base__color_u32_argb_premul background_color,\n             uint32_t max_incl_dimension) {\n  // Check args.\n  switch (pixel_blend) {\n    case WUFFS_BASE__PIXEL_BLEND__SRC:\n    case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:\n      break;\n    default:\n      return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);\n  }\n\n  wuffs_base__image_config image_config = wuffs_base__null_image_config();\n  uint64_t start_pos = io_buf.reader_position();\n  bool redirected = false;\n  int32_t fourcc = 0;\nredirect:\n  do {\n    // Determine the image format.\n    if (!redirected) {\n      while (true) {\n        fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice());\n        if (fourcc > 0) {\n          break;\n        } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {\n          break;\n        } else if (io_buf.meta.closed ||" +
 	" (io_buf.writer_length() == 0)) {\n          fourcc = 0;\n          break;\n        }\n        std::string error_message = input.CopyIn(&io_buf);\n        if (!error_message.empty()) {\n          return DecodeImageResult(std::move(error_message));\n        }\n      }\n    } else {\n      wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();\n      wuffs_base__more_information minfo = wuffs_base__empty_more_information();\n      wuffs_base__status tmm_status =\n          image_decoder->tell_me_more(&empty, &minfo, &io_buf);\n      if (tmm_status.repr != nullptr) {\n        return DecodeImageResult(tmm_status.message());\n      }\n      if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {\n        return DecodeImageResult(DecodeImage_UnsupportedImageFormat);\n      }\n      uint64_t pos = minfo.io_redirect__range().min_incl;\n      std::string error_message = DecodeImageAdvanceIOBuf(\n          input, io_buf, !input.BringsItsOwnIOBuffer(), start_pos, pos);\n      if (!error_message.empty()) {\n        return" +
 	" DecodeImageResult(std::move(error_message));\n      }\n      fourcc = (int32_t)(minfo.io_redirect__fourcc());\n      if (fourcc == 0) {\n        return DecodeImageResult(DecodeImage_UnsupportedImageFormat);\n      }\n      image_decoder.reset();\n    }\n\n    // Select the image decoder.\n    image_decoder = callbacks.SelectDecoder(\n        (uint32_t)fourcc,\n        fourcc ? wuffs_base__empty_slice_u8() : io_buf.reader_slice());\n    if (!image_decoder) {\n      return DecodeImageResult(DecodeImage_UnsupportedImageFormat);\n    }\n\n    // Decode the image config.\n    while (true) {\n      wuffs_base__status id_dic_status =\n          image_decoder->decode_image_config(&image_config, &io_buf);\n      if (id_dic_status.repr == nullptr) {\n        break;\n      } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {\n        if (redirected) {\n          return DecodeImageResult(DecodeImage_UnsupportedImageFormat);\n        }\n        redirected = true;\n        goto redirect;\n      } else if (id_dic_status.repr != wuffs_bas" +
 	"e__suspension__short_read) {\n        return DecodeImageResult(id_dic_status.message());\n      } else if (io_buf.meta.closed) {\n        return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);\n      } else {\n        std::string error_message = input.CopyIn(&io_buf);\n        if (!error_message.empty()) {\n          return DecodeImageResult(std::move(error_message));\n        }\n      }\n    }\n  } while (false);\n\n  // Select the pixel format.\n  uint32_t w = image_config.pixcfg.width();\n  uint32_t h = image_config.pixcfg.height();\n  if ((w > max_incl_dimension) || (h > max_incl_dimension)) {\n    return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);\n  }\n  wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);\n  if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {\n    switch (pixel_format.repr) {\n      case WUFFS_BASE__PIXEL_FORMAT__BGR_565:\n      case WUFFS_BASE__PIXEL_FORMAT__BGR:\n      case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n      case WUFFS_BASE__PIXEL_FORMAT" +
-	"__BGRA_NONPREMUL_4X16LE:\n      case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n      case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:\n      case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:\n        break;\n      default:\n        return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);\n    }\n    image_config.pixcfg.set(pixel_format.repr,\n                            WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);\n  }\n\n  // Allocate the pixel buffer.\n  uint64_t pixbuf_len_min_incl = 0;\n  if ((w > 0) && (h > 0)) {\n    pixbuf_len_min_incl = image_config.pixcfg.pixbuf_len();\n    if (pixbuf_len_min_incl == 0) {\n      return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);\n    }\n  }\n  bool valid_background_color =\n      wuffs_base__color_u32_argb_premul__is_valid(background_color);\n  DecodeImageCallbacks::AllocResult alloc_pixbuf_result =\n      callbacks.AllocPixbuf(image_config, valid_background_color);\n  if (!alloc_pixbuf_result.error_message.empty()) {\n    return DecodeImageResult(std::move(alloc_pixbuf_result.error_mes" +
-	"sage));\n  } else if (alloc_pixbuf_result.mem_slice.len < pixbuf_len_min_incl) {\n    return DecodeImageResult(DecodeImage_BufferIsTooShort);\n  }\n  wuffs_base__pixel_buffer pixel_buffer;\n  wuffs_base__status pb_sfs_status = pixel_buffer.set_from_slice(\n      &image_config.pixcfg, alloc_pixbuf_result.mem_slice);\n  if (!pb_sfs_status.is_ok()) {\n    return DecodeImageResult(pb_sfs_status.message());\n  }\n  if (valid_background_color) {\n    wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(\n        pixel_buffer.pixcfg.bounds(), background_color);\n    if (pb_scufr_status.repr != nullptr) {\n      return DecodeImageResult(pb_scufr_status.message());\n    }\n  }\n\n  // Allocate the work buffer. Wuffs' decoders conventionally assume that this\n  // can be uninitialized memory.\n  wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();\n  DecodeImageCallbacks::AllocResult alloc_workbuf_result =\n      callbacks.AllocWorkbuf(workbuf_len, true);\n  if (!alloc_workbuf_result.error_message.empty()" +
-	") {\n    return DecodeImageResult(std::move(alloc_workbuf_result.error_message));\n  } else if (alloc_workbuf_result.mem_slice.len < workbuf_len.min_incl) {\n    return DecodeImageResult(DecodeImage_BufferIsTooShort);\n  }\n\n  // Decode the frame config.\n  wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();\n  while (true) {\n    wuffs_base__status id_dfc_status =\n        image_decoder->decode_frame_config(&frame_config, &io_buf);\n    if (id_dfc_status.repr == nullptr) {\n      break;\n    } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {\n      return DecodeImageResult(id_dfc_status.message());\n    } else if (io_buf.meta.closed) {\n      return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);\n    } else {\n      std::string error_message = input.CopyIn(&io_buf);\n      if (!error_message.empty()) {\n        return DecodeImageResult(std::move(error_message));\n      }\n    }\n  }\n\n  // Decode the frame (the pixels).\n  //\n  // From here on, always returns the pixel_buffer. If we get" +
-	" this far, we can\n  // still display a partial image, even if we encounter an error.\n  std::string message(\"\");\n  if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&\n      frame_config.overwrite_instead_of_blend()) {\n    pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;\n  }\n  while (true) {\n    wuffs_base__status id_df_status =\n        image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,\n                                    alloc_workbuf_result.mem_slice, nullptr);\n    if (id_df_status.repr == nullptr) {\n      break;\n    } else if (id_df_status.repr != wuffs_base__suspension__short_read) {\n      message = id_df_status.message();\n      break;\n    } else if (io_buf.meta.closed) {\n      message = DecodeImage_UnexpectedEndOfFile;\n      break;\n    } else {\n      std::string error_message = input.CopyIn(&io_buf);\n      if (!error_message.empty()) {\n        message = std::move(error_message);\n        break;\n      }\n    }\n  }\n  return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),\n            " +
-	"               alloc_pixbuf_result.mem_slice, pixel_buffer,\n                           std::move(message));\n}\n\n}  // namespace\n\nDecodeImageResult  //\nDecodeImage(DecodeImageCallbacks& callbacks,\n            sync_io::Input& input,\n            wuffs_base__pixel_blend pixel_blend,\n            wuffs_base__color_u32_argb_premul background_color,\n            uint32_t max_incl_dimension) {\n  wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();\n  wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();\n  std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);\n  if (!io_buf) {\n    fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);\n    fallback_io_buf =\n        wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);\n    io_buf = &fallback_io_buf;\n  }\n\n  wuffs_base__image_decoder::unique_ptr image_decoder(nullptr, &free);\n  DecodeImageResult result =\n      DecodeImage0(image_decoder, callbacks, input, *io_buf, pixel_blend,\n                   background_color, max_incl_dimension" +
-	");\n  callbacks.Done(result, input, *io_buf, std::move(image_decoder));\n  return result;\n}\n\n}  // namespace wuffs_aux\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)\n" +
+	"__BGRA_NONPREMUL_4X16LE:\n      case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n      case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:\n      case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:\n        break;\n      default:\n        return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);\n    }\n    image_config.pixcfg.set(pixel_format.repr,\n                            WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);\n  }\n\n  // Allocate the pixel buffer.\n  bool valid_background_color =\n      wuffs_base__color_u32_argb_premul__is_valid(background_color);\n  DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =\n      callbacks.AllocPixbuf(image_config, valid_background_color);\n  if (!alloc_pixbuf_result.error_message.empty()) {\n    return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));\n  }\n  wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;\n  if (valid_background_color) {\n    wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(\n        pixel_buffer.pixcfg.bounds(), b" +
+	"ackground_color);\n    if (pb_scufr_status.repr != nullptr) {\n      return DecodeImageResult(pb_scufr_status.message());\n    }\n  }\n\n  // Allocate the work buffer. Wuffs' decoders conventionally assume that this\n  // can be uninitialized memory.\n  wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();\n  DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =\n      callbacks.AllocWorkbuf(workbuf_len, true);\n  if (!alloc_workbuf_result.error_message.empty()) {\n    return DecodeImageResult(std::move(alloc_workbuf_result.error_message));\n  } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {\n    return DecodeImageResult(DecodeImage_BufferIsTooShort);\n  }\n\n  // Decode the frame config.\n  wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();\n  while (true) {\n    wuffs_base__status id_dfc_status =\n        image_decoder->decode_frame_config(&frame_config, &io_buf);\n    if (id_dfc_status.repr == nullptr) {\n      break;\n    } else if (id_dfc_status.repr != wuffs_b" +
+	"ase__suspension__short_read) {\n      return DecodeImageResult(id_dfc_status.message());\n    } else if (io_buf.meta.closed) {\n      return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);\n    } else {\n      std::string error_message = input.CopyIn(&io_buf);\n      if (!error_message.empty()) {\n        return DecodeImageResult(std::move(error_message));\n      }\n    }\n  }\n\n  // Decode the frame (the pixels).\n  //\n  // From here on, always returns the pixel_buffer. If we get this far, we can\n  // still display a partial image, even if we encounter an error.\n  std::string message(\"\");\n  if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&\n      frame_config.overwrite_instead_of_blend()) {\n    pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;\n  }\n  while (true) {\n    wuffs_base__status id_df_status =\n        image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,\n                                    alloc_workbuf_result.workbuf, nullptr);\n    if (id_df_status.repr == nullptr) {\n      break;\n    } else if (" +
+	"id_df_status.repr != wuffs_base__suspension__short_read) {\n      message = id_df_status.message();\n      break;\n    } else if (io_buf.meta.closed) {\n      message = DecodeImage_UnexpectedEndOfFile;\n      break;\n    } else {\n      std::string error_message = input.CopyIn(&io_buf);\n      if (!error_message.empty()) {\n        message = std::move(error_message);\n        break;\n      }\n    }\n  }\n  return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),\n                           pixel_buffer, std::move(message));\n}\n\n}  // namespace\n\nDecodeImageResult  //\nDecodeImage(DecodeImageCallbacks& callbacks,\n            sync_io::Input& input,\n            wuffs_base__pixel_blend pixel_blend,\n            wuffs_base__color_u32_argb_premul background_color,\n            uint32_t max_incl_dimension) {\n  wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();\n  wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();\n  std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);\n  if (!io_buf) {\n    fallba" +
+	"ck_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);\n    fallback_io_buf =\n        wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);\n    io_buf = &fallback_io_buf;\n  }\n\n  wuffs_base__image_decoder::unique_ptr image_decoder(nullptr, &free);\n  DecodeImageResult result =\n      DecodeImage0(image_decoder, callbacks, input, *io_buf, pixel_blend,\n                   background_color, max_incl_dimension);\n  callbacks.Done(result, input, *io_buf, std::move(image_decoder));\n  return result;\n}\n\n}  // namespace wuffs_aux\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)\n" +
 	""
 
 const AuxImageHh = "" +
-	"// ---------------- Auxiliary - Image\n\nnamespace wuffs_aux {\n\nstruct DecodeImageResult {\n  DecodeImageResult(MemOwner&& pixbuf_mem_owner0,\n                    wuffs_base__slice_u8 pixbuf_mem_slice0,\n                    wuffs_base__pixel_buffer pixbuf0,\n                    std::string&& error_message0);\n  DecodeImageResult(std::string&& error_message0);\n\n  MemOwner pixbuf_mem_owner;\n  wuffs_base__slice_u8 pixbuf_mem_slice;\n  wuffs_base__pixel_buffer pixbuf;\n  std::string error_message;\n};\n\n// DecodeImageCallbacks are the callbacks given to DecodeImage. They are always\n// called in this order:\n//  1. SelectDecoder\n//  2. SelectPixfmt\n//  3. AllocPixbuf\n//  4. AllocWorkbuf\n//  5. Done\n//\n// It may return early - the third callback might not be invoked if the second\n// one fails - but the final callback (Done) is always invoked.\nclass DecodeImageCallbacks {\n public:\n  // AllocResult holds a memory allocation (the result of malloc or new, a\n  // statically allocated pointer, etc), or an error message. The memory i" +
-	"s\n  // de-allocated when mem_owner goes out of scope and is destroyed.\n  struct AllocResult {\n    AllocResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 mem_slice0);\n    AllocResult(std::string&& error_message0);\n\n    MemOwner mem_owner;\n    wuffs_base__slice_u8 mem_slice;\n    std::string error_message;\n  };\n\n  virtual ~DecodeImageCallbacks();\n\n  // SelectDecoder returns the image decoder for the input data's file format.\n  // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).\n  //\n  // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],\n  // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that the\n  // caller is responsible for examining the opening bytes (a prefix) of the\n  // input data. SelectDecoder implementations should not modify those bytes.\n  //\n  // SelectDecoder might be called more than once, since some image file\n  // formats can wrap others. For example, a nominal BMP file can actually\n  // contain a JPEG or a PNG.\n  //\n  // The default Se" +
-	"lectDecoder accepts the FOURCC codes listed below. For\n  // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance\n  // of the ETC file format is optional (for each value of ETC) and depends on\n  // the corresponding module to be enabled at compile time (i.e. #define'ing\n  // WUFFS_CONFIG__MODULE__ETC).\n  //  - WUFFS_BASE__FOURCC__BMP\n  //  - WUFFS_BASE__FOURCC__GIF\n  //  - WUFFS_BASE__FOURCC__NIE\n  //  - WUFFS_BASE__FOURCC__PNG\n  //  - WUFFS_BASE__FOURCC__WBMP\n  virtual wuffs_base__image_decoder::unique_ptr  //\n  SelectDecoder(uint32_t fourcc, wuffs_base__slice_u8 prefix);\n\n  // SelectPixfmt returns the destination pixel format for AllocPixbuf. It\n  // should return wuffs_base__make_pixel_format(etc) called with one of:\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGR_565\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGR\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL\n  //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPR" +
-	"EMUL\n  //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL\n  // or return image_config.pixcfg.pixel_format(). The latter means to use the\n  // image file's natural pixel format. For example, GIF images' natural pixel\n  // format is an indexed one.\n  //\n  // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).\n  //\n  // The default SelectPixfmt implementation returns\n  // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which\n  // is 4 bytes per pixel (8 bits per channel × 4 channels).\n  virtual wuffs_base__pixel_format  //\n  SelectPixfmt(const wuffs_base__image_config& image_config);\n\n  // AllocPixbuf allocates the pixel buffer.\n  //\n  // allow_uninitialized_memory will be true if a valid background_color was\n  // passed to DecodeImage, since the pixel buffer's contents will be\n  // overwritten with that color after AllocPixbuf returns.\n  //\n  // The default AllocPixbuf implementation allocates either uninitialized or\n  // zeroed memory. Zeroed memory typically corresponds to f" +
-	"illing with opaque\n  // black or transparent black, depending on the pixel format.\n  virtual AllocResult  //\n  AllocPixbuf(const wuffs_base__image_config& image_config,\n              bool allow_uninitialized_memory);\n\n  // AllocWorkbuf allocates the work buffer. The allocated buffer's length\n  // should be at least len_range.min_incl, but larger allocations (up to\n  // len_range.max_incl) may have better performance (by using more memory).\n  //\n  // The default AllocWorkbuf implementation allocates len_range.max_incl bytes\n  // of either uninitialized or zeroed memory.\n  virtual AllocResult  //\n  AllocWorkbuf(wuffs_base__range_ii_u64 len_range,\n               bool allow_uninitialized_memory);\n\n  // Done is always the last Callback method called by DecodeImage, whether or\n  // not parsing the input encountered an error. Even when successful, trailing\n  // data may remain in input and buffer.\n  //\n  // The image_decoder is the one returned by SelectDecoder (if SelectDecoder\n  // was successful), or a no-op uniq" +
-	"ue_ptr otherwise. Like any unique_ptr,\n  // ownership moves to the Done implementation.\n  //\n  // Do not keep a reference to buffer or buffer.data.ptr after Done returns,\n  // as DecodeImage may then de-allocate the backing array.\n  //\n  // The default Done implementation is a no-op, other than running the\n  // image_decoder unique_ptr destructor.\n  virtual void  //\n  Done(DecodeImageResult& result,\n       sync_io::Input& input,\n       IOBuffer& buffer,\n       wuffs_base__image_decoder::unique_ptr image_decoder);\n};\n\nextern const char DecodeImage_BufferIsTooShort[];\nextern const char DecodeImage_MaxInclDimensionExceeded[];\nextern const char DecodeImage_OutOfMemory[];\nextern const char DecodeImage_UnexpectedEndOfFile[];\nextern const char DecodeImage_UnsupportedImageFormat[];\nextern const char DecodeImage_UnsupportedPixelBlend[];\nextern const char DecodeImage_UnsupportedPixelConfiguration[];\nextern const char DecodeImage_UnsupportedPixelFormat[];\n\n// DecodeImage decodes the image data in input. A variety of ima" +
-	"ge file formats\n// can be decoded, depending on what callbacks.SelectDecoder returns.\n//\n// For animated formats, only the first frame is returned, since the API is\n// simpler for synchronous I/O and having DecodeImage only return when\n// completely done, but rendering animation often involves handling other\n// events in between animation frames. To decode multiple frames of animated\n// images, or for asynchronous I/O (e.g. when decoding an image streamed over\n// the network), use Wuffs' lower level C API instead of its higher level,\n// simplified C++ API (the wuffs_aux API).\n//\n// The DecodeImageResult's fields depend on whether decoding succeeded:\n//  - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()\n//    is true.\n//  - On partial success (e.g. the input file was truncated but we are still\n//    able to decode some of the pixels), error_message is non-empty but\n//    pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to\n//    accept or reject partial success.\n/" +
-	"/  - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()\n//    is false.\n//\n// The callbacks allocate the pixel buffer memory and work buffer memory. On\n// success, pixel buffer memory ownership is passed to the DecodeImage caller\n// as the returned pixbuf_mem_owner. Regardless of success or failure, the work\n// buffer memory is deleted.\n//\n// The pixel_blend (one of the constants listed below) determines how to\n// composite the decoded image over the pixel buffer's original pixels (as\n// returned by callbacks.AllocPixbuf):\n//  - WUFFS_BASE__PIXEL_BLEND__SRC\n//  - WUFFS_BASE__PIXEL_BLEND__SRC_OVER\n//\n// The background_color is used to fill the pixel buffer after\n// callbacks.AllocPixbuf returns, if it is valid in the\n// wuffs_base__color_u32_argb_premul__is_valid sense. The default value,\n// 0x0000_0001, is not valid since its Blue channel value (0x01) is greater\n// than its Alpha channel value (0x00). A valid background_color will typically\n// be overwritten when pixel_blend is WUFFS_BASE" +
-	"__PIXEL_BLEND__SRC, but might\n// still be visible on partial (not total) success or when pixel_blend is\n// WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.\n//\n// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's\n// width or height is greater than max_incl_dimension.\nDecodeImageResult  //\nDecodeImage(DecodeImageCallbacks& callbacks,\n            sync_io::Input& input,\n            wuffs_base__pixel_blend pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC,\n            wuffs_base__color_u32_argb_premul background_color = 1,  // Invalid.\n            uint32_t max_incl_dimension = 1048575);  // 0x000F_FFFF\n\n}  // namespace wuffs_aux\n" +
+	"// ---------------- Auxiliary - Image\n\nnamespace wuffs_aux {\n\nstruct DecodeImageResult {\n  DecodeImageResult(MemOwner&& pixbuf_mem_owner0,\n                    wuffs_base__pixel_buffer pixbuf0,\n                    std::string&& error_message0);\n  DecodeImageResult(std::string&& error_message0);\n\n  MemOwner pixbuf_mem_owner;\n  wuffs_base__pixel_buffer pixbuf;\n  std::string error_message;\n};\n\n// DecodeImageCallbacks are the callbacks given to DecodeImage. They are always\n// called in this order:\n//  1. SelectDecoder\n//  2. SelectPixfmt\n//  3. AllocPixbuf\n//  4. AllocWorkbuf\n//  5. Done\n//\n// It may return early - the third callback might not be invoked if the second\n// one fails - but the final callback (Done) is always invoked.\nclass DecodeImageCallbacks {\n public:\n  // AllocPixbufResult holds a memory allocation (the result of malloc or new,\n  // a statically allocated pointer, etc), or an error message. The memory is\n  // de-allocated when mem_owner goes out of scope and is destroyed.\n  struct AllocPixbufResu" +
+	"lt {\n    AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);\n    AllocPixbufResult(std::string&& error_message0);\n\n    MemOwner mem_owner;\n    wuffs_base__pixel_buffer pixbuf;\n    std::string error_message;\n  };\n\n  // AllocWorkbufResult holds a memory allocation (the result of malloc or new,\n  // a statically allocated pointer, etc), or an error message. The memory is\n  // de-allocated when mem_owner goes out of scope and is destroyed.\n  struct AllocWorkbufResult {\n    AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);\n    AllocWorkbufResult(std::string&& error_message0);\n\n    MemOwner mem_owner;\n    wuffs_base__slice_u8 workbuf;\n    std::string error_message;\n  };\n\n  virtual ~DecodeImageCallbacks();\n\n  // SelectDecoder returns the image decoder for the input data's file format.\n  // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).\n  //\n  // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],\n  // such as WUFFS_BASE__F" +
+	"OURCC__JPEG. A zero FourCC value means that the\n  // caller is responsible for examining the opening bytes (a prefix) of the\n  // input data. SelectDecoder implementations should not modify those bytes.\n  //\n  // SelectDecoder might be called more than once, since some image file\n  // formats can wrap others. For example, a nominal BMP file can actually\n  // contain a JPEG or a PNG.\n  //\n  // The default SelectDecoder accepts the FOURCC codes listed below. For\n  // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance\n  // of the ETC file format is optional (for each value of ETC) and depends on\n  // the corresponding module to be enabled at compile time (i.e. #define'ing\n  // WUFFS_CONFIG__MODULE__ETC).\n  //  - WUFFS_BASE__FOURCC__BMP\n  //  - WUFFS_BASE__FOURCC__GIF\n  //  - WUFFS_BASE__FOURCC__NIE\n  //  - WUFFS_BASE__FOURCC__PNG\n  //  - WUFFS_BASE__FOURCC__WBMP\n  virtual wuffs_base__image_decoder::unique_ptr  //\n  SelectDecoder(uint32_t fourcc, wuffs_base__slice_u8 prefix);\n\n  // SelectPix" +
+	"fmt returns the destination pixel format for AllocPixbuf. It\n  // should return wuffs_base__make_pixel_format(etc) called with one of:\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGR_565\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGR\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE\n  //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL\n  //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL\n  //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL\n  // or return image_config.pixcfg.pixel_format(). The latter means to use the\n  // image file's natural pixel format. For example, GIF images' natural pixel\n  // format is an indexed one.\n  //\n  // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).\n  //\n  // The default SelectPixfmt implementation returns\n  // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which\n  // is 4 bytes per pixel (8 bits per channel × 4 channels).\n  virtual wuffs_base__pixel_format  //\n  SelectPixfmt(const wuffs_base__image_config& image_" +
+	"config);\n\n  // AllocPixbuf allocates the pixel buffer.\n  //\n  // allow_uninitialized_memory will be true if a valid background_color was\n  // passed to DecodeImage, since the pixel buffer's contents will be\n  // overwritten with that color after AllocPixbuf returns.\n  //\n  // The default AllocPixbuf implementation allocates either uninitialized or\n  // zeroed memory. Zeroed memory typically corresponds to filling with opaque\n  // black or transparent black, depending on the pixel format.\n  virtual AllocPixbufResult  //\n  AllocPixbuf(const wuffs_base__image_config& image_config,\n              bool allow_uninitialized_memory);\n\n  // AllocWorkbuf allocates the work buffer. The allocated buffer's length\n  // should be at least len_range.min_incl, but larger allocations (up to\n  // len_range.max_incl) may have better performance (by using more memory).\n  //\n  // The default AllocWorkbuf implementation allocates len_range.max_incl bytes\n  // of either uninitialized or zeroed memory.\n  virtual AllocWorkbufResult  //" +
+	"\n  AllocWorkbuf(wuffs_base__range_ii_u64 len_range,\n               bool allow_uninitialized_memory);\n\n  // Done is always the last Callback method called by DecodeImage, whether or\n  // not parsing the input encountered an error. Even when successful, trailing\n  // data may remain in input and buffer.\n  //\n  // The image_decoder is the one returned by SelectDecoder (if SelectDecoder\n  // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,\n  // ownership moves to the Done implementation.\n  //\n  // Do not keep a reference to buffer or buffer.data.ptr after Done returns,\n  // as DecodeImage may then de-allocate the backing array.\n  //\n  // The default Done implementation is a no-op, other than running the\n  // image_decoder unique_ptr destructor.\n  virtual void  //\n  Done(DecodeImageResult& result,\n       sync_io::Input& input,\n       IOBuffer& buffer,\n       wuffs_base__image_decoder::unique_ptr image_decoder);\n};\n\nextern const char DecodeImage_BufferIsTooShort[];\nextern const char DecodeImag" +
+	"e_MaxInclDimensionExceeded[];\nextern const char DecodeImage_OutOfMemory[];\nextern const char DecodeImage_UnexpectedEndOfFile[];\nextern const char DecodeImage_UnsupportedImageFormat[];\nextern const char DecodeImage_UnsupportedPixelBlend[];\nextern const char DecodeImage_UnsupportedPixelConfiguration[];\nextern const char DecodeImage_UnsupportedPixelFormat[];\n\n// DecodeImage decodes the image data in input. A variety of image file formats\n// can be decoded, depending on what callbacks.SelectDecoder returns.\n//\n// For animated formats, only the first frame is returned, since the API is\n// simpler for synchronous I/O and having DecodeImage only return when\n// completely done, but rendering animation often involves handling other\n// events in between animation frames. To decode multiple frames of animated\n// images, or for asynchronous I/O (e.g. when decoding an image streamed over\n// the network), use Wuffs' lower level C API instead of its higher level,\n// simplified C++ API (the wuffs_aux API).\n//\n// The DecodeIm" +
+	"ageResult's fields depend on whether decoding succeeded:\n//  - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()\n//    is true.\n//  - On partial success (e.g. the input file was truncated but we are still\n//    able to decode some of the pixels), error_message is non-empty but\n//    pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to\n//    accept or reject partial success.\n//  - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()\n//    is false.\n//\n// The callbacks allocate the pixel buffer memory and work buffer memory. On\n// success, pixel buffer memory ownership is passed to the DecodeImage caller\n// as the returned pixbuf_mem_owner. Regardless of success or failure, the work\n// buffer memory is deleted.\n//\n// The pixel_blend (one of the constants listed below) determines how to\n// composite the decoded image over the pixel buffer's original pixels (as\n// returned by callbacks.AllocPixbuf):\n//  - WUFFS_BASE__PIXEL_BLEND__SRC\n//  - WUFFS_BASE" +
+	"__PIXEL_BLEND__SRC_OVER\n//\n// The background_color is used to fill the pixel buffer after\n// callbacks.AllocPixbuf returns, if it is valid in the\n// wuffs_base__color_u32_argb_premul__is_valid sense. The default value,\n// 0x0000_0001, is not valid since its Blue channel value (0x01) is greater\n// than its Alpha channel value (0x00). A valid background_color will typically\n// be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might\n// still be visible on partial (not total) success or when pixel_blend is\n// WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.\n//\n// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's\n// width or height is greater than max_incl_dimension.\nDecodeImageResult  //\nDecodeImage(DecodeImageCallbacks& callbacks,\n            sync_io::Input& input,\n            wuffs_base__pixel_blend pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC,\n            wuffs_base__color_u32_argb_premul background_color = 1,  // Invalid.\n            uint32_" +
+	"t max_incl_dimension = 1048575);  // 0x000F_FFFF\n\n}  // namespace wuffs_aux\n" +
 	""
 
 const AuxJsonCc = "" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 0ac8a62..52c326f 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -1287,6 +1287,58 @@
 }
 
 static inline wuffs_base__table_u8  //
+wuffs_base__make_table_u8(uint8_t* ptr,
+                          size_t width,
+                          size_t height,
+                          size_t stride) {
+  wuffs_base__table_u8 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u16  //
+wuffs_base__make_table_u16(uint16_t* ptr,
+                           size_t width,
+                           size_t height,
+                           size_t stride) {
+  wuffs_base__table_u16 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u32  //
+wuffs_base__make_table_u32(uint32_t* ptr,
+                           size_t width,
+                           size_t height,
+                           size_t stride) {
+  wuffs_base__table_u32 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u64  //
+wuffs_base__make_table_u64(uint64_t* ptr,
+                           size_t width,
+                           size_t height,
+                           size_t stride) {
+  wuffs_base__table_u64 ret;
+  ret.ptr = ptr;
+  ret.width = width;
+  ret.height = height;
+  ret.stride = stride;
+  return ret;
+}
+
+static inline wuffs_base__table_u8  //
 wuffs_base__empty_table_u8() {
   wuffs_base__table_u8 ret;
   ret.ptr = NULL;
@@ -9571,13 +9623,11 @@
 
 struct DecodeImageResult {
   DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
-                    wuffs_base__slice_u8 pixbuf_mem_slice0,
                     wuffs_base__pixel_buffer pixbuf0,
                     std::string&& error_message0);
   DecodeImageResult(std::string&& error_message0);
 
   MemOwner pixbuf_mem_owner;
-  wuffs_base__slice_u8 pixbuf_mem_slice;
   wuffs_base__pixel_buffer pixbuf;
   std::string error_message;
 };
@@ -9594,15 +9644,27 @@
 // one fails - but the final callback (Done) is always invoked.
 class DecodeImageCallbacks {
  public:
-  // AllocResult holds a memory allocation (the result of malloc or new, a
-  // statically allocated pointer, etc), or an error message. The memory is
+  // AllocPixbufResult holds a memory allocation (the result of malloc or new,
+  // a statically allocated pointer, etc), or an error message. The memory is
   // de-allocated when mem_owner goes out of scope and is destroyed.
-  struct AllocResult {
-    AllocResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 mem_slice0);
-    AllocResult(std::string&& error_message0);
+  struct AllocPixbufResult {
+    AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
+    AllocPixbufResult(std::string&& error_message0);
 
     MemOwner mem_owner;
-    wuffs_base__slice_u8 mem_slice;
+    wuffs_base__pixel_buffer pixbuf;
+    std::string error_message;
+  };
+
+  // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
+  // a statically allocated pointer, etc), or an error message. The memory is
+  // de-allocated when mem_owner goes out of scope and is destroyed.
+  struct AllocWorkbufResult {
+    AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
+    AllocWorkbufResult(std::string&& error_message0);
+
+    MemOwner mem_owner;
+    wuffs_base__slice_u8 workbuf;
     std::string error_message;
   };
 
@@ -9663,7 +9725,7 @@
   // The default AllocPixbuf implementation allocates either uninitialized or
   // zeroed memory. Zeroed memory typically corresponds to filling with opaque
   // black or transparent black, depending on the pixel format.
-  virtual AllocResult  //
+  virtual AllocPixbufResult  //
   AllocPixbuf(const wuffs_base__image_config& image_config,
               bool allow_uninitialized_memory);
 
@@ -9673,7 +9735,7 @@
   //
   // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
   // of either uninitialized or zeroed memory.
-  virtual AllocResult  //
+  virtual AllocWorkbufResult  //
   AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
                bool allow_uninitialized_memory);
 
@@ -38965,31 +39027,39 @@
 namespace wuffs_aux {
 
 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
-                                     wuffs_base__slice_u8 pixbuf_mem_slice0,
                                      wuffs_base__pixel_buffer pixbuf0,
                                      std::string&& error_message0)
     : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
-      pixbuf_mem_slice(pixbuf_mem_slice0),
       pixbuf(pixbuf0),
       error_message(std::move(error_message0)) {}
 
 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
     : pixbuf_mem_owner(nullptr, &free),
-      pixbuf_mem_slice(wuffs_base__empty_slice_u8()),
       pixbuf(wuffs_base__null_pixel_buffer()),
       error_message(std::move(error_message0)) {}
 
 DecodeImageCallbacks::~DecodeImageCallbacks() {}
 
-DecodeImageCallbacks::AllocResult::AllocResult(MemOwner&& mem_owner0,
-                                               wuffs_base__slice_u8 mem_slice0)
-    : mem_owner(std::move(mem_owner0)),
-      mem_slice(mem_slice0),
-      error_message("") {}
+DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
+    MemOwner&& mem_owner0,
+    wuffs_base__pixel_buffer pixbuf0)
+    : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
 
-DecodeImageCallbacks::AllocResult::AllocResult(std::string&& error_message0)
+DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
+    std::string&& error_message0)
     : mem_owner(nullptr, &free),
-      mem_slice(wuffs_base__empty_slice_u8()),
+      pixbuf(wuffs_base__null_pixel_buffer()),
+      error_message(std::move(error_message0)) {}
+
+DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
+    MemOwner&& mem_owner0,
+    wuffs_base__slice_u8 workbuf0)
+    : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
+
+DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
+    std::string&& error_message0)
+    : mem_owner(nullptr, &free),
+      workbuf(wuffs_base__empty_slice_u8()),
       error_message(std::move(error_message0)) {}
 
 wuffs_base__image_decoder::unique_ptr  //
@@ -39035,41 +39105,51 @@
   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
 }
 
-DecodeImageCallbacks::AllocResult  //
+DecodeImageCallbacks::AllocPixbufResult  //
 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
                                   bool allow_uninitialized_memory) {
   uint32_t w = image_config.pixcfg.width();
   uint32_t h = image_config.pixcfg.height();
   if ((w == 0) || (h == 0)) {
-    return AllocResult("");
+    return AllocPixbufResult("");
   }
   uint64_t len = image_config.pixcfg.pixbuf_len();
   if ((len == 0) || (SIZE_MAX < len)) {
-    return AllocResult(DecodeImage_UnsupportedPixelConfiguration);
+    return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
   }
   void* ptr =
       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
-  return ptr ? AllocResult(
-                   MemOwner(ptr, &free),
-                   wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len))
-             : AllocResult(DecodeImage_OutOfMemory);
+  if (!ptr) {
+    return AllocPixbufResult(DecodeImage_OutOfMemory);
+  }
+  wuffs_base__pixel_buffer pixbuf;
+  wuffs_base__status status = pixbuf.set_from_slice(
+      &image_config.pixcfg,
+      wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
+  if (!status.is_ok()) {
+    free(ptr);
+    return AllocPixbufResult(status.message());
+  }
+  return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
 }
 
-DecodeImageCallbacks::AllocResult  //
+DecodeImageCallbacks::AllocWorkbufResult  //
 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
                                    bool allow_uninitialized_memory) {
   uint64_t len = len_range.max_incl;
   if (len == 0) {
-    return AllocResult("");
+    return AllocWorkbufResult("");
   } else if (SIZE_MAX < len) {
-    return AllocResult(DecodeImage_OutOfMemory);
+    return AllocWorkbufResult(DecodeImage_OutOfMemory);
   }
   void* ptr =
       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
-  return ptr ? AllocResult(
-                   MemOwner(ptr, &free),
-                   wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len))
-             : AllocResult(DecodeImage_OutOfMemory);
+  if (!ptr) {
+    return AllocWorkbufResult(DecodeImage_OutOfMemory);
+  }
+  return AllocWorkbufResult(
+      MemOwner(ptr, &free),
+      wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
 }
 
 void  //
@@ -39252,28 +39332,14 @@
   }
 
   // Allocate the pixel buffer.
-  uint64_t pixbuf_len_min_incl = 0;
-  if ((w > 0) && (h > 0)) {
-    pixbuf_len_min_incl = image_config.pixcfg.pixbuf_len();
-    if (pixbuf_len_min_incl == 0) {
-      return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
-    }
-  }
   bool valid_background_color =
       wuffs_base__color_u32_argb_premul__is_valid(background_color);
-  DecodeImageCallbacks::AllocResult alloc_pixbuf_result =
+  DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
       callbacks.AllocPixbuf(image_config, valid_background_color);
   if (!alloc_pixbuf_result.error_message.empty()) {
     return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
-  } else if (alloc_pixbuf_result.mem_slice.len < pixbuf_len_min_incl) {
-    return DecodeImageResult(DecodeImage_BufferIsTooShort);
   }
-  wuffs_base__pixel_buffer pixel_buffer;
-  wuffs_base__status pb_sfs_status = pixel_buffer.set_from_slice(
-      &image_config.pixcfg, alloc_pixbuf_result.mem_slice);
-  if (!pb_sfs_status.is_ok()) {
-    return DecodeImageResult(pb_sfs_status.message());
-  }
+  wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
   if (valid_background_color) {
     wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
         pixel_buffer.pixcfg.bounds(), background_color);
@@ -39285,11 +39351,11 @@
   // Allocate the work buffer. Wuffs' decoders conventionally assume that this
   // can be uninitialized memory.
   wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
-  DecodeImageCallbacks::AllocResult alloc_workbuf_result =
+  DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
       callbacks.AllocWorkbuf(workbuf_len, true);
   if (!alloc_workbuf_result.error_message.empty()) {
     return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
-  } else if (alloc_workbuf_result.mem_slice.len < workbuf_len.min_incl) {
+  } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
     return DecodeImageResult(DecodeImage_BufferIsTooShort);
   }
 
@@ -39324,7 +39390,7 @@
   while (true) {
     wuffs_base__status id_df_status =
         image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
-                                    alloc_workbuf_result.mem_slice, nullptr);
+                                    alloc_workbuf_result.workbuf, nullptr);
     if (id_df_status.repr == nullptr) {
       break;
     } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
@@ -39342,8 +39408,7 @@
     }
   }
   return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
-                           alloc_pixbuf_result.mem_slice, pixel_buffer,
-                           std::move(message));
+                           pixel_buffer, std::move(message));
 }
 
 }  // namespace