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