Skip to main content

mozjpeg/
component.rs

1pub use crate::ffi::jpeg_component_info as CompInfo;
2use crate::ffi::DCTSIZE;
3use crate::qtable::QTable;
4
5pub trait CompInfoExt {
6    /// Number of pixels per row, including padding to MCU
7    fn row_stride(&self) -> usize;
8    /// Total height, including padding to MCU
9    fn col_stride(&self) -> usize;
10
11    /// h,v samplinig (1..4). Number of pixels per sample (may be opposite of what you expect!)
12    fn sampling(&self) -> (u8, u8);
13
14    // Quantization table, if available
15    fn qtable(&self) -> Option<QTable>;
16
17    // Number of blocks per row
18    fn width_in_blocks(&self) -> usize;
19
20    // Number of block rows
21    fn height_in_blocks(&self) -> usize;
22}
23
24impl CompInfoExt for CompInfo {
25    fn qtable(&self) -> Option<QTable> {
26        unsafe { self.quant_table.as_ref() }.map(|q_in| {
27            let mut qtable = QTable { coeffs: [0; 64] };
28            for (out, q) in qtable.coeffs.iter_mut().zip(q_in.quantval.iter()) {
29                *out = u32::from(*q);
30            }
31            qtable
32        })
33    }
34
35    fn sampling(&self) -> (u8, u8) {
36        (self.h_samp_factor as u8, self.v_samp_factor as u8)
37    }
38
39    fn row_stride(&self) -> usize {
40        assert!(self.width_in_blocks > 0);
41        self.width_in_blocks as usize * DCTSIZE
42    }
43
44    fn col_stride(&self) -> usize {
45        assert!(self.height_in_blocks > 0);
46        self.height_in_blocks as usize * DCTSIZE
47    }
48
49    fn width_in_blocks(&self) -> usize {
50        self.width_in_blocks as _
51    }
52
53    fn height_in_blocks(&self) -> usize {
54        self.height_in_blocks as _
55    }
56}