std/jpeg: tighten decoder workbuf_len worst case
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 4e1c680..e667f57 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -8648,7 +8648,7 @@
 
 // ---------------- Public Consts
 
-#define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 274877906944
+#define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 17184063744
 
 // ---------------- Struct Declarations
 
@@ -8809,7 +8809,8 @@
     uint8_t f_components_h[4];
     uint8_t f_components_v[4];
     uint8_t f_components_tq[4];
-    uint32_t f_components_workbuf_strides[4];
+    uint32_t f_components_workbuf_widths[4];
+    uint32_t f_components_workbuf_heights[4];
     uint64_t f_components_workbuf_offsets[5];
     uint32_t f_scan_num_components;
     uint8_t f_scan_comps_cselector[4];
@@ -37756,10 +37757,6 @@
   bool v_has_h3 = false;
   bool v_has_v24 = false;
   bool v_has_v3 = false;
-  uint64_t v_workbuf_fragment_length0 = 0;
-  uint64_t v_workbuf_fragment_length1 = 0;
-  uint64_t v_workbuf_fragment_length2 = 0;
-  uint64_t v_workbuf_fragment_length3 = 0;
 
   const uint8_t* iop_a_src = NULL;
   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
@@ -37991,31 +37988,33 @@
     } else {
       self->private_impl.f_height_in_mcus = ((self->private_impl.f_height + 31) / 32);
     }
-    self->private_impl.f_components_workbuf_strides[0] = (8 * ((uint32_t)(self->private_impl.f_width_in_mcus)) * ((uint32_t)(self->private_impl.f_components_h[0])));
-    self->private_impl.f_components_workbuf_strides[1] = (8 * ((uint32_t)(self->private_impl.f_width_in_mcus)) * ((uint32_t)(self->private_impl.f_components_h[1])));
-    self->private_impl.f_components_workbuf_strides[2] = (8 * ((uint32_t)(self->private_impl.f_width_in_mcus)) * ((uint32_t)(self->private_impl.f_components_h[2])));
-    self->private_impl.f_components_workbuf_strides[3] = (8 * ((uint32_t)(self->private_impl.f_width_in_mcus)) * ((uint32_t)(self->private_impl.f_components_h[3])));
-    v_workbuf_fragment_length0 = (8 *
-        ((uint64_t)(self->private_impl.f_components_workbuf_strides[0])) *
-        ((uint64_t)(self->private_impl.f_height_in_mcus)) *
-        ((uint64_t)(self->private_impl.f_components_v[0])));
-    v_workbuf_fragment_length1 = (8 *
-        ((uint64_t)(self->private_impl.f_components_workbuf_strides[1])) *
-        ((uint64_t)(self->private_impl.f_height_in_mcus)) *
-        ((uint64_t)(self->private_impl.f_components_v[1])));
-    v_workbuf_fragment_length2 = (8 *
-        ((uint64_t)(self->private_impl.f_components_workbuf_strides[2])) *
-        ((uint64_t)(self->private_impl.f_height_in_mcus)) *
-        ((uint64_t)(self->private_impl.f_components_v[2])));
-    v_workbuf_fragment_length3 = (8 *
-        ((uint64_t)(self->private_impl.f_components_workbuf_strides[3])) *
-        ((uint64_t)(self->private_impl.f_height_in_mcus)) *
-        ((uint64_t)(self->private_impl.f_components_v[3])));
+    v_i = 0;
+    while (v_i < self->private_impl.f_num_components) {
+      if (self->private_impl.f_components_h[v_i] == 1) {
+        self->private_impl.f_components_workbuf_widths[v_i] = (((self->private_impl.f_width + 7) / 8) * 8);
+      } else if (self->private_impl.f_components_h[v_i] == 2) {
+        self->private_impl.f_components_workbuf_widths[v_i] = (((self->private_impl.f_width + 15) / 16) * 16);
+      } else if (self->private_impl.f_components_h[v_i] == 3) {
+        self->private_impl.f_components_workbuf_widths[v_i] = (((self->private_impl.f_width + 23) / 24) * 24);
+      } else {
+        self->private_impl.f_components_workbuf_widths[v_i] = (((self->private_impl.f_width + 31) / 32) * 32);
+      }
+      if (self->private_impl.f_components_v[v_i] == 1) {
+        self->private_impl.f_components_workbuf_heights[v_i] = (((self->private_impl.f_height + 7) / 8) * 8);
+      } else if (self->private_impl.f_components_v[v_i] == 2) {
+        self->private_impl.f_components_workbuf_heights[v_i] = (((self->private_impl.f_height + 15) / 16) * 16);
+      } else if (self->private_impl.f_components_v[v_i] == 3) {
+        self->private_impl.f_components_workbuf_heights[v_i] = (((self->private_impl.f_height + 23) / 24) * 24);
+      } else {
+        self->private_impl.f_components_workbuf_heights[v_i] = (((self->private_impl.f_height + 31) / 32) * 32);
+      }
+      v_i += 1;
+    }
     self->private_impl.f_components_workbuf_offsets[0] = 0;
-    self->private_impl.f_components_workbuf_offsets[1] = (self->private_impl.f_components_workbuf_offsets[0] + v_workbuf_fragment_length0);
-    self->private_impl.f_components_workbuf_offsets[2] = (self->private_impl.f_components_workbuf_offsets[1] + v_workbuf_fragment_length1);
-    self->private_impl.f_components_workbuf_offsets[3] = (self->private_impl.f_components_workbuf_offsets[2] + v_workbuf_fragment_length2);
-    self->private_impl.f_components_workbuf_offsets[4] = (self->private_impl.f_components_workbuf_offsets[3] + v_workbuf_fragment_length3);
+    self->private_impl.f_components_workbuf_offsets[1] = (self->private_impl.f_components_workbuf_offsets[0] + (((uint64_t)(self->private_impl.f_components_workbuf_widths[0])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[0]))));
+    self->private_impl.f_components_workbuf_offsets[2] = (self->private_impl.f_components_workbuf_offsets[1] + (((uint64_t)(self->private_impl.f_components_workbuf_widths[1])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[1]))));
+    self->private_impl.f_components_workbuf_offsets[3] = (self->private_impl.f_components_workbuf_offsets[2] + (((uint64_t)(self->private_impl.f_components_workbuf_widths[2])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[2]))));
+    self->private_impl.f_components_workbuf_offsets[4] = (self->private_impl.f_components_workbuf_offsets[3] + (((uint64_t)(self->private_impl.f_components_workbuf_widths[3])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[3]))));
 
     goto ok;
     ok:
@@ -38852,7 +38851,7 @@
           v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
           v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
           v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
-          v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_strides[v_csel]));
+          v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
           v_offset = (self->private_impl.f_components_workbuf_offsets[v_csel] + (8 * (((v_h * ((uint64_t)(v_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) + (((v_v * ((uint64_t)(v_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride))));
           if (v_offset <= ((uint64_t)(a_workbuf.len))) {
             wuffs_jpeg__decoder__decode_idct(self,
@@ -39347,7 +39346,7 @@
       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_length);
     }
     wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), a_workbuf);
-    v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_strides[0]));
+    v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[0]));
     if (v_stride <= ((uint64_t)(a_workbuf.len))) {
       a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, v_stride);
     } else {
@@ -39400,18 +39399,18 @@
       v_src1,
       v_src2,
       v_src3,
-      (8 * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[0]))),
-      (8 * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[1]))),
-      (8 * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[2]))),
-      (8 * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[3]))),
-      (8 * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[0]))),
-      (8 * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[1]))),
-      (8 * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[2]))),
-      (8 * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[3]))),
-      self->private_impl.f_components_workbuf_strides[0],
-      self->private_impl.f_components_workbuf_strides[1],
-      self->private_impl.f_components_workbuf_strides[2],
-      self->private_impl.f_components_workbuf_strides[3],
+      self->private_impl.f_components_workbuf_widths[0],
+      self->private_impl.f_components_workbuf_widths[1],
+      self->private_impl.f_components_workbuf_widths[2],
+      self->private_impl.f_components_workbuf_widths[3],
+      self->private_impl.f_components_workbuf_heights[0],
+      self->private_impl.f_components_workbuf_heights[1],
+      self->private_impl.f_components_workbuf_heights[2],
+      self->private_impl.f_components_workbuf_heights[3],
+      self->private_impl.f_components_workbuf_widths[0],
+      self->private_impl.f_components_workbuf_widths[1],
+      self->private_impl.f_components_workbuf_widths[2],
+      self->private_impl.f_components_workbuf_widths[3],
       self->private_impl.f_components_h[0],
       self->private_impl.f_components_h[1],
       self->private_impl.f_components_h[2],
diff --git a/std/jpeg/decode_jpeg.wuffs b/std/jpeg/decode_jpeg.wuffs
index 33793fd..65a4461 100644
--- a/std/jpeg/decode_jpeg.wuffs
+++ b/std/jpeg/decode_jpeg.wuffs
@@ -35,7 +35,7 @@
 
 pri status "#internal error: inconsistent decoder state"
 
-pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0x40_0000_0000
+pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0x4_0040_0100
 
 pub struct decoder? implements base.image_decoder(
         width  : base.u32[..= 0xFFFF],
@@ -62,14 +62,15 @@
 
         // components_workbuf_offsets, indexed by (b) and (b + 1), is the i and
         // j bounds in the workbuf[i .. j] slice holding the post-IDCT values.
-        // components_workbuf_strides[b] is the stride between its rows.
+        // components_workbuf_widths[b] is the row width, which is also the row
+        // stride (there is no slack).
         //
         // For example, a 4:2:0 chroma-subsampled, 36 pixels wide × 28 pixels
         // high image has 6 blocks (4 Y, 1 Cb, 1 Cr; 8×8 samples each) per MCU.
         // Each MCU is 16×16 pixels. The image is 3 MCUs wide × 2 MCUs high.
         // The post-IDCT image dimensions round up to 48 × 32 pixels.
         //
-        // The components_workbuf_strides array is:
+        // The components_workbuf_widths array is:
         //   0: 0x30 = 48  // Y
         //   1: 0x18 = 24  // Cb
         //   2: 0x18 = 24  // Cr
@@ -81,8 +82,9 @@
         //   2: 0x790 = 1920 = previous + (24 * 16)
         //   3: 0x900 = 2304 = previous + (24 * 16)
         //   4: 0x900 = 2304 = previous + ( 0 *  0)
-        components_workbuf_strides : array[4] base.u32[..= 0x4_0000],
-        components_workbuf_offsets : array[5] base.u64[..= 0x40_0000_0000],
+        components_workbuf_widths  : array[4] base.u32[..= 0x1_0008],
+        components_workbuf_heights : array[4] base.u32[..= 0x1_0008],
+        components_workbuf_offsets : array[5] base.u64[..= 0x4_0040_0100],  // 4 * 0x1_0008 * 0x1_0008.
 
         scan_num_components  : base.u32[..= 4],
         scan_comps_cselector : array[4] base.u8[..= 3],
@@ -374,11 +376,6 @@
     var has_v24 : base.bool
     var has_v3  : base.bool
 
-    var workbuf_fragment_length0 : base.u64[..= 0x10_0000_0000]
-    var workbuf_fragment_length1 : base.u64[..= 0x10_0000_0000]
-    var workbuf_fragment_length2 : base.u64[..= 0x10_0000_0000]
-    var workbuf_fragment_length3 : base.u64[..= 0x10_0000_0000]
-
     if this.payload_length < 6 {
         return "#bad SOF marker"
     }
@@ -501,29 +498,42 @@
         this.height_in_mcus = (this.height + 0x1F) / 0x20
     }
 
-    this.components_workbuf_strides[0] = 8 *
-            (this.width_in_mcus as base.u32) * (this.components_h[0] as base.u32)
-    this.components_workbuf_strides[1] = 8 *
-            (this.width_in_mcus as base.u32) * (this.components_h[1] as base.u32)
-    this.components_workbuf_strides[2] = 8 *
-            (this.width_in_mcus as base.u32) * (this.components_h[2] as base.u32)
-    this.components_workbuf_strides[3] = 8 *
-            (this.width_in_mcus as base.u32) * (this.components_h[3] as base.u32)
+    i = 0
+    while i < this.num_components {
+        assert i < 4 via "a < b: a < c; c <= b"(c: this.num_components)
 
-    workbuf_fragment_length0 = 8 * (this.components_workbuf_strides[0] as base.u64) *
-            (this.height_in_mcus as base.u64) * (this.components_v[0] as base.u64)
-    workbuf_fragment_length1 = 8 * (this.components_workbuf_strides[1] as base.u64) *
-            (this.height_in_mcus as base.u64) * (this.components_v[1] as base.u64)
-    workbuf_fragment_length2 = 8 * (this.components_workbuf_strides[2] as base.u64) *
-            (this.height_in_mcus as base.u64) * (this.components_v[2] as base.u64)
-    workbuf_fragment_length3 = 8 * (this.components_workbuf_strides[3] as base.u64) *
-            (this.height_in_mcus as base.u64) * (this.components_v[3] as base.u64)
+        if this.components_h[i] == 1 {
+            this.components_workbuf_widths[i] = ((this.width + 0x07) / 0x08) * 0x08
+        } else if this.components_h[i] == 2 {
+            this.components_workbuf_widths[i] = ((this.width + 0x0F) / 0x10) * 0x10
+        } else if this.components_h[i] == 3 {
+            this.components_workbuf_widths[i] = ((this.width + 0x17) / 0x18) * 0x18
+        } else {
+            this.components_workbuf_widths[i] = ((this.width + 0x1F) / 0x20) * 0x20
+        }
+
+        if this.components_v[i] == 1 {
+            this.components_workbuf_heights[i] = ((this.height + 0x07) / 0x08) * 0x08
+        } else if this.components_v[i] == 2 {
+            this.components_workbuf_heights[i] = ((this.height + 0x0F) / 0x10) * 0x10
+        } else if this.components_v[i] == 3 {
+            this.components_workbuf_heights[i] = ((this.height + 0x17) / 0x18) * 0x18
+        } else {
+            this.components_workbuf_heights[i] = ((this.height + 0x1F) / 0x20) * 0x20
+        }
+
+        i += 1
+    } endwhile
 
     this.components_workbuf_offsets[0] = 0
-    this.components_workbuf_offsets[1] = this.components_workbuf_offsets[0] + workbuf_fragment_length0
-    this.components_workbuf_offsets[2] = this.components_workbuf_offsets[1] + workbuf_fragment_length1
-    this.components_workbuf_offsets[3] = this.components_workbuf_offsets[2] + workbuf_fragment_length2
-    this.components_workbuf_offsets[4] = this.components_workbuf_offsets[3] + workbuf_fragment_length3
+    this.components_workbuf_offsets[1] = this.components_workbuf_offsets[0] +
+            ((this.components_workbuf_widths[0] as base.u64) * (this.components_workbuf_heights[0] as base.u64))
+    this.components_workbuf_offsets[2] = this.components_workbuf_offsets[1] +
+            ((this.components_workbuf_widths[1] as base.u64) * (this.components_workbuf_heights[1] as base.u64))
+    this.components_workbuf_offsets[3] = this.components_workbuf_offsets[2] +
+            ((this.components_workbuf_widths[2] as base.u64) * (this.components_workbuf_heights[2] as base.u64))
+    this.components_workbuf_offsets[4] = this.components_workbuf_offsets[3] +
+            ((this.components_workbuf_widths[3] as base.u64) * (this.components_workbuf_heights[3] as base.u64))
 }
 
 pub func decoder.decode_frame_config?(dst: nptr base.frame_config, src: base.io_reader) {
@@ -991,7 +1001,7 @@
                 csel = this.scan_comps_cselector[this.mcu_blocks_sselector[b]]
                 h = this.components_h[csel] as base.u64
                 v = this.components_v[csel] as base.u64
-                stride = this.components_workbuf_strides[csel] as base.u64
+                stride = this.components_workbuf_widths[csel] as base.u64
                 offset = this.components_workbuf_offsets[csel] + (8 *
                         ((((h * (mx as base.u64)) + (this.scan_comps_bx_offset[b] as base.u64))) +
                         ((((v * (my as base.u64)) + (this.scan_comps_by_offset[b] as base.u64))) * stride)))
@@ -1360,7 +1370,7 @@
                 dst: dst,
                 dst_palette: args.dst.palette_or_else(fallback: this.dst_palette[..]),
                 src: args.workbuf)
-        stride = this.components_workbuf_strides[0] as base.u64
+        stride = this.components_workbuf_widths[0] as base.u64
         if stride <= args.workbuf.length() {
             args.workbuf = args.workbuf[stride ..]
         } else {
@@ -1407,18 +1417,18 @@
             src1: src1,
             src2: src2,
             src3: src3,
-            width0: 8 * this.width_in_mcus * (this.components_h[0] as base.u32),
-            width1: 8 * this.width_in_mcus * (this.components_h[1] as base.u32),
-            width2: 8 * this.width_in_mcus * (this.components_h[2] as base.u32),
-            width3: 8 * this.width_in_mcus * (this.components_h[3] as base.u32),
-            height0: 8 * this.height_in_mcus * (this.components_v[0] as base.u32),
-            height1: 8 * this.height_in_mcus * (this.components_v[1] as base.u32),
-            height2: 8 * this.height_in_mcus * (this.components_v[2] as base.u32),
-            height3: 8 * this.height_in_mcus * (this.components_v[3] as base.u32),
-            stride0: this.components_workbuf_strides[0],
-            stride1: this.components_workbuf_strides[1],
-            stride2: this.components_workbuf_strides[2],
-            stride3: this.components_workbuf_strides[3],
+            width0: this.components_workbuf_widths[0],
+            width1: this.components_workbuf_widths[1],
+            width2: this.components_workbuf_widths[2],
+            width3: this.components_workbuf_widths[3],
+            height0: this.components_workbuf_heights[0],
+            height1: this.components_workbuf_heights[1],
+            height2: this.components_workbuf_heights[2],
+            height3: this.components_workbuf_heights[3],
+            stride0: this.components_workbuf_widths[0],
+            stride1: this.components_workbuf_widths[1],
+            stride2: this.components_workbuf_widths[2],
+            stride3: this.components_workbuf_widths[3],
             h0: this.components_h[0],
             h1: this.components_h[1],
             h2: this.components_h[2],