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 self.decode_with_output_region_and_ht_decoder_with_retained_baseline(
134 decoder_context,
135 None,
136 None,
137 retained_baseline_bytes,
138 )?;
139
140 let components = &decoder_context.tile_decode_context.channel_data;
141 let component_owner_capacity = components.capacity();
142 let num_components =
143 u16::try_from(components.len()).map_err(|_| ValidationError::TooManyChannels)?;
144 let width = self.width();
145 let height = self.height();
146 let pixel_count = checked_decode_sample_count(width, height)?;
147 let bytes_per_sample = native_bytes_per_sample(bit_depth)?;
148 let capacity =
149 checked_decode_byte_len3(pixel_count, usize::from(num_components), bytes_per_sample)?;
150 let mut budget = NativeOutputBudget::for_decoded_channels(
151 retained_baseline_bytes,
152 components,
153 component_owner_capacity,
154 )?;
155 budget.include_bit_capacity(components.len())?;
156 budget.include_elements::<u8>(capacity)?;
157 let component_signed = Self::try_component_signedness(components)?;
158 budget.include_bit_capacity_overage(components.len(), component_signed.capacity())?;
159 let signed = component_signed.iter().all(|signed| *signed);
160 let mut data = Vec::new();
161 try_reserve_decode_elements(&mut data, capacity)?;
162 budget.include_capacity_overage::<u8>(capacity, data.capacity())?;
163 for index in 0..pixel_count {
164 for component in components {
165 Self::push_component_native_sample_bytes(&mut data, component, index, bit_depth);
166 }
167 }
168 if data.len() != capacity {
169 bail!(DecodingError::CodeBlockDecodeFailure);
170 }
171 let bitmap = RawBitmap {
172 data,
173 width,
174 height,
175 bit_depth,
176 signed,
177 component_signed,
178 num_components,
179 bytes_per_sample: u8::try_from(bytes_per_sample)
180 .map_err(|_| ValidationError::ImageTooLarge)?,
181 };
182 NativeOutputBudget::validate_raw_pack(
183 retained_baseline_bytes,
184 components,
185 component_owner_capacity,
186 &bitmap,
187 )?;
188 Ok(bitmap)
189 }
190
191 pub fn decode_native_region_with_context(
198 &self,
199 roi: (u32, u32, u32, u32),
200 decoder_context: &mut DecoderContext<'a>,
201 ) -> Result<RawBitmap> {
202 validate_roi((self.width(), self.height()), roi)?;
203 if self.requires_exact_integer_decode() {
204 return self.decode_native_region_via_full_decode(roi, decoder_context);
205 }
206 let bit_depth = self.uniform_header_bit_depth()?;
207 self.decode_with_output_region(decoder_context, Some(roi))?;
208
209 let components = &decoder_context.tile_decode_context.channel_data;
210 let component_owner_capacity = components.capacity();
211 let num_components =
212 u16::try_from(components.len()).map_err(|_| ValidationError::TooManyChannels)?;
213 let bytes_per_sample = native_bytes_per_sample(bit_depth)?;
214 let (_x, _y, width, height) = roi;
215 let capacity = checked_decode_byte_len4(
216 width as usize,
217 height as usize,
218 usize::from(num_components),
219 bytes_per_sample,
220 )?;
221 let retained_image_bytes = self.retained_metadata_bytes()?;
222 let mut budget = NativeOutputBudget::for_decoded_channels(
223 retained_image_bytes,
224 components,
225 component_owner_capacity,
226 )?;
227 budget.include_bit_capacity(components.len())?;
228 budget.include_elements::<u8>(capacity)?;
229 let mut data = Vec::new();
230 let component_signed = Self::try_component_signedness(components)?;
231 budget.include_bit_capacity_overage(components.len(), component_signed.capacity())?;
232 try_reserve_decode_elements(&mut data, capacity)?;
233 budget.include_capacity_overage::<u8>(capacity, data.capacity())?;
234 let signed = component_signed.iter().all(|signed| *signed);
235
236 for row in 0..height as usize {
237 for col in 0..width as usize {
238 let index = row * width as usize + col;
239 for component in components {
240 Self::push_component_native_sample_bytes(
241 &mut data, component, index, bit_depth,
242 );
243 }
244 }
245 }
246 if data.len() != capacity {
247 bail!(DecodingError::CodeBlockDecodeFailure);
248 }
249
250 let bitmap = RawBitmap {
251 data,
252 width,
253 height,
254 bit_depth,
255 signed,
256 component_signed,
257 num_components,
258 bytes_per_sample: u8::try_from(bytes_per_sample)
259 .map_err(|_| ValidationError::ImageTooLarge)?,
260 };
261 NativeOutputBudget::validate_raw_pack(
262 retained_image_bytes,
263 components,
264 component_owner_capacity,
265 &bitmap,
266 )?;
267 Ok(bitmap)
268 }
269
270 fn try_component_signedness(components: &[ComponentData]) -> Result<Vec<bool>> {
271 let mut signedness = Vec::new();
272 try_reserve_decode_elements(&mut signedness, components.len())?;
273 signedness.extend(components.iter().map(|component| component.signed));
274 Ok(signedness)
275 }
276
277 pub(super) fn component_plane_sampling_at(&self, component_idx: usize) -> (u8, u8) {
278 if self.settings.resolve_palette_indices && self.boxes.palette.is_some() {
279 return (1, 1);
280 }
281 self.header
282 .component_infos
283 .get(component_idx)
284 .map_or((1, 1), |component| {
285 (
286 component.size_info.horizontal_resolution,
287 component.size_info.vertical_resolution,
288 )
289 })
290 }
291
292 pub(super) fn try_borrow_component_planes<'ctx>(
293 &self,
294 components: &'ctx [ComponentData],
295 component_owner_capacity: usize,
296 dimensions: (u32, u32),
297 ) -> Result<DecodedComponents<'ctx>> {
298 let retained_image_bytes = self.retained_metadata_bytes()?;
299 let mut budget = NativeOutputBudget::for_component_pack(
300 retained_image_bytes,
301 components,
302 component_owner_capacity,
303 )?;
304 budget.include_elements::<ComponentPlane<'_>>(components.len())?;
305 budget.include_color_space_clone(&self.color_space)?;
306 let color_space = try_clone_color_space(&self.color_space)?;
307 budget.include_color_space_clone_overage(&self.color_space, &color_space)?;
308 let mut planes = Vec::new();
309 try_reserve_decode_elements(&mut planes, components.len())?;
310 budget
311 .include_capacity_overage::<ComponentPlane<'_>>(components.len(), planes.capacity())?;
312 for (component_idx, component) in components.iter().enumerate() {
313 planes.push(ComponentPlane {
314 samples: component.container.truncated(),
315 dimensions,
316 bit_depth: component.bit_depth,
317 signed: component.signed,
318 sampling: self.component_plane_sampling_at(component_idx),
319 });
320 }
321
322 let mut packed = DecodedComponents {
323 dimensions,
324 color_space,
325 has_alpha: self.has_alpha,
326 planes,
327 live_bytes: 0,
328 };
329 packed.live_bytes = NativeOutputBudget::validate_borrowed_pack(
330 retained_image_bytes,
331 components,
332 component_owner_capacity,
333 &packed,
334 )?;
335 Ok(packed)
336 }
337
338 fn uniform_header_bit_depth(&self) -> Result<u8> {
339 let Some(first) = self.header.component_infos.first() else {
340 bail!(DecodingError::CodeBlockDecodeFailure);
341 };
342 if self
343 .header
344 .component_infos
345 .iter()
346 .any(|component| component.size_info.precision != first.size_info.precision)
347 {
348 bail!(DecodingError::UnsupportedFeature(
349 "decode_native requires uniform component bit depths; use decode_components for mixed-depth images"
350 ));
351 }
352 if first.size_info.precision > 38 {
353 bail!(DecodingError::UnsupportedFeature(
354 "decode_native supports JPEG 2000 Part 1 component precision up to 38 bits"
355 ));
356 }
357 Ok(first.size_info.precision)
358 }
359
360 pub(super) fn validate_component_plane_precision(&self) -> Result<()> {
361 if self
362 .header
363 .component_infos
364 .iter()
365 .any(|component| component.size_info.precision > 24)
366 {
367 bail!(DecodingError::UnsupportedFeature(
368 "decode_components currently supports component planes up to 24 bits per component"
369 ));
370 }
371 Ok(())
372 }
373}