1use gamut_core::{Error, Result};
23
24use crate::vp8l::bit_io::{BitReader, BitWriter};
25
26pub const MAX_CODE_LENGTH: usize = 15;
28pub const NUM_LITERAL_CODES: usize = 256;
30pub const NUM_LENGTH_CODES: usize = 24;
32pub const NUM_DISTANCE_CODES: usize = 40;
34pub const CODE_LENGTH_CODES: usize = 19;
36
37pub const CODE_LENGTH_CODE_ORDER: [usize; CODE_LENGTH_CODES] = [
39 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
40];
41
42const DEFAULT_CODE_LENGTH: u8 = 8;
44
45#[must_use]
47pub fn green_alphabet_size(color_cache_size: usize) -> usize {
48 NUM_LITERAL_CODES + NUM_LENGTH_CODES + color_cache_size
49}
50
51#[must_use]
54pub fn reverse_bits(value: u16, num_bits: u8) -> u16 {
55 let mut v = value;
56 let mut r = 0u16;
57 for _ in 0..num_bits {
58 r = (r << 1) | (v & 1);
59 v >>= 1;
60 }
61 r
62}
63
64#[derive(Debug, Clone)]
70pub struct PrefixCode {
71 counts: [u16; MAX_CODE_LENGTH + 1],
73 symbols: Vec<u16>,
75 single: Option<u16>,
77}
78
79impl PrefixCode {
80 pub fn from_code_lengths(code_lengths: &[u8]) -> Result<Self> {
88 let mut counts = [0u16; MAX_CODE_LENGTH + 1];
89 let mut n_used = 0usize;
90 let mut last_used = 0u16;
91 for (sym, &len) in code_lengths.iter().enumerate() {
92 if len as usize > MAX_CODE_LENGTH {
93 return Err(Error::InvalidInput("VP8L: prefix code length too large"));
94 }
95 if len > 0 {
96 counts[len as usize] += 1;
97 n_used += 1;
98 last_used = sym as u16;
99 }
100 }
101 if n_used == 0 {
102 return Err(Error::InvalidInput("VP8L: empty prefix code"));
103 }
104 if n_used == 1 {
105 return Ok(Self {
106 counts,
107 symbols: Vec::new(),
108 single: Some(last_used),
109 });
110 }
111 let mut left = 1i32;
113 for &count in counts.iter().take(MAX_CODE_LENGTH + 1).skip(1) {
114 left <<= 1;
115 left -= i32::from(count);
116 if left < 0 {
117 return Err(Error::InvalidInput("VP8L: over-subscribed prefix code"));
118 }
119 }
120 if left != 0 {
121 return Err(Error::InvalidInput("VP8L: incomplete prefix code"));
122 }
123 let mut offsets = [0usize; MAX_CODE_LENGTH + 2];
125 for len in 1..=MAX_CODE_LENGTH {
126 offsets[len + 1] = offsets[len] + usize::from(counts[len]);
127 }
128 let mut symbols = vec![0u16; n_used];
129 for (sym, &len) in code_lengths.iter().enumerate() {
130 if len > 0 {
131 let slot = &mut offsets[len as usize];
132 symbols[*slot] = sym as u16;
133 *slot += 1;
134 }
135 }
136 Ok(Self {
137 counts,
138 symbols,
139 single: None,
140 })
141 }
142
143 pub fn read_symbol(&self, r: &mut BitReader<'_>) -> Result<u16> {
149 if let Some(sym) = self.single {
150 return Ok(sym);
151 }
152 let mut code: i32 = 0;
153 let mut first: i32 = 0;
154 let mut index: usize = 0;
155 for len in 1..=MAX_CODE_LENGTH {
156 code |= r.read_bit()? as i32;
157 let count = i32::from(self.counts[len]);
158 if code - first < count {
159 let pos = index + (code - first) as usize;
160 return self
161 .symbols
162 .get(pos)
163 .copied()
164 .ok_or(Error::InvalidInput("VP8L: prefix code index out of range"));
165 }
166 index += count as usize;
167 first += count;
168 first <<= 1;
169 code <<= 1;
170 }
171 Err(Error::InvalidInput("VP8L: invalid prefix code"))
172 }
173}
174
175pub fn read_prefix_code(r: &mut BitReader<'_>, alphabet_size: usize) -> Result<PrefixCode> {
182 if r.read_bit()? == 1 {
183 read_simple_prefix_code(r, alphabet_size)
184 } else {
185 read_normal_prefix_code(r, alphabet_size)
186 }
187}
188
189fn read_simple_prefix_code(r: &mut BitReader<'_>, alphabet_size: usize) -> Result<PrefixCode> {
191 let num_symbols = r.read_bit()? + 1; let is_first_8bits = r.read_bit()?;
193 let mut lengths = vec![0u8; alphabet_size];
194 let symbol0 = r.read_bits(1 + 7 * is_first_8bits)? as usize;
195 if symbol0 >= alphabet_size {
196 return Err(Error::InvalidInput(
197 "VP8L: simple prefix symbol out of range",
198 ));
199 }
200 lengths[symbol0] = 1;
201 if num_symbols == 2 {
202 let symbol1 = r.read_bits(8)? as usize;
203 if symbol1 >= alphabet_size {
204 return Err(Error::InvalidInput(
205 "VP8L: simple prefix symbol out of range",
206 ));
207 }
208 lengths[symbol1] = 1;
209 }
210 PrefixCode::from_code_lengths(&lengths)
211}
212
213fn read_normal_prefix_code(r: &mut BitReader<'_>, alphabet_size: usize) -> Result<PrefixCode> {
216 let num_code_lengths = 4 + r.read_bits(4)? as usize;
217 if num_code_lengths > CODE_LENGTH_CODES {
218 return Err(Error::InvalidInput("VP8L: too many code-length codes"));
219 }
220 let mut cl_lengths = [0u8; CODE_LENGTH_CODES];
221 for &order in CODE_LENGTH_CODE_ORDER.iter().take(num_code_lengths) {
222 cl_lengths[order] = r.read_bits(3)? as u8;
223 }
224 let cl_code = PrefixCode::from_code_lengths(&cl_lengths)?;
225
226 let mut max_symbol = if r.read_bit()? != 0 {
227 let length_nbits = 2 + 2 * r.read_bits(3)?;
228 2 + r.read_bits(length_nbits)? as usize
229 } else {
230 alphabet_size
231 };
232 if max_symbol > alphabet_size {
233 return Err(Error::InvalidInput("VP8L: max_symbol exceeds alphabet"));
234 }
235
236 let mut lengths = vec![0u8; alphabet_size];
237 let mut prev_len = DEFAULT_CODE_LENGTH;
238 let mut symbol = 0usize;
239 while symbol < alphabet_size {
240 if max_symbol == 0 {
241 break;
242 }
243 max_symbol -= 1;
244 let code = cl_code.read_symbol(r)?;
245 if code < 16 {
246 lengths[symbol] = code as u8;
247 symbol += 1;
248 if code != 0 {
249 prev_len = code as u8;
250 }
251 } else {
252 let (extra_bits, repeat_offset, value) = match code {
253 16 => (2u32, 3usize, prev_len),
254 17 => (3, 3, 0),
255 18 => (7, 11, 0),
256 _ => return Err(Error::InvalidInput("VP8L: invalid code-length symbol")),
257 };
258 let repeat = repeat_offset + r.read_bits(extra_bits)? as usize;
259 if symbol + repeat > alphabet_size {
260 return Err(Error::InvalidInput(
261 "VP8L: code-length repeat overruns alphabet",
262 ));
263 }
264 for _ in 0..repeat {
265 lengths[symbol] = value;
266 symbol += 1;
267 }
268 }
269 }
270 PrefixCode::from_code_lengths(&lengths)
271}
272
273#[derive(Debug, Clone)]
275pub struct PrefixCodeGroup {
276 pub green: PrefixCode,
278 pub red: PrefixCode,
280 pub blue: PrefixCode,
282 pub alpha: PrefixCode,
284 pub distance: PrefixCode,
286}
287
288pub fn read_prefix_code_group(
295 r: &mut BitReader<'_>,
296 color_cache_size: usize,
297) -> Result<PrefixCodeGroup> {
298 Ok(PrefixCodeGroup {
299 green: read_prefix_code(r, green_alphabet_size(color_cache_size))?,
300 red: read_prefix_code(r, NUM_LITERAL_CODES)?,
301 blue: read_prefix_code(r, NUM_LITERAL_CODES)?,
302 alpha: read_prefix_code(r, NUM_LITERAL_CODES)?,
303 distance: read_prefix_code(r, NUM_DISTANCE_CODES)?,
304 })
305}
306
307#[must_use]
314pub fn canonical_codes(lengths: &[u8]) -> Vec<u16> {
315 let mut bl_count = [0u32; MAX_CODE_LENGTH + 1];
316 for &len in lengths {
317 if len > 0 && (len as usize) <= MAX_CODE_LENGTH {
318 bl_count[len as usize] += 1;
319 }
320 }
321 let mut next_code = [0u32; MAX_CODE_LENGTH + 1];
322 let mut code = 0u32;
323 for bits in 1..=MAX_CODE_LENGTH {
324 code = (code + bl_count[bits - 1]) << 1;
325 next_code[bits] = code;
326 }
327 let mut codes = vec![0u16; lengths.len()];
328 for (sym, &len) in lengths.iter().enumerate() {
329 if len > 0 && (len as usize) <= MAX_CODE_LENGTH {
330 let c = next_code[len as usize];
331 next_code[len as usize] += 1;
332 codes[sym] = reverse_bits(c as u16, len);
333 }
334 }
335 codes
336}
337
338#[must_use]
346pub fn build_length_limited_lengths(histogram: &[u32], max_len: u8) -> Vec<u8> {
347 let n = histogram.len();
348 let used = histogram.iter().filter(|&&h| h > 0).count();
349 if used == 0 {
350 return vec![0u8; n];
351 }
352 if used == 1 {
353 let mut lengths = vec![0u8; n];
354 if let Some(sym) = (0..n).find(|&i| histogram[i] > 0) {
355 lengths[sym] = 1;
356 }
357 return lengths;
358 }
359 let mut count_min = 1u32;
360 loop {
361 let depths = huffman_pass(histogram, count_min);
362 let max_depth = depths.iter().copied().max().unwrap_or(0);
363 if max_depth <= u32::from(max_len) {
364 return depths.iter().map(|&d| d as u8).collect();
365 }
366 count_min = count_min.saturating_mul(2);
367 }
368}
369
370fn huffman_pass(histogram: &[u32], count_min: u32) -> Vec<u32> {
373 use std::cmp::Reverse;
374 use std::collections::BinaryHeap;
375
376 struct Node {
378 left: i32,
379 right: i32,
380 sym: i32,
381 }
382
383 let n = histogram.len();
384 let mut lengths = vec![0u32; n];
385 let mut nodes: Vec<Node> = Vec::new();
386 let mut heap: BinaryHeap<Reverse<(u64, usize)>> = BinaryHeap::new();
388 for (sym, &count) in histogram.iter().enumerate() {
389 if count > 0 {
390 let idx = nodes.len();
391 nodes.push(Node {
392 left: -1,
393 right: -1,
394 sym: sym as i32,
395 });
396 heap.push(Reverse((u64::from(count.max(count_min)), idx)));
397 }
398 }
399 if nodes.len() == 1 {
400 if let Some(sym) = (0..n).find(|&i| histogram[i] > 0) {
401 lengths[sym] = 1;
402 }
403 return lengths;
404 }
405 while heap.len() > 1 {
406 let (Some(Reverse((wa, a))), Some(Reverse((wb, b)))) = (heap.pop(), heap.pop()) else {
407 break;
408 };
409 let idx = nodes.len();
410 nodes.push(Node {
411 left: a as i32,
412 right: b as i32,
413 sym: -1,
414 });
415 heap.push(Reverse((wa + wb, idx)));
416 }
417 let Some(Reverse((_, root))) = heap.pop() else {
418 return lengths;
419 };
420 let mut stack = vec![(root, 0u32)];
422 while let Some((idx, depth)) = stack.pop() {
423 let Some(node) = nodes.get(idx) else { continue };
424 if node.sym >= 0 {
425 if let Some(slot) = lengths.get_mut(node.sym as usize) {
426 *slot = depth;
427 }
428 } else {
429 stack.push((node.left as usize, depth + 1));
430 stack.push((node.right as usize, depth + 1));
431 }
432 }
433 lengths
434}
435
436#[derive(Debug, Clone)]
439pub struct PrefixEncoder {
440 lengths: Vec<u8>,
441 codes: Vec<u16>,
442 single: bool,
443}
444
445impl PrefixEncoder {
446 #[must_use]
448 pub fn from_lengths(lengths: &[u8]) -> Self {
449 let codes = canonical_codes(lengths);
450 let single = lengths.iter().filter(|&&l| l > 0).count() <= 1;
451 Self {
452 lengths: lengths.to_vec(),
453 codes,
454 single,
455 }
456 }
457
458 #[must_use]
460 pub fn lengths(&self) -> &[u8] {
461 &self.lengths
462 }
463
464 pub fn write_symbol(&self, w: &mut BitWriter, symbol: usize) {
466 if self.single {
467 return;
468 }
469 if let (Some(&code), Some(&len)) = (self.codes.get(symbol), self.lengths.get(symbol)) {
470 w.write_bits(u32::from(code), u32::from(len));
471 }
472 }
473}
474
475pub fn write_normal_prefix_code(w: &mut BitWriter, lengths: &[u8]) {
482 w.write_bits(0, 1); let mut cl_hist = [0u32; CODE_LENGTH_CODES];
486 for &len in lengths {
487 if (len as usize) < CODE_LENGTH_CODES {
488 cl_hist[len as usize] += 1;
489 }
490 }
491 let cl_lengths = build_length_limited_lengths(&cl_hist, 7);
493 let cl_encoder = PrefixEncoder::from_lengths(&cl_lengths);
494
495 let mut num_code_lengths = CODE_LENGTH_CODES;
497 while num_code_lengths > 4 && cl_lengths[CODE_LENGTH_CODE_ORDER[num_code_lengths - 1]] == 0 {
498 num_code_lengths -= 1;
499 }
500 w.write_bits((num_code_lengths - 4) as u32, 4);
501 for &order in CODE_LENGTH_CODE_ORDER.iter().take(num_code_lengths) {
502 w.write_bits(u32::from(cl_lengths[order]), 3);
503 }
504
505 w.write_bits(0, 1); for &len in lengths {
507 cl_encoder.write_symbol(w, len as usize);
508 }
509}
510
511pub fn write_simple_prefix_code(w: &mut BitWriter, symbols: &[u16]) {
515 w.write_bits(1, 1); let num_symbols = symbols.len().clamp(1, 2);
517 w.write_bits((num_symbols - 1) as u32, 1);
518 let symbol0 = symbols.first().copied().unwrap_or(0);
519 let is_first_8bits = u32::from(symbol0 > 1);
520 w.write_bits(is_first_8bits, 1);
521 w.write_bits(u32::from(symbol0), 1 + 7 * is_first_8bits);
522 if num_symbols == 2 {
523 let symbol1 = symbols.get(1).copied().unwrap_or(0);
524 w.write_bits(u32::from(symbol1), 8);
525 }
526}
527
528#[cfg(test)]
529mod tests {
530 use super::*;
531
532 #[test]
533 fn reverse_bits_matches_manual() {
534 assert_eq!(reverse_bits(0b1, 1), 0b1);
535 assert_eq!(reverse_bits(0b10, 2), 0b01);
536 assert_eq!(reverse_bits(0b1011, 4), 0b1101);
537 assert_eq!(reverse_bits(0b0000_0001, 8), 0b1000_0000);
538 for v in 0u16..256 {
540 assert_eq!(reverse_bits(reverse_bits(v, 8), 8), v);
541 }
542 }
543
544 fn assert_code_round_trips(histogram: &[u32], stream: &[usize], max_len: u8) {
547 let lengths = build_length_limited_lengths(histogram, max_len);
548 assert!(lengths.iter().all(|&l| l <= max_len), "length exceeds cap");
549 let encoder = PrefixEncoder::from_lengths(&lengths);
550 let mut w = BitWriter::new();
551 for &s in stream {
552 encoder.write_symbol(&mut w, s);
553 }
554 let bytes = w.finish();
555 let decoder = PrefixCode::from_code_lengths(&lengths).expect("valid lengths");
556 let mut r = BitReader::new(&bytes);
557 for &s in stream {
558 assert_eq!(decoder.read_symbol(&mut r).unwrap() as usize, s);
559 }
560 }
561
562 #[test]
563 fn round_trips_varied_histograms() {
564 let uniform: Vec<u32> = vec![1; 16];
566 assert_code_round_trips(&uniform, &[0, 5, 15, 3, 8, 8, 0], 15);
567
568 let mut skewed = vec![1u32; 32];
569 skewed[7] = 10_000;
570 skewed[19] = 2_000;
571 assert_code_round_trips(&skewed, &[7, 7, 19, 0, 31, 7], 15);
572
573 let mut two = vec![0u32; 256];
574 two[10] = 5;
575 two[200] = 9;
576 assert_code_round_trips(&two, &[10, 200, 10, 10, 200], 15);
577
578 let mut single = vec![0u32; 40];
579 single[12] = 99;
580 assert_code_round_trips(&single, &[12, 12, 12], 15);
582 }
583
584 #[test]
585 fn forces_and_caps_15_bit_lengths() {
586 let mut hist = vec![0u32; 64];
589 let (mut a, mut b) = (1u32, 1u32);
590 for h in hist.iter_mut() {
591 *h = a;
592 let next = a.saturating_add(b);
593 a = b;
594 b = next;
595 }
596 let lengths = build_length_limited_lengths(&hist, 15);
597 assert!(lengths.iter().all(|&l| l <= 15));
598 let stream: Vec<usize> = (0..64).collect();
600 assert_code_round_trips(&hist, &stream, 15);
601 }
602
603 #[test]
604 fn normal_code_length_coding_round_trips() {
605 let mut hist = vec![0u32; 256];
608 for (i, h) in hist.iter_mut().enumerate() {
609 *h = (i as u32 % 7) + 1;
610 }
611 let lengths = build_length_limited_lengths(&hist, 15);
612 let encoder = PrefixEncoder::from_lengths(&lengths);
613
614 let stream: Vec<usize> = vec![0, 1, 2, 100, 255, 17, 42, 42, 7];
615 let mut w = BitWriter::new();
616 write_normal_prefix_code(&mut w, &lengths);
617 for &s in &stream {
618 encoder.write_symbol(&mut w, s);
619 }
620 let bytes = w.finish();
621
622 let mut r = BitReader::new(&bytes);
623 let decoder = read_prefix_code(&mut r, 256).expect("valid code description");
624 for &s in &stream {
625 assert_eq!(decoder.read_symbol(&mut r).unwrap() as usize, s);
626 }
627 }
628
629 #[test]
630 fn simple_code_length_coding_round_trips() {
631 for symbols in [
632 vec![0u16],
633 vec![1u16],
634 vec![5u16],
635 vec![3u16, 200],
636 vec![0u16, 1],
637 ] {
638 let mut lengths = vec![0u8; 256];
639 for &s in &symbols {
640 lengths[s as usize] = 1;
641 }
642 let encoder = PrefixEncoder::from_lengths(&lengths);
643 let stream: Vec<usize> = symbols.iter().map(|&s| s as usize).collect();
644
645 let mut w = BitWriter::new();
646 write_simple_prefix_code(&mut w, &symbols);
647 for &s in &stream {
648 encoder.write_symbol(&mut w, s);
649 }
650 let bytes = w.finish();
651
652 let mut r = BitReader::new(&bytes);
653 let decoder = read_prefix_code(&mut r, 256).expect("valid simple code");
654 for &s in &stream {
655 assert_eq!(decoder.read_symbol(&mut r).unwrap() as usize, s);
656 }
657 }
658 }
659
660 #[test]
661 fn rejects_malformed_lengths() {
662 assert!(matches!(
664 PrefixCode::from_code_lengths(&[1, 1, 1]),
665 Err(Error::InvalidInput(_))
666 ));
667 assert!(matches!(
669 PrefixCode::from_code_lengths(&[1, 2]),
670 Err(Error::InvalidInput(_))
671 ));
672 assert!(matches!(
674 PrefixCode::from_code_lengths(&[16, 0]),
675 Err(Error::InvalidInput(_))
676 ));
677 assert!(matches!(
679 PrefixCode::from_code_lengths(&[0, 0, 0]),
680 Err(Error::InvalidInput(_))
681 ));
682 }
683
684 #[test]
685 fn single_symbol_consumes_no_bits() {
686 let code = PrefixCode::from_code_lengths(&[0, 0, 3, 0]).expect("single leaf");
687 let mut r = BitReader::new(&[]); assert_eq!(code.read_symbol(&mut r).unwrap(), 2);
689 assert_eq!(code.read_symbol(&mut r).unwrap(), 2);
690 }
691
692 #[test]
693 fn green_alphabet_size_includes_cache() {
694 assert_eq!(green_alphabet_size(0), 280);
695 assert_eq!(green_alphabet_size(1024), 280 + 1024);
696 }
697
698 #[test]
699 fn reads_prefix_code_group() {
700 let mut w = BitWriter::new();
702 for _ in 0..5 {
703 write_simple_prefix_code(&mut w, &[0]);
704 }
705 let bytes = w.finish();
706 let mut r = BitReader::new(&bytes);
707 let group = read_prefix_code_group(&mut r, 0).expect("group");
708 let mut rr = BitReader::new(&[]);
709 assert_eq!(group.green.read_symbol(&mut rr).unwrap(), 0);
710 assert_eq!(group.distance.read_symbol(&mut rr).unwrap(), 0);
711 }
712}