1use alloc::vec::Vec;
15use alloc::{format, vec};
16
17use zune_core::log::trace;
18
19use crate::alloc::string::ToString;
20use crate::decoder::MAX_COMPONENTS;
21use crate::errors::DecodeErrors;
22use crate::upsampler::upsample_no_op;
23const MAX_SAMP_FACTOR: usize = 4;
24
25pub type UpSampler = fn(
29 input: &[i16],
30 in_near: &[i16],
31 in_far: &[i16],
32 scratch_space: &mut [i16],
33 output: &mut [i16]
34);
35
36#[derive(Clone)]
38pub(crate) struct Components {
39 pub component_id: ComponentID,
41 pub vertical_sample: usize,
43 pub horizontal_sample: usize,
45 pub dc_huff_table: usize,
47 pub ac_huff_table: usize,
49 pub quantization_table_number: u8,
51 pub quantization_table: [i32; 64],
53 pub dc_pred: i32,
55 pub up_sampler: UpSampler,
58 pub width_stride: usize,
60 pub id: u8,
62 pub needed: bool,
64 pub raw_coeff: Vec<i16>,
66 pub upsample_dest: Vec<i16>,
68 pub row_up: Vec<i16>,
70 pub row: Vec<i16>,
72 pub first_row_upsample_dest: Vec<i16>,
73 pub idct_pos: usize,
74 pub x: usize,
75 pub w2: usize,
76 pub y: usize,
77 pub sample_ratio: SampleRatios,
78 pub fix_an_annoying_bug: usize
80}
81
82impl Components {
83 #[inline]
85 pub fn from(a: [u8; 3], pos: u8) -> Result<Components, DecodeErrors> {
86 let id = match pos {
94 0 => ComponentID::Y,
95 1 => ComponentID::Cb,
96 2 => ComponentID::Cr,
97 3 => ComponentID::Q,
98 _ => {
99 return Err(DecodeErrors::Format(format!(
100 "Unknown component id found,{pos}, expected value between 1 and 4"
101 )))
102 }
103 };
104
105 let horizontal_sample = (a[1] >> 4) as usize;
106 let vertical_sample = (a[1] & 0x0f) as usize;
107 if horizontal_sample > MAX_SAMP_FACTOR {
110 return Err(DecodeErrors::Format(format!(
111 "Bogus Horizontal Sampling Factor {horizontal_sample}"
112 )));
113 }
114 if vertical_sample > MAX_SAMP_FACTOR {
115 return Err(DecodeErrors::Format(format!(
116 "Bogus Vertical Sampling Factor {vertical_sample}"
117 )));
118 }
119
120 let quantization_table_number = a[2];
121 if usize::from(quantization_table_number) >= MAX_COMPONENTS {
123 return Err(DecodeErrors::Format(format!(
124 "Too large quantization number :{quantization_table_number}, expected value between 0 and {MAX_COMPONENTS}"
125 )));
126 }
127 if !horizontal_sample.is_power_of_two() {
130 return Err(DecodeErrors::Format(format!(
131 "Horizontal sample is not a power of two({horizontal_sample}) cannot decode"
132 )));
133 }
134
135 if vertical_sample == 0 {
141 return Err(DecodeErrors::Format("Vertical sample is zero".to_string()));
143 }
144 trace!(
145 "Component ID:{:?} \tHS:{} VS:{} QT:{}",
146 id,
147 horizontal_sample,
148 vertical_sample,
149 quantization_table_number
150 );
151
152 Ok(Components {
153 component_id: id,
154 vertical_sample,
155 horizontal_sample,
156 quantization_table_number,
157 first_row_upsample_dest: vec![],
158 dc_huff_table: 0,
160 ac_huff_table: 0,
161 quantization_table: [0; 64],
162 dc_pred: 0,
163 up_sampler: upsample_no_op,
164 width_stride: horizontal_sample,
166 id: a[0],
167 needed: true,
168 raw_coeff: vec![],
169 upsample_dest: vec![],
170 row_up: vec![],
171 row: vec![],
172 idct_pos: 0,
173 x: 0,
174 y: 0,
175 w2: 0,
176 sample_ratio: SampleRatios::None,
177 fix_an_annoying_bug: 1
178 })
179 }
180 pub fn setup_upsample_scanline(&mut self) {
191 self.row = vec![0; self.width_stride * self.vertical_sample];
192 self.row_up = vec![0; self.width_stride * self.vertical_sample];
193 self.first_row_upsample_dest =
194 vec![128; self.vertical_sample * self.width_stride * self.sample_ratio.sample()];
195 self.upsample_dest =
196 vec![0; self.width_stride * self.sample_ratio.sample() * self.fix_an_annoying_bug * 8];
197 }
198}
199
200#[derive(Copy, Debug, Clone, PartialEq, Eq)]
202pub enum ComponentID {
203 Y,
205 Cb,
207 Cr,
209 Q
211}
212
213#[derive(Copy, Debug, Clone, PartialEq, Eq, Default)]
214pub enum SampleRatios {
215 HV,
216 V,
217 H,
218 Generic(usize, usize),
219 #[default]
220 None
221}
222
223impl SampleRatios {
224 pub fn sample(self) -> usize {
225 match self {
226 SampleRatios::HV => 4,
227 SampleRatios::V | SampleRatios::H => 2,
228 SampleRatios::Generic(a, b) => a * b,
229 SampleRatios::None => 1
230 }
231 }
232}