Let GIF decode BGR/RGB, not just BGRA/RGBA
diff --git a/internal/cgen/base/image-impl.c b/internal/cgen/base/image-impl.c
index 8b1fb5d..abac9ec 100644
--- a/internal/cgen/base/image-impl.c
+++ b/internal/cgen/base/image-impl.c
@@ -29,6 +29,61 @@
 }
 
 static uint64_t  //
+wuffs_base__pixel_swizzler__copy_3_1(wuffs_base__slice_u8 dst,
+                                     wuffs_base__slice_u8 dst_palette,
+                                     wuffs_base__slice_u8 src) {
+  if (dst_palette.len != 1024) {
+    return 0;
+  }
+  size_t dst_len3 = dst.len / 3;
+  size_t len = dst_len3 < src.len ? dst_len3 : src.len;
+  uint8_t* d = dst.ptr;
+  uint8_t* s = src.ptr;
+  size_t n = len;
+
+  // N is the loop unroll count.
+  const int N = 4;
+
+  // The comparison in the while condition is ">", not ">=", because with ">=",
+  // the last 4-byte store could write past the end of the dst slice.
+  //
+  // Each 4-byte store writes one too many bytes, but a subsequent store will
+  // overwrite that with the correct byte. There is always another store,
+  // whether a 4-byte store in this loop or a 1-byte store in the next loop.
+  while (n > N) {
+    wuffs_base__store_u32le(
+        d + (0 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));
+    wuffs_base__store_u32le(
+        d + (1 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));
+    wuffs_base__store_u32le(
+        d + (2 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));
+    wuffs_base__store_u32le(
+        d + (3 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));
+
+    s += 1 * N;
+    d += 3 * N;
+    n -= (size_t)(1 * N);
+  }
+
+  while (n >= 1) {
+    uint32_t color =
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4));
+    d[0] = (uint8_t)(color >> 0);
+    d[1] = (uint8_t)(color >> 8);
+    d[2] = (uint8_t)(color >> 16);
+
+    s += 1 * 1;
+    d += 3 * 1;
+    n -= (size_t)(1 * 1);
+  }
+
+  return len;
+}
+static uint64_t  //
 wuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,
                                      wuffs_base__slice_u8 dst_palette,
                                      wuffs_base__slice_u8 src) {
@@ -39,8 +94,9 @@
   size_t len = dst_len4 < src.len ? dst_len4 : src.len;
   uint8_t* d = dst.ptr;
   uint8_t* s = src.ptr;
-
   size_t n = len;
+
+  // N is the loop unroll count.
   const int N = 4;
 
   while (n >= N) {
@@ -125,6 +181,13 @@
           }
           func = wuffs_base__pixel_swizzler__copy_1_1;
           break;
+        case WUFFS_BASE__PIXEL_FORMAT__BGR:
+          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+              1024) {
+            break;
+          }
+          func = wuffs_base__pixel_swizzler__copy_3_1;
+          break;
         case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
@@ -134,6 +197,13 @@
           }
           func = wuffs_base__pixel_swizzler__copy_4_1;
           break;
+        case WUFFS_BASE__PIXEL_FORMAT__RGB:
+          if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
+                                                         src_palette) != 1024) {
+            break;
+          }
+          func = wuffs_base__pixel_swizzler__copy_3_1;
+          break;
         case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index 96105e8..2cf5e13 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -24,11 +24,13 @@
 	""
 
 const baseImageImplC = "" +
-	"// ---------------- Images\n\nconst uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {\n    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n    0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,\n};\n\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__copy_1_1(wuffs_base__slice_u8 dst,\n                                     wuffs_base__slice_u8 dst_palette,\n                                     wuffs_base__slice_u8 src) {\n  return wuffs_base__slice_u8__copy_from_slice(dst, src);\n}\n\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,\n                                     wuffs_base__slice_u8 dst_palette,\n                                     wuffs_base__slice_u8 src) {\n  if (dst_palette.len != 1024) {\n    return 0;\n  }\n  size_t dst_len4 = dst.len / 4;\n  size_t len = dst_len4 < src.len ? dst_len4 : src.len;\n  uint8_t* d = dst.ptr;\n  uint8_t* s = src.ptr;\n\n  size_t n = len;\n  const int N = 4;\n\n  while (n >= N) {\n    wuffs_base__store_u32le(\n        d + (0 * 4),\n        wuffs_base__load_u3" +
-	"2le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n    wuffs_base__store_u32le(\n        d + (1 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));\n    wuffs_base__store_u32le(\n        d + (2 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));\n    wuffs_base__store_u32le(\n        d + (3 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));\n\n    s += 1 * N;\n    d += 4 * N;\n    n -= (size_t)(1 * N);\n  }\n\n  while (n >= 1) {\n    wuffs_base__store_u32le(\n        d + (0 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n\n    s += 1 * 1;\n    d += 4 * 1;\n    n -= (size_t)(1 * 1);\n  }\n\n  return len;\n}\n\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__swap_rgbx_bgrx(wuffs_base__slice_u8 dst,\n                                           wuffs_base__slice_u8 src) {\n  size_t len4 = (dst.len < src.len ? dst.len : src.len) / 4;\n  uint8_t* d = dst.ptr;\n  uint8_t* s = src.ptr;\n\n  size_t n = len4;\n  while (n--) {\n    uin" +
-	"t8_t b0 = s[0];\n    uint8_t b1 = s[1];\n    uint8_t b2 = s[2];\n    uint8_t b3 = s[3];\n    d[0] = b2;\n    d[1] = b1;\n    d[2] = b0;\n    d[3] = b3;\n    s += 4;\n    d += 4;\n  }\n  return len4 * 4;\n}\n\nwuffs_base__status  //\nwuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,\n                                    wuffs_base__pixel_format dst_format,\n                                    wuffs_base__slice_u8 dst_palette,\n                                    wuffs_base__pixel_format src_format,\n                                    wuffs_base__slice_u8 src_palette) {\n  if (!p) {\n    return wuffs_base__error__bad_receiver;\n  }\n\n  // TODO: support many more formats.\n\n  uint64_t (*func)(wuffs_base__slice_u8 dst, wuffs_base__slice_u8 dst_palette,\n                   wuffs_base__slice_u8 src) = NULL;\n\n  switch (src_format) {\n    case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n      switch (dst_format) {\n        case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__INDEXE" +
-	"D__BGRA_PREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n              1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_1_1;\n          break;\n        case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:\n          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n              1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_4_1;\n          break;\n        case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:\n          if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n                                                         src_palette) != 1024) {\n            break;\n          }\n          func = wuffs_base__pixel_" +
-	"swizzler__copy_4_1;\n          break;\n        default:\n          break;\n      }\n      break;\n\n    default:\n      break;\n  }\n\n  p->private_impl.func = func;\n  return func ? NULL : wuffs_base__error__unsupported_option;\n}\n\nuint64_t  //\nwuffs_base__pixel_swizzler__swizzle_packed(const wuffs_base__pixel_swizzler* p,\n                                           wuffs_base__slice_u8 dst,\n                                           wuffs_base__slice_u8 dst_palette,\n                                           wuffs_base__slice_u8 src) {\n  if (p && p->private_impl.func) {\n    return (*(p->private_impl.func))(dst, dst_palette, src);\n  }\n  return 0;\n}\n" +
+	"// ---------------- Images\n\nconst uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {\n    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n    0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,\n};\n\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__copy_1_1(wuffs_base__slice_u8 dst,\n                                     wuffs_base__slice_u8 dst_palette,\n                                     wuffs_base__slice_u8 src) {\n  return wuffs_base__slice_u8__copy_from_slice(dst, src);\n}\n\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__copy_3_1(wuffs_base__slice_u8 dst,\n                                     wuffs_base__slice_u8 dst_palette,\n                                     wuffs_base__slice_u8 src) {\n  if (dst_palette.len != 1024) {\n    return 0;\n  }\n  size_t dst_len3 = dst.len / 3;\n  size_t len = dst_len3 < src.len ? dst_len3 : src.len;\n  uint8_t* d = dst.ptr;\n  uint8_t* s = src.ptr;\n  size_t n = len;\n\n  // N is the loop unroll count.\n  const int N = 4;\n\n  // The comparison in the while condition is \">\", not \">=\", be" +
+	"cause with \">=\",\n  // the last 4-byte store could write past the end of the dst slice.\n  //\n  // Each 4-byte store writes one too many bytes, but a subsequent store will\n  // overwrite that with the correct byte. There is always another store,\n  // whether a 4-byte store in this loop or a 1-byte store in the next loop.\n  while (n > N) {\n    wuffs_base__store_u32le(\n        d + (0 * 3),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n    wuffs_base__store_u32le(\n        d + (1 * 3),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));\n    wuffs_base__store_u32le(\n        d + (2 * 3),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));\n    wuffs_base__store_u32le(\n        d + (3 * 3),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));\n\n    s += 1 * N;\n    d += 3 * N;\n    n -= (size_t)(1 * N);\n  }\n\n  while (n >= 1) {\n    uint32_t color =\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4));\n    d[0" +
+	"] = (uint8_t)(color >> 0);\n    d[1] = (uint8_t)(color >> 8);\n    d[2] = (uint8_t)(color >> 16);\n\n    s += 1 * 1;\n    d += 3 * 1;\n    n -= (size_t)(1 * 1);\n  }\n\n  return len;\n}\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,\n                                     wuffs_base__slice_u8 dst_palette,\n                                     wuffs_base__slice_u8 src) {\n  if (dst_palette.len != 1024) {\n    return 0;\n  }\n  size_t dst_len4 = dst.len / 4;\n  size_t len = dst_len4 < src.len ? dst_len4 : src.len;\n  uint8_t* d = dst.ptr;\n  uint8_t* s = src.ptr;\n  size_t n = len;\n\n  // N is the loop unroll count.\n  const int N = 4;\n\n  while (n >= N) {\n    wuffs_base__store_u32le(\n        d + (0 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n    wuffs_base__store_u32le(\n        d + (1 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));\n    wuffs_base__store_u32le(\n        d + (2 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + (" +
+	"(uint32_t)(s[2]) * 4)));\n    wuffs_base__store_u32le(\n        d + (3 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));\n\n    s += 1 * N;\n    d += 4 * N;\n    n -= (size_t)(1 * N);\n  }\n\n  while (n >= 1) {\n    wuffs_base__store_u32le(\n        d + (0 * 4),\n        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));\n\n    s += 1 * 1;\n    d += 4 * 1;\n    n -= (size_t)(1 * 1);\n  }\n\n  return len;\n}\n\nstatic uint64_t  //\nwuffs_base__pixel_swizzler__swap_rgbx_bgrx(wuffs_base__slice_u8 dst,\n                                           wuffs_base__slice_u8 src) {\n  size_t len4 = (dst.len < src.len ? dst.len : src.len) / 4;\n  uint8_t* d = dst.ptr;\n  uint8_t* s = src.ptr;\n\n  size_t n = len4;\n  while (n--) {\n    uint8_t b0 = s[0];\n    uint8_t b1 = s[1];\n    uint8_t b2 = s[2];\n    uint8_t b3 = s[3];\n    d[0] = b2;\n    d[1] = b1;\n    d[2] = b0;\n    d[3] = b3;\n    s += 4;\n    d += 4;\n  }\n  return len4 * 4;\n}\n\nwuffs_base__status  //\nwuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_s" +
+	"wizzler* p,\n                                    wuffs_base__pixel_format dst_format,\n                                    wuffs_base__slice_u8 dst_palette,\n                                    wuffs_base__pixel_format src_format,\n                                    wuffs_base__slice_u8 src_palette) {\n  if (!p) {\n    return wuffs_base__error__bad_receiver;\n  }\n\n  // TODO: support many more formats.\n\n  uint64_t (*func)(wuffs_base__slice_u8 dst, wuffs_base__slice_u8 dst_palette,\n                   wuffs_base__slice_u8 src) = NULL;\n\n  switch (src_format) {\n    case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n      switch (dst_format) {\n        case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:\n          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n              1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_1_1;\n       " +
+	"   break;\n        case WUFFS_BASE__PIXEL_FORMAT__BGR:\n          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n              1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_3_1;\n          break;\n        case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:\n          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=\n              1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_4_1;\n          break;\n        case WUFFS_BASE__PIXEL_FORMAT__RGB:\n          if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n                                                         src_palette) != 1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_3_1;\n          break;\n        case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__RGBA_PR" +
+	"EMUL:\n        case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:\n          if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,\n                                                         src_palette) != 1024) {\n            break;\n          }\n          func = wuffs_base__pixel_swizzler__copy_4_1;\n          break;\n        default:\n          break;\n      }\n      break;\n\n    default:\n      break;\n  }\n\n  p->private_impl.func = func;\n  return func ? NULL : wuffs_base__error__unsupported_option;\n}\n\nuint64_t  //\nwuffs_base__pixel_swizzler__swizzle_packed(const wuffs_base__pixel_swizzler* p,\n                                           wuffs_base__slice_u8 dst,\n                                           wuffs_base__slice_u8 dst_palette,\n                                           wuffs_base__slice_u8 src) {\n  if (p && p->private_impl.func) {\n    return (*(p->private_impl.func))(dst, dst_palette, src);\n  }\n  return 0;\n}\n" +
 	""
 
 const baseCorePrivateH = "" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 1d2b578..75df621 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -4834,6 +4834,61 @@
 }
 
 static uint64_t  //
+wuffs_base__pixel_swizzler__copy_3_1(wuffs_base__slice_u8 dst,
+                                     wuffs_base__slice_u8 dst_palette,
+                                     wuffs_base__slice_u8 src) {
+  if (dst_palette.len != 1024) {
+    return 0;
+  }
+  size_t dst_len3 = dst.len / 3;
+  size_t len = dst_len3 < src.len ? dst_len3 : src.len;
+  uint8_t* d = dst.ptr;
+  uint8_t* s = src.ptr;
+  size_t n = len;
+
+  // N is the loop unroll count.
+  const int N = 4;
+
+  // The comparison in the while condition is ">", not ">=", because with ">=",
+  // the last 4-byte store could write past the end of the dst slice.
+  //
+  // Each 4-byte store writes one too many bytes, but a subsequent store will
+  // overwrite that with the correct byte. There is always another store,
+  // whether a 4-byte store in this loop or a 1-byte store in the next loop.
+  while (n > N) {
+    wuffs_base__store_u32le(
+        d + (0 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));
+    wuffs_base__store_u32le(
+        d + (1 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));
+    wuffs_base__store_u32le(
+        d + (2 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));
+    wuffs_base__store_u32le(
+        d + (3 * 3),
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));
+
+    s += 1 * N;
+    d += 3 * N;
+    n -= (size_t)(1 * N);
+  }
+
+  while (n >= 1) {
+    uint32_t color =
+        wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4));
+    d[0] = (uint8_t)(color >> 0);
+    d[1] = (uint8_t)(color >> 8);
+    d[2] = (uint8_t)(color >> 16);
+
+    s += 1 * 1;
+    d += 3 * 1;
+    n -= (size_t)(1 * 1);
+  }
+
+  return len;
+}
+static uint64_t  //
 wuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,
                                      wuffs_base__slice_u8 dst_palette,
                                      wuffs_base__slice_u8 src) {
@@ -4844,8 +4899,9 @@
   size_t len = dst_len4 < src.len ? dst_len4 : src.len;
   uint8_t* d = dst.ptr;
   uint8_t* s = src.ptr;
-
   size_t n = len;
+
+  // N is the loop unroll count.
   const int N = 4;
 
   while (n >= N) {
@@ -4930,6 +4986,13 @@
           }
           func = wuffs_base__pixel_swizzler__copy_1_1;
           break;
+        case WUFFS_BASE__PIXEL_FORMAT__BGR:
+          if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+              1024) {
+            break;
+          }
+          func = wuffs_base__pixel_swizzler__copy_3_1;
+          break;
         case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
@@ -4939,6 +5002,13 @@
           }
           func = wuffs_base__pixel_swizzler__copy_4_1;
           break;
+        case WUFFS_BASE__PIXEL_FORMAT__RGB:
+          if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
+                                                         src_palette) != 1024) {
+            break;
+          }
+          func = wuffs_base__pixel_swizzler__copy_3_1;
+          break;
         case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
         case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
@@ -11175,17 +11245,20 @@
   uint64_t v_n = 0;
   uint64_t v_src_ri = 0;
   uint32_t v_bytes_per_pixel = 0;
-  uint32_t v_pixfmt = 0;
+  uint32_t v_pixfmt_channels = 0;
   wuffs_base__table_u8 v_tab = {0};
   uint64_t v_i = 0;
   uint64_t v_j = 0;
 
-  v_bytes_per_pixel = 1;
-  v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
-  if ((v_pixfmt == 1157662856) || (v_pixfmt == 1426098312) ||
-      (v_pixfmt == 1174440072) || (v_pixfmt == 1442875528) ||
-      (v_pixfmt == 1191217288) || (v_pixfmt == 1459652744)) {
+  v_pixfmt_channels = (wuffs_base__pixel_buffer__pixel_format(a_pb) & 65535);
+  if (v_pixfmt_channels == 34952) {
     v_bytes_per_pixel = 4;
+  } else if (v_pixfmt_channels == 2184) {
+    v_bytes_per_pixel = 3;
+  } else if (v_pixfmt_channels == 8) {
+    v_bytes_per_pixel = 1;
+  } else {
+    return wuffs_base__error__unsupported_option;
   }
   v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
 label_0_continue:;
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index 37364c8..0cd3067 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -1110,19 +1110,22 @@
 	var n               base.u64
 	var src_ri          base.u64
 	var bytes_per_pixel base.u32[..64]
-	var pixfmt          base.u32
+	var pixfmt_channels base.u32
 	var tab             table base.u8
 	var i               base.u64
 	var j               base.u64
 
 	// TODO: a Wuffs (not just C) name for the WUFFS_BASE__PIXEL_FORMAT__ETC
 	// magic pixfmt constants. Also, support more formats.
-	bytes_per_pixel = 1
-	pixfmt = args.pb.pixel_format()
-	if (pixfmt == 0x45008888) or (pixfmt == 0x55008888) or
-		(pixfmt == 0x46008888) or (pixfmt == 0x56008888) or
-		(pixfmt == 0x47008888) or (pixfmt == 0x57008888) {
+	pixfmt_channels = args.pb.pixel_format() & 0xFFFF
+	if (pixfmt_channels == 0x8888) {
 		bytes_per_pixel = 4
+	} else if (pixfmt_channels == 0x0888) {
+		bytes_per_pixel = 3
+	} else if (pixfmt_channels == 0x0008) {
+		bytes_per_pixel = 1
+	} else {
+		return base."#unsupported option"
 	}
 
 	tab = args.pb.plane(p:0)
diff --git a/test/c/std/gif.c b/test/c/std/gif.c
index 796f65b..876bb9f 100644
--- a/test/c/std/gif.c
+++ b/test/c/std/gif.c
@@ -432,15 +432,49 @@
     if (ind_want.meta.wi > (expanded_want.data.len / 4)) {
       RETURN_FAIL("indexes are too long to expand into the work buffer");
     }
-    size_t i;
-    for (i = 0; i < ind_want.meta.wi; i++) {
-      uint8_t index = ind_want.data.ptr[i];
-      expanded_want.data.ptr[4 * i + 0] = pal_want_array[4 * index + 0];
-      expanded_want.data.ptr[4 * i + 1] = pal_want_array[4 * index + 1];
-      expanded_want.data.ptr[4 * i + 2] = pal_want_array[4 * index + 2];
-      expanded_want.data.ptr[4 * i + 3] = pal_want_array[4 * index + 3];
+
+    if (dst_pixfmt == WUFFS_BASE__PIXEL_FORMAT__BGR) {
+      size_t i;
+      for (i = 0; i < ind_want.meta.wi; i++) {
+        uint8_t index = ind_want.data.ptr[i];
+        expanded_want.data.ptr[3 * i + 0] = pal_want_array[4 * index + 0];
+        expanded_want.data.ptr[3 * i + 1] = pal_want_array[4 * index + 1];
+        expanded_want.data.ptr[3 * i + 2] = pal_want_array[4 * index + 2];
+      }
+      expanded_want.meta.wi = 3 * ind_want.meta.wi;
+    } else if (dst_pixfmt == WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL) {
+      size_t i;
+      for (i = 0; i < ind_want.meta.wi; i++) {
+        uint8_t index = ind_want.data.ptr[i];
+        expanded_want.data.ptr[4 * i + 0] = pal_want_array[4 * index + 0];
+        expanded_want.data.ptr[4 * i + 1] = pal_want_array[4 * index + 1];
+        expanded_want.data.ptr[4 * i + 2] = pal_want_array[4 * index + 2];
+        expanded_want.data.ptr[4 * i + 3] = pal_want_array[4 * index + 3];
+      }
+      expanded_want.meta.wi = 4 * ind_want.meta.wi;
+    } else if (dst_pixfmt == WUFFS_BASE__PIXEL_FORMAT__RGB) {
+      size_t i;
+      for (i = 0; i < ind_want.meta.wi; i++) {
+        uint8_t index = ind_want.data.ptr[i];
+        expanded_want.data.ptr[3 * i + 0] = pal_want_array[4 * index + 2];
+        expanded_want.data.ptr[3 * i + 1] = pal_want_array[4 * index + 1];
+        expanded_want.data.ptr[3 * i + 2] = pal_want_array[4 * index + 0];
+      }
+      expanded_want.meta.wi = 3 * ind_want.meta.wi;
+    } else if (dst_pixfmt == WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL) {
+      size_t i;
+      for (i = 0; i < ind_want.meta.wi; i++) {
+        uint8_t index = ind_want.data.ptr[i];
+        expanded_want.data.ptr[4 * i + 0] = pal_want_array[4 * index + 2];
+        expanded_want.data.ptr[4 * i + 1] = pal_want_array[4 * index + 1];
+        expanded_want.data.ptr[4 * i + 2] = pal_want_array[4 * index + 0];
+        expanded_want.data.ptr[4 * i + 3] = pal_want_array[4 * index + 3];
+      }
+      expanded_want.meta.wi = 4 * ind_want.meta.wi;
+    } else {
+      return "unsupported pixel format";
     }
-    expanded_want.meta.wi = 4 * ind_want.meta.wi;
+
     status = check_io_buffers_equal("pixels ", &got, &expanded_want);
     if (status) {
       return status;
@@ -1148,7 +1182,14 @@
   return NULL;
 }
 
-const char* test_wuffs_gif_decode_bgra_nonpremul() {
+const char* test_wuffs_gif_decode_pixfmt_bgr() {
+  CHECK_FOCUS(__func__);
+  return do_test_wuffs_gif_decode(
+      "test/data/bricks-dither.gif", "test/data/bricks-dither.palette",
+      "test/data/bricks-dither.indexes", 0, WUFFS_BASE__PIXEL_FORMAT__BGR);
+}
+
+const char* test_wuffs_gif_decode_pixfmt_bgra_nonpremul() {
   CHECK_FOCUS(__func__);
   return do_test_wuffs_gif_decode("test/data/bricks-dither.gif",
                                   "test/data/bricks-dither.palette",
@@ -1156,6 +1197,21 @@
                                   WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL);
 }
 
+const char* test_wuffs_gif_decode_pixfmt_rgb() {
+  CHECK_FOCUS(__func__);
+  return do_test_wuffs_gif_decode(
+      "test/data/bricks-dither.gif", "test/data/bricks-dither.palette",
+      "test/data/bricks-dither.indexes", 0, WUFFS_BASE__PIXEL_FORMAT__RGB);
+}
+
+const char* test_wuffs_gif_decode_pixfmt_rgba_nonpremul() {
+  CHECK_FOCUS(__func__);
+  return do_test_wuffs_gif_decode("test/data/bricks-dither.gif",
+                                  "test/data/bricks-dither.palette",
+                                  "test/data/bricks-dither.indexes", 0,
+                                  WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL);
+}
+
 const char* test_wuffs_gif_decode_input_is_a_gif_just_one_read() {
   CHECK_FOCUS(__func__);
   return do_test_wuffs_gif_decode(
@@ -2208,7 +2264,6 @@
     test_wuffs_gif_decode_animated_medium,                   //
     test_wuffs_gif_decode_animated_small,                    //
     test_wuffs_gif_decode_background_color,                  //
-    test_wuffs_gif_decode_bgra_nonpremul,                    //
     test_wuffs_gif_decode_delay_num_frames_decoded,          //
     test_wuffs_gif_decode_empty_palette,                     //
     test_wuffs_gif_decode_first_frame_is_opaque,             //
@@ -2226,6 +2281,10 @@
     test_wuffs_gif_decode_pixel_data_not_enough,             //
     test_wuffs_gif_decode_pixel_data_too_much_sans_quirk,    //
     test_wuffs_gif_decode_pixel_data_too_much_with_quirk,    //
+    test_wuffs_gif_decode_pixfmt_bgr,                        //
+    test_wuffs_gif_decode_pixfmt_bgra_nonpremul,             //
+    test_wuffs_gif_decode_pixfmt_rgb,                        //
+    test_wuffs_gif_decode_pixfmt_rgba_nonpremul,             //
     test_wuffs_gif_decode_zero_width_frame,                  //
     test_wuffs_gif_frame_dirty_rect,                         //
     test_wuffs_gif_num_decoded_frame_configs,                //