1use std::collections::HashMap;
4
5use crate::decoder::header::parse_still_webp;
6use crate::decoder::lossy::DecodedImage;
7use crate::decoder::vp8::get_lossless_info;
8use crate::decoder::vp8i::WebpFormat;
9use crate::decoder::DecoderError;
10
11const ARGB_BLACK: u32 = 0xff00_0000;
12const MAX_ALLOWED_CODE_LENGTH: usize = 15;
13const MAX_CACHE_BITS: usize = 11;
14const NUM_LITERAL_CODES: usize = 256;
15const NUM_LENGTH_CODES: usize = 24;
16const NUM_DISTANCE_CODES: usize = 40;
17const NUM_CODE_LENGTH_CODES: usize = 19;
18const MIN_HUFFMAN_BITS: usize = 2;
19const NUM_HUFFMAN_BITS: usize = 3;
20const MIN_TRANSFORM_BITS: usize = 2;
21const NUM_TRANSFORM_BITS: usize = 3;
22const DEFAULT_CODE_LENGTH: u8 = 8;
23const CODE_LENGTH_REPEAT_CODE: usize = 16;
24const CODE_LENGTH_EXTRA_BITS: [usize; 3] = [2, 3, 7];
25const CODE_LENGTH_REPEAT_OFFSETS: [usize; 3] = [3, 3, 11];
26const CODE_LENGTH_CODE_ORDER: [usize; NUM_CODE_LENGTH_CODES] = [
27 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
28];
29const CODE_TO_PLANE: [u8; 120] = [
30 0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a, 0x26, 0x2a, 0x38, 0x05, 0x37, 0x39,
31 0x15, 0x1b, 0x36, 0x3a, 0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b, 0x46, 0x4a,
32 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03, 0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d,
33 0x44, 0x4c, 0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e, 0x66, 0x6a, 0x22, 0x2e,
34 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b, 0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f,
35 0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b, 0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e,
36 0x00, 0x74, 0x7c, 0x41, 0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f, 0x40, 0x72,
37 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70,
38];
39const COLOR_CACHE_HASH_MUL: u32 = 0x1e35_a7bd;
40
41#[derive(Debug, Clone)]
42struct LosslessBitReader<'a> {
43 data: &'a [u8],
44 bit_pos: usize,
45}
46
47impl<'a> LosslessBitReader<'a> {
48 fn new(data: &'a [u8]) -> Self {
49 Self { data, bit_pos: 0 }
50 }
51
52 fn read_bit(&mut self) -> Result<u32, DecoderError> {
53 self.read_bits(1)
54 }
55
56 fn read_bits(&mut self, num_bits: usize) -> Result<u32, DecoderError> {
57 if num_bits > 24 {
58 return Err(DecoderError::InvalidParam("VP8L bit read is too wide"));
59 }
60 let end = self
61 .bit_pos
62 .checked_add(num_bits)
63 .ok_or(DecoderError::Bitstream("VP8L bit position overflow"))?;
64 if end > self.data.len() * 8 {
65 return Err(DecoderError::NotEnoughData("VP8L bitstream"));
66 }
67
68 let mut value = 0u32;
69 for bit_index in 0..num_bits {
70 let stream_bit = self.bit_pos + bit_index;
71 let byte = self.data[stream_bit >> 3];
72 let bit = (byte >> (stream_bit & 7)) & 1;
73 value |= (bit as u32) << bit_index;
74 }
75 self.bit_pos = end;
76 Ok(value)
77 }
78}
79
80#[derive(Debug, Clone)]
81struct HuffmanTree {
82 single_symbol: Option<u16>,
83 by_len: Vec<HashMap<u16, u16>>,
84 max_len: usize,
85}
86
87impl HuffmanTree {
88 fn from_code_lengths(code_lengths: &[u8]) -> Result<Self, DecoderError> {
89 let mut counts = [0i32; MAX_ALLOWED_CODE_LENGTH + 1];
90 let mut single_symbol = None;
91 let mut num_symbols = 0usize;
92
93 for (symbol, &len) in code_lengths.iter().enumerate() {
94 let bits = len as usize;
95 if bits > MAX_ALLOWED_CODE_LENGTH {
96 return Err(DecoderError::Bitstream("invalid VP8L Huffman code length"));
97 }
98 if bits > 0 {
99 counts[bits] += 1;
100 single_symbol = Some(symbol as u16);
101 num_symbols += 1;
102 }
103 }
104
105 if num_symbols == 0 {
106 return Err(DecoderError::Bitstream("empty VP8L Huffman tree"));
107 }
108 if num_symbols == 1 {
109 return Ok(Self {
110 single_symbol,
111 by_len: Vec::new(),
112 max_len: 0,
113 });
114 }
115
116 let mut left = 1i32;
117 for bits in 1..=MAX_ALLOWED_CODE_LENGTH {
118 left = (left << 1) - counts[bits];
119 if left < 0 {
120 return Err(DecoderError::Bitstream("oversubscribed VP8L Huffman tree"));
121 }
122 }
123 if left != 0 {
124 return Err(DecoderError::Bitstream("incomplete VP8L Huffman tree"));
125 }
126
127 let mut next_code = [0u32; MAX_ALLOWED_CODE_LENGTH + 1];
128 let mut code = 0u32;
129 for bits in 1..=MAX_ALLOWED_CODE_LENGTH {
130 code = (code + counts[bits - 1] as u32) << 1;
131 next_code[bits] = code;
132 }
133
134 let mut by_len = (0..=MAX_ALLOWED_CODE_LENGTH)
135 .map(|_| HashMap::new())
136 .collect::<Vec<_>>();
137 let mut max_len = 0usize;
138
139 for (symbol, &len) in code_lengths.iter().enumerate() {
140 let bits = len as usize;
141 if bits == 0 {
142 continue;
143 }
144 let canonical = next_code[bits];
145 next_code[bits] += 1;
146 by_len[bits].insert(reverse_bits(canonical, bits), symbol as u16);
147 max_len = max_len.max(bits);
148 }
149
150 Ok(Self {
151 single_symbol: None,
152 by_len,
153 max_len,
154 })
155 }
156
157 fn read_symbol(&self, br: &mut LosslessBitReader<'_>) -> Result<u16, DecoderError> {
158 if let Some(symbol) = self.single_symbol {
159 return Ok(symbol);
160 }
161
162 let mut code = 0u16;
163 for bits in 1..=self.max_len {
164 code |= (br.read_bit()? as u16) << (bits - 1);
165 if let Some(&symbol) = self.by_len[bits].get(&code) {
166 return Ok(symbol);
167 }
168 }
169
170 Err(DecoderError::Bitstream("invalid VP8L Huffman symbol"))
171 }
172}
173
174#[derive(Debug, Clone)]
175struct ColorCache {
176 colors: Vec<u32>,
177 hash_shift: u32,
178}
179
180impl ColorCache {
181 fn new(hash_bits: usize) -> Result<Self, DecoderError> {
182 if !(1..=MAX_CACHE_BITS).contains(&hash_bits) {
183 return Err(DecoderError::Bitstream("invalid VP8L color cache size"));
184 }
185 let size = 1usize << hash_bits;
186 Ok(Self {
187 colors: vec![0; size],
188 hash_shift: (32 - hash_bits) as u32,
189 })
190 }
191
192 fn insert(&mut self, argb: u32) {
193 let key = ((argb.wrapping_mul(COLOR_CACHE_HASH_MUL)) >> self.hash_shift) as usize;
194 self.colors[key] = argb;
195 }
196
197 fn lookup(&self, key: usize) -> Result<u32, DecoderError> {
198 self.colors
199 .get(key)
200 .copied()
201 .ok_or(DecoderError::Bitstream("invalid VP8L color cache lookup"))
202 }
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
206enum TransformType {
207 Predictor,
208 CrossColor,
209 SubtractGreen,
210 ColorIndexing,
211}
212
213#[derive(Debug, Clone)]
214struct Transform {
215 kind: TransformType,
216 bits: usize,
217 xsize: usize,
218 ysize: usize,
219 data: Vec<u32>,
220}
221
222#[derive(Debug, Clone)]
223struct HTreeGroup {
224 green: HuffmanTree,
225 red: HuffmanTree,
226 blue: HuffmanTree,
227 alpha: HuffmanTree,
228 dist: HuffmanTree,
229}
230
231#[derive(Debug, Clone)]
232struct HuffmanMetadata {
233 huffman_subsample_bits: usize,
234 huffman_xsize: usize,
235 huffman_image: Option<Vec<usize>>,
236 groups: Vec<HTreeGroup>,
237}
238
239impl HuffmanMetadata {
240 fn group_index(&self, x: usize, y: usize) -> usize {
241 if let Some(image) = &self.huffman_image {
242 image[(y >> self.huffman_subsample_bits) * self.huffman_xsize
243 + (x >> self.huffman_subsample_bits)]
244 } else {
245 0
246 }
247 }
248}
249
250struct LosslessDecoder<'a> {
251 br: LosslessBitReader<'a>,
252}
253
254impl<'a> LosslessDecoder<'a> {
255 fn new(data: &'a [u8]) -> Self {
256 Self {
257 br: LosslessBitReader::new(data),
258 }
259 }
260
261 fn decode_image_stream(
262 &mut self,
263 xsize: usize,
264 ysize: usize,
265 top_level: bool,
266 ) -> Result<Vec<u32>, DecoderError> {
267 let mut transforms = Vec::new();
268 let mut transform_xsize = xsize;
269 let transform_ysize = ysize;
270
271 if top_level {
272 let mut transforms_seen = 0u32;
273 while self.br.read_bit()? == 1 {
274 let transform =
275 self.read_transform(transform_xsize, transform_ysize, &mut transforms_seen)?;
276 if matches!(transform.kind, TransformType::ColorIndexing) {
277 transform_xsize = subsample_size(transform_xsize, transform.bits);
278 }
279 transforms.push(transform);
280 }
281 }
282
283 let color_cache_bits = if self.br.read_bit()? == 1 {
284 let bits = self.br.read_bits(4)? as usize;
285 if !(1..=MAX_CACHE_BITS).contains(&bits) {
286 return Err(DecoderError::Bitstream("invalid VP8L color cache bits"));
287 }
288 bits
289 } else {
290 0
291 };
292
293 let metadata = self.read_huffman_codes(
294 transform_xsize,
295 transform_ysize,
296 color_cache_bits,
297 top_level,
298 )?;
299 let mut data = self.decode_image_data(
300 transform_xsize,
301 transform_ysize,
302 color_cache_bits,
303 &metadata,
304 )?;
305
306 if top_level {
307 for transform in transforms.iter().rev() {
308 data = apply_inverse_transform(transform, &data)?;
309 }
310 }
311
312 Ok(data)
313 }
314
315 fn read_transform(
316 &mut self,
317 xsize: usize,
318 ysize: usize,
319 transforms_seen: &mut u32,
320 ) -> Result<Transform, DecoderError> {
321 let type_bits = self.br.read_bits(2)? as usize;
322 let kind = match type_bits {
323 0 => TransformType::Predictor,
324 1 => TransformType::CrossColor,
325 2 => TransformType::SubtractGreen,
326 3 => TransformType::ColorIndexing,
327 _ => unreachable!(),
328 };
329
330 if (*transforms_seen & (1u32 << type_bits)) != 0 {
331 return Err(DecoderError::Bitstream("duplicate VP8L transform"));
332 }
333 *transforms_seen |= 1u32 << type_bits;
334
335 match kind {
336 TransformType::Predictor | TransformType::CrossColor => {
337 let bits = MIN_TRANSFORM_BITS + self.br.read_bits(NUM_TRANSFORM_BITS)? as usize;
338 let data = self.decode_image_stream(
339 subsample_size(xsize, bits),
340 subsample_size(ysize, bits),
341 false,
342 )?;
343 Ok(Transform {
344 kind,
345 bits,
346 xsize,
347 ysize,
348 data,
349 })
350 }
351 TransformType::SubtractGreen => Ok(Transform {
352 kind,
353 bits: 0,
354 xsize,
355 ysize,
356 data: Vec::new(),
357 }),
358 TransformType::ColorIndexing => {
359 let num_colors = self.br.read_bits(8)? as usize + 1;
360 let bits = if num_colors > 16 {
361 0
362 } else if num_colors > 4 {
363 1
364 } else if num_colors > 2 {
365 2
366 } else {
367 3
368 };
369 let palette = self.decode_image_stream(num_colors, 1, false)?;
370 let expanded = expand_color_map(&palette, num_colors, bits);
371 Ok(Transform {
372 kind,
373 bits,
374 xsize,
375 ysize,
376 data: expanded,
377 })
378 }
379 }
380 }
381
382 fn read_huffman_codes(
383 &mut self,
384 xsize: usize,
385 ysize: usize,
386 color_cache_bits: usize,
387 allow_meta: bool,
388 ) -> Result<HuffmanMetadata, DecoderError> {
389 let mut huffman_subsample_bits = 0usize;
390 let mut huffman_xsize = 0usize;
391 let mut huffman_image = None;
392 let mapping = if allow_meta && self.br.read_bit()? == 1 {
393 huffman_subsample_bits =
394 MIN_HUFFMAN_BITS + self.br.read_bits(NUM_HUFFMAN_BITS)? as usize;
395 huffman_xsize = subsample_size(xsize, huffman_subsample_bits);
396 let huffman_ysize = subsample_size(ysize, huffman_subsample_bits);
397 let image = self.decode_image_stream(huffman_xsize, huffman_ysize, false)?;
398
399 let mut max_group = 0usize;
400 let raw_groups = image
401 .iter()
402 .map(|&pixel| ((pixel >> 8) & 0xffff) as usize)
403 .inspect(|&group| max_group = max_group.max(group))
404 .collect::<Vec<_>>();
405 let mut mapping = vec![None; max_group + 1];
406 let mut dense_image = Vec::with_capacity(raw_groups.len());
407 let mut next_group = 0usize;
408 for group in raw_groups {
409 let dense = if let Some(index) = mapping[group] {
410 index
411 } else {
412 let index = next_group;
413 mapping[group] = Some(index);
414 next_group += 1;
415 index
416 };
417 dense_image.push(dense);
418 }
419 huffman_image = Some(dense_image);
420 mapping
421 } else {
422 vec![Some(0)]
423 };
424
425 let num_groups = mapping.iter().flatten().count();
426 let mut groups = vec![None; num_groups];
427 for dense in mapping {
428 let group = self.read_htree_group(color_cache_bits)?;
429 if let Some(index) = dense {
430 groups[index] = Some(group);
431 }
432 }
433
434 let groups = groups
435 .into_iter()
436 .map(|group| group.ok_or(DecoderError::Bitstream("missing VP8L Huffman group")))
437 .collect::<Result<Vec<_>, _>>()?;
438
439 Ok(HuffmanMetadata {
440 huffman_subsample_bits,
441 huffman_xsize,
442 huffman_image,
443 groups,
444 })
445 }
446
447 fn read_htree_group(&mut self, color_cache_bits: usize) -> Result<HTreeGroup, DecoderError> {
448 let green_alphabet_size = NUM_LITERAL_CODES
449 + NUM_LENGTH_CODES
450 + if color_cache_bits > 0 {
451 1usize << color_cache_bits
452 } else {
453 0
454 };
455
456 Ok(HTreeGroup {
457 green: self.read_huffman_code(green_alphabet_size)?,
458 red: self.read_huffman_code(NUM_LITERAL_CODES)?,
459 blue: self.read_huffman_code(NUM_LITERAL_CODES)?,
460 alpha: self.read_huffman_code(NUM_LITERAL_CODES)?,
461 dist: self.read_huffman_code(NUM_DISTANCE_CODES)?,
462 })
463 }
464
465 fn read_huffman_code(&mut self, alphabet_size: usize) -> Result<HuffmanTree, DecoderError> {
466 let mut code_lengths = vec![0u8; alphabet_size];
467 let simple_code = self.br.read_bit()? == 1;
468
469 if simple_code {
470 let num_symbols = self.br.read_bit()? as usize + 1;
471 let first_symbol_len_code = self.br.read_bit()? as usize;
472 let first_bits = if first_symbol_len_code == 0 { 1 } else { 8 };
473 let first_symbol = self.br.read_bits(first_bits)? as usize;
474 if first_symbol >= alphabet_size {
475 return Err(DecoderError::Bitstream(
476 "invalid VP8L simple Huffman symbol",
477 ));
478 }
479 code_lengths[first_symbol] = 1;
480 if num_symbols == 2 {
481 let second_symbol = self.br.read_bits(8)? as usize;
482 if second_symbol >= alphabet_size {
483 return Err(DecoderError::Bitstream(
484 "invalid VP8L simple Huffman symbol",
485 ));
486 }
487 code_lengths[second_symbol] = 1;
488 }
489 } else {
490 let mut code_length_code_lengths = [0u8; NUM_CODE_LENGTH_CODES];
491 let num_codes = self.br.read_bits(4)? as usize + 4;
492 if num_codes > NUM_CODE_LENGTH_CODES {
493 return Err(DecoderError::Bitstream("too many VP8L code length codes"));
494 }
495 for i in 0..num_codes {
496 code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] = self.br.read_bits(3)? as u8;
497 }
498 let code_length_tree = HuffmanTree::from_code_lengths(&code_length_code_lengths)?;
499 self.read_huffman_code_lengths(&code_length_tree, &mut code_lengths)?;
500 }
501
502 HuffmanTree::from_code_lengths(&code_lengths)
503 }
504
505 fn read_huffman_code_lengths(
506 &mut self,
507 code_length_tree: &HuffmanTree,
508 code_lengths: &mut [u8],
509 ) -> Result<(), DecoderError> {
510 let num_symbols = code_lengths.len();
511 let mut max_symbol = if self.br.read_bit()? == 1 {
512 let length_nbits = 2 + 2 * self.br.read_bits(3)? as usize;
513 let value = 2 + self.br.read_bits(length_nbits)? as usize;
514 if value > num_symbols {
515 return Err(DecoderError::Bitstream(
516 "invalid VP8L Huffman code length span",
517 ));
518 }
519 value
520 } else {
521 num_symbols
522 };
523
524 let mut symbol = 0usize;
525 let mut prev_code_len = DEFAULT_CODE_LENGTH;
526 while symbol < num_symbols {
527 if max_symbol == 0 {
528 break;
529 }
530 max_symbol -= 1;
531
532 let code_len = code_length_tree.read_symbol(&mut self.br)? as usize;
533 if code_len < CODE_LENGTH_REPEAT_CODE {
534 code_lengths[symbol] = code_len as u8;
535 if code_len != 0 {
536 prev_code_len = code_len as u8;
537 }
538 symbol += 1;
539 continue;
540 }
541
542 let slot = code_len
543 .checked_sub(CODE_LENGTH_REPEAT_CODE)
544 .ok_or(DecoderError::Bitstream("invalid VP8L repeat code"))?;
545 if slot >= CODE_LENGTH_EXTRA_BITS.len() {
546 return Err(DecoderError::Bitstream("invalid VP8L repeat code"));
547 }
548 let repeat = self.br.read_bits(CODE_LENGTH_EXTRA_BITS[slot])? as usize
549 + CODE_LENGTH_REPEAT_OFFSETS[slot];
550 if symbol + repeat > num_symbols {
551 return Err(DecoderError::Bitstream("VP8L repeat overruns code lengths"));
552 }
553 let value = if code_len == CODE_LENGTH_REPEAT_CODE {
554 prev_code_len
555 } else {
556 0
557 };
558 for len in &mut code_lengths[symbol..symbol + repeat] {
559 *len = value;
560 }
561 symbol += repeat;
562 }
563
564 Ok(())
565 }
566
567 fn decode_image_data(
568 &mut self,
569 width: usize,
570 height: usize,
571 color_cache_bits: usize,
572 metadata: &HuffmanMetadata,
573 ) -> Result<Vec<u32>, DecoderError> {
574 let mut data = vec![0u32; width * height];
575 let mut color_cache = if color_cache_bits > 0 {
576 Some(ColorCache::new(color_cache_bits)?)
577 } else {
578 None
579 };
580 let mut pos = 0usize;
581 let len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
582 let color_cache_limit = len_code_limit
583 + if color_cache_bits > 0 {
584 1usize << color_cache_bits
585 } else {
586 0
587 };
588
589 while pos < data.len() {
590 let x = pos % width;
591 let y = pos / width;
592 let group = &metadata.groups[metadata.group_index(x, y)];
593 let code = group.green.read_symbol(&mut self.br)? as usize;
594
595 if code < NUM_LITERAL_CODES {
596 let red = group.red.read_symbol(&mut self.br)? as u32;
597 let blue = group.blue.read_symbol(&mut self.br)? as u32;
598 let alpha = group.alpha.read_symbol(&mut self.br)? as u32;
599 let pixel = (alpha << 24) | (red << 16) | ((code as u32) << 8) | blue;
600 data[pos] = pixel;
601 if let Some(cache) = &mut color_cache {
602 cache.insert(pixel);
603 }
604 pos += 1;
605 } else if code < len_code_limit {
606 let length = get_copy_value(code - NUM_LITERAL_CODES, &mut self.br)?;
607 let dist_symbol = group.dist.read_symbol(&mut self.br)? as usize;
608 let dist_code = get_copy_value(dist_symbol, &mut self.br)?;
609 let dist = plane_code_to_distance(width, dist_code);
610 if dist > pos || pos + length > data.len() {
611 return Err(DecoderError::Bitstream("invalid VP8L backward reference"));
612 }
613 for i in 0..length {
614 let pixel = data[pos + i - dist];
615 data[pos + i] = pixel;
616 if let Some(cache) = &mut color_cache {
617 cache.insert(pixel);
618 }
619 }
620 pos += length;
621 } else if code < color_cache_limit {
622 let key = code - len_code_limit;
623 let cache = color_cache
624 .as_mut()
625 .ok_or(DecoderError::Bitstream("unexpected VP8L color cache code"))?;
626 let pixel = cache.lookup(key)?;
627 data[pos] = pixel;
628 cache.insert(pixel);
629 pos += 1;
630 } else {
631 return Err(DecoderError::Bitstream("invalid VP8L green Huffman symbol"));
632 }
633 }
634
635 Ok(data)
636 }
637}
638
639fn reverse_bits(mut code: u32, bits: usize) -> u16 {
640 let mut out = 0u32;
641 for _ in 0..bits {
642 out = (out << 1) | (code & 1);
643 code >>= 1;
644 }
645 out as u16
646}
647
648fn subsample_size(size: usize, bits: usize) -> usize {
649 (size + (1usize << bits) - 1) >> bits
650}
651
652fn get_copy_value(symbol: usize, br: &mut LosslessBitReader<'_>) -> Result<usize, DecoderError> {
653 if symbol < 4 {
654 Ok(symbol + 1)
655 } else {
656 let extra_bits = (symbol - 2) >> 1;
657 let offset = (2 + (symbol & 1)) << extra_bits;
658 Ok(offset + br.read_bits(extra_bits)? as usize + 1)
659 }
660}
661
662fn plane_code_to_distance(width: usize, plane_code: usize) -> usize {
663 if plane_code > CODE_TO_PLANE.len() {
664 plane_code - CODE_TO_PLANE.len()
665 } else {
666 let dist_code = CODE_TO_PLANE[plane_code - 1];
667 let y_offset = (dist_code >> 4) as isize;
668 let x_offset = 8isize - (dist_code & 0x0f) as isize;
669 let dist = y_offset * width as isize + x_offset;
670 dist.max(1) as usize
671 }
672}
673
674fn add_pixels(a: u32, b: u32) -> u32 {
675 let alpha = (((a >> 24) as u8).wrapping_add((b >> 24) as u8)) as u32;
676 let red = (((a >> 16) as u8).wrapping_add((b >> 16) as u8)) as u32;
677 let green = (((a >> 8) as u8).wrapping_add((b >> 8) as u8)) as u32;
678 let blue = ((a as u8).wrapping_add(b as u8)) as u32;
679 (alpha << 24) | (red << 16) | (green << 8) | blue
680}
681
682fn average2(a: u32, b: u32) -> u32 {
683 (((a ^ b) & 0xfefe_fefeu32) >> 1) + (a & b)
684}
685
686fn clip255(value: i32) -> u32 {
687 value.clamp(0, 255) as u32
688}
689
690fn clamped_add_subtract_full(left: u32, top: u32, top_left: u32) -> u32 {
691 let alpha = clip255((left >> 24) as i32 + (top >> 24) as i32 - (top_left >> 24) as i32);
692 let red = clip255(
693 ((left >> 16) & 0xff) as i32 + ((top >> 16) & 0xff) as i32
694 - ((top_left >> 16) & 0xff) as i32,
695 );
696 let green = clip255(
697 ((left >> 8) & 0xff) as i32 + ((top >> 8) & 0xff) as i32 - ((top_left >> 8) & 0xff) as i32,
698 );
699 let blue = clip255((left & 0xff) as i32 + (top & 0xff) as i32 - (top_left & 0xff) as i32);
700 (alpha << 24) | (red << 16) | (green << 8) | blue
701}
702
703fn clamped_add_subtract_half(left: u32, top: u32, top_left: u32) -> u32 {
704 let avg = average2(left, top);
705 let alpha = clip255((avg >> 24) as i32 + ((avg >> 24) as i32 - (top_left >> 24) as i32) / 2);
706 let red = clip255(
707 ((avg >> 16) & 0xff) as i32
708 + (((avg >> 16) & 0xff) as i32 - ((top_left >> 16) & 0xff) as i32) / 2,
709 );
710 let green = clip255(
711 ((avg >> 8) & 0xff) as i32
712 + (((avg >> 8) & 0xff) as i32 - ((top_left >> 8) & 0xff) as i32) / 2,
713 );
714 let blue = clip255((avg & 0xff) as i32 + ((avg & 0xff) as i32 - (top_left & 0xff) as i32) / 2);
715 (alpha << 24) | (red << 16) | (green << 8) | blue
716}
717
718fn select_predictor(left: u32, top: u32, top_left: u32) -> u32 {
719 let pred_alpha = ((left >> 24) as i32) + ((top >> 24) as i32) - ((top_left >> 24) as i32);
720 let pred_red = ((left >> 16) & 0xff) as i32 + ((top >> 16) & 0xff) as i32
721 - ((top_left >> 16) & 0xff) as i32;
722 let pred_green =
723 ((left >> 8) & 0xff) as i32 + ((top >> 8) & 0xff) as i32 - ((top_left >> 8) & 0xff) as i32;
724 let pred_blue = (left & 0xff) as i32 + (top & 0xff) as i32 - (top_left & 0xff) as i32;
725
726 let left_distance = (pred_alpha - ((left >> 24) as i32)).abs()
727 + (pred_red - (((left >> 16) & 0xff) as i32)).abs()
728 + (pred_green - (((left >> 8) & 0xff) as i32)).abs()
729 + (pred_blue - ((left & 0xff) as i32)).abs();
730 let top_distance = (pred_alpha - ((top >> 24) as i32)).abs()
731 + (pred_red - (((top >> 16) & 0xff) as i32)).abs()
732 + (pred_green - (((top >> 8) & 0xff) as i32)).abs()
733 + (pred_blue - ((top & 0xff) as i32)).abs();
734
735 if left_distance < top_distance {
736 left
737 } else {
738 top
739 }
740}
741
742fn predictor(mode: u8, left: u32, top: u32, top_left: u32, top_right: u32) -> u32 {
743 match mode {
744 0 | 14 | 15 => ARGB_BLACK,
745 1 => left,
746 2 => top,
747 3 => top_right,
748 4 => top_left,
749 5 => average2(average2(left, top_right), top),
750 6 => average2(left, top_left),
751 7 => average2(left, top),
752 8 => average2(top_left, top),
753 9 => average2(top, top_right),
754 10 => average2(average2(left, top_left), average2(top, top_right)),
755 11 => select_predictor(left, top, top_left),
756 12 => clamped_add_subtract_full(left, top, top_left),
757 13 => clamped_add_subtract_half(left, top, top_left),
758 _ => ARGB_BLACK,
759 }
760}
761
762fn color_transform_delta(transform: u8, color: u8) -> i32 {
763 ((transform as i8 as i32) * (color as i8 as i32)) >> 5
764}
765
766fn expand_color_map(palette: &[u32], num_colors: usize, bits: usize) -> Vec<u32> {
767 let final_num_colors = 1usize << (8 >> bits);
768 let mut expanded = vec![0u32; final_num_colors];
769 if num_colors == 0 {
770 return expanded;
771 }
772
773 expanded[0] = palette[0];
774 for i in 1..num_colors {
775 expanded[i] = add_pixels(palette[i], expanded[i - 1]);
776 }
777 expanded
778}
779
780fn apply_inverse_transform(transform: &Transform, input: &[u32]) -> Result<Vec<u32>, DecoderError> {
781 match transform.kind {
782 TransformType::SubtractGreen => Ok(input
783 .iter()
784 .map(|&argb| {
785 let green = (argb >> 8) & 0xff;
786 let red = (((argb >> 16) & 0xff) + green) & 0xff;
787 let blue = ((argb & 0xff) + green) & 0xff;
788 (argb & 0xff00_ff00) | (red << 16) | blue
789 })
790 .collect()),
791 TransformType::CrossColor => {
792 let expected_len = transform
793 .xsize
794 .checked_mul(transform.ysize)
795 .ok_or(DecoderError::Bitstream("VP8L transform size overflow"))?;
796 if input.len() != expected_len {
797 return Err(DecoderError::Bitstream("VP8L cross-color size mismatch"));
798 }
799 let tiles_per_row = subsample_size(transform.xsize, transform.bits);
800 let mut output = vec![0u32; input.len()];
801 for y in 0..transform.ysize {
802 for x in 0..transform.xsize {
803 let argb = input[y * transform.xsize + x];
804 let code = transform.data
805 [(y >> transform.bits) * tiles_per_row + (x >> transform.bits)];
806 let green_to_red = code as u8;
807 let green_to_blue = ((code >> 8) & 0xff) as u8;
808 let red_to_blue = ((code >> 16) & 0xff) as u8;
809 let green = ((argb >> 8) & 0xff) as u8;
810 let mut red = ((argb >> 16) & 0xff) as i32;
811 let mut blue = (argb & 0xff) as i32;
812 red = (red + color_transform_delta(green_to_red, green)) & 0xff;
813 blue = (blue + color_transform_delta(green_to_blue, green)) & 0xff;
814 blue = (blue + color_transform_delta(red_to_blue, red as u8)) & 0xff;
815 output[y * transform.xsize + x] =
816 (argb & 0xff00_ff00) | ((red as u32) << 16) | (blue as u32);
817 }
818 }
819 Ok(output)
820 }
821 TransformType::Predictor => {
822 let expected_len = transform
823 .xsize
824 .checked_mul(transform.ysize)
825 .ok_or(DecoderError::Bitstream("VP8L transform size overflow"))?;
826 if input.len() != expected_len {
827 return Err(DecoderError::Bitstream("VP8L predictor size mismatch"));
828 }
829 let tiles_per_row = subsample_size(transform.xsize, transform.bits);
830 let mut output = vec![0u32; input.len()];
831 for y in 0..transform.ysize {
832 for x in 0..transform.xsize {
833 let residual = input[y * transform.xsize + x];
834 let pred = if y == 0 {
835 if x == 0 {
836 ARGB_BLACK
837 } else {
838 output[y * transform.xsize + x - 1]
839 }
840 } else if x == 0 {
841 output[(y - 1) * transform.xsize]
842 } else {
843 let left = output[y * transform.xsize + x - 1];
844 let top = output[(y - 1) * transform.xsize + x];
845 let top_left = output[(y - 1) * transform.xsize + x - 1];
846 let top_right = if x + 1 < transform.xsize {
847 output[(y - 1) * transform.xsize + x + 1]
848 } else {
849 output[y * transform.xsize]
850 };
851 let mode = ((transform.data
852 [(y >> transform.bits) * tiles_per_row + (x >> transform.bits)]
853 >> 8)
854 & 0x0f) as u8;
855 predictor(mode, left, top, top_left, top_right)
856 };
857 output[y * transform.xsize + x] = add_pixels(residual, pred);
858 }
859 }
860 Ok(output)
861 }
862 TransformType::ColorIndexing => {
863 let reduced_width = subsample_size(transform.xsize, transform.bits);
864 let expected_len = reduced_width
865 .checked_mul(transform.ysize)
866 .ok_or(DecoderError::Bitstream("VP8L transform size overflow"))?;
867 if input.len() != expected_len {
868 return Err(DecoderError::Bitstream("VP8L color indexing size mismatch"));
869 }
870
871 let bits_per_pixel = 8 >> transform.bits;
872 let pixels_per_byte = 1usize << transform.bits;
873 let bit_mask = (1u32 << bits_per_pixel) - 1;
874 let mut output = vec![0u32; transform.xsize * transform.ysize];
875
876 if transform.bits == 0 {
877 for (dst, &src) in output.iter_mut().zip(input.iter()) {
878 let index = ((src >> 8) & 0xff) as usize;
879 *dst = transform.data.get(index).copied().unwrap_or(0);
880 }
881 return Ok(output);
882 }
883
884 for y in 0..transform.ysize {
885 let src_row = &input[y * reduced_width..(y + 1) * reduced_width];
886 let dst_row = &mut output[y * transform.xsize..(y + 1) * transform.xsize];
887 let mut x = 0usize;
888 for &packed in src_row {
889 let mut indices = (packed >> 8) & 0xff;
890 for _ in 0..pixels_per_byte {
891 if x >= transform.xsize {
892 break;
893 }
894 let index = (indices & bit_mask) as usize;
895 dst_row[x] = transform.data.get(index).copied().unwrap_or(0);
896 indices >>= bits_per_pixel;
897 x += 1;
898 }
899 }
900 }
901
902 Ok(output)
903 }
904 }
905}
906
907fn argb_to_rgba(argb: &[u32]) -> Vec<u8> {
908 let mut rgba = vec![0u8; argb.len() * 4];
909 for (index, &pixel) in argb.iter().enumerate() {
910 let base = index * 4;
911 rgba[base] = ((pixel >> 16) & 0xff) as u8;
912 rgba[base + 1] = ((pixel >> 8) & 0xff) as u8;
913 rgba[base + 2] = (pixel & 0xff) as u8;
914 rgba[base + 3] = (pixel >> 24) as u8;
915 }
916 rgba
917}
918
919pub(crate) fn decode_lossless_vp8l_to_argb(
920 data: &[u8],
921) -> Result<(usize, usize, Vec<u32>), DecoderError> {
922 let info = get_lossless_info(data)?;
923 let bitstream = data
924 .get(5..)
925 .ok_or(DecoderError::NotEnoughData("VP8L frame payload"))?;
926 let mut decoder = LosslessDecoder::new(bitstream);
927 let argb = decoder.decode_image_stream(info.width, info.height, true)?;
928 if argb.len() != info.width * info.height {
929 return Err(DecoderError::Bitstream("decoded VP8L image has wrong size"));
930 }
931 Ok((info.width, info.height, argb))
932}
933
934pub fn decode_lossless_vp8l_to_rgba(data: &[u8]) -> Result<DecodedImage, DecoderError> {
936 let (width, height, argb) = decode_lossless_vp8l_to_argb(data)?;
937
938 Ok(DecodedImage {
939 width,
940 height,
941 rgba: argb_to_rgba(&argb),
942 })
943}
944
945pub fn decode_lossless_webp_to_rgba(data: &[u8]) -> Result<DecodedImage, DecoderError> {
947 let parsed = parse_still_webp(data)?;
948 if parsed.features.format != WebpFormat::Lossless {
949 return Err(DecoderError::Unsupported(
950 "expected a still lossless WebP image",
951 ));
952 }
953 decode_lossless_vp8l_to_rgba(parsed.image_data)
954}