1use crate::error::{CodecError, CodecResult};
10
11const VP8L_SIGNATURE: u8 = 0x2F;
13
14const MAX_DIMENSION: u32 = 16384;
16
17const MAX_HUFFMAN_GROUPS: usize = 256 * 256;
19
20const MAX_COLOR_CACHE_BITS: u32 = 11;
22
23const NUM_LITERAL_CODES: u16 = 256;
25
26const NUM_LENGTH_CODES: u16 = 24;
28
29const NUM_DISTANCE_CODES: u16 = 40;
31
32const MAX_ALLOWED_CODE_LENGTH: u8 = 15;
34
35const CODE_LENGTH_CODE_ORDER: [u8; 19] = [
37 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
38];
39
40const NUM_CODE_LENGTH_CODES: usize = 19;
42
43const DISTANCE_MAP: [(i8, i8); 120] = [
45 (0, 1),
46 (1, 0),
47 (1, 1),
48 (-1, 1),
49 (0, 2),
50 (2, 0),
51 (1, 2),
52 (-1, 2),
53 (2, 1),
54 (-2, 1),
55 (2, 2),
56 (-2, 2),
57 (0, 3),
58 (3, 0),
59 (1, 3),
60 (-1, 3),
61 (3, 1),
62 (-3, 1),
63 (2, 3),
64 (-2, 3),
65 (3, 2),
66 (-3, 2),
67 (0, 4),
68 (4, 0),
69 (1, 4),
70 (-1, 4),
71 (4, 1),
72 (-4, 1),
73 (3, 3),
74 (-3, 3),
75 (2, 4),
76 (-2, 4),
77 (4, 2),
78 (-4, 2),
79 (0, 5),
80 (3, 4),
81 (-3, 4),
82 (4, 3),
83 (-4, 3),
84 (5, 0),
85 (1, 5),
86 (-1, 5),
87 (5, 1),
88 (-5, 1),
89 (2, 5),
90 (-2, 5),
91 (5, 2),
92 (-5, 2),
93 (4, 4),
94 (-4, 4),
95 (3, 5),
96 (-3, 5),
97 (5, 3),
98 (-5, 3),
99 (0, 6),
100 (6, 0),
101 (1, 6),
102 (-1, 6),
103 (6, 1),
104 (-6, 1),
105 (2, 6),
106 (-2, 6),
107 (6, 2),
108 (-6, 2),
109 (4, 5),
110 (-4, 5),
111 (5, 4),
112 (-5, 4),
113 (3, 6),
114 (-3, 6),
115 (6, 3),
116 (-6, 3),
117 (0, 7),
118 (7, 0),
119 (1, 7),
120 (-1, 7),
121 (5, 5),
122 (-5, 5),
123 (7, 1),
124 (-7, 1),
125 (4, 6),
126 (-4, 6),
127 (6, 4),
128 (-6, 4),
129 (2, 7),
130 (-2, 7),
131 (7, 2),
132 (-7, 2),
133 (3, 7),
134 (-3, 7),
135 (7, 3),
136 (-7, 3),
137 (5, 6),
138 (-5, 6),
139 (6, 5),
140 (-6, 5),
141 (8, 0),
142 (4, 7),
143 (-4, 7),
144 (7, 4),
145 (-7, 4),
146 (8, 1),
147 (8, 2),
148 (6, 6),
149 (-6, 6),
150 (8, 3),
151 (5, 7),
152 (-5, 7),
153 (7, 5),
154 (-7, 5),
155 (8, 4),
156 (6, 7),
157 (-6, 7),
158 (7, 6),
159 (-7, 6),
160 (8, 5),
161 (7, 7),
162 (-7, 7),
163 (8, 6),
164 (8, 7),
165];
166
167#[derive(Debug, Clone)]
169pub struct Vp8lHeader {
170 pub width: u32,
172 pub height: u32,
174 pub alpha_is_used: bool,
176 pub version: u8,
178}
179
180impl Vp8lHeader {
181 pub fn parse(data: &[u8]) -> CodecResult<Self> {
183 if data.len() < 5 {
184 return Err(CodecError::InvalidBitstream("VP8L header too short".into()));
185 }
186 if data[0] != VP8L_SIGNATURE {
187 return Err(CodecError::InvalidBitstream(format!(
188 "Invalid VP8L signature: 0x{:02X}",
189 data[0]
190 )));
191 }
192 let val = u32::from(data[1])
194 | (u32::from(data[2]) << 8)
195 | (u32::from(data[3]) << 16)
196 | (u32::from(data[4]) << 24);
197
198 let width = (val & 0x3FFF) + 1;
199 let height = ((val >> 14) & 0x3FFF) + 1;
200 let alpha_is_used = ((val >> 28) & 1) != 0;
201 let version = ((val >> 29) & 0x7) as u8;
202
203 if version != 0 {
204 return Err(CodecError::InvalidBitstream(format!(
205 "Unsupported VP8L version: {version}"
206 )));
207 }
208 if width > MAX_DIMENSION || height > MAX_DIMENSION {
209 return Err(CodecError::InvalidBitstream(format!(
210 "Image dimensions too large: {width}x{height}"
211 )));
212 }
213
214 Ok(Self {
215 width,
216 height,
217 alpha_is_used,
218 version,
219 })
220 }
221}
222
223pub struct Vp8lBitReader<'a> {
227 data: &'a [u8],
228 pos: usize,
229 bit_pos: u32,
230 value: u64,
231 bits_in_value: u32,
232}
233
234impl<'a> Vp8lBitReader<'a> {
235 pub fn new(data: &'a [u8]) -> Self {
237 let mut reader = Self {
238 data,
239 pos: 0,
240 bit_pos: 0,
241 value: 0,
242 bits_in_value: 0,
243 };
244 reader.fill();
245 reader
246 }
247
248 fn fill(&mut self) {
250 while self.bits_in_value < 56 && self.pos < self.data.len() {
251 self.value |= u64::from(self.data[self.pos]) << self.bits_in_value;
252 self.pos += 1;
253 self.bits_in_value += 8;
254 }
255 }
256
257 pub fn read_bits(&mut self, n: u32) -> CodecResult<u32> {
259 if n == 0 {
260 return Ok(0);
261 }
262 if n > 32 {
263 return Err(CodecError::InvalidBitstream(
264 "Cannot read more than 32 bits at once".into(),
265 ));
266 }
267 if self.bits_in_value < n {
268 self.fill();
269 }
270 if self.bits_in_value < n {
271 return Err(CodecError::NeedMoreData);
272 }
273 let mask = if n == 32 { u32::MAX } else { (1u32 << n) - 1 };
274 let result = (self.value as u32) & mask;
275 self.value >>= n;
276 self.bits_in_value -= n;
277 self.bit_pos += n;
278 Ok(result)
279 }
280
281 #[inline]
283 pub fn read_bit(&mut self) -> CodecResult<bool> {
284 Ok(self.read_bits(1)? != 0)
285 }
286
287 pub fn peek_bits(&mut self, n: u32) -> CodecResult<u32> {
289 if n == 0 {
290 return Ok(0);
291 }
292 if self.bits_in_value < n {
293 self.fill();
294 }
295 if self.bits_in_value < n {
296 return Err(CodecError::NeedMoreData);
297 }
298 let mask = if n == 32 { u32::MAX } else { (1u32 << n) - 1 };
299 Ok((self.value as u32) & mask)
300 }
301
302 pub fn advance(&mut self, n: u32) {
304 self.value >>= n;
305 self.bits_in_value = self.bits_in_value.saturating_sub(n);
306 self.bit_pos += n;
307 }
308}
309
310#[derive(Debug, Clone, Copy, Default)]
314pub struct HuffmanCode {
315 pub bits: u8,
317 pub value: u16,
319}
320
321#[derive(Debug, Clone)]
323pub struct HuffmanTree {
324 lut: Vec<HuffmanCode>,
326 lut_bits: u8,
328 second_level: Vec<(usize, u8)>,
330 lut2: Vec<HuffmanCode>,
332}
333
334impl HuffmanTree {
335 fn build(code_lengths: &[u8], alphabet_size: u16) -> CodecResult<Self> {
337 let max_len = code_lengths.iter().copied().max().unwrap_or(0);
338 if max_len == 0 {
339 let mut lut = vec![HuffmanCode::default(); 1];
341 lut[0] = HuffmanCode { bits: 0, value: 0 };
342 return Ok(Self {
343 lut,
344 lut_bits: 0,
345 second_level: Vec::new(),
346 lut2: Vec::new(),
347 });
348 }
349
350 let lut_bits = max_len.min(8);
351 let table_size = 1usize << lut_bits;
352 let mut lut = vec![HuffmanCode::default(); table_size];
353
354 let mut bl_count = vec![0u32; (max_len as usize) + 1];
356 for &cl in code_lengths.iter().take(alphabet_size as usize) {
357 if cl > 0 {
358 bl_count[cl as usize] += 1;
359 }
360 }
361
362 let mut next_code = vec![0u32; (max_len as usize) + 1];
364 {
365 let mut code: u32 = 0;
366 for bits in 1..=max_len as usize {
367 code = (code + bl_count[bits - 1]) << 1;
368 next_code[bits] = code;
369 }
370 }
371
372 let mut codes = Vec::with_capacity(alphabet_size as usize);
374 for symbol in 0..alphabet_size {
375 let cl = if (symbol as usize) < code_lengths.len() {
376 code_lengths[symbol as usize]
377 } else {
378 0
379 };
380 if cl > 0 {
381 let c = next_code[cl as usize];
382 next_code[cl as usize] += 1;
383 codes.push((symbol, cl, c));
384 }
385 }
386
387 let mut second_level = Vec::new();
389 let mut lut2 = Vec::new();
390
391 for &(symbol, cl, code) in &codes {
392 if cl <= lut_bits {
393 let rev = reverse_bits(code, cl);
395 let step = 1u32 << cl;
396 let mut idx = rev;
397 while idx < table_size as u32 {
398 lut[idx as usize] = HuffmanCode {
399 bits: cl,
400 value: symbol,
401 };
402 idx += step;
403 }
404 }
405 }
406
407 if max_len > lut_bits {
409 let mut max_second_bits: Vec<u8> = vec![0; table_size];
412 for &(_symbol, cl, code) in &codes {
413 if cl > lut_bits {
414 let rev = reverse_bits(code, cl);
415 let idx = rev & ((1u32 << lut_bits) - 1);
416 let remaining = cl - lut_bits;
417 if remaining > max_second_bits[idx as usize] {
418 max_second_bits[idx as usize] = remaining;
419 }
420 }
421 }
422
423 for first_idx in 0..table_size {
425 let sb = max_second_bits[first_idx];
426 if sb > 0 {
427 let offset = lut2.len();
428 let size2 = 1usize << sb;
429 lut2.resize(lut2.len() + size2, HuffmanCode::default());
430 let sl_index = second_level.len();
432 second_level.push((offset, sb));
433 lut[first_idx] = HuffmanCode {
434 bits: lut_bits + sb, value: sl_index as u16,
436 };
437 }
438 }
439
440 for &(symbol, cl, code) in &codes {
442 if cl > lut_bits {
443 let rev = reverse_bits(code, cl);
444 let first_idx = (rev & ((1u32 << lut_bits) - 1)) as usize;
445 let entry = &lut[first_idx];
446 let sl_index = entry.value as usize;
447 let (offset, sb) = second_level[sl_index];
448 let remaining = cl - lut_bits;
449 let rev2 = rev >> lut_bits;
450 let step = 1u32 << remaining;
451 let mut idx = rev2;
452 while idx < (1u32 << sb) {
453 lut2[offset + idx as usize] = HuffmanCode {
454 bits: cl,
455 value: symbol,
456 };
457 idx += step;
458 }
459 }
460 }
461 }
462
463 Ok(Self {
464 lut,
465 lut_bits,
466 second_level,
467 lut2,
468 })
469 }
470
471 fn read_symbol(&self, br: &mut Vp8lBitReader<'_>) -> CodecResult<u16> {
473 if self.lut_bits == 0 {
474 return Ok(self.lut.first().map_or(0, |c| c.value));
476 }
477 let peek = br.peek_bits(u32::from(self.lut_bits))?;
478 let entry = self.lut[peek as usize];
479
480 if entry.bits <= self.lut_bits {
481 br.advance(u32::from(entry.bits));
482 Ok(entry.value)
483 } else {
484 let sl_index = entry.value as usize;
486 if sl_index >= self.second_level.len() {
487 return Err(CodecError::InvalidBitstream(
488 "Invalid Huffman second-level index".into(),
489 ));
490 }
491 let (offset, sb) = self.second_level[sl_index];
492 let total_bits = self.lut_bits + sb;
493 let peek2 = br.peek_bits(u32::from(total_bits))?;
494 let idx2 = (peek2 >> self.lut_bits) as usize;
495 if offset + idx2 >= self.lut2.len() {
496 return Err(CodecError::InvalidBitstream(
497 "Huffman second-level table overflow".into(),
498 ));
499 }
500 let entry2 = self.lut2[offset + idx2];
501 br.advance(u32::from(entry2.bits));
502 Ok(entry2.value)
503 }
504 }
505}
506
507fn reverse_bits(val: u32, n: u8) -> u32 {
509 let mut result = 0u32;
510 let mut v = val;
511 for _ in 0..n {
512 result = (result << 1) | (v & 1);
513 v >>= 1;
514 }
515 result
516}
517
518#[derive(Debug, Clone)]
522struct HuffmanGroup {
523 green: HuffmanTree,
525 red: HuffmanTree,
527 blue: HuffmanTree,
529 alpha: HuffmanTree,
531 distance: HuffmanTree,
533}
534
535#[derive(Debug, Clone)]
539pub enum Transform {
540 Predictor {
542 size_bits: u8,
544 data: Vec<u32>,
546 },
547 ColorTransform {
549 size_bits: u8,
551 data: Vec<ColorTransformElement>,
553 },
554 SubtractGreen,
556 ColorIndexing {
558 palette: Vec<u32>,
560 bits_per_pixel: u8,
562 },
563}
564
565#[derive(Debug, Clone, Copy, Default)]
567pub struct ColorTransformElement {
568 pub green_to_red: i8,
570 pub green_to_blue: i8,
572 pub red_to_blue: i8,
574}
575
576struct ColorCache {
580 colors: Vec<u32>,
581 hash_shift: u32,
582}
583
584impl ColorCache {
585 fn new(bits: u32) -> Self {
586 let size = 1usize << bits;
587 Self {
588 colors: vec![0u32; size],
589 hash_shift: 32 - bits,
590 }
591 }
592
593 fn lookup(&self, index: u32) -> u32 {
594 self.colors[index as usize & (self.colors.len() - 1)]
595 }
596
597 fn insert(&mut self, argb: u32) {
598 let hash = (0x1E35_A7BDu64.wrapping_mul(u64::from(argb)) >> self.hash_shift) as usize;
599 let len = self.colors.len();
600 self.colors[hash & (len - 1)] = argb;
601 }
602}
603
604pub struct DecodedImage {
608 pub width: u32,
610 pub height: u32,
612 pub pixels: Vec<u32>,
614 pub has_alpha: bool,
616}
617
618pub struct Vp8lDecoder {
622 width: u32,
623 height: u32,
624 alpha_is_used: bool,
625 transforms: Vec<Transform>,
626}
627
628impl Vp8lDecoder {
629 pub fn new() -> Self {
631 Self {
632 width: 0,
633 height: 0,
634 alpha_is_used: false,
635 transforms: Vec::new(),
636 }
637 }
638
639 pub fn decode(&mut self, data: &[u8]) -> CodecResult<DecodedImage> {
641 let header = Vp8lHeader::parse(data)?;
642 self.width = header.width;
643 self.height = header.height;
644 self.alpha_is_used = header.alpha_is_used;
645 self.transforms.clear();
646
647 let mut br = Vp8lBitReader::new(&data[5..]);
649
650 let (decoded_width, decoded_height) = self.read_transforms(&mut br)?;
652
653 let pixels = self.decode_image_data(&mut br, decoded_width, decoded_height)?;
655
656 let pixels = self.apply_transforms(pixels, decoded_width, decoded_height)?;
658
659 Ok(DecodedImage {
660 width: self.width,
661 height: self.height,
662 pixels,
663 has_alpha: self.alpha_is_used,
664 })
665 }
666
667 fn read_transforms(&mut self, br: &mut Vp8lBitReader<'_>) -> CodecResult<(u32, u32)> {
672 let mut width = self.width;
673 let height = self.height;
674
675 while br.read_bit()? {
676 let transform_type = br.read_bits(2)?;
677 match transform_type {
678 0 => {
679 let size_bits = br.read_bits(3)? as u8;
681 let block_size = 1u32 << (size_bits + 2);
682 let tw = div_round_up(width, block_size);
683 let th = div_round_up(height, block_size);
684 let data = self.decode_image_data(br, tw, th)?;
685 self.transforms.push(Transform::Predictor {
686 size_bits: size_bits + 2,
687 data,
688 });
689 }
690 1 => {
691 let size_bits = br.read_bits(3)? as u8;
693 let block_size = 1u32 << (size_bits + 2);
694 let tw = div_round_up(width, block_size);
695 let th = div_round_up(height, block_size);
696 let pixels = self.decode_image_data(br, tw, th)?;
697 let data: Vec<ColorTransformElement> = pixels
698 .iter()
699 .map(|&p| ColorTransformElement {
700 green_to_red: ((p >> 8) & 0xFF) as i8,
701 green_to_blue: ((p >> 16) & 0xFF) as i8,
702 red_to_blue: (p & 0xFF) as i8,
703 })
704 .collect();
705 self.transforms.push(Transform::ColorTransform {
706 size_bits: size_bits + 2,
707 data,
708 });
709 }
710 2 => {
711 self.transforms.push(Transform::SubtractGreen);
713 }
714 3 => {
715 let num_colors = br.read_bits(8)? + 1;
717 let palette = self.decode_image_data(br, num_colors, 1)?;
718 let bits_per_pixel = if num_colors <= 2 {
719 1
720 } else if num_colors <= 4 {
721 2
722 } else if num_colors <= 16 {
723 4
724 } else {
725 8
726 };
727 if bits_per_pixel < 8 {
728 width = div_round_up(width * u32::from(bits_per_pixel), 8);
729 }
730 self.transforms.push(Transform::ColorIndexing {
731 palette,
732 bits_per_pixel,
733 });
734 }
735 _ => {
736 return Err(CodecError::InvalidBitstream(
737 "Invalid transform type".into(),
738 ));
739 }
740 }
741 }
742 Ok((width, height))
743 }
744
745 fn decode_image_data(
750 &self,
751 br: &mut Vp8lBitReader<'_>,
752 width: u32,
753 height: u32,
754 ) -> CodecResult<Vec<u32>> {
755 let color_cache_bits = if br.read_bit()? {
757 let bits = br.read_bits(4)?;
758 if bits > MAX_COLOR_CACHE_BITS {
759 return Err(CodecError::InvalidBitstream(format!(
760 "Color cache bits too large: {bits}"
761 )));
762 }
763 Some(bits)
764 } else {
765 None
766 };
767
768 let num_color_cache_codes = color_cache_bits.map(|b| 1u16 << b).unwrap_or(0);
769
770 let huffman_groups = self.read_huffman_codes(br, width, height, num_color_cache_codes)?;
772
773 let total_pixels = (width as usize)
775 .checked_mul(height as usize)
776 .ok_or_else(|| CodecError::InvalidBitstream("Image too large".into()))?;
777
778 let mut pixels = vec![0u32; total_pixels];
779 let mut color_cache = color_cache_bits.map(ColorCache::new);
780
781 let mut idx = 0usize;
782 while idx < total_pixels {
783 let group_idx = if huffman_groups.len() == 1 {
785 0
786 } else {
787 0
790 };
791 let group = huffman_groups.get(group_idx).ok_or_else(|| {
792 CodecError::InvalidBitstream("Invalid Huffman group index".into())
793 })?;
794
795 let green_sym = group.green.read_symbol(br)?;
796
797 if green_sym < NUM_LITERAL_CODES {
798 let red = group.red.read_symbol(br)? as u32;
800 let blue = group.blue.read_symbol(br)? as u32;
801 let alpha = group.alpha.read_symbol(br)? as u32;
802
803 let argb = (alpha << 24) | (red << 16) | (u32::from(green_sym) << 8) | blue;
804 pixels[idx] = argb;
805 if let Some(ref mut cache) = color_cache {
806 cache.insert(argb);
807 }
808 idx += 1;
809 } else if green_sym < NUM_LITERAL_CODES + NUM_LENGTH_CODES {
810 let length_prefix = green_sym - NUM_LITERAL_CODES;
812 let length = prefix_code_to_value(length_prefix, br)?;
813
814 let dist_sym = group.distance.read_symbol(br)?;
815 let dist_raw = prefix_code_to_value(dist_sym, br)?;
816 let dist = distance_map_to_pixel_dist(dist_raw as usize, width as usize);
817
818 if dist == 0 || dist > idx {
819 return Err(CodecError::InvalidBitstream(format!(
820 "Invalid backward reference distance: {dist}, position: {idx}"
821 )));
822 }
823
824 let length = length as usize;
825 for i in 0..length {
826 if idx + i >= total_pixels {
827 break;
828 }
829 let src = idx + i - dist;
830 pixels[idx + i] = pixels[src];
831 if let Some(ref mut cache) = color_cache {
832 cache.insert(pixels[idx + i]);
833 }
834 }
835 idx += length;
836 } else {
837 let cache_idx = green_sym - NUM_LITERAL_CODES - NUM_LENGTH_CODES;
839 let cache = color_cache.as_ref().ok_or_else(|| {
840 CodecError::InvalidBitstream("Color cache code without color cache".into())
841 })?;
842 let argb = cache.lookup(u32::from(cache_idx));
843 pixels[idx] = argb;
844 if let Some(ref mut cache) = color_cache {
845 cache.insert(argb);
846 }
847 idx += 1;
848 }
849 }
850
851 Ok(pixels)
852 }
853
854 fn read_huffman_codes(
859 &self,
860 br: &mut Vp8lBitReader<'_>,
861 _width: u32,
862 _height: u32,
863 num_color_cache_codes: u16,
864 ) -> CodecResult<Vec<HuffmanGroup>> {
865 let use_meta = br.read_bit()?;
867 let num_groups = if use_meta {
868 let _prefix_bits = br.read_bits(3)? + 2;
869 1usize
873 } else {
874 1usize
875 };
876
877 if num_groups > MAX_HUFFMAN_GROUPS {
878 return Err(CodecError::InvalidBitstream(
879 "Too many Huffman groups".into(),
880 ));
881 }
882
883 let green_alphabet = NUM_LITERAL_CODES + NUM_LENGTH_CODES + num_color_cache_codes;
884 let red_alphabet = NUM_LITERAL_CODES;
885 let blue_alphabet = NUM_LITERAL_CODES;
886 let alpha_alphabet = NUM_LITERAL_CODES;
887 let dist_alphabet = NUM_DISTANCE_CODES;
888
889 let mut groups = Vec::with_capacity(num_groups);
890 for _ in 0..num_groups {
891 let green = read_huffman_tree(br, green_alphabet)?;
892 let red = read_huffman_tree(br, red_alphabet)?;
893 let blue = read_huffman_tree(br, blue_alphabet)?;
894 let alpha = read_huffman_tree(br, alpha_alphabet)?;
895 let distance = read_huffman_tree(br, dist_alphabet)?;
896
897 groups.push(HuffmanGroup {
898 green,
899 red,
900 blue,
901 alpha,
902 distance,
903 });
904 }
905
906 Ok(groups)
907 }
908
909 fn apply_transforms(
914 &self,
915 mut pixels: Vec<u32>,
916 decoded_width: u32,
917 decoded_height: u32,
918 ) -> CodecResult<Vec<u32>> {
919 for transform in self.transforms.iter().rev() {
921 match transform {
922 Transform::Predictor { size_bits, data } => {
923 pixels = self.inverse_predictor(
924 &pixels,
925 decoded_width,
926 decoded_height,
927 *size_bits,
928 data,
929 )?;
930 }
931 Transform::ColorTransform { size_bits, data } => {
932 pixels = self.inverse_color_transform(
933 &pixels,
934 decoded_width,
935 decoded_height,
936 *size_bits,
937 data,
938 );
939 }
940 Transform::SubtractGreen => {
941 self.inverse_subtract_green(&mut pixels);
942 }
943 Transform::ColorIndexing {
944 palette,
945 bits_per_pixel,
946 } => {
947 pixels = self.inverse_color_indexing(
948 &pixels,
949 decoded_width,
950 decoded_height,
951 palette,
952 *bits_per_pixel,
953 )?;
954 }
955 }
956 }
957 Ok(pixels)
958 }
959
960 fn inverse_predictor(
962 &self,
963 pixels: &[u32],
964 width: u32,
965 height: u32,
966 size_bits: u8,
967 predictor_data: &[u32],
968 ) -> CodecResult<Vec<u32>> {
969 let w = width as usize;
970 let h = height as usize;
971 let block_size = 1usize << size_bits;
972 let pred_w = div_round_up(width, block_size as u32) as usize;
973
974 let mut out = pixels.to_vec();
975
976 if !out.is_empty() {
978 out[0] = add_pixels(out[0], 0xFF00_0000);
979 }
980
981 for x in 1..w.min(out.len()) {
983 out[x] = add_pixels(out[x], out[x - 1]);
984 }
985
986 for y in 1..h {
988 let row_start = y * w;
989 if row_start >= out.len() {
990 break;
991 }
992 out[row_start] = add_pixels(out[row_start], out[row_start - w]);
994
995 for x in 1..w {
996 let idx = row_start + x;
997 if idx >= out.len() {
998 break;
999 }
1000 let bx = x / block_size;
1001 let by = (y - 1) / block_size;
1002 let pred_idx = by * pred_w + bx;
1003 let mode = if pred_idx < predictor_data.len() {
1004 ((predictor_data[pred_idx] >> 8) & 0xFF) as u8
1005 } else {
1006 0
1007 };
1008
1009 let left = out[idx - 1];
1010 let top = out[idx - w];
1011 let top_left = out[idx - w - 1];
1012 let top_right = if x + 1 < w {
1013 out[idx - w + 1]
1014 } else {
1015 out[idx - w]
1016 };
1017
1018 let predicted = predict(mode, left, top, top_left, top_right);
1019 out[idx] = add_pixels(out[idx], predicted);
1020 }
1021 }
1022
1023 Ok(out)
1024 }
1025
1026 fn inverse_color_transform(
1028 &self,
1029 pixels: &[u32],
1030 width: u32,
1031 height: u32,
1032 size_bits: u8,
1033 transform_data: &[ColorTransformElement],
1034 ) -> Vec<u32> {
1035 let w = width as usize;
1036 let h = height as usize;
1037 let block_size = 1usize << size_bits;
1038 let tw = div_round_up(width, block_size as u32) as usize;
1039
1040 let mut out = pixels.to_vec();
1041
1042 for y in 0..h {
1043 for x in 0..w {
1044 let idx = y * w + x;
1045 if idx >= out.len() {
1046 break;
1047 }
1048 let bx = x / block_size;
1049 let by = y / block_size;
1050 let ti = by * tw + bx;
1051 let ct = if ti < transform_data.len() {
1052 transform_data[ti]
1053 } else {
1054 ColorTransformElement::default()
1055 };
1056
1057 let argb = out[idx];
1058 let green = ((argb >> 8) & 0xFF) as i32;
1059 let red = ((argb >> 16) & 0xFF) as i32;
1060 let blue = (argb & 0xFF) as i32;
1061 let alpha = (argb >> 24) & 0xFF;
1062
1063 let new_red = (red + color_transform_delta(ct.green_to_red as i32, green)) & 0xFF;
1064 let new_blue = (blue
1065 + color_transform_delta(ct.green_to_blue as i32, green)
1066 + color_transform_delta(ct.red_to_blue as i32, new_red))
1067 & 0xFF;
1068
1069 out[idx] = (alpha << 24)
1070 | ((new_red as u32) << 16)
1071 | (((green as u32) & 0xFF) << 8)
1072 | (new_blue as u32);
1073 }
1074 }
1075
1076 out
1077 }
1078
1079 fn inverse_subtract_green(&self, pixels: &mut [u32]) {
1081 for pixel in pixels.iter_mut() {
1082 let green = (*pixel >> 8) & 0xFF;
1083 let red = ((*pixel >> 16) & 0xFF).wrapping_add(green) & 0xFF;
1084 let blue = (*pixel & 0xFF).wrapping_add(green) & 0xFF;
1085 *pixel = (*pixel & 0xFF00_FF00) | (red << 16) | blue;
1086 }
1087 }
1088
1089 fn inverse_color_indexing(
1091 &self,
1092 pixels: &[u32],
1093 _packed_width: u32,
1094 height: u32,
1095 palette: &[u32],
1096 bits_per_pixel: u8,
1097 ) -> CodecResult<Vec<u32>> {
1098 let out_width = self.width as usize;
1099 let out_height = height as usize;
1100 let total = out_width * out_height;
1101 let mut out = Vec::with_capacity(total);
1102
1103 let pixels_per_byte = 8 / bits_per_pixel as usize;
1104 let mask = (1u32 << bits_per_pixel) - 1;
1105
1106 for y in 0..out_height {
1107 for x in 0..out_width {
1108 let packed_x = x / pixels_per_byte;
1109 let sub_idx = x % pixels_per_byte;
1110 let src_idx = y * (_packed_width as usize) + packed_x;
1111 let packed_val = if src_idx < pixels.len() {
1112 (pixels[src_idx] >> 8) & 0xFF
1114 } else {
1115 0
1116 };
1117
1118 let index = (packed_val >> (sub_idx as u32 * u32::from(bits_per_pixel))) & mask;
1119 let color = if (index as usize) < palette.len() {
1120 palette[index as usize]
1121 } else {
1122 0xFF00_0000
1123 };
1124 out.push(color);
1125 }
1126 }
1127
1128 Ok(out)
1129 }
1130}
1131
1132impl Default for Vp8lDecoder {
1133 fn default() -> Self {
1134 Self::new()
1135 }
1136}
1137
1138fn read_huffman_tree(br: &mut Vp8lBitReader<'_>, alphabet_size: u16) -> CodecResult<HuffmanTree> {
1142 let simple = br.read_bit()?;
1143 if simple {
1144 read_simple_huffman(br, alphabet_size)
1145 } else {
1146 read_normal_huffman(br, alphabet_size)
1147 }
1148}
1149
1150fn read_simple_huffman(br: &mut Vp8lBitReader<'_>, alphabet_size: u16) -> CodecResult<HuffmanTree> {
1152 let num_symbols = br.read_bits(1)? + 1;
1153 let is_first_8bit = br.read_bit()?;
1154
1155 let symbol0 = if is_first_8bit {
1156 br.read_bits(8)? as u16
1157 } else {
1158 br.read_bits(1)? as u16
1159 };
1160
1161 if symbol0 >= alphabet_size {
1162 return Err(CodecError::InvalidBitstream(format!(
1163 "Simple Huffman symbol {symbol0} >= alphabet size {alphabet_size}"
1164 )));
1165 }
1166
1167 if num_symbols == 1 {
1168 let mut code_lengths = vec![0u8; alphabet_size as usize];
1169 code_lengths[symbol0 as usize] = 1;
1170 let lut = vec![
1172 HuffmanCode {
1173 bits: 0,
1174 value: symbol0,
1175 };
1176 1
1177 ];
1178 return Ok(HuffmanTree {
1179 lut,
1180 lut_bits: 0,
1181 second_level: Vec::new(),
1182 lut2: Vec::new(),
1183 });
1184 }
1185
1186 let symbol1 = br.read_bits(8)? as u16;
1188 if symbol1 >= alphabet_size {
1189 return Err(CodecError::InvalidBitstream(format!(
1190 "Simple Huffman symbol {symbol1} >= alphabet size {alphabet_size}"
1191 )));
1192 }
1193
1194 let mut code_lengths = vec![0u8; alphabet_size as usize];
1195 code_lengths[symbol0 as usize] = 1;
1196 code_lengths[symbol1 as usize] = 1;
1197 HuffmanTree::build(&code_lengths, alphabet_size)
1198}
1199
1200fn read_normal_huffman(br: &mut Vp8lBitReader<'_>, alphabet_size: u16) -> CodecResult<HuffmanTree> {
1202 let num_code_length_codes = br.read_bits(4)? as usize + 4;
1204 if num_code_length_codes > NUM_CODE_LENGTH_CODES {
1205 return Err(CodecError::InvalidBitstream(format!(
1206 "Too many code length codes: {num_code_length_codes}"
1207 )));
1208 }
1209
1210 let mut cl_code_lengths = [0u8; NUM_CODE_LENGTH_CODES];
1212 for i in 0..num_code_length_codes {
1213 cl_code_lengths[CODE_LENGTH_CODE_ORDER[i] as usize] = br.read_bits(3)? as u8;
1214 }
1215
1216 let cl_tree = HuffmanTree::build(&cl_code_lengths, NUM_CODE_LENGTH_CODES as u16)?;
1218
1219 let mut code_lengths = vec![0u8; alphabet_size as usize];
1221 let mut i = 0usize;
1222 let mut prev_code_length = 8u8;
1223
1224 while i < alphabet_size as usize {
1225 let sym = cl_tree.read_symbol(br)?;
1226 match sym {
1227 0..=15 => {
1228 code_lengths[i] = sym as u8;
1229 if sym != 0 {
1230 prev_code_length = sym as u8;
1231 }
1232 i += 1;
1233 }
1234 16 => {
1235 let repeat = br.read_bits(2)? as usize + 3;
1237 for _ in 0..repeat {
1238 if i >= alphabet_size as usize {
1239 break;
1240 }
1241 code_lengths[i] = prev_code_length;
1242 i += 1;
1243 }
1244 }
1245 17 => {
1246 let repeat = br.read_bits(3)? as usize + 3;
1248 i += repeat;
1249 }
1250 18 => {
1251 let repeat = br.read_bits(7)? as usize + 11;
1253 i += repeat;
1254 }
1255 _ => {
1256 return Err(CodecError::InvalidBitstream(format!(
1257 "Invalid code length symbol: {sym}"
1258 )));
1259 }
1260 }
1261 }
1262
1263 HuffmanTree::build(&code_lengths, alphabet_size)
1264}
1265
1266fn prefix_code_to_value(prefix_code: u16, br: &mut Vp8lBitReader<'_>) -> CodecResult<u32> {
1270 if prefix_code < 4 {
1271 return Ok(u32::from(prefix_code) + 1);
1272 }
1273 let extra_bits = (u32::from(prefix_code) - 2) >> 1;
1274 let offset = (2 + (u32::from(prefix_code) & 1)) << extra_bits;
1275 let extra = br.read_bits(extra_bits)?;
1276 Ok(offset + extra + 1)
1277}
1278
1279fn distance_map_to_pixel_dist(dist_code: usize, xsize: usize) -> usize {
1281 if dist_code == 0 {
1282 return 0;
1283 }
1284 if dist_code <= 120 {
1285 let (dx, dy) = DISTANCE_MAP[dist_code - 1];
1286 let dist = i64::from(dy) * xsize as i64 + i64::from(dx);
1287 if dist < 1 {
1288 return 1;
1289 }
1290 dist as usize
1291 } else {
1292 dist_code - 120
1293 }
1294}
1295
1296use super::vp8l_pixel::{
1298 add_pixels, average2, channels_to_pixel, clamp_add_subtract_full, clamp_add_subtract_half,
1299 color_transform_delta, div_round_up, pixel_channels, predict, select,
1300};
1301
1302#[cfg(test)]
1305mod tests {
1306 use super::*;
1307
1308 #[test]
1311 fn test_parse_header_basic() {
1312 let val: u32 = 3 | (2 << 14);
1319 let mut data = vec![VP8L_SIGNATURE];
1320 data.extend_from_slice(&val.to_le_bytes());
1321
1322 let header = Vp8lHeader::parse(&data).expect("should parse");
1323 assert_eq!(header.width, 4);
1324 assert_eq!(header.height, 3);
1325 assert!(!header.alpha_is_used);
1326 assert_eq!(header.version, 0);
1327 }
1328
1329 #[test]
1330 fn test_parse_header_with_alpha() {
1331 let val: u32 = 9 | (4 << 14) | (1 << 28);
1333 let mut data = vec![VP8L_SIGNATURE];
1334 data.extend_from_slice(&val.to_le_bytes());
1335
1336 let header = Vp8lHeader::parse(&data).expect("should parse");
1337 assert_eq!(header.width, 10);
1338 assert_eq!(header.height, 5);
1339 assert!(header.alpha_is_used);
1340 assert_eq!(header.version, 0);
1341 }
1342
1343 #[test]
1344 fn test_parse_header_bad_signature() {
1345 let data = [0x00, 0x00, 0x00, 0x00, 0x00];
1346 assert!(Vp8lHeader::parse(&data).is_err());
1347 }
1348
1349 #[test]
1350 fn test_parse_header_bad_version() {
1351 let val: u32 = 3 | (2 << 14) | (1 << 29); let mut data = vec![VP8L_SIGNATURE];
1353 data.extend_from_slice(&val.to_le_bytes());
1354 assert!(Vp8lHeader::parse(&data).is_err());
1355 }
1356
1357 #[test]
1358 fn test_parse_header_too_short() {
1359 let data = [VP8L_SIGNATURE, 0x00];
1360 assert!(Vp8lHeader::parse(&data).is_err());
1361 }
1362
1363 #[test]
1366 fn test_bitreader_read_bits() {
1367 let data = [0xA5, 0xFF];
1370 let mut br = Vp8lBitReader::new(&data);
1371 let val = br.read_bits(4).expect("should read");
1373 assert_eq!(val, 0x5);
1374 let val = br.read_bits(4).expect("should read");
1376 assert_eq!(val, 0xA);
1377 }
1378
1379 #[test]
1380 fn test_bitreader_read_bit() {
1381 let data = [0x01];
1382 let mut br = Vp8lBitReader::new(&data);
1383 assert!(br.read_bit().expect("should read")); assert!(!br.read_bit().expect("should read")); }
1386
1387 #[test]
1388 fn test_bitreader_read_zero_bits() {
1389 let data = [0xFF];
1390 let mut br = Vp8lBitReader::new(&data);
1391 assert_eq!(br.read_bits(0).expect("should read"), 0);
1392 }
1393
1394 #[test]
1395 fn test_bitreader_peek_and_advance() {
1396 let data = [0xAB, 0xCD];
1397 let mut br = Vp8lBitReader::new(&data);
1398 let peeked = br.peek_bits(8).expect("should peek");
1399 assert_eq!(peeked, 0xAB);
1400 br.advance(4);
1401 let next = br.read_bits(4).expect("should read");
1402 assert_eq!(next, 0x0A); }
1404
1405 #[test]
1408 fn test_reverse_bits() {
1409 assert_eq!(reverse_bits(0b110, 3), 0b011);
1410 assert_eq!(reverse_bits(0b1010, 4), 0b0101);
1411 assert_eq!(reverse_bits(0b1, 1), 0b1);
1412 assert_eq!(reverse_bits(0b0, 1), 0b0);
1413 }
1414
1415 #[test]
1418 fn test_add_pixels() {
1419 let a = 0x01020304u32;
1420 let b = 0x05060708u32;
1421 let result = add_pixels(a, b);
1422 assert_eq!((result >> 24) & 0xFF, 0x06);
1423 assert_eq!((result >> 16) & 0xFF, 0x08);
1424 assert_eq!((result >> 8) & 0xFF, 0x0A);
1425 assert_eq!(result & 0xFF, 0x0C);
1426 }
1427
1428 #[test]
1429 fn test_add_pixels_wrapping() {
1430 let a = 0xFF800180u32;
1431 let b = 0x01810281u32;
1432 let result = add_pixels(a, b);
1433 assert_eq!((result >> 24) & 0xFF, 0x00); assert_eq!((result >> 16) & 0xFF, 0x01); assert_eq!((result >> 8) & 0xFF, 0x03); assert_eq!(result & 0xFF, 0x01); }
1438
1439 #[test]
1440 fn test_average2() {
1441 let a = 0xFF000000u32;
1442 let b = 0xFF000000u32;
1443 assert_eq!(average2(a, b), 0xFF000000);
1444
1445 let a = 0xFF640000u32; let b = 0xFFC80000u32; let result = average2(a, b);
1448 assert_eq!((result >> 16) & 0xFF, 150); }
1450
1451 #[test]
1452 fn test_select_predictor() {
1453 let left = 0xFF640000u32; let top = 0xFF0A0000u32; let top_left = 0xFF0A0000u32; let result = select(left, top, top_left);
1461 assert_eq!(result, left);
1462 }
1463
1464 #[test]
1465 fn test_clamp_add_subtract_full() {
1466 let left = channels_to_pixel([255, 100, 50, 30]);
1467 let top = channels_to_pixel([255, 80, 60, 20]);
1468 let top_left = channels_to_pixel([255, 90, 55, 25]);
1469 let result = clamp_add_subtract_full(left, top, top_left);
1471 let ch = pixel_channels(result);
1472 assert_eq!(ch[0], 255);
1473 assert_eq!(ch[1], 90);
1474 assert_eq!(ch[2], 55);
1475 assert_eq!(ch[3], 25);
1476 }
1477
1478 #[test]
1479 fn test_clamp_add_subtract_full_clamping() {
1480 let left = channels_to_pixel([255, 250, 10, 5]);
1481 let top = channels_to_pixel([255, 240, 5, 3]);
1482 let top_left = channels_to_pixel([255, 100, 200, 200]);
1483 let result = clamp_add_subtract_full(left, top, top_left);
1485 let ch = pixel_channels(result);
1486 assert_eq!(ch[1], 255);
1487 assert_eq!(ch[2], 0);
1488 assert_eq!(ch[3], 0);
1489 }
1490
1491 #[test]
1494 fn test_distance_map_code_1() {
1495 let dist = distance_map_to_pixel_dist(1, 10);
1497 assert_eq!(dist, 10);
1498 }
1499
1500 #[test]
1501 fn test_distance_map_code_2() {
1502 let dist = distance_map_to_pixel_dist(2, 10);
1504 assert_eq!(dist, 1);
1505 }
1506
1507 #[test]
1508 fn test_distance_map_negative_dx() {
1509 let dist = distance_map_to_pixel_dist(4, 10);
1511 assert_eq!(dist, 9);
1512 }
1513
1514 #[test]
1515 fn test_distance_map_over_120() {
1516 let dist = distance_map_to_pixel_dist(130, 10);
1518 assert_eq!(dist, 10);
1519 }
1520
1521 #[test]
1522 fn test_distance_map_clamp_to_1() {
1523 let dist = distance_map_to_pixel_dist(1, 1);
1526 assert_eq!(dist, 1);
1527 }
1528
1529 #[test]
1532 fn test_prefix_code_small() {
1533 let data = [0xFF; 4];
1535 let mut br = Vp8lBitReader::new(&data);
1536 assert_eq!(prefix_code_to_value(0, &mut br).expect("ok"), 1);
1537 assert_eq!(prefix_code_to_value(1, &mut br).expect("ok"), 2);
1538 assert_eq!(prefix_code_to_value(2, &mut br).expect("ok"), 3);
1539 assert_eq!(prefix_code_to_value(3, &mut br).expect("ok"), 4);
1540 }
1541
1542 #[test]
1543 fn test_prefix_code_with_extra_bits() {
1544 let data = [0x00; 4];
1547 let mut br = Vp8lBitReader::new(&data);
1548 assert_eq!(prefix_code_to_value(4, &mut br).expect("ok"), 5);
1549 }
1550
1551 #[test]
1554 fn test_huffman_single_symbol() {
1555 let code_lengths = [0u8, 1, 0, 0];
1557 let tree = HuffmanTree::build(&code_lengths, 4).expect("should build");
1558 let data = [0x00; 4];
1559 let mut br = Vp8lBitReader::new(&data);
1560 let sym = tree.read_symbol(&mut br).expect("should decode");
1561 assert_eq!(sym, 1);
1562 }
1563
1564 #[test]
1565 fn test_huffman_two_symbols() {
1566 let code_lengths = [1u8, 1];
1568 let tree = HuffmanTree::build(&code_lengths, 2).expect("should build");
1569
1570 let data = [0x00];
1572 let mut br = Vp8lBitReader::new(&data);
1573 assert_eq!(tree.read_symbol(&mut br).expect("ok"), 0);
1574
1575 let data = [0x01];
1577 let mut br = Vp8lBitReader::new(&data);
1578 assert_eq!(tree.read_symbol(&mut br).expect("ok"), 1);
1579 }
1580
1581 #[test]
1582 fn test_huffman_three_symbols() {
1583 let code_lengths = [1u8, 2, 2];
1586 let tree = HuffmanTree::build(&code_lengths, 3).expect("should build");
1587
1588 let data = [0b0000_0000];
1590 let mut br = Vp8lBitReader::new(&data);
1591 assert_eq!(tree.read_symbol(&mut br).expect("ok"), 0);
1592
1593 let data = [0b0000_0001];
1596 let mut br = Vp8lBitReader::new(&data);
1597 assert_eq!(tree.read_symbol(&mut br).expect("ok"), 1);
1598
1599 let data = [0b0000_0011];
1602 let mut br = Vp8lBitReader::new(&data);
1603 assert_eq!(tree.read_symbol(&mut br).expect("ok"), 2);
1604 }
1605
1606 #[test]
1609 fn test_inverse_subtract_green() {
1610 let decoder = Vp8lDecoder::new();
1611 let mut pixels = vec![0x00_20_40_60u32]; decoder.inverse_subtract_green(&mut pixels);
1613 assert_eq!((pixels[0] >> 16) & 0xFF, 0x60);
1616 assert_eq!(pixels[0] & 0xFF, 0xA0);
1617 assert_eq!((pixels[0] >> 8) & 0xFF, 0x40);
1619 }
1620
1621 #[test]
1624 fn test_color_transform_delta() {
1625 assert_eq!(color_transform_delta(4, 8), 1);
1627 assert_eq!(color_transform_delta(-4i32 as i32, 8), -1);
1629 }
1630
1631 #[test]
1634 fn test_predict_modes() {
1635 let left = 0xFF112233u32;
1636 let top = 0xFF445566u32;
1637 let top_left = 0xFF778899u32;
1638 let top_right = 0xFFAABBCCu32;
1639
1640 assert_eq!(predict(0, left, top, top_left, top_right), 0xFF000000);
1641 assert_eq!(predict(1, left, top, top_left, top_right), left);
1642 assert_eq!(predict(2, left, top, top_left, top_right), top);
1643 assert_eq!(predict(3, left, top, top_left, top_right), top_right);
1644 assert_eq!(predict(4, left, top, top_left, top_right), top_left);
1645 }
1646
1647 #[test]
1648 fn test_predict_average_modes() {
1649 let left = channels_to_pixel([255, 100, 50, 30]);
1650 let top = channels_to_pixel([255, 200, 100, 60]);
1651
1652 let result = predict(7, left, top, left, top);
1654 let ch = pixel_channels(result);
1655 assert_eq!(ch[1], 150); assert_eq!(ch[2], 75); assert_eq!(ch[3], 45); }
1659
1660 #[test]
1663 fn test_div_round_up() {
1664 assert_eq!(div_round_up(10, 3), 4);
1665 assert_eq!(div_round_up(9, 3), 3);
1666 assert_eq!(div_round_up(1, 1), 1);
1667 assert_eq!(div_round_up(0, 5), 0);
1668 }
1669
1670 #[test]
1673 fn test_color_cache() {
1674 let mut cache = ColorCache::new(4); let color = 0xFF112233u32;
1676 cache.insert(color);
1677 let hash = (0x1E35_A7BDu64.wrapping_mul(u64::from(color)) >> 28) as u32;
1679 assert_eq!(cache.lookup(hash), color);
1680 }
1681
1682 #[test]
1685 fn test_decoder_new() {
1686 let decoder = Vp8lDecoder::new();
1687 assert_eq!(decoder.width, 0);
1688 assert_eq!(decoder.height, 0);
1689 }
1690
1691 #[test]
1692 fn test_decoder_default() {
1693 let decoder = Vp8lDecoder::default();
1694 assert_eq!(decoder.width, 0);
1695 }
1696
1697 fn build_1x1_bitstream(argb: u32) -> Vec<u8> {
1702 let green = ((argb >> 8) & 0xFF) as u8;
1703 let red = ((argb >> 16) & 0xFF) as u8;
1704 let blue = (argb & 0xFF) as u8;
1705 let alpha = ((argb >> 24) & 0xFF) as u8;
1706
1707 let mut bits = BitWriter::new();
1716
1717 bits.write(0, 1);
1719
1720 bits.write(0, 1);
1722
1723 bits.write(0, 1);
1725
1726 write_single_symbol_tree(&mut bits, u16::from(green));
1729 write_single_symbol_tree(&mut bits, u16::from(red));
1731 write_single_symbol_tree(&mut bits, u16::from(blue));
1733 write_single_symbol_tree(&mut bits, u16::from(alpha));
1735 write_single_symbol_tree(&mut bits, 0);
1737
1738 let body = bits.finish();
1742
1743 let val: u32 = 0 | (0 << 14); let val = val | if alpha != 255 { 1 << 28 } else { 0 };
1747 let mut data = vec![VP8L_SIGNATURE];
1748 data.extend_from_slice(&val.to_le_bytes());
1749 data.extend_from_slice(&body);
1750 data
1751 }
1752
1753 fn write_single_symbol_tree(bw: &mut BitWriter, symbol: u16) {
1755 bw.write(1, 1);
1757 bw.write(0, 1);
1759 bw.write(1, 1);
1761 bw.write(u32::from(symbol), 8);
1763 }
1764
1765 struct BitWriter {
1767 bytes: Vec<u8>,
1768 current: u64,
1769 bits_used: u32,
1770 }
1771
1772 impl BitWriter {
1773 fn new() -> Self {
1774 Self {
1775 bytes: Vec::new(),
1776 current: 0,
1777 bits_used: 0,
1778 }
1779 }
1780
1781 fn write(&mut self, val: u32, n: u32) {
1782 self.current |= u64::from(val) << self.bits_used;
1783 self.bits_used += n;
1784 while self.bits_used >= 8 {
1785 self.bytes.push((self.current & 0xFF) as u8);
1786 self.current >>= 8;
1787 self.bits_used -= 8;
1788 }
1789 }
1790
1791 fn finish(mut self) -> Vec<u8> {
1792 if self.bits_used > 0 {
1793 self.bytes.push((self.current & 0xFF) as u8);
1794 }
1795 self.bytes
1796 }
1797 }
1798
1799 #[test]
1800 fn test_decode_1x1_white() {
1801 let data = build_1x1_bitstream(0xFFFF_FFFF);
1802 let mut decoder = Vp8lDecoder::new();
1803 let result = decoder.decode(&data).expect("should decode");
1804 assert_eq!(result.width, 1);
1805 assert_eq!(result.height, 1);
1806 assert_eq!(result.pixels.len(), 1);
1807 assert_eq!(result.pixels[0], 0xFFFF_FFFF);
1808 }
1809
1810 #[test]
1811 fn test_decode_1x1_red() {
1812 let data = build_1x1_bitstream(0xFFFF_0000);
1813 let mut decoder = Vp8lDecoder::new();
1814 let result = decoder.decode(&data).expect("should decode");
1815 assert_eq!(result.pixels[0], 0xFFFF_0000);
1816 }
1817
1818 #[test]
1819 fn test_decode_1x1_with_alpha() {
1820 let data = build_1x1_bitstream(0x80FF_0000);
1821 let mut decoder = Vp8lDecoder::new();
1822 let result = decoder.decode(&data).expect("should decode");
1823 assert_eq!(result.pixels[0], 0x80FF_0000);
1824 assert!(result.has_alpha);
1825 }
1826
1827 #[test]
1828 fn test_decode_1x1_black() {
1829 let data = build_1x1_bitstream(0xFF00_0000);
1830 let mut decoder = Vp8lDecoder::new();
1831 let result = decoder.decode(&data).expect("should decode");
1832 assert_eq!(result.pixels[0], 0xFF00_0000);
1833 }
1834
1835 #[test]
1836 fn test_decode_invalid_data() {
1837 let data = [0x00, 0x01]; let mut decoder = Vp8lDecoder::new();
1839 assert!(decoder.decode(&data).is_err());
1840 }
1841
1842 fn build_2x2_bitstream(pixels: [u32; 4]) -> Vec<u8> {
1844 let greens: Vec<u8> = pixels.iter().map(|p| ((p >> 8) & 0xFF) as u8).collect();
1850 let reds: Vec<u8> = pixels.iter().map(|p| ((p >> 16) & 0xFF) as u8).collect();
1851 let blues: Vec<u8> = pixels.iter().map(|p| (p & 0xFF) as u8).collect();
1852 let alphas: Vec<u8> = pixels.iter().map(|p| ((p >> 24) & 0xFF) as u8).collect();
1853
1854 let g = greens[0];
1857 let r = reds[0];
1858 let b = blues[0];
1859 let a = alphas[0];
1860 assert!(
1861 greens.iter().all(|&v| v == g),
1862 "Non-uniform green channel in test helper"
1863 );
1864 assert!(
1865 reds.iter().all(|&v| v == r),
1866 "Non-uniform red channel in test helper"
1867 );
1868 assert!(
1869 blues.iter().all(|&v| v == b),
1870 "Non-uniform blue channel in test helper"
1871 );
1872 assert!(
1873 alphas.iter().all(|&v| v == a),
1874 "Non-uniform alpha channel in test helper"
1875 );
1876
1877 let mut bits = BitWriter::new();
1878
1879 bits.write(0, 1);
1881 bits.write(0, 1);
1883 bits.write(0, 1);
1885
1886 write_single_symbol_tree(&mut bits, u16::from(g));
1888 write_single_symbol_tree(&mut bits, u16::from(r));
1889 write_single_symbol_tree(&mut bits, u16::from(b));
1890 write_single_symbol_tree(&mut bits, u16::from(a));
1891 write_single_symbol_tree(&mut bits, 0);
1892
1893 let body = bits.finish();
1894
1895 let val: u32 = 1 | (1 << 14); let val = val | if a != 255 { 1 << 28 } else { 0 };
1898 let mut data = vec![VP8L_SIGNATURE];
1899 data.extend_from_slice(&val.to_le_bytes());
1900 data.extend_from_slice(&body);
1901 data
1902 }
1903
1904 #[test]
1905 fn test_decode_2x2_uniform() {
1906 let color = 0xFF336699u32;
1907 let data = build_2x2_bitstream([color; 4]);
1908 let mut decoder = Vp8lDecoder::new();
1909 let result = decoder.decode(&data).expect("should decode");
1910 assert_eq!(result.width, 2);
1911 assert_eq!(result.height, 2);
1912 assert_eq!(result.pixels.len(), 4);
1913 for p in &result.pixels {
1914 assert_eq!(*p, color);
1915 }
1916 }
1917}