std/lzw: change set_literal_width to set_quirk
diff --git a/doc/changelog.md b/doc/changelog.md
index 2ec1c6c..83723aa 100644
--- a/doc/changelog.md
+++ b/doc/changelog.md
@@ -3,10 +3,10 @@
 
 ## Work In Progress
 
+- Changed `lzw.set_literal_width` to `lzw.set_quirk`.
 - Changed `set_quirk_enabled!(quirk: u32, enabled: bool)` to `set_quirk!(key:
   u32, value: u64) status`.
 
-
 The dot points below probably aren't of interest unless you're _writing_ Wuffs
 code (instead of writing C/C++ code that _uses_ Wuffs' standard library).
 
diff --git a/doc/note/quirks.md b/doc/note/quirks.md
index a24d1e3..193f3bd 100644
--- a/doc/note/quirks.md
+++ b/doc/note/quirks.md
@@ -30,20 +30,26 @@
 
 ## Wuffs API
 
-Each quirk is assigned a `uint32_t` value, packed using the [base38 namespace
+Each quirk is assigned a `uint32_t` number, packed using the [base38 namespace
 convention](/doc/note/base38-and-fourcc.md). Decoders and encoders can have a
-`set_quirk!(key: base.u32, value: base.u64) base.status` method whose first
-argument is this `uint32_t` value.
+`set_quirk!(key: base.u32, value: base.u64) base.status` method whose key
+argument is this `uint32_t` number.
 
 For example, the base38 encoding of `"gif "` and `"json"` is `0x0F8586` and
-`0x124265` respectively, so that the GIF-specific quirks have a `uint32_t`
-value of `((0x0F8586 << 10) | g)`, and the JSON-specific quirks have a
-`uint32_t` value of `((0x124265 << 10) | j)`, for some small integers `g` and
-`j`. The high bits are a namespace. The overall quirk values are different even
-if `g` and `j` re-use the same 10-bit integer.
+`0x124265` respectively, so that the GIF-specific quirks have a `uint32_t` key
+of `((0x0F8586 << 10) | g)` and the JSON-specific quirks have a `uint32_t` key
+of `((0x124265 << 10) | j)`, for some small integers `g` and `j`. The high bits
+are a namespace. The overall quirk keys are different even if `g` and `j`
+re-use the same 10-bit integer.
 
 The generated `C` language file defines human-readable names for those constant
-values, such as `WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK`.
+numbers, such as `WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK`.
+
+The value argument (a `uint64_t` number) is often effectively a boolean: zero
+means to disable and non-zero to enable the quirk. But `set_quirk` is sometimes
+also used to pass out-of-band configuration, and not necessarily due to
+underspecified file formats, such as `WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE`.
+For those cases, zero typically means to use the default configuration.
 
 
 ## Listing
@@ -61,4 +67,5 @@
 
 - [GIF image decoder quirks](/std/gif/decode_quirks.wuffs)
 - [JSON decoder quirks](/std/json/decode_quirks.wuffs)
+- [LZW decoder quirks](/std/lzw/decode_quirks.wuffs)
 - [ZLIB decoder quirks](/std/zlib/decode_quirks.wuffs)
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index e29195f..3a9bc18 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -7694,6 +7694,8 @@
 
 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
 
+#define WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE 1348378624
+
 // ---------------- Struct Declarations
 
 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
@@ -7752,11 +7754,6 @@
     uint32_t a_key,
     uint64_t a_value);
 
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
-wuffs_lzw__decoder__set_literal_width(
-    wuffs_lzw__decoder* self,
-    uint32_t a_lw);
-
 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
 wuffs_lzw__decoder__workbuf_len(
     const wuffs_lzw__decoder* self);
@@ -7799,7 +7796,7 @@
     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
     wuffs_base__vtable null_vtable;
 
-    uint32_t f_set_literal_width_arg;
+    uint32_t f_pending_literal_width_plus_one;
     uint32_t f_literal_width;
     uint32_t f_clear_code;
     uint32_t f_end_code;
@@ -7892,12 +7889,6 @@
     return wuffs_lzw__decoder__set_quirk(this, a_key, a_value);
   }
 
-  inline wuffs_base__empty_struct
-  set_literal_width(
-      uint32_t a_lw) {
-    return wuffs_lzw__decoder__set_literal_width(this, a_lw);
-  }
-
   inline wuffs_base__range_ii_u64
   workbuf_len() const {
     return wuffs_lzw__decoder__workbuf_len(this);
@@ -31051,6 +31042,8 @@
 
 // ---------------- Private Consts
 
+#define WUFFS_LZW__QUIRKS_BASE 1348378624
+
 // ---------------- Private Initializer Prototypes
 
 // ---------------- Private Function Prototypes
@@ -31167,30 +31160,16 @@
         : wuffs_base__error__initialize_not_called);
   }
 
+  if (a_key == 1348378624) {
+    if (a_value > 9) {
+      return wuffs_base__make_status(wuffs_base__error__bad_argument);
+    }
+    self->private_impl.f_pending_literal_width_plus_one = ((uint32_t)(a_value));
+    return wuffs_base__make_status(NULL);
+  }
   return wuffs_base__make_status(wuffs_base__error__unsupported_option);
 }
 
-// -------- func lzw.decoder.set_literal_width
-
-WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
-wuffs_lzw__decoder__set_literal_width(
-    wuffs_lzw__decoder* self,
-    uint32_t a_lw) {
-  if (!self) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
-    return wuffs_base__make_empty_struct();
-  }
-  if (a_lw > 8) {
-    self->private_impl.magic = WUFFS_BASE__DISABLED;
-    return wuffs_base__make_empty_struct();
-  }
-
-  self->private_impl.f_set_literal_width_arg = (a_lw + 1);
-  return wuffs_base__make_empty_struct();
-}
-
 // -------- func lzw.decoder.workbuf_len
 
 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
@@ -31243,8 +31222,8 @@
     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
 
     self->private_impl.f_literal_width = 8;
-    if (self->private_impl.f_set_literal_width_arg > 0) {
-      self->private_impl.f_literal_width = (self->private_impl.f_set_literal_width_arg - 1);
+    if (self->private_impl.f_pending_literal_width_plus_one > 0) {
+      self->private_impl.f_literal_width = (self->private_impl.f_pending_literal_width_plus_one - 1);
     }
     self->private_impl.f_clear_code = (((uint32_t)(1)) << self->private_impl.f_literal_width);
     self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1);
@@ -34006,7 +33985,7 @@
       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
       goto exit;
     }
-    wuffs_lzw__decoder__set_literal_width(&self->private_data.f_lzw, ((uint32_t)(v_lw)));
+    wuffs_lzw__decoder__set_quirk(&self->private_data.f_lzw, 1348378624, ((uint64_t)((1 + v_lw))));
     self->private_impl.f_previous_lzw_decode_ended_abruptly = true;
 
     ok:
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index c4619e1..74600fe 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -899,7 +899,7 @@
     if lw > 8 {
         return "#bad literal width"
     }
-    this.lzw.set_literal_width!(lw: lw as base.u32)
+    this.lzw.set_quirk!(key: lzw.QUIRK_LITERAL_WIDTH_PLUS_ONE, value: (1 + lw) as base.u64)
 
     this.previous_lzw_decode_ended_abruptly = true
 }
diff --git a/std/lzw/decode_lzw.wuffs b/std/lzw/decode_lzw.wuffs
index 01ee8f5..c02a6de 100644
--- a/std/lzw/decode_lzw.wuffs
+++ b/std/lzw/decode_lzw.wuffs
@@ -28,11 +28,11 @@
 pub const DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE : base.u64 = 0
 
 pub struct decoder? implements base.io_transformer(
-        // set_literal_width_arg is 1 plus the saved argument passed to
-        // set_literal_width. This is assigned to the literal_width field at the
-        // start of transform_io. During that method, calling set_literal_width
-        // will change set_literal_width_arg but not literal_width.
-        set_literal_width_arg : base.u32[..= 9],
+        // pending_literal_width_plus_one is 1 plus the saved argument passed
+        // to set_quirk. This is assigned to the literal_width field at the
+        // start of transform_io. During that method, calling set_quirk will
+        // change pending_literal_width_plus_one but not literal_width.
+        pending_literal_width_plus_one : base.u32[..= 9],
 
         // read_from state that does not change during a decode call.
         literal_width : base.u32[..= 8],
@@ -71,13 +71,16 @@
 )
 
 pub func decoder.set_quirk!(key: base.u32, value: base.u64) base.status {
+    if args.key == QUIRK_LITERAL_WIDTH_PLUS_ONE {
+        if args.value > 9 {
+            return base."#bad argument"
+        }
+        this.pending_literal_width_plus_one = args.value as base.u32
+        return ok
+    }
     return base."#unsupported option"
 }
 
-pub func decoder.set_literal_width!(lw: base.u32[..= 8]) {
-    this.set_literal_width_arg = args.lw + 1
-}
-
 pub func decoder.workbuf_len() base.range_ii_u64 {
     return this.util.make_range_ii_u64(min_incl: 0, max_incl: 0)
 }
@@ -87,8 +90,8 @@
 
     // Initialize read_from state.
     this.literal_width = 8
-    if this.set_literal_width_arg > 0 {
-        this.literal_width = this.set_literal_width_arg - 1
+    if this.pending_literal_width_plus_one > 0 {
+        this.literal_width = this.pending_literal_width_plus_one - 1
     }
     this.clear_code = (1 as base.u32) << this.literal_width
     this.end_code = this.clear_code + 1
diff --git a/std/lzw/decode_quirks.wuffs b/std/lzw/decode_quirks.wuffs
new file mode 100644
index 0000000..4a29a07
--- /dev/null
+++ b/std/lzw/decode_quirks.wuffs
@@ -0,0 +1,28 @@
+// Copyright 2023 The Wuffs Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// --------
+
+// Quirks are discussed in (/doc/note/quirks.md).
+//
+// The base38 encoding of "lzw " is 0x1417A8. Left shifting by 10 gives
+// 0x505E_A000.
+pri const QUIRKS_BASE : base.u32 = 0x505E_A000
+
+// --------
+
+// When this quirk is set (to a value in the range 0 ..= 9), a positive value
+// is one more than the initial number of bits of a literal code. Zero means to
+// use the default literal width, 8.
+pub const QUIRK_LITERAL_WIDTH_PLUS_ONE : base.u32 = 0x505E_A000 | 0x00
diff --git a/test/c/std/lzw.c b/test/c/std/lzw.c
index a18faaa..eeee121 100644
--- a/test/c/std/lzw.c
+++ b/test/c/std/lzw.c
@@ -149,7 +149,8 @@
                wuffs_lzw__decoder__initialize(
                    &dec, sizeof dec, WUFFS_VERSION,
                    WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
-  wuffs_lzw__decoder__set_literal_width(&dec, literal_width);
+  wuffs_lzw__decoder__set_quirk(&dec, WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE,
+                                literal_width + 1);
   int num_iters = 0;
   while (true) {
     num_iters++;
@@ -267,7 +268,8 @@
                wuffs_lzw__decoder__initialize(
                    &dec, sizeof dec, WUFFS_VERSION,
                    WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
-  wuffs_lzw__decoder__set_literal_width(&dec, 7);
+  wuffs_lzw__decoder__set_quirk(&dec, WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE,
+                                7 + 1);
 
   wuffs_base__status status =
       wuffs_lzw__decoder__transform_io(&dec, &have, &src, g_work_slice_u8);
@@ -310,7 +312,8 @@
                wuffs_lzw__decoder__initialize(
                    &dec, sizeof dec, WUFFS_VERSION,
                    WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
-  wuffs_lzw__decoder__set_literal_width(&dec, 8);
+  wuffs_lzw__decoder__set_quirk(&dec, WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE,
+                                8 + 1);
 
   CHECK_STATUS("transform_io", wuffs_lzw__decoder__transform_io(
                                    &dec, &have, &src, g_work_slice_u8));
@@ -333,7 +336,8 @@
                wuffs_lzw__decoder__initialize(
                    &dec, sizeof dec, WUFFS_VERSION,
                    WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
-  wuffs_lzw__decoder__set_literal_width(&dec, width);
+  wuffs_lzw__decoder__set_quirk(&dec, WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE,
+                                width + 1);
 
   wuffs_base__io_buffer have = ((wuffs_base__io_buffer){
       .data = g_have_slice_u8,