Spin out base-interfaces sub-module

$ ls -l gen/lib/c/*/{lib*,*base*} | awk '{print $5 " " $9}'

Before:
167952 gen/lib/c/clang-5.0-dynamic/libwuffs.so
 20664 gen/lib/c/clang-5.0-dynamic/wuffs-base-core.lo
205656 gen/lib/c/clang-5.0-static/libwuffs.a
 20960 gen/lib/c/clang-5.0-static/wuffs-base-core.o
188064 gen/lib/c/gcc-dynamic/libwuffs.so
 18936 gen/lib/c/gcc-dynamic/wuffs-base-core.lo
232976 gen/lib/c/gcc-static/libwuffs.a
 18920 gen/lib/c/gcc-static/wuffs-base-core.o

After:
167976 gen/lib/c/clang-5.0-dynamic/libwuffs.so
 13944 gen/lib/c/clang-5.0-dynamic/wuffs-base-core.lo
  8128 gen/lib/c/clang-5.0-dynamic/wuffs-base-interfaces.lo
207150 gen/lib/c/clang-5.0-static/libwuffs.a
 14240 gen/lib/c/clang-5.0-static/wuffs-base-core.o
  8128 gen/lib/c/clang-5.0-static/wuffs-base-interfaces.o
188088 gen/lib/c/gcc-dynamic/libwuffs.so
 13296 gen/lib/c/gcc-dynamic/wuffs-base-core.lo
  7384 gen/lib/c/gcc-dynamic/wuffs-base-interfaces.lo
234766 gen/lib/c/gcc-static/libwuffs.a
 13432 gen/lib/c/gcc-static/wuffs-base-core.o
  7192 gen/lib/c/gcc-static/wuffs-base-interfaces.o
diff --git a/internal/cgen/base/all-impl.c b/internal/cgen/base/all-impl.c
index 931bd1e..2bb67b1 100644
--- a/internal/cgen/base/all-impl.c
+++ b/internal/cgen/base/all-impl.c
@@ -110,7 +110,7 @@
 
 // !! INSERT wuffs_base__status strings.
 
-// !! INSERT InterfaceDefinitions.
+// !! INSERT vtable names.
 
 // !! INSERT base/image-impl.c.
 
@@ -121,6 +121,15 @@
         // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
 
 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+    defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
+
+// !! INSERT InterfaceDefinitions.
+
+#endif  // !defined(WUFFS_CONFIG__MODULES) ||
+        // defined(WUFFS_CONFIG__MODULE__BASE) ||
+        // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
     defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)
 
 // !! INSERT base/f64conv-submodule.c.
diff --git a/internal/cgen/cgen.go b/internal/cgen/cgen.go
index 916c831..313959f 100644
--- a/internal/cgen/cgen.go
+++ b/internal/cgen/cgen.go
@@ -98,6 +98,7 @@
 var BaseSubModules = []string{
 	"core",
 	"f64conv",
+	"interfaces",
 	"pixconv",
 }
 
@@ -133,6 +134,14 @@
 				"// !! INSERT base/image-impl.c.\n":        insertBaseImageImplC,
 				"// !! INSERT base/pixconv-submodule.c.\n": insertBasePixConvSubmoduleC,
 				"// !! INSERT base/strconv-impl.c.\n":      insertBaseStrConvImplC,
+				"// !! INSERT vtable names.\n": func(b *buffer) error {
+					for _, n := range builtin.Interfaces {
+						buf.printf("const char* wuffs_base__%s__vtable_name = "+
+							"\"{vtable}wuffs_base__%s\";\n\n", n, n)
+
+					}
+					return nil
+				},
 				"// !! INSERT wuffs_base__status strings.\n": func(b *buffer) error {
 					for _, z := range builtin.Statuses {
 						msg, _ := t.Unescape(z)
@@ -373,10 +382,13 @@
 	}
 
 	buf.writes("// ---------------- Interface Declarations.\n\n")
-	for i, n := range builtin.Interfaces {
-		if i > 0 {
-			buf.writes("// --------\n\n")
-		}
+
+	buf.writes("// For modular builds that divide the base module into sub-modules, using these\n")
+	buf.writes("// functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not\n")
+	buf.writes("// just WUFFS_CONFIG__MODULE__BASE__CORE.\n\n")
+
+	for _, n := range builtin.Interfaces {
+		buf.writes("// --------\n\n")
 
 		qid := t.QID{t.IDBase, builtInTokenMap.ByName(n)}
 
@@ -456,9 +468,6 @@
 
 		qid := t.QID{t.IDBase, builtInTokenMap.ByName(n)}
 
-		buf.printf("const char* wuffs_base__%s__vtable_name = "+
-			"\"{vtable}wuffs_base__%s\";\n\n", n, n)
-
 		for _, f := range builtInInterfaceMethods[qid] {
 			returnsStatus := f.Effect().Coroutine() ||
 				((f.Out() != nil) && f.Out().IsStatus())
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index c777ef6..cf32c5c 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -23,8 +23,8 @@
 	"" +
 	"// ----------------\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \\\n    defined(WUFFS_CONFIG__MODULE__BASE__CORE)\n\nconst uint8_t wuffs_base__low_bits_mask__u8[9] = {\n    0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF,\n};\n\nconst uint16_t wuffs_base__low_bits_mask__u16[17] = {\n    0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,\n    0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,\n};\n\nconst uint32_t wuffs_base__low_bits_mask__u32[33] = {\n    0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,\n    0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,\n    0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,\n    0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,\n    0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,\n    0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,\n};\n\nconst uint64_t wuffs_base__low_bits_mask__u64[65] = {\n    0x0000000000000000, 0x000" +
 	"0000000000001, 0x0000000000000003,\n    0x0000000000000007, 0x000000000000000F, 0x000000000000001F,\n    0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,\n    0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,\n    0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,\n    0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,\n    0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,\n    0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,\n    0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,\n    0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,\n    0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,\n    0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,\n    0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,\n    0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,\n    0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,\n    0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,\n    0x0000FFFFFFFFFFFF, 0x000" +
-	"1FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,\n    0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,\n    0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,\n    0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,\n    0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,\n    0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,\n};\n\n// !! INSERT wuffs_base__status strings.\n\n// !! INSERT InterfaceDefinitions.\n\n// !! INSERT base/image-impl.c.\n\n// !! INSERT base/strconv-impl.c.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE)  ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__CORE)\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \\\n    defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)\n\n// !! INSERT base/f64conv-submodule.c.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODU" +
-	"LE__BASE) || \\\n    defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)\n\n// !! INSERT base/pixconv-submodule.c.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // WUFFS_IMPLEMENTATION\n\n// !! WUFFS MONOLITHIC RELEASE DISCARDS EVERYTHING BELOW.\n\n#endif  // WUFFS_INCLUDE_GUARD__BASE\n" +
+	"1FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,\n    0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,\n    0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,\n    0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,\n    0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,\n    0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,\n};\n\n// !! INSERT wuffs_base__status strings.\n\n// !! INSERT vtable names.\n\n// !! INSERT base/image-impl.c.\n\n// !! INSERT base/strconv-impl.c.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE)  ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__CORE)\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \\\n    defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)\n\n// !! INSERT InterfaceDefinitions.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BA" +
+	"SE) || \\\n    defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)\n\n// !! INSERT base/f64conv-submodule.c.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \\\n    defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)\n\n// !! INSERT base/pixconv-submodule.c.\n\n#endif  // !defined(WUFFS_CONFIG__MODULES) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE) ||\n        // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)\n\n#ifdef __cplusplus\n}  // extern \"C\"\n#endif\n\n#endif  // WUFFS_IMPLEMENTATION\n\n// !! WUFFS MONOLITHIC RELEASE DISCARDS EVERYTHING BELOW.\n\n#endif  // WUFFS_INCLUDE_GUARD__BASE\n" +
 	""
 
 const baseImageImplC = "" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 54ea261..cba1b02 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -4120,6 +4120,12 @@
 
 // ---------------- Interface Declarations.
 
+// For modular builds that divide the base module into sub-modules, using these
+// functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+
+// --------
+
 extern const char* wuffs_base__hasher_u32__vtable_name;
 
 typedef struct {
@@ -7953,592 +7959,18 @@
     "#base: unsupported pixel swizzler option";
 const char* wuffs_base__error__too_much_data = "#base: too much data";
 
-// ---------------- Interface Definitions.
-
 const char* wuffs_base__hasher_u32__vtable_name =
     "{vtable}wuffs_base__hasher_u32";
 
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
-wuffs_base__hasher_u32__set_quirk_enabled(wuffs_base__hasher_u32* self,
-                                          uint32_t a_quirk,
-                                          bool a_enabled) {
-  if (!self) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_empty_struct();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
-      const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
-          (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_empty_struct();
-}
-
-WUFFS_BASE__MAYBE_STATIC uint32_t  //
-wuffs_base__hasher_u32__update_u32(wuffs_base__hasher_u32* self,
-                                   wuffs_base__slice_u8 a_x) {
-  if (!self) {
-    return 0;
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return 0;
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
-      const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
-          (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->update_u32)(self, a_x);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return 0;
-}
-
-// --------
-
 const char* wuffs_base__image_decoder__vtable_name =
     "{vtable}wuffs_base__image_decoder";
 
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__image_decoder__decode_frame(
-    wuffs_base__image_decoder* self,
-    wuffs_base__pixel_buffer* a_dst,
-    wuffs_base__io_buffer* a_src,
-    wuffs_base__pixel_blend a_blend,
-    wuffs_base__slice_u8 a_workbuf,
-    wuffs_base__decode_frame_options* a_opts) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf,
-                                        a_opts);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__image_decoder__decode_frame_config(wuffs_base__image_decoder* self,
-                                               wuffs_base__frame_config* a_dst,
-                                               wuffs_base__io_buffer* a_src) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__image_decoder__decode_image_config(wuffs_base__image_decoder* self,
-                                               wuffs_base__image_config* a_dst,
-                                               wuffs_base__io_buffer* a_src) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32  //
-wuffs_base__image_decoder__frame_dirty_rect(
-    const wuffs_base__image_decoder* self) {
-  if (!self) {
-    return wuffs_base__utility__empty_rect_ie_u32();
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return wuffs_base__utility__empty_rect_ie_u32();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->frame_dirty_rect)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__utility__empty_rect_ie_u32();
-}
-
-WUFFS_BASE__MAYBE_STATIC uint32_t  //
-wuffs_base__image_decoder__num_animation_loops(
-    const wuffs_base__image_decoder* self) {
-  if (!self) {
-    return 0;
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return 0;
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->num_animation_loops)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return 0;
-}
-
-WUFFS_BASE__MAYBE_STATIC uint64_t  //
-wuffs_base__image_decoder__num_decoded_frame_configs(
-    const wuffs_base__image_decoder* self) {
-  if (!self) {
-    return 0;
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return 0;
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->num_decoded_frame_configs)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return 0;
-}
-
-WUFFS_BASE__MAYBE_STATIC uint64_t  //
-wuffs_base__image_decoder__num_decoded_frames(
-    const wuffs_base__image_decoder* self) {
-  if (!self) {
-    return 0;
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return 0;
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->num_decoded_frames)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return 0;
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__image_decoder__restart_frame(wuffs_base__image_decoder* self,
-                                         uint64_t a_index,
-                                         uint64_t a_io_position) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
-wuffs_base__image_decoder__set_quirk_enabled(wuffs_base__image_decoder* self,
-                                             uint32_t a_quirk,
-                                             bool a_enabled) {
-  if (!self) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_empty_struct();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_empty_struct();
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
-wuffs_base__image_decoder__set_report_metadata(wuffs_base__image_decoder* self,
-                                               uint32_t a_fourcc,
-                                               bool a_report) {
-  if (!self) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_empty_struct();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_empty_struct();
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__image_decoder__tell_me_more(wuffs_base__image_decoder* self,
-                                        wuffs_base__io_buffer* a_dst,
-                                        wuffs_base__more_information* a_minfo,
-                                        wuffs_base__io_buffer* a_src) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
-wuffs_base__image_decoder__workbuf_len(const wuffs_base__image_decoder* self) {
-  if (!self) {
-    return wuffs_base__utility__empty_range_ii_u64();
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return wuffs_base__utility__empty_range_ii_u64();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
-      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->workbuf_len)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__utility__empty_range_ii_u64();
-}
-
-// --------
-
 const char* wuffs_base__io_transformer__vtable_name =
     "{vtable}wuffs_base__io_transformer";
 
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
-wuffs_base__io_transformer__set_quirk_enabled(wuffs_base__io_transformer* self,
-                                              uint32_t a_quirk,
-                                              bool a_enabled) {
-  if (!self) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_empty_struct();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
-      const wuffs_base__io_transformer__func_ptrs* func_ptrs =
-          (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_empty_struct();
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__io_transformer__transform_io(wuffs_base__io_transformer* self,
-                                         wuffs_base__io_buffer* a_dst,
-                                         wuffs_base__io_buffer* a_src,
-                                         wuffs_base__slice_u8 a_workbuf) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
-      const wuffs_base__io_transformer__func_ptrs* func_ptrs =
-          (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
-wuffs_base__io_transformer__workbuf_len(
-    const wuffs_base__io_transformer* self) {
-  if (!self) {
-    return wuffs_base__utility__empty_range_ii_u64();
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return wuffs_base__utility__empty_range_ii_u64();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
-      const wuffs_base__io_transformer__func_ptrs* func_ptrs =
-          (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->workbuf_len)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__utility__empty_range_ii_u64();
-}
-
-// --------
-
 const char* wuffs_base__token_decoder__vtable_name =
     "{vtable}wuffs_base__token_decoder";
 
-WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
-wuffs_base__token_decoder__decode_tokens(wuffs_base__token_decoder* self,
-                                         wuffs_base__token_buffer* a_dst,
-                                         wuffs_base__io_buffer* a_src,
-                                         wuffs_base__slice_u8 a_workbuf) {
-  if (!self) {
-    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_status(
-        (self->private_impl.magic == WUFFS_BASE__DISABLED)
-            ? wuffs_base__error__disabled_by_previous_error
-            : wuffs_base__error__initialize_not_called);
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
-      const wuffs_base__token_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
-wuffs_base__token_decoder__set_quirk_enabled(wuffs_base__token_decoder* self,
-                                             uint32_t a_quirk,
-                                             bool a_enabled) {
-  if (!self) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_empty_struct();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
-      const wuffs_base__token_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__make_empty_struct();
-}
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
-wuffs_base__token_decoder__workbuf_len(const wuffs_base__token_decoder* self) {
-  if (!self) {
-    return wuffs_base__utility__empty_range_ii_u64();
-  }
-  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
-      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
-    return wuffs_base__utility__empty_range_ii_u64();
-  }
-
-  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
-  int i;
-  for (i = 0; i < 63; i++) {
-    if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
-      const wuffs_base__token_decoder__func_ptrs* func_ptrs =
-          (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
-      return (*func_ptrs->workbuf_len)(self);
-    } else if (v->vtable_name == NULL) {
-      break;
-    }
-    v++;
-  }
-
-  return wuffs_base__utility__empty_range_ii_u64();
-}
-
 // ---------------- Images
 
 const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
@@ -9294,6 +8726,587 @@
         // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
 
 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+    defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
+
+// ---------------- Interface Definitions.
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
+wuffs_base__hasher_u32__set_quirk_enabled(wuffs_base__hasher_u32* self,
+                                          uint32_t a_quirk,
+                                          bool a_enabled) {
+  if (!self) {
+    return wuffs_base__make_empty_struct();
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_empty_struct();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+      const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+          (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__MAYBE_STATIC uint32_t  //
+wuffs_base__hasher_u32__update_u32(wuffs_base__hasher_u32* self,
+                                   wuffs_base__slice_u8 a_x) {
+  if (!self) {
+    return 0;
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return 0;
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+      const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+          (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->update_u32)(self, a_x);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return 0;
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__image_decoder__decode_frame(
+    wuffs_base__image_decoder* self,
+    wuffs_base__pixel_buffer* a_dst,
+    wuffs_base__io_buffer* a_src,
+    wuffs_base__pixel_blend a_blend,
+    wuffs_base__slice_u8 a_workbuf,
+    wuffs_base__decode_frame_options* a_opts) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf,
+                                        a_opts);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__image_decoder__decode_frame_config(wuffs_base__image_decoder* self,
+                                               wuffs_base__frame_config* a_dst,
+                                               wuffs_base__io_buffer* a_src) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__image_decoder__decode_image_config(wuffs_base__image_decoder* self,
+                                               wuffs_base__image_config* a_dst,
+                                               wuffs_base__io_buffer* a_src) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32  //
+wuffs_base__image_decoder__frame_dirty_rect(
+    const wuffs_base__image_decoder* self) {
+  if (!self) {
+    return wuffs_base__utility__empty_rect_ie_u32();
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return wuffs_base__utility__empty_rect_ie_u32();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->frame_dirty_rect)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__utility__empty_rect_ie_u32();
+}
+
+WUFFS_BASE__MAYBE_STATIC uint32_t  //
+wuffs_base__image_decoder__num_animation_loops(
+    const wuffs_base__image_decoder* self) {
+  if (!self) {
+    return 0;
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return 0;
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->num_animation_loops)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t  //
+wuffs_base__image_decoder__num_decoded_frame_configs(
+    const wuffs_base__image_decoder* self) {
+  if (!self) {
+    return 0;
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return 0;
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->num_decoded_frame_configs)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t  //
+wuffs_base__image_decoder__num_decoded_frames(
+    const wuffs_base__image_decoder* self) {
+  if (!self) {
+    return 0;
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return 0;
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->num_decoded_frames)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__image_decoder__restart_frame(wuffs_base__image_decoder* self,
+                                         uint64_t a_index,
+                                         uint64_t a_io_position) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
+wuffs_base__image_decoder__set_quirk_enabled(wuffs_base__image_decoder* self,
+                                             uint32_t a_quirk,
+                                             bool a_enabled) {
+  if (!self) {
+    return wuffs_base__make_empty_struct();
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_empty_struct();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
+wuffs_base__image_decoder__set_report_metadata(wuffs_base__image_decoder* self,
+                                               uint32_t a_fourcc,
+                                               bool a_report) {
+  if (!self) {
+    return wuffs_base__make_empty_struct();
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_empty_struct();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__image_decoder__tell_me_more(wuffs_base__image_decoder* self,
+                                        wuffs_base__io_buffer* a_dst,
+                                        wuffs_base__more_information* a_minfo,
+                                        wuffs_base__io_buffer* a_src) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
+wuffs_base__image_decoder__workbuf_len(const wuffs_base__image_decoder* self) {
+  if (!self) {
+    return wuffs_base__utility__empty_range_ii_u64();
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return wuffs_base__utility__empty_range_ii_u64();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+      const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->workbuf_len)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__utility__empty_range_ii_u64();
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
+wuffs_base__io_transformer__set_quirk_enabled(wuffs_base__io_transformer* self,
+                                              uint32_t a_quirk,
+                                              bool a_enabled) {
+  if (!self) {
+    return wuffs_base__make_empty_struct();
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_empty_struct();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+      const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+          (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__io_transformer__transform_io(wuffs_base__io_transformer* self,
+                                         wuffs_base__io_buffer* a_dst,
+                                         wuffs_base__io_buffer* a_src,
+                                         wuffs_base__slice_u8 a_workbuf) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+      const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+          (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
+wuffs_base__io_transformer__workbuf_len(
+    const wuffs_base__io_transformer* self) {
+  if (!self) {
+    return wuffs_base__utility__empty_range_ii_u64();
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return wuffs_base__utility__empty_range_ii_u64();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+      const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+          (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->workbuf_len)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__utility__empty_range_ii_u64();
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
+wuffs_base__token_decoder__decode_tokens(wuffs_base__token_decoder* self,
+                                         wuffs_base__token_buffer* a_dst,
+                                         wuffs_base__io_buffer* a_src,
+                                         wuffs_base__slice_u8 a_workbuf) {
+  if (!self) {
+    return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_status(
+        (self->private_impl.magic == WUFFS_BASE__DISABLED)
+            ? wuffs_base__error__disabled_by_previous_error
+            : wuffs_base__error__initialize_not_called);
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+      const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
+wuffs_base__token_decoder__set_quirk_enabled(wuffs_base__token_decoder* self,
+                                             uint32_t a_quirk,
+                                             bool a_enabled) {
+  if (!self) {
+    return wuffs_base__make_empty_struct();
+  }
+  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+    return wuffs_base__make_empty_struct();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+      const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
+wuffs_base__token_decoder__workbuf_len(const wuffs_base__token_decoder* self) {
+  if (!self) {
+    return wuffs_base__utility__empty_range_ii_u64();
+  }
+  if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+      (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+    return wuffs_base__utility__empty_range_ii_u64();
+  }
+
+  const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+  int i;
+  for (i = 0; i < 63; i++) {
+    if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+      const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+          (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+      return (*func_ptrs->workbuf_len)(self);
+    } else if (v->vtable_name == NULL) {
+      break;
+    }
+    v++;
+  }
+
+  return wuffs_base__utility__empty_range_ii_u64();
+}
+
+#endif  // !defined(WUFFS_CONFIG__MODULES) ||
+        // defined(WUFFS_CONFIG__MODULE__BASE) ||
+        // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
     defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)
 
   // ---------------- IEEE 754 Floating Point