1#[derive(Debug, Clone)]
12pub struct QuantTable {
13 pub values: [u16; 64],
15}
16
17impl QuantTable {
18 pub fn new(values: [u16; 64]) -> Self {
19 Self { values }
20 }
21}
22
23#[derive(Debug, Clone)]
28pub struct DctGrid {
29 blocks_wide: usize,
31 blocks_tall: usize,
33 coeffs: Vec<i16>,
35}
36
37impl DctGrid {
38 pub fn new(blocks_wide: usize, blocks_tall: usize) -> Self {
40 Self {
41 blocks_wide,
42 blocks_tall,
43 coeffs: vec![0i16; blocks_wide * blocks_tall * 64],
44 }
45 }
46
47 pub fn blocks_wide(&self) -> usize {
48 self.blocks_wide
49 }
50
51 pub fn blocks_tall(&self) -> usize {
52 self.blocks_tall
53 }
54
55 pub fn get(&self, br: usize, bc: usize, i: usize, j: usize) -> i16 {
59 self.coeffs[self.index(br, bc, i, j)]
60 }
61
62 pub fn set(&mut self, br: usize, bc: usize, i: usize, j: usize, val: i16) {
64 let idx = self.index(br, bc, i, j);
65 self.coeffs[idx] = val;
66 }
67
68 pub fn block_mut(&mut self, br: usize, bc: usize) -> &mut [i16] {
70 let start = (br * self.blocks_wide + bc) * 64;
71 &mut self.coeffs[start..start + 64]
72 }
73
74 pub fn block(&self, br: usize, bc: usize) -> &[i16] {
76 let start = (br * self.blocks_wide + bc) * 64;
77 &self.coeffs[start..start + 64]
78 }
79
80 pub fn total_blocks(&self) -> usize {
82 self.blocks_wide * self.blocks_tall
83 }
84
85 pub fn coeffs_mut(&mut self) -> &mut [i16] {
91 &mut self.coeffs
92 }
93
94 pub fn coeffs(&self) -> &[i16] {
96 &self.coeffs
97 }
98
99 fn index(&self, br: usize, bc: usize, i: usize, j: usize) -> usize {
100 debug_assert!(br < self.blocks_tall, "block row {br} >= {}", self.blocks_tall);
101 debug_assert!(bc < self.blocks_wide, "block col {bc} >= {}", self.blocks_wide);
102 debug_assert!(i < 8 && j < 8);
103 (br * self.blocks_wide + bc) * 64 + i * 8 + j
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn grid_get_set() {
113 let mut grid = DctGrid::new(2, 3);
114 assert_eq!(grid.blocks_wide(), 2);
115 assert_eq!(grid.blocks_tall(), 3);
116 assert_eq!(grid.total_blocks(), 6);
117
118 assert_eq!(grid.get(0, 0, 0, 0), 0);
120 assert_eq!(grid.get(2, 1, 7, 7), 0);
121
122 grid.set(1, 0, 3, 4, 42);
123 assert_eq!(grid.get(1, 0, 3, 4), 42);
124
125 assert_eq!(grid.get(1, 0, 3, 3), 0);
127 assert_eq!(grid.get(0, 0, 3, 4), 0);
128 }
129
130 #[test]
131 fn block_slice_access() {
132 let mut grid = DctGrid::new(1, 1);
133 grid.set(0, 0, 0, 0, 100); grid.set(0, 0, 7, 7, -50);
135
136 let blk = grid.block(0, 0);
137 assert_eq!(blk[0], 100);
138 assert_eq!(blk[63], -50);
139 assert_eq!(blk.len(), 64);
140 }
141
142 #[test]
143 fn block_mut_access() {
144 let mut grid = DctGrid::new(2, 2);
145 let blk = grid.block_mut(1, 1);
146 for (i, v) in blk.iter_mut().enumerate() {
147 *v = i as i16;
148 }
149 assert_eq!(grid.get(1, 1, 0, 0), 0);
150 assert_eq!(grid.get(1, 1, 0, 1), 1);
151 assert_eq!(grid.get(1, 1, 7, 7), 63);
152 assert_eq!(grid.get(0, 0, 0, 0), 0);
154 }
155
156 #[test]
157 fn quant_table() {
158 let mut vals = [0u16; 64];
159 vals[0] = 16;
160 vals[63] = 99;
161 let qt = QuantTable::new(vals);
162 assert_eq!(qt.values[0], 16);
163 assert_eq!(qt.values[63], 99);
164 }
165}