1use alloc::vec::Vec;
6
7use crate::color::{ComponentPlane, DecodedComponents, DecodedNativeComponents, RawBitmap};
8use crate::error::{bail, DecodingError, Result, ValidationError};
9use crate::j2c::{self, ComponentData, DecoderContext, Reversible53CoefficientImage};
10use crate::{
11 checked_decode_byte_len3, checked_decode_byte_len4, checked_decode_sample_count,
12 native_bytes_per_sample, try_reserve_decode_elements, validate_roi,
13};
14
15use super::native::{try_clone_color_space, NativeOutputBudget};
16use super::Image;
17
18impl<'a> Image<'a> {
19 pub fn decode_native(&self) -> Result<RawBitmap> {
32 let mut decoder_context = DecoderContext::default();
33 self.decode_native_with_context(&mut decoder_context)
34 }
35
36 #[doc(hidden)]
47 pub fn decode_native_with_retained_capacity(
48 &self,
49 retained_capacity: usize,
50 ) -> Result<RawBitmap> {
51 let retained_baseline_bytes = super::allocation::combine_retained_bytes(
52 retained_capacity,
53 self.retained_metadata_bytes()?,
54 )?;
55 let mut decoder_context = DecoderContext::default();
56 self.decode_native_with_context_and_retained_baseline(
57 &mut decoder_context,
58 retained_baseline_bytes,
59 )
60 }
61
62 #[doc(hidden)]
68 pub fn decode_reversible_53_coefficients(&self) -> Result<Reversible53CoefficientImage> {
69 let mut decoder_context = DecoderContext::default();
70 self.decode_reversible_53_coefficients_with_context(&mut decoder_context)
71 }
72
73 #[doc(hidden)]
76 pub fn decode_reversible_53_coefficients_with_context(
77 &self,
78 decoder_context: &mut DecoderContext<'a>,
79 ) -> Result<Reversible53CoefficientImage> {
80 j2c::recode::extract_reversible_53_coefficients(
81 self.codestream,
82 &self.header,
83 self.retained_metadata_bytes()?,
84 decoder_context,
85 )
86 }
87
88 pub fn decode_native_region(&self, roi: (u32, u32, u32, u32)) -> Result<RawBitmap> {
94 self.decode_native_region_with_context(roi, &mut DecoderContext::default())
95 }
96
97 pub fn decode_native_region_components(
104 &self,
105 roi: (u32, u32, u32, u32),
106 ) -> Result<DecodedNativeComponents> {
107 self.decode_native_region_components_with_context(roi, &mut DecoderContext::default())
108 }
109
110 pub fn decode_native_with_context(
117 &self,
118 decoder_context: &mut DecoderContext<'a>,
119 ) -> Result<RawBitmap> {
120 let retained_baseline_bytes = self.retained_metadata_bytes()?;
121 self.decode_native_with_context_and_retained_baseline(
122 decoder_context,
123 retained_baseline_bytes,
124 )
125 }
126
127 pub(crate) fn decode_native_with_context_and_retained_baseline(
128 &self,
129 decoder_context: &mut DecoderContext<'a>,
130 retained_baseline_bytes: usize,
131 ) -> Result<RawBitmap> {
132 let bit_depth = self.uniform_header_bit_depth()?;
133 let mut ht_decoder = None;
134 decoder_context.set_output_region(None);
135 let decode_result = j2c::decode(
136 self.codestream,
137 &self.header,
138 retained_baseline_bytes,
139 decoder_context,
140 &mut ht_decoder,
141 );
142 decoder_context.set_output_region(None);
143 decode_result?;
144
145 let components = &decoder_context.tile_decode_context.channel_data;
146 let component_owner_capacity = components.capacity();
147 let num_components =
148 u16::try_from(components.len()).map_err(|_| ValidationError::TooManyChannels)?;
149 let width = self.width();
150 let height = self.height();
151 let pixel_count = checked_decode_sample_count(width, height)?;
152 let bytes_per_sample = native_bytes_per_sample(bit_depth)?;
153 let capacity =
154 checked_decode_byte_len3(pixel_count, usize::from(num_components), bytes_per_sample)?;
155 let mut budget = NativeOutputBudget::for_decoded_channels(
156 retained_baseline_bytes,
157 components,
158 component_owner_capacity,
159 )?;
160 budget.include_bit_capacity(components.len())?;
161 budget.include_elements::<u8>(capacity)?;
162 let component_signed = Self::try_component_signedness(components)?;
163 budget.include_bit_capacity_overage(components.len(), component_signed.capacity())?;
164 let signed = component_signed.iter().all(|signed| *signed);
165 let mut data = Vec::new();
166 try_reserve_decode_elements(&mut data, capacity)?;
167 budget.include_capacity_overage::<u8>(capacity, data.capacity())?;
168 for index in 0..pixel_count {
169 for component in components {
170 Self::push_component_native_sample_bytes(&mut data, component, index, bit_depth);
171 }
172 }
173 if data.len() != capacity {
174 bail!(DecodingError::CodeBlockDecodeFailure);
175 }
176 let bitmap = RawBitmap {
177 data,
178 width,
179 height,
180 bit_depth,
181 signed,
182 component_signed,
183 num_components,
184 bytes_per_sample: u8::try_from(bytes_per_sample)
185 .map_err(|_| ValidationError::ImageTooLarge)?,
186 };
187 NativeOutputBudget::validate_raw_pack(
188 retained_baseline_bytes,
189 components,
190 component_owner_capacity,
191 &bitmap,
192 )?;
193 Ok(bitmap)
194 }
195
196 pub fn decode_native_region_with_context(
203 &self,
204 roi: (u32, u32, u32, u32),
205 decoder_context: &mut DecoderContext<'a>,
206 ) -> Result<RawBitmap> {
207 validate_roi((self.width(), self.height()), roi)?;
208 if self.requires_exact_integer_decode() {
209 return self.decode_native_region_via_full_decode(roi, decoder_context);
210 }
211 let bit_depth = self.uniform_header_bit_depth()?;
212 let retained_image_bytes = self.retained_metadata_bytes()?;
213 let mut ht_decoder = None;
214 decoder_context.set_output_region(Some(roi));
215 let decode_result = j2c::decode(
216 self.codestream,
217 &self.header,
218 retained_image_bytes,
219 decoder_context,
220 &mut ht_decoder,
221 );
222 decoder_context.set_output_region(None);
223 decode_result?;
224
225 let components = &decoder_context.tile_decode_context.channel_data;
226 let component_owner_capacity = components.capacity();
227 let num_components =
228 u16::try_from(components.len()).map_err(|_| ValidationError::TooManyChannels)?;
229 let bytes_per_sample = native_bytes_per_sample(bit_depth)?;
230 let (_x, _y, width, height) = roi;
231 let capacity = checked_decode_byte_len4(
232 width as usize,
233 height as usize,
234 usize::from(num_components),
235 bytes_per_sample,
236 )?;
237 let mut budget = NativeOutputBudget::for_decoded_channels(
238 retained_image_bytes,
239 components,
240 component_owner_capacity,
241 )?;
242 budget.include_bit_capacity(components.len())?;
243 budget.include_elements::<u8>(capacity)?;
244 let mut data = Vec::new();
245 let component_signed = Self::try_component_signedness(components)?;
246 budget.include_bit_capacity_overage(components.len(), component_signed.capacity())?;
247 try_reserve_decode_elements(&mut data, capacity)?;
248 budget.include_capacity_overage::<u8>(capacity, data.capacity())?;
249 let signed = component_signed.iter().all(|signed| *signed);
250
251 for row in 0..height as usize {
252 for col in 0..width as usize {
253 let index = row * width as usize + col;
254 for component in components {
255 Self::push_component_native_sample_bytes(
256 &mut data, component, index, bit_depth,
257 );
258 }
259 }
260 }
261 if data.len() != capacity {
262 bail!(DecodingError::CodeBlockDecodeFailure);
263 }
264
265 let bitmap = RawBitmap {
266 data,
267 width,
268 height,
269 bit_depth,
270 signed,
271 component_signed,
272 num_components,
273 bytes_per_sample: u8::try_from(bytes_per_sample)
274 .map_err(|_| ValidationError::ImageTooLarge)?,
275 };
276 NativeOutputBudget::validate_raw_pack(
277 retained_image_bytes,
278 components,
279 component_owner_capacity,
280 &bitmap,
281 )?;
282 Ok(bitmap)
283 }
284
285 fn try_component_signedness(components: &[ComponentData]) -> Result<Vec<bool>> {
286 let mut signedness = Vec::new();
287 try_reserve_decode_elements(&mut signedness, components.len())?;
288 signedness.extend(components.iter().map(|component| component.signed));
289 Ok(signedness)
290 }
291
292 pub(super) fn component_plane_sampling_at(&self, component_idx: usize) -> (u8, u8) {
293 if self.settings.resolve_palette_indices && self.boxes.palette.is_some() {
294 return (1, 1);
295 }
296 self.header
297 .component_infos
298 .get(component_idx)
299 .map_or((1, 1), |component| {
300 (
301 component.size_info.horizontal_resolution,
302 component.size_info.vertical_resolution,
303 )
304 })
305 }
306
307 pub(super) fn try_borrow_component_planes<'ctx>(
308 &self,
309 components: &'ctx [ComponentData],
310 component_owner_capacity: usize,
311 dimensions: (u32, u32),
312 ) -> Result<DecodedComponents<'ctx>> {
313 let retained_image_bytes = self.retained_metadata_bytes()?;
314 let mut budget = NativeOutputBudget::for_decoded_channels(
315 retained_image_bytes,
316 components,
317 component_owner_capacity,
318 )?;
319 budget.include_elements::<ComponentPlane<'_>>(components.len())?;
320 budget.include_color_space_clone(&self.color_space)?;
321 let color_space = try_clone_color_space(&self.color_space)?;
322 budget.include_color_space_clone_overage(&self.color_space, &color_space)?;
323 let mut planes = Vec::new();
324 try_reserve_decode_elements(&mut planes, components.len())?;
325 budget
326 .include_capacity_overage::<ComponentPlane<'_>>(components.len(), planes.capacity())?;
327 for (component_idx, component) in components.iter().enumerate() {
328 planes.push(ComponentPlane {
329 samples: component.container.truncated(),
330 dimensions,
331 bit_depth: component.bit_depth,
332 signed: component.signed,
333 sampling: self.component_plane_sampling_at(component_idx),
334 });
335 }
336
337 let mut packed = DecodedComponents {
338 dimensions,
339 color_space,
340 has_alpha: self.has_alpha,
341 planes,
342 live_bytes: 0,
343 };
344 packed.live_bytes = NativeOutputBudget::validate_borrowed_pack(
345 retained_image_bytes,
346 components,
347 component_owner_capacity,
348 &packed,
349 )?;
350 Ok(packed)
351 }
352
353 fn uniform_header_bit_depth(&self) -> Result<u8> {
354 let Some(first) = self.header.component_infos.first() else {
355 bail!(DecodingError::CodeBlockDecodeFailure);
356 };
357 if self
358 .header
359 .component_infos
360 .iter()
361 .any(|component| component.size_info.precision != first.size_info.precision)
362 {
363 bail!(DecodingError::UnsupportedFeature(
364 "decode_native requires uniform component bit depths; use decode_components for mixed-depth images"
365 ));
366 }
367 if first.size_info.precision > 38 {
368 bail!(DecodingError::UnsupportedFeature(
369 "decode_native supports JPEG 2000 Part 1 component precision up to 38 bits"
370 ));
371 }
372 Ok(first.size_info.precision)
373 }
374
375 pub(super) fn validate_component_plane_precision(&self) -> Result<()> {
376 if self
377 .header
378 .component_infos
379 .iter()
380 .any(|component| component.size_info.precision > 24)
381 {
382 bail!(DecodingError::UnsupportedFeature(
383 "decode_components currently supports component planes up to 24 bits per component"
384 ));
385 }
386 Ok(())
387 }
388}