1//! Decoding of lossless WebP images
2//!
3//! [Lossless spec](https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification)
4//!
5
6use std::{
7 error, fmt,
8 io::Read,
9 ops::{AddAssign, Shl},
10};
11
12use byteorder::ReadBytesExt;
13
14use crate::{error::DecodingError, ImageError, ImageFormat, ImageResult};
15
16use super::huffman::HuffmanTree;
17use super::lossless_transform::{add_pixels, TransformType};
18
19const CODE_LENGTH_CODES: usize = 19;
20const CODE_LENGTH_CODE_ORDER: [usize; CODE_LENGTH_CODES] = [
21 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
22];
23
24#[rustfmt::skip]
25const DISTANCE_MAP: [(i8, i8); 120] = [
26 (0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), (-1, 2),
27 (2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), (1, 3), (-1, 3),
28 (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), (-3, 2), (0, 4), (4, 0),
29 (1, 4), (-1, 4), (4, 1), (-4, 1), (3, 3), (-3, 3), (2, 4), (-2, 4),
30 (4, 2), (-4, 2), (0, 5), (3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0),
31 (1, 5), (-1, 5), (5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2),
32 (4, 4), (-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0),
33 (1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), (-6, 2),
34 (4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), (6, 3), (-6, 3),
35 (0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), (-5, 5), (7, 1), (-7, 1),
36 (4, 6), (-4, 6), (6, 4), (-6, 4), (2, 7), (-2, 7), (7, 2), (-7, 2),
37 (3, 7), (-3, 7), (7, 3), (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5),
38 (8, 0), (4, 7), (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6),
39 (-6, 6), (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7),
40 (-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)
41];
42
43const GREEN: usize = 0;
44const RED: usize = 1;
45const BLUE: usize = 2;
46const ALPHA: usize = 3;
47const DIST: usize = 4;
48
49const HUFFMAN_CODES_PER_META_CODE: usize = 5;
50
51type HuffmanCodeGroup = [HuffmanTree; HUFFMAN_CODES_PER_META_CODE];
52
53const ALPHABET_SIZE: [u16; HUFFMAN_CODES_PER_META_CODE] = [256 + 24, 256, 256, 256, 40];
54
55#[inline]
56pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
57 ((u32::from(size) + (1u32 << bits) - 1) >> bits)
58 .try_into()
59 .unwrap()
60}
61
62#[derive(Debug, Clone, Copy)]
63pub(crate) enum DecoderError {
64 /// Signature of 0x2f not found
65 LosslessSignatureInvalid(u8),
66 /// Version Number must be 0
67 VersionNumberInvalid(u8),
68
69 ///
70 InvalidColorCacheBits(u8),
71
72 HuffmanError,
73
74 BitStreamError,
75
76 TransformError,
77}
78
79impl fmt::Display for DecoderError {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 match self {
82 DecoderError::LosslessSignatureInvalid(sig: &u8) => {
83 f.write_fmt(format_args!("Invalid lossless signature: {}", sig))
84 }
85 DecoderError::VersionNumberInvalid(num: &u8) => {
86 f.write_fmt(format_args!("Invalid version number: {}", num))
87 }
88 DecoderError::InvalidColorCacheBits(num: &u8) => f.write_fmt(format_args!(
89 "Invalid color cache(must be between 1-11): {}",
90 num
91 )),
92 DecoderError::HuffmanError => f.write_fmt(format_args!("Error building Huffman Tree")),
93 DecoderError::BitStreamError => {
94 f.write_fmt(format_args!("Error while reading bitstream"))
95 }
96 DecoderError::TransformError => {
97 f.write_fmt(format_args!("Error while reading or writing transforms"))
98 }
99 }
100 }
101}
102
103impl From<DecoderError> for ImageError {
104 fn from(e: DecoderError) -> ImageError {
105 ImageError::Decoding(DecodingError::new(format:ImageFormat::WebP.into(), err:e))
106 }
107}
108
109impl error::Error for DecoderError {}
110
111const NUM_TRANSFORM_TYPES: usize = 4;
112
113//Decodes lossless WebP images
114#[derive(Debug)]
115pub(crate) struct LosslessDecoder<R> {
116 r: R,
117 bit_reader: BitReader,
118 frame: LosslessFrame,
119 transforms: [Option<TransformType>; NUM_TRANSFORM_TYPES],
120 transform_order: Vec<u8>,
121}
122
123impl<R: Read> LosslessDecoder<R> {
124 /// Create a new decoder
125 pub(crate) fn new(r: R) -> LosslessDecoder<R> {
126 LosslessDecoder {
127 r,
128 bit_reader: BitReader::new(),
129 frame: Default::default(),
130 transforms: [None, None, None, None],
131 transform_order: Vec::new(),
132 }
133 }
134
135 /// Reads the frame
136 pub(crate) fn decode_frame(&mut self) -> ImageResult<&LosslessFrame> {
137 let signature = self.r.read_u8()?;
138
139 if signature != 0x2f {
140 return Err(DecoderError::LosslessSignatureInvalid(signature).into());
141 }
142
143 let mut buf = Vec::new();
144 self.r.read_to_end(&mut buf)?;
145 self.bit_reader.init(buf);
146
147 self.frame.width = self.bit_reader.read_bits::<u16>(14)? + 1;
148 self.frame.height = self.bit_reader.read_bits::<u16>(14)? + 1;
149
150 let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
151
152 let version_num = self.bit_reader.read_bits::<u8>(3)?;
153
154 if version_num != 0 {
155 return Err(DecoderError::VersionNumberInvalid(version_num).into());
156 }
157
158 let mut data = self.decode_image_stream(self.frame.width, self.frame.height, true)?;
159
160 for &trans_index in self.transform_order.iter().rev() {
161 let trans = self.transforms[usize::from(trans_index)].as_ref().unwrap();
162 trans.apply_transform(&mut data, self.frame.width, self.frame.height)?;
163 }
164
165 self.frame.buf = data;
166 Ok(&self.frame)
167 }
168
169 //used for alpha data in extended decoding
170 pub(crate) fn decode_frame_implicit_dims(
171 &mut self,
172 width: u16,
173 height: u16,
174 ) -> ImageResult<&LosslessFrame> {
175 let mut buf = Vec::new();
176 self.r.read_to_end(&mut buf)?;
177 self.bit_reader.init(buf);
178
179 self.frame.width = width;
180 self.frame.height = height;
181
182 let mut data = self.decode_image_stream(self.frame.width, self.frame.height, true)?;
183
184 //transform_order is vector of indices(0-3) into transforms in order decoded
185 for &trans_index in self.transform_order.iter().rev() {
186 let trans = self.transforms[usize::from(trans_index)].as_ref().unwrap();
187 trans.apply_transform(&mut data, self.frame.width, self.frame.height)?;
188 }
189
190 self.frame.buf = data;
191 Ok(&self.frame)
192 }
193
194 /// Reads Image data from the bitstream
195 /// Can be in any of the 5 roles described in the Specification
196 /// ARGB Image role has different behaviour to the other 4
197 /// xsize and ysize describe the size of the blocks where each block has its own entropy code
198 fn decode_image_stream(
199 &mut self,
200 xsize: u16,
201 ysize: u16,
202 is_argb_img: bool,
203 ) -> ImageResult<Vec<u32>> {
204 let trans_xsize = if is_argb_img {
205 self.read_transforms()?
206 } else {
207 xsize
208 };
209
210 let color_cache_bits = self.read_color_cache()?;
211
212 let color_cache = color_cache_bits.map(|bits| {
213 let size = 1 << bits;
214 let cache = vec![0u32; size];
215 ColorCache {
216 color_cache_bits: bits,
217 color_cache: cache,
218 }
219 });
220
221 let huffman_info = self.read_huffman_codes(is_argb_img, trans_xsize, ysize, color_cache)?;
222
223 //decode data
224 let data = self.decode_image_data(trans_xsize, ysize, huffman_info)?;
225
226 Ok(data)
227 }
228
229 /// Reads transforms and their data from the bitstream
230 fn read_transforms(&mut self) -> ImageResult<u16> {
231 let mut xsize = self.frame.width;
232
233 while self.bit_reader.read_bits::<u8>(1)? == 1 {
234 let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
235
236 if self.transforms[usize::from(transform_type_val)].is_some() {
237 //can only have one of each transform, error
238 return Err(DecoderError::TransformError.into());
239 }
240
241 self.transform_order.push(transform_type_val);
242
243 let transform_type = match transform_type_val {
244 0 => {
245 //predictor
246
247 let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
248
249 let block_xsize = subsample_size(xsize, size_bits);
250 let block_ysize = subsample_size(self.frame.height, size_bits);
251
252 let data = self.decode_image_stream(block_xsize, block_ysize, false)?;
253
254 TransformType::PredictorTransform {
255 size_bits,
256 predictor_data: data,
257 }
258 }
259 1 => {
260 //color transform
261
262 let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
263
264 let block_xsize = subsample_size(xsize, size_bits);
265 let block_ysize = subsample_size(self.frame.height, size_bits);
266
267 let data = self.decode_image_stream(block_xsize, block_ysize, false)?;
268
269 TransformType::ColorTransform {
270 size_bits,
271 transform_data: data,
272 }
273 }
274 2 => {
275 //subtract green
276
277 TransformType::SubtractGreen
278 }
279 3 => {
280 let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
281
282 let mut color_map = self.decode_image_stream(color_table_size, 1, false)?;
283
284 let bits = if color_table_size <= 2 {
285 3
286 } else if color_table_size <= 4 {
287 2
288 } else if color_table_size <= 16 {
289 1
290 } else {
291 0
292 };
293 xsize = subsample_size(xsize, bits);
294
295 Self::adjust_color_map(&mut color_map);
296
297 TransformType::ColorIndexingTransform {
298 table_size: color_table_size,
299 table_data: color_map,
300 }
301 }
302 _ => unreachable!(),
303 };
304
305 self.transforms[usize::from(transform_type_val)] = Some(transform_type);
306 }
307
308 Ok(xsize)
309 }
310
311 /// Adjusts the color map since it's subtraction coded
312 fn adjust_color_map(color_map: &mut [u32]) {
313 for i in 1..color_map.len() {
314 color_map[i] = add_pixels(color_map[i], color_map[i - 1]);
315 }
316 }
317
318 /// Reads huffman codes associated with an image
319 fn read_huffman_codes(
320 &mut self,
321 read_meta: bool,
322 xsize: u16,
323 ysize: u16,
324 color_cache: Option<ColorCache>,
325 ) -> ImageResult<HuffmanInfo> {
326 let mut num_huff_groups = 1;
327
328 let mut huffman_bits = 0;
329 let mut huffman_xsize = 1;
330 let mut huffman_ysize = 1;
331 let mut entropy_image = Vec::new();
332
333 if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
334 //meta huffman codes
335 huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
336 huffman_xsize = subsample_size(xsize, huffman_bits);
337 huffman_ysize = subsample_size(ysize, huffman_bits);
338
339 entropy_image = self.decode_image_stream(huffman_xsize, huffman_ysize, false)?;
340
341 for pixel in entropy_image.iter_mut() {
342 let meta_huff_code = (*pixel >> 8) & 0xffff;
343
344 *pixel = meta_huff_code;
345
346 if meta_huff_code >= num_huff_groups {
347 num_huff_groups = meta_huff_code + 1;
348 }
349 }
350 }
351
352 let mut hufftree_groups = Vec::new();
353
354 for _i in 0..num_huff_groups {
355 let mut group: HuffmanCodeGroup = Default::default();
356 for j in 0..HUFFMAN_CODES_PER_META_CODE {
357 let mut alphabet_size = ALPHABET_SIZE[j];
358 if j == 0 {
359 if let Some(color_cache) = color_cache.as_ref() {
360 alphabet_size += 1 << color_cache.color_cache_bits;
361 }
362 }
363
364 let tree = self.read_huffman_code(alphabet_size)?;
365 group[j] = tree;
366 }
367 hufftree_groups.push(group);
368 }
369
370 let huffman_mask = if huffman_bits == 0 {
371 !0
372 } else {
373 (1 << huffman_bits) - 1
374 };
375
376 let info = HuffmanInfo {
377 xsize: huffman_xsize,
378 _ysize: huffman_ysize,
379 color_cache,
380 image: entropy_image,
381 bits: huffman_bits,
382 mask: huffman_mask,
383 huffman_code_groups: hufftree_groups,
384 };
385
386 Ok(info)
387 }
388
389 /// Decodes and returns a single huffman tree
390 fn read_huffman_code(&mut self, alphabet_size: u16) -> ImageResult<HuffmanTree> {
391 let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
392
393 if simple {
394 let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
395
396 let mut code_lengths = vec![u16::from(num_symbols - 1)];
397 let mut codes = vec![0];
398 let mut symbols = Vec::new();
399
400 let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
401 symbols.push(self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?);
402
403 if num_symbols == 2 {
404 symbols.push(self.bit_reader.read_bits::<u16>(8)?);
405 code_lengths.push(1);
406 codes.push(1);
407 }
408
409 HuffmanTree::build_explicit(code_lengths, codes, symbols)
410 } else {
411 let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
412
413 let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
414 for i in 0..num_code_lengths {
415 code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
416 self.bit_reader.read_bits(3)?;
417 }
418
419 let new_code_lengths =
420 self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
421
422 HuffmanTree::build_implicit(new_code_lengths)
423 }
424 }
425
426 /// Reads huffman code lengths
427 fn read_huffman_code_lengths(
428 &mut self,
429 code_length_code_lengths: Vec<u16>,
430 num_symbols: u16,
431 ) -> ImageResult<Vec<u16>> {
432 let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
433
434 let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
435 let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
436 2 + self.bit_reader.read_bits::<u16>(length_nbits)?
437 } else {
438 num_symbols
439 };
440
441 let mut code_lengths = vec![0; usize::from(num_symbols)];
442 let mut prev_code_len = 8; //default code length
443
444 let mut symbol = 0;
445 while symbol < num_symbols {
446 if max_symbol == 0 {
447 break;
448 }
449 max_symbol -= 1;
450
451 let code_len = table.read_symbol(&mut self.bit_reader)?;
452
453 if code_len < 16 {
454 code_lengths[usize::from(symbol)] = code_len;
455 symbol += 1;
456 if code_len != 0 {
457 prev_code_len = code_len;
458 }
459 } else {
460 let use_prev = code_len == 16;
461 let slot = code_len - 16;
462 let extra_bits = match slot {
463 0 => 2,
464 1 => 3,
465 2 => 7,
466 _ => return Err(DecoderError::BitStreamError.into()),
467 };
468 let repeat_offset = match slot {
469 0 | 1 => 3,
470 2 => 11,
471 _ => return Err(DecoderError::BitStreamError.into()),
472 };
473
474 let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
475
476 if symbol + repeat > num_symbols {
477 return Err(DecoderError::BitStreamError.into());
478 } else {
479 let length = if use_prev { prev_code_len } else { 0 };
480 while repeat > 0 {
481 repeat -= 1;
482 code_lengths[usize::from(symbol)] = length;
483 symbol += 1;
484 }
485 }
486 }
487 }
488
489 Ok(code_lengths)
490 }
491
492 /// Decodes the image data using the huffman trees and either of the 3 methods of decoding
493 fn decode_image_data(
494 &mut self,
495 width: u16,
496 height: u16,
497 mut huffman_info: HuffmanInfo,
498 ) -> ImageResult<Vec<u32>> {
499 let num_values = usize::from(width) * usize::from(height);
500 let mut data = vec![0; num_values];
501
502 let huff_index = huffman_info.get_huff_index(0, 0);
503 let mut tree = &huffman_info.huffman_code_groups[huff_index];
504 let mut last_cached = 0;
505 let mut index = 0;
506 let mut x = 0;
507 let mut y = 0;
508 while index < num_values {
509 if (x & huffman_info.mask) == 0 {
510 let index = huffman_info.get_huff_index(x, y);
511 tree = &huffman_info.huffman_code_groups[index];
512 }
513
514 let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
515
516 //check code
517 if code < 256 {
518 //literal, so just use huffman codes and read as argb
519 let red = tree[RED].read_symbol(&mut self.bit_reader)?;
520 let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
521 let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
522
523 data[index] = (u32::from(alpha) << 24)
524 + (u32::from(red) << 16)
525 + (u32::from(code) << 8)
526 + u32::from(blue);
527
528 index += 1;
529 x += 1;
530 if x >= width {
531 x = 0;
532 y += 1;
533 }
534 } else if code < 256 + 24 {
535 //backward reference, so go back and use that to add image data
536 let length_symbol = code - 256;
537 let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
538
539 let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
540 let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
541 let dist = Self::plane_code_to_distance(width, dist_code);
542
543 if index < dist || num_values - index < length {
544 return Err(DecoderError::BitStreamError.into());
545 }
546
547 for i in 0..length {
548 data[index + i] = data[index + i - dist];
549 }
550 index += length;
551 x += u16::try_from(length).unwrap();
552 while x >= width {
553 x -= width;
554 y += 1;
555 }
556 if index < num_values {
557 let index = huffman_info.get_huff_index(x, y);
558 tree = &huffman_info.huffman_code_groups[index];
559 }
560 } else {
561 //color cache, so use previously stored pixels to get this pixel
562 let key = code - 256 - 24;
563
564 if let Some(color_cache) = huffman_info.color_cache.as_mut() {
565 //cache old colors
566 while last_cached < index {
567 color_cache.insert(data[last_cached]);
568 last_cached += 1;
569 }
570 data[index] = color_cache.lookup(key.into())?;
571 } else {
572 return Err(DecoderError::BitStreamError.into());
573 }
574 index += 1;
575 x += 1;
576 if x >= width {
577 x = 0;
578 y += 1;
579 }
580 }
581 }
582
583 Ok(data)
584 }
585
586 /// Reads color cache data from the bitstream
587 fn read_color_cache(&mut self) -> ImageResult<Option<u8>> {
588 if self.bit_reader.read_bits::<u8>(1)? == 1 {
589 let code_bits = self.bit_reader.read_bits::<u8>(4)?;
590
591 if !(1..=11).contains(&code_bits) {
592 return Err(DecoderError::InvalidColorCacheBits(code_bits).into());
593 }
594
595 Ok(Some(code_bits))
596 } else {
597 Ok(None)
598 }
599 }
600
601 /// Gets the copy distance from the prefix code and bitstream
602 fn get_copy_distance(bit_reader: &mut BitReader, prefix_code: u16) -> ImageResult<usize> {
603 if prefix_code < 4 {
604 return Ok(usize::from(prefix_code + 1));
605 }
606 let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
607 let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
608
609 Ok(offset + bit_reader.read_bits::<usize>(extra_bits)? + 1)
610 }
611
612 /// Gets distance to pixel
613 fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
614 if plane_code > 120 {
615 plane_code - 120
616 } else {
617 let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
618
619 let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
620 if dist < 1 {
621 return 1;
622 }
623 dist.try_into().unwrap()
624 }
625 }
626}
627
628#[derive(Debug, Clone)]
629struct HuffmanInfo {
630 xsize: u16,
631 _ysize: u16,
632 color_cache: Option<ColorCache>,
633 image: Vec<u32>,
634 bits: u8,
635 mask: u16,
636 huffman_code_groups: Vec<HuffmanCodeGroup>,
637}
638
639impl HuffmanInfo {
640 fn get_huff_index(&self, x: u16, y: u16) -> usize {
641 if self.bits == 0 {
642 return 0;
643 }
644 let position: usize = usize::from((y >> self.bits) * self.xsize + (x >> self.bits));
645 let meta_huff_code: usize = self.image[position].try_into().unwrap();
646 meta_huff_code
647 }
648}
649
650#[derive(Debug, Clone)]
651struct ColorCache {
652 color_cache_bits: u8,
653 color_cache: Vec<u32>,
654}
655
656impl ColorCache {
657 fn insert(&mut self, color: u32) {
658 let index: u32 = (0x1e35a7bdu32.overflowing_mul(color).0) >> (32 - self.color_cache_bits);
659 self.color_cache[index as usize] = color;
660 }
661
662 fn lookup(&self, index: usize) -> ImageResult<u32> {
663 match self.color_cache.get(index) {
664 Some(&value: u32) => Ok(value),
665 None => Err(DecoderError::BitStreamError.into()),
666 }
667 }
668}
669
670#[derive(Debug, Clone)]
671pub(crate) struct BitReader {
672 buf: Vec<u8>,
673 index: usize,
674 bit_count: u8,
675}
676
677impl BitReader {
678 fn new() -> BitReader {
679 BitReader {
680 buf: Vec::new(),
681 index: 0,
682 bit_count: 0,
683 }
684 }
685
686 fn init(&mut self, buf: Vec<u8>) {
687 self.buf = buf;
688 }
689
690 pub(crate) fn read_bits<T>(&mut self, num: u8) -> ImageResult<T>
691 where
692 T: num_traits::Unsigned + Shl<u8, Output = T> + AddAssign<T> + From<bool>,
693 {
694 let mut value: T = T::zero();
695
696 for i in 0..num {
697 if self.buf.len() <= self.index {
698 return Err(DecoderError::BitStreamError.into());
699 }
700 let bit_true = self.buf[self.index] & (1 << self.bit_count) != 0;
701 value += T::from(bit_true) << i;
702 self.bit_count = if self.bit_count == 7 {
703 self.index += 1;
704 0
705 } else {
706 self.bit_count + 1
707 };
708 }
709
710 Ok(value)
711 }
712}
713
714#[derive(Debug, Clone, Default)]
715pub(crate) struct LosslessFrame {
716 pub(crate) width: u16,
717 pub(crate) height: u16,
718
719 pub(crate) buf: Vec<u32>,
720}
721
722impl LosslessFrame {
723 /// Fills a buffer by converting from argb to rgba
724 pub(crate) fn fill_rgba(&self, buf: &mut [u8]) {
725 for (&argb_val: u32, chunk: &mut [u8]) in self.buf.iter().zip(buf.chunks_exact_mut(chunk_size:4)) {
726 chunk[0] = ((argb_val >> 16) & 0xff).try_into().unwrap();
727 chunk[1] = ((argb_val >> 8) & 0xff).try_into().unwrap();
728 chunk[2] = (argb_val & 0xff).try_into().unwrap();
729 chunk[3] = ((argb_val >> 24) & 0xff).try_into().unwrap();
730 }
731 }
732
733 /// Get buffer size from the image
734 pub(crate) fn get_buf_size(&self) -> usize {
735 usize::from(self.width) * usize::from(self.height) * 4
736 }
737
738 /// Fills a buffer with just the green values from the lossless decoding
739 /// Used in extended alpha decoding
740 pub(crate) fn fill_green(&self, buf: &mut [u8]) {
741 for (&argb_val: u32, buf_value: &mut u8) in self.buf.iter().zip(buf.iter_mut()) {
742 *buf_value = ((argb_val >> 8) & 0xff).try_into().unwrap();
743 }
744 }
745}
746
747#[cfg(test)]
748mod test {
749
750 use super::BitReader;
751
752 #[test]
753 fn bit_read_test() {
754 let mut bit_reader = BitReader::new();
755
756 //10011100 01000001 11100001
757 let buf = vec![0x9C, 0x41, 0xE1];
758
759 bit_reader.init(buf);
760
761 assert_eq!(bit_reader.read_bits::<u8>(3).unwrap(), 4); //100
762 assert_eq!(bit_reader.read_bits::<u8>(2).unwrap(), 3); //11
763 assert_eq!(bit_reader.read_bits::<u8>(6).unwrap(), 12); //001100
764 assert_eq!(bit_reader.read_bits::<u16>(10).unwrap(), 40); //0000101000
765 assert_eq!(bit_reader.read_bits::<u8>(3).unwrap(), 7); //111
766 }
767
768 #[test]
769 fn bit_read_error_test() {
770 let mut bit_reader = BitReader::new();
771
772 //01101010
773 let buf = vec![0x6A];
774
775 bit_reader.init(buf);
776
777 assert_eq!(bit_reader.read_bits::<u8>(3).unwrap(), 2); //010
778 assert_eq!(bit_reader.read_bits::<u8>(5).unwrap(), 13); //01101
779 assert!(bit_reader.read_bits::<u8>(4).is_err()); //error
780 }
781}
782