jxl_coding/
permutation.rs1use jxl_bitstream::Bitstream;
2
3pub fn read_permutation(
5 bitstream: &mut Bitstream,
6 decoder: &mut crate::Decoder,
7 size: u32,
8 skip: u32,
9) -> crate::CodingResult<Vec<usize>> {
10 let end = decoder.read_varint(bitstream, get_context(size))?;
11 if end > size - skip {
12 tracing::error!(size, skip, end, "Invalid permutation");
13 return Err(crate::Error::InvalidPermutation);
14 }
15
16 let mut lehmer = vec![0u32; end as usize];
17 let mut prev_val = 0u32;
18 for (idx, val) in lehmer.iter_mut().enumerate() {
19 let idx = idx as u32;
20 *val = decoder.read_varint(bitstream, get_context(prev_val))?;
21 if *val >= size - skip - idx {
22 tracing::error!(idx = idx + skip, size, lehmer = *val, "Invalid permutation");
23 return Err(crate::Error::InvalidPermutation);
24 }
25 prev_val = *val;
26 }
27
28 let mut temp = ((skip as usize)..(size as usize)).collect::<Vec<_>>();
29 let mut permutation = Vec::with_capacity(size as usize);
30 for idx in 0..skip {
31 permutation.push(idx as usize);
32 }
33 for idx in lehmer {
34 permutation.push(temp.remove(idx as usize));
35 }
36 permutation.extend(temp);
37
38 Ok(permutation)
39}
40
41fn get_context(x: u32) -> u32 {
42 crate::add_log2_ceil(x).min(7)
43}