Allow an LZW literal width of 0
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 251be3b..dbf5a7b 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -8140,12 +8140,12 @@
if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
return wuffs_base__make_empty_struct();
}
- if (a_lw < 1 || a_lw > 8) {
+ 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;
+ self->private_impl.f_set_literal_width_arg = (a_lw + 1);
return wuffs_base__make_empty_struct();
}
@@ -8198,7 +8198,7 @@
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;
+ (self->private_impl.f_set_literal_width_arg - 1);
}
self->private_impl.f_clear_code =
(((uint32_t)(1)) << self->private_impl.f_literal_width);
@@ -9307,7 +9307,7 @@
uint8_t t_1 = *iop_a_src++;
v_lw = t_1;
}
- if ((v_lw < 1) || (8 < v_lw)) {
+ if (v_lw > 8) {
status = wuffs_gif__error__bad_literal_width;
goto exit;
}
@@ -10800,7 +10800,7 @@
uint8_t t_2 = *iop_a_src++;
v_lw = t_2;
}
- if ((v_lw < 1) || (8 < v_lw)) {
+ if (v_lw > 8) {
status = wuffs_gif__error__bad_literal_width;
goto exit;
}
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index 920d714..e999ff2 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -451,7 +451,7 @@
// Process the LZW literal width.
lw = args.src.read_u8?()
- if (lw < 1) or (8 < lw) {
+ if lw > 8 {
return "#bad literal width"
}
@@ -942,9 +942,9 @@
// Process the LZW literal width. The spec says that "images which have one
// color bit must be indicated as having a code size [i.e. literal width]
- // of 2", but in practice, some encoders use a literal width of 1.
+ // of 2", but in practice, some encoders use a literal width of 1 or 0.
lw = args.src.read_u8?()
- if (lw < 1) or (8 < lw) {
+ if lw > 8 {
return "#bad literal width"
}
this.lzw.set_literal_width!(lw:lw as base.u32)
diff --git a/std/lzw/decode_lzw.wuffs b/std/lzw/decode_lzw.wuffs
index 2a984ae..5f02e99 100644
--- a/std/lzw/decode_lzw.wuffs
+++ b/std/lzw/decode_lzw.wuffs
@@ -27,11 +27,11 @@
pub const decoder_workbuf_len_max_incl_worst_case base.u64 = 0
pub struct decoder?(
- // set_literal_width_arg is the saved argument passed to set_literal_width.
- // This field is copied to the literal_width field at the start of
- // decode_io_writer. During that method, calling set_literal_width will
- // change set_literal_width_arg but not literal_width.
- set_literal_width_arg base.u32[..8],
+ // 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 decode_io_writer. During that method, calling set_literal_width
+ // will change set_literal_width_arg but not literal_width.
+ set_literal_width_arg base.u32[..9],
// read_from state that does not change during a decode call.
literal_width base.u32[..8],
@@ -69,8 +69,8 @@
output array[8192 + 7] base.u8,
)
-pub func decoder.set_literal_width!(lw base.u32[1..8]) {
- this.set_literal_width_arg = args.lw
+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 {
@@ -83,7 +83,7 @@
// Initialize read_from state.
this.literal_width = 8
if this.set_literal_width_arg > 0 {
- this.literal_width = this.set_literal_width_arg
+ this.literal_width = this.set_literal_width_arg - 1
}
this.clear_code = (1 as base.u32) << this.literal_width
this.end_code = this.clear_code + 1