diff --git a/crates/image/src/gif.rs b/crates/image/src/gif.rs index bcd97a5..8e75100 100644 --- a/crates/image/src/gif.rs +++ b/crates/image/src/gif.rs @@ -147,8 +147,8 @@ impl LzwDecoder { if self.next_code < 4096 { self.table.push((prefix, suffix)); self.next_code += 1; - // Increase code size when we've filled the current capacity - if self.next_code > (1 << self.code_size) && self.code_size < 12 { + // Increase code size when all codes at the current size are used (early change) + if self.next_code >= (1 << self.code_size) && self.code_size < 12 { self.code_size += 1; } } @@ -848,7 +848,7 @@ mod tests { fn lzw_simple_sequence() { // LZW with min code size 2 (codes 0-3 are literal, 4=clear, 5=eoi) // Encode a simple sequence: clear, 0, 1, 0, 1, eoi - // Using 3-bit codes (min_code_size=2, initial code_size=3) + // initial code_size=3, bumps to 4 after next_code reaches 8 let mut bits: u64 = 0; let mut bit_pos = 0u32; @@ -856,9 +856,9 @@ mod tests { (4, 3), // clear code (0, 3), // literal 0 (1, 3), // literal 1 - (0, 3), // literal 0 - (1, 3), // literal 1 - (5, 3), // eoi + (0, 3), // literal 0 → add_entry makes next_code=8, code_size→4 + (1, 4), // literal 1 (now 4 bits) + (5, 4), // eoi (4 bits) ]; for &(code, nbits) in codes { @@ -1256,11 +1256,11 @@ mod tests { // LZW min code size = 2 (4 literal codes: 0,1,2,3; clear=4, eoi=5) gif.push(2); - // Encode: clear(4), 0, 1, 2, 3, eoi(5) — all 3-bit codes - // 9 codes * 3 bits = 18 bits = 3 bytes (with padding) + // Encode: clear(4), 0, 1, 2, 3, eoi(5) + // code_size starts at 3, bumps to 4 after code 2 (next_code reaches 8) let mut bits: u64 = 0; let mut bp = 0u32; - for &(code, nbits) in &[(4u16, 3u8), (0, 3), (1, 3), (2, 3), (3, 3), (5, 3)] { + for &(code, nbits) in &[(4u16, 3u8), (0, 3), (1, 3), (2, 3), (3, 4), (5, 4)] { bits |= (code as u64) << bp; bp += nbits as u32; }