base: support YCC_MODEL__BT_601_STUDIO_RANGE
diff --git a/internal/cgen/base/image-public.h b/internal/cgen/base/image-public.h
index f55210a..6483fcf 100644
--- a/internal/cgen/base/image-public.h
+++ b/internal/cgen/base/image-public.h
@@ -294,8 +294,28 @@
 
 // wuffs_base__color_ycc__as__color_u32 converts from YCbCr to 0xAARRGGBB. The
 // alpha bits are always 0xFF.
+//
+// There is no YCC_MODEL (like bt601fr) in the macro name. For backwards
+// compatibility, it uses WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE, like JPEG.
+#define wuffs_base__color_ycc__as__color_u32 \
+  wuffs_base__color_ycc_bt601fr__as__color_u32
+
+// wuffs_base__color_ycc__as__color_u32_abgr is like
+// wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
+// 0xAABBGGRR order, not 0xAARRGGBB.
+//
+// There is no YCC_MODEL (like bt601fr) in the macro name. For backwards
+// compatibility, it uses WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE, like JPEG.
+#define wuffs_base__color_ycc__as__color_u32_abgr \
+  wuffs_base__color_ycc_bt601fr__as__color_u32_abgr
+
+// wuffs_base__color_ycc_bt601fr__as__color_u32 is
+// wuffs_base__color_ycc__as__color_u32 for
+// WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE.
 static inline wuffs_base__color_u32_argb_premul  //
-wuffs_base__color_ycc__as__color_u32(uint8_t yy, uint8_t cb, uint8_t cr) {
+wuffs_base__color_ycc_bt601fr__as__color_u32(uint8_t yy,
+                                             uint8_t cb,
+                                             uint8_t cr) {
   // Work in 16.16 fixed point arithmetic (so that 'one half' is (1 << 15)) and
   // bias the chroma values by 0x80.
   uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
@@ -344,11 +364,13 @@
          ((0x00FF0000 & bb32) >> 16);
 }
 
-// wuffs_base__color_ycc__as__color_u32_abgr is like
-// wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
-// 0xAABBGGRR order, not 0xAARRGGBB.
+// wuffs_base__color_ycc_bt601fr__as__color_u32_abgr is
+// wuffs_base__color_ycc__as__color_u32_abgr for
+// WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE.
 static inline uint32_t  //
-wuffs_base__color_ycc__as__color_u32_abgr(uint8_t yy, uint8_t cb, uint8_t cr) {
+wuffs_base__color_ycc_bt601fr__as__color_u32_abgr(uint8_t yy,
+                                                  uint8_t cb,
+                                                  uint8_t cr) {
   uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
   uint32_t cb32 = (((uint32_t)cb) - 0x80);
   uint32_t cr32 = (((uint32_t)cr) - 0x80);
@@ -370,8 +392,66 @@
          ((0x00FF0000 & rr32) >> 16);
 }
 
-// wuffs_base__color_swap_u32_argb_abgr converts between 0xAARRGGBB and
-// 0xAABBGGRR.
+// wuffs_base__color_ycc_bt601sr__as__color_u32 is
+// wuffs_base__color_ycc__as__color_u32 for
+// WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE.
+static inline wuffs_base__color_u32_argb_premul  //
+wuffs_base__color_ycc_bt601sr__as__color_u32(uint8_t yy,
+                                             uint8_t cb,
+                                             uint8_t cr) {
+  // The constants here match those used in libwebp's src/dsp/yuv.h, using
+  // 18.14 fixed point arithmetic. (1 << 14) equals 16384.
+  //
+  // 19077 ≈ 16384 * 1.164
+  // 26149 ≈ 16384 * 1.596
+  //  6419 ≈ 16384 * 0.392
+  // 13320 ≈ 16384 * 0.813
+  // 33050 ≈ 16384 * 2.017
+  // 14234 ≈ 16384 * 0.869
+  //  8708 ≈ 16384 * 0.531
+  // 17685 ≈ 16384 * 1.079
+
+  int32_t y0 = ((int32_t)yy * 19077) >> 8;
+  int32_t rr = ((int32_t)cr * 26149) >> 8;
+  int32_t gb = ((int32_t)cb * 6419) >> 8;
+  int32_t gr = ((int32_t)cr * 13320) >> 8;
+  int32_t bb = ((int32_t)cb * 33050) >> 8;
+
+  int32_t r1 = y0 + rr - 14234;
+  int32_t g1 = y0 - gb - gr + 8708;
+  int32_t b1 = y0 + bb - 17685;
+
+  uint32_t r = (r1 < 0) ? 0u : (r1 > 16320) ? 255u : ((uint32_t)r1 >> 6);
+  uint32_t g = (g1 < 0) ? 0u : (g1 > 16320) ? 255u : ((uint32_t)g1 >> 6);
+  uint32_t b = (b1 < 0) ? 0u : (b1 > 16320) ? 255u : ((uint32_t)b1 >> 6);
+
+  return 0xFF000000u | (r << 16) | (g << 8) | b;
+}
+
+// wuffs_base__color_ycc_bt601sr__as__color_u32_abgr is
+// wuffs_base__color_ycc__as__color_u32_abgr for
+// WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE.
+static inline uint32_t  //
+wuffs_base__color_ycc_bt601sr__as__color_u32_abgr(uint8_t yy,
+                                                  uint8_t cb,
+                                                  uint8_t cr) {
+  int32_t y0 = ((int32_t)yy * 19077) >> 8;
+  int32_t rr = ((int32_t)cr * 26149) >> 8;
+  int32_t gb = ((int32_t)cb * 6419) >> 8;
+  int32_t gr = ((int32_t)cr * 13320) >> 8;
+  int32_t bb = ((int32_t)cb * 33050) >> 8;
+
+  int32_t r1 = y0 + rr - 14234;
+  int32_t g1 = y0 - gb - gr + 8708;
+  int32_t b1 = y0 + bb - 17685;
+
+  uint32_t r = (r1 < 0) ? 0u : (r1 > 16320) ? 255u : ((uint32_t)r1 >> 6);
+  uint32_t g = (g1 < 0) ? 0u : (g1 > 16320) ? 255u : ((uint32_t)g1 >> 6);
+  uint32_t b = (b1 < 0) ? 0u : (b1 > 16320) ? 255u : ((uint32_t)b1 >> 6);
+
+  return 0xFF000000u | (b << 16) | (g << 8) | r;
+}
+
 static inline uint32_t  //
 wuffs_base__color_swap_u32_argb_abgr(uint32_t u) {
   uint32_t o = u & 0xFF00FF00ul;
diff --git a/internal/cgen/base/pixconv-submodule-x86-avx2.c b/internal/cgen/base/pixconv-submodule-x86-avx2.c
index 2b55691..fb377ce 100644
--- a/internal/cgen/base/pixconv-submodule-x86-avx2.c
+++ b/internal/cgen/base/pixconv-submodule-x86-avx2.c
@@ -14,7 +14,7 @@
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -23,7 +23,7 @@
     const uint8_t* up1,
     const uint8_t* up2) {
   if ((x + 32u) > x_end) {
-    wuffs_private_impl__swizzle_ycc__convert_3_bgrx(  //
+    wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx(  //
         dst, x, x_end, y, up0, up1, up2);
     return;
   }
@@ -48,7 +48,7 @@
       +0x0000, -0x8000, +0x0000, -0x8000,        //
       +0x0000, -0x8000, +0x0000, -0x8000);
 
-  // Per wuffs_base__color_ycc__as__color_u32, the formulae:
+  // Per wuffs_base__color_ycc_bt601fr__as__color_u32, the formulae:
   //
   //  R = Y                + 1.40200 * Cr
   //  G = Y - 0.34414 * Cb - 0.71414 * Cr
@@ -287,7 +287,7 @@
 // except for the lines marked with a § and that comments were stripped.
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -296,7 +296,7 @@
     const uint8_t* up1,
     const uint8_t* up2) {
   if ((x + 32u) > x_end) {
-    wuffs_private_impl__swizzle_ycc__convert_3_rgbx(  //
+    wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx(  //
         dst, x, x_end, y, up0, up1, up2);
     return;
   }
diff --git a/internal/cgen/base/pixconv-submodule-ycck.c b/internal/cgen/base/pixconv-submodule-ycck.c
index 2570eec..f5678e4 100644
--- a/internal/cgen/base/pixconv-submodule-ycck.c
+++ b/internal/cgen/base/pixconv-submodule-ycck.c
@@ -13,7 +13,7 @@
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -24,7 +24,7 @@
 
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -124,8 +124,8 @@
     const uint8_t* up3) {
   for (; x < x_end; x++) {
     // We invert once again: 0xFFu means no ink instead of full ink.
-    uint32_t color =                           //
-        wuffs_base__color_ycc__as__color_u32(  //
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601fr__as__color_u32(  //
             *up0++, *up1++, *up2++);
     uint32_t r = 0xFFu - (0xFFu & (color >> 16u));
     uint32_t g = 0xFFu - (0xFFu & (color >> 8u));
@@ -169,7 +169,7 @@
 }
 
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_general(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_general(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -178,28 +178,29 @@
     const uint8_t* up1,
     const uint8_t* up2) {
   for (; x < x_end; x++) {
-    uint32_t color =                           //
-        wuffs_base__color_ycc__as__color_u32(  //
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601fr__as__color_u32(  //
             *up0++, *up1++, *up2++);
     wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
   }
 }
 
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_bgrx(wuffs_base__pixel_buffer* dst,
-                                                uint32_t x,
-                                                uint32_t x_end,
-                                                uint32_t y,
-                                                const uint8_t* up0,
-                                                const uint8_t* up1,
-                                                const uint8_t* up2) {
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
   size_t dst_stride = dst->private_impl.planes[0].stride;
   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
 
   for (; x < x_end; x++) {
-    uint32_t color =                           //
-        wuffs_base__color_ycc__as__color_u32(  //
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601fr__as__color_u32(  //
             *up0++, *up1++, *up2++);
     wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
     dst_iter += 4u;
@@ -207,20 +208,82 @@
 }
 
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_rgbx(wuffs_base__pixel_buffer* dst,
-                                                uint32_t x,
-                                                uint32_t x_end,
-                                                uint32_t y,
-                                                const uint8_t* up0,
-                                                const uint8_t* up1,
-                                                const uint8_t* up2) {
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
   size_t dst_stride = dst->private_impl.planes[0].stride;
   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
 
   for (; x < x_end; x++) {
-    uint32_t color =                                //
-        wuffs_base__color_ycc__as__color_u32_abgr(  //
+    uint32_t color =                                        //
+        wuffs_base__color_ycc_bt601fr__as__color_u32_abgr(  //
+            *up0++, *up1++, *up2++);
+    wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
+    dst_iter += 4u;
+  }
+}
+
+static void  //
+wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_general(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
+  for (; x < x_end; x++) {
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601sr__as__color_u32(  //
+            *up0++, *up1++, *up2++);
+    wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
+  }
+}
+
+static void  //
+wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_bgrx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
+  size_t dst_stride = dst->private_impl.planes[0].stride;
+  uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+                      (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+  for (; x < x_end; x++) {
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601sr__as__color_u32(  //
+            *up0++, *up1++, *up2++);
+    wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
+    dst_iter += 4u;
+  }
+}
+
+static void  //
+wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_rgbx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
+  size_t dst_stride = dst->private_impl.planes[0].stride;
+  uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+                      (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+  for (; x < x_end; x++) {
+    uint32_t color =                                        //
+        wuffs_base__color_ycc_bt601sr__as__color_u32_abgr(  //
             *up0++, *up1++, *up2++);
     wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
     dst_iter += 4u;
@@ -1442,6 +1505,24 @@
 
   if (ycc_model >= WUFFS_BASE__YCC_MODEL__RGB) {
     conv3func = &wuffs_private_impl__swizzle_rgb__convert_3_general;
+
+  } else if (ycc_model == WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE) {
+    switch (dst->pixcfg.private_impl.pixfmt.repr) {
+      case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_bgrx;
+        break;
+      case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_rgbx;
+        break;
+      default:
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_general;
+        break;
+    }
+
   } else {
     switch (dst->pixcfg.private_impl.pixfmt.repr) {
       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
@@ -1449,25 +1530,27 @@
       case WUFFS_BASE__PIXEL_FORMAT__BGRX:
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
         if (wuffs_base__cpu_arch__have_x86_avx2()) {
-          conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2;
+          conv3func =
+              &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx_x86_avx2;
           break;
         }
 #endif
-        conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx;
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx;
         break;
       case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
       case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
       case WUFFS_BASE__PIXEL_FORMAT__RGBX:
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
         if (wuffs_base__cpu_arch__have_x86_avx2()) {
-          conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2;
+          conv3func =
+              &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx_x86_avx2;
           break;
         }
 #endif
-        conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx;
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx;
         break;
       default:
-        conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_general;
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_general;
         break;
     }
   }
@@ -1563,6 +1646,10 @@
   }
 
   if ((h3 != 0u) || (v3 != 0u)) {
+    if (ycc_model == WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE) {
+      return wuffs_base__make_status(
+          wuffs_base__error__unsupported_pixel_swizzler_option);
+    }
     wuffs_private_impl__swizzle_ycc__convert_4_func conv4func =
         (ycc_model >= WUFFS_BASE__YCC_MODEL__RGB)
             ? &wuffs_private_impl__swizzle_cmyk__convert_4_general
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 58dc5b4..1d9bfe3 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -4638,8 +4638,28 @@
 
 // wuffs_base__color_ycc__as__color_u32 converts from YCbCr to 0xAARRGGBB. The
 // alpha bits are always 0xFF.
+//
+// There is no YCC_MODEL (like bt601fr) in the macro name. For backwards
+// compatibility, it uses WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE, like JPEG.
+#define wuffs_base__color_ycc__as__color_u32 \
+  wuffs_base__color_ycc_bt601fr__as__color_u32
+
+// wuffs_base__color_ycc__as__color_u32_abgr is like
+// wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
+// 0xAABBGGRR order, not 0xAARRGGBB.
+//
+// There is no YCC_MODEL (like bt601fr) in the macro name. For backwards
+// compatibility, it uses WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE, like JPEG.
+#define wuffs_base__color_ycc__as__color_u32_abgr \
+  wuffs_base__color_ycc_bt601fr__as__color_u32_abgr
+
+// wuffs_base__color_ycc_bt601fr__as__color_u32 is
+// wuffs_base__color_ycc__as__color_u32 for
+// WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE.
 static inline wuffs_base__color_u32_argb_premul  //
-wuffs_base__color_ycc__as__color_u32(uint8_t yy, uint8_t cb, uint8_t cr) {
+wuffs_base__color_ycc_bt601fr__as__color_u32(uint8_t yy,
+                                             uint8_t cb,
+                                             uint8_t cr) {
   // Work in 16.16 fixed point arithmetic (so that 'one half' is (1 << 15)) and
   // bias the chroma values by 0x80.
   uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
@@ -4688,11 +4708,13 @@
          ((0x00FF0000 & bb32) >> 16);
 }
 
-// wuffs_base__color_ycc__as__color_u32_abgr is like
-// wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
-// 0xAABBGGRR order, not 0xAARRGGBB.
+// wuffs_base__color_ycc_bt601fr__as__color_u32_abgr is
+// wuffs_base__color_ycc__as__color_u32_abgr for
+// WUFFS_BASE__YCC_MODEL__BT_601_FULL_RANGE.
 static inline uint32_t  //
-wuffs_base__color_ycc__as__color_u32_abgr(uint8_t yy, uint8_t cb, uint8_t cr) {
+wuffs_base__color_ycc_bt601fr__as__color_u32_abgr(uint8_t yy,
+                                                  uint8_t cb,
+                                                  uint8_t cr) {
   uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
   uint32_t cb32 = (((uint32_t)cb) - 0x80);
   uint32_t cr32 = (((uint32_t)cr) - 0x80);
@@ -4714,8 +4736,66 @@
          ((0x00FF0000 & rr32) >> 16);
 }
 
-// wuffs_base__color_swap_u32_argb_abgr converts between 0xAARRGGBB and
-// 0xAABBGGRR.
+// wuffs_base__color_ycc_bt601sr__as__color_u32 is
+// wuffs_base__color_ycc__as__color_u32 for
+// WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE.
+static inline wuffs_base__color_u32_argb_premul  //
+wuffs_base__color_ycc_bt601sr__as__color_u32(uint8_t yy,
+                                             uint8_t cb,
+                                             uint8_t cr) {
+  // The constants here match those used in libwebp's src/dsp/yuv.h, using
+  // 18.14 fixed point arithmetic. (1 << 14) equals 16384.
+  //
+  // 19077 ≈ 16384 * 1.164
+  // 26149 ≈ 16384 * 1.596
+  //  6419 ≈ 16384 * 0.392
+  // 13320 ≈ 16384 * 0.813
+  // 33050 ≈ 16384 * 2.017
+  // 14234 ≈ 16384 * 0.869
+  //  8708 ≈ 16384 * 0.531
+  // 17685 ≈ 16384 * 1.079
+
+  int32_t y0 = ((int32_t)yy * 19077) >> 8;
+  int32_t rr = ((int32_t)cr * 26149) >> 8;
+  int32_t gb = ((int32_t)cb * 6419) >> 8;
+  int32_t gr = ((int32_t)cr * 13320) >> 8;
+  int32_t bb = ((int32_t)cb * 33050) >> 8;
+
+  int32_t r1 = y0 + rr - 14234;
+  int32_t g1 = y0 - gb - gr + 8708;
+  int32_t b1 = y0 + bb - 17685;
+
+  uint32_t r = (r1 < 0) ? 0u : (r1 > 16320) ? 255u : ((uint32_t)r1 >> 6);
+  uint32_t g = (g1 < 0) ? 0u : (g1 > 16320) ? 255u : ((uint32_t)g1 >> 6);
+  uint32_t b = (b1 < 0) ? 0u : (b1 > 16320) ? 255u : ((uint32_t)b1 >> 6);
+
+  return 0xFF000000u | (r << 16) | (g << 8) | b;
+}
+
+// wuffs_base__color_ycc_bt601sr__as__color_u32_abgr is
+// wuffs_base__color_ycc__as__color_u32_abgr for
+// WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE.
+static inline uint32_t  //
+wuffs_base__color_ycc_bt601sr__as__color_u32_abgr(uint8_t yy,
+                                                  uint8_t cb,
+                                                  uint8_t cr) {
+  int32_t y0 = ((int32_t)yy * 19077) >> 8;
+  int32_t rr = ((int32_t)cr * 26149) >> 8;
+  int32_t gb = ((int32_t)cb * 6419) >> 8;
+  int32_t gr = ((int32_t)cr * 13320) >> 8;
+  int32_t bb = ((int32_t)cb * 33050) >> 8;
+
+  int32_t r1 = y0 + rr - 14234;
+  int32_t g1 = y0 - gb - gr + 8708;
+  int32_t b1 = y0 + bb - 17685;
+
+  uint32_t r = (r1 < 0) ? 0u : (r1 > 16320) ? 255u : ((uint32_t)r1 >> 6);
+  uint32_t g = (g1 < 0) ? 0u : (g1 > 16320) ? 255u : ((uint32_t)g1 >> 6);
+  uint32_t b = (b1 < 0) ? 0u : (b1 > 16320) ? 255u : ((uint32_t)b1 >> 6);
+
+  return 0xFF000000u | (b << 16) | (g << 8) | r;
+}
+
 static inline uint32_t  //
 wuffs_base__color_swap_u32_argb_abgr(uint32_t u) {
   uint32_t o = u & 0xFF00FF00ul;
@@ -32258,7 +32338,7 @@
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -32269,7 +32349,7 @@
 
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -32369,8 +32449,8 @@
     const uint8_t* up3) {
   for (; x < x_end; x++) {
     // We invert once again: 0xFFu means no ink instead of full ink.
-    uint32_t color =                           //
-        wuffs_base__color_ycc__as__color_u32(  //
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601fr__as__color_u32(  //
             *up0++, *up1++, *up2++);
     uint32_t r = 0xFFu - (0xFFu & (color >> 16u));
     uint32_t g = 0xFFu - (0xFFu & (color >> 8u));
@@ -32414,7 +32494,7 @@
 }
 
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_general(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_general(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -32423,28 +32503,29 @@
     const uint8_t* up1,
     const uint8_t* up2) {
   for (; x < x_end; x++) {
-    uint32_t color =                           //
-        wuffs_base__color_ycc__as__color_u32(  //
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601fr__as__color_u32(  //
             *up0++, *up1++, *up2++);
     wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
   }
 }
 
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_bgrx(wuffs_base__pixel_buffer* dst,
-                                                uint32_t x,
-                                                uint32_t x_end,
-                                                uint32_t y,
-                                                const uint8_t* up0,
-                                                const uint8_t* up1,
-                                                const uint8_t* up2) {
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
   size_t dst_stride = dst->private_impl.planes[0].stride;
   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
 
   for (; x < x_end; x++) {
-    uint32_t color =                           //
-        wuffs_base__color_ycc__as__color_u32(  //
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601fr__as__color_u32(  //
             *up0++, *up1++, *up2++);
     wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
     dst_iter += 4u;
@@ -32452,20 +32533,82 @@
 }
 
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_rgbx(wuffs_base__pixel_buffer* dst,
-                                                uint32_t x,
-                                                uint32_t x_end,
-                                                uint32_t y,
-                                                const uint8_t* up0,
-                                                const uint8_t* up1,
-                                                const uint8_t* up2) {
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
   size_t dst_stride = dst->private_impl.planes[0].stride;
   uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
                       (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
 
   for (; x < x_end; x++) {
-    uint32_t color =                                //
-        wuffs_base__color_ycc__as__color_u32_abgr(  //
+    uint32_t color =                                        //
+        wuffs_base__color_ycc_bt601fr__as__color_u32_abgr(  //
+            *up0++, *up1++, *up2++);
+    wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
+    dst_iter += 4u;
+  }
+}
+
+static void  //
+wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_general(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
+  for (; x < x_end; x++) {
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601sr__as__color_u32(  //
+            *up0++, *up1++, *up2++);
+    wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
+  }
+}
+
+static void  //
+wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_bgrx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
+  size_t dst_stride = dst->private_impl.planes[0].stride;
+  uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+                      (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+  for (; x < x_end; x++) {
+    uint32_t color =                                   //
+        wuffs_base__color_ycc_bt601sr__as__color_u32(  //
+            *up0++, *up1++, *up2++);
+    wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
+    dst_iter += 4u;
+  }
+}
+
+static void  //
+wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_rgbx(
+    wuffs_base__pixel_buffer* dst,
+    uint32_t x,
+    uint32_t x_end,
+    uint32_t y,
+    const uint8_t* up0,
+    const uint8_t* up1,
+    const uint8_t* up2) {
+  size_t dst_stride = dst->private_impl.planes[0].stride;
+  uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+                      (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+  for (; x < x_end; x++) {
+    uint32_t color =                                        //
+        wuffs_base__color_ycc_bt601sr__as__color_u32_abgr(  //
             *up0++, *up1++, *up2++);
     wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
     dst_iter += 4u;
@@ -33687,6 +33830,24 @@
 
   if (ycc_model >= WUFFS_BASE__YCC_MODEL__RGB) {
     conv3func = &wuffs_private_impl__swizzle_rgb__convert_3_general;
+
+  } else if (ycc_model == WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE) {
+    switch (dst->pixcfg.private_impl.pixfmt.repr) {
+      case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_bgrx;
+        break;
+      case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+      case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_rgbx;
+        break;
+      default:
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601sr__convert_3_general;
+        break;
+    }
+
   } else {
     switch (dst->pixcfg.private_impl.pixfmt.repr) {
       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
@@ -33694,25 +33855,27 @@
       case WUFFS_BASE__PIXEL_FORMAT__BGRX:
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
         if (wuffs_base__cpu_arch__have_x86_avx2()) {
-          conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2;
+          conv3func =
+              &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx_x86_avx2;
           break;
         }
 #endif
-        conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx;
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx;
         break;
       case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
       case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
       case WUFFS_BASE__PIXEL_FORMAT__RGBX:
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
         if (wuffs_base__cpu_arch__have_x86_avx2()) {
-          conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2;
+          conv3func =
+              &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx_x86_avx2;
           break;
         }
 #endif
-        conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx;
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx;
         break;
       default:
-        conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_general;
+        conv3func = &wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_general;
         break;
     }
   }
@@ -33808,6 +33971,10 @@
   }
 
   if ((h3 != 0u) || (v3 != 0u)) {
+    if (ycc_model == WUFFS_BASE__YCC_MODEL__BT_601_STUDIO_RANGE) {
+      return wuffs_base__make_status(
+          wuffs_base__error__unsupported_pixel_swizzler_option);
+    }
     wuffs_private_impl__swizzle_ycc__convert_4_func conv4func =
         (ycc_model >= WUFFS_BASE__YCC_MODEL__RGB)
             ? &wuffs_private_impl__swizzle_cmyk__convert_4_general
@@ -33841,7 +34008,7 @@
 #if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3)
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -33850,7 +34017,7 @@
     const uint8_t* up1,
     const uint8_t* up2) {
   if ((x + 32u) > x_end) {
-    wuffs_private_impl__swizzle_ycc__convert_3_bgrx(  //
+    wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_bgrx(  //
         dst, x, x_end, y, up0, up1, up2);
     return;
   }
@@ -33875,7 +34042,7 @@
       +0x0000, -0x8000, +0x0000, -0x8000,        //
       +0x0000, -0x8000, +0x0000, -0x8000);
 
-  // Per wuffs_base__color_ycc__as__color_u32, the formulae:
+  // Per wuffs_base__color_ycc_bt601fr__as__color_u32, the formulae:
   //
   //  R = Y                + 1.40200 * Cr
   //  G = Y - 0.34414 * Cb - 0.71414 * Cr
@@ -34114,7 +34281,7 @@
 // except for the lines marked with a § and that comments were stripped.
 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
 static void  //
-wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2(
+wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx_x86_avx2(
     wuffs_base__pixel_buffer* dst,
     uint32_t x,
     uint32_t x_end,
@@ -34123,7 +34290,7 @@
     const uint8_t* up1,
     const uint8_t* up2) {
   if ((x + 32u) > x_end) {
-    wuffs_private_impl__swizzle_ycc__convert_3_rgbx(  //
+    wuffs_private_impl__swizzle_ycc_bt601fr__convert_3_rgbx(  //
         dst, x, x_end, y, up0, up1, up2);
     return;
   }