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::jp2::DecodedImage;
11use crate::CpuDecodeParallelism;
12use crate::{
13 checked_decode_byte_len3, checked_decode_byte_len4, checked_decode_sample_count,
14 native_bytes_per_sample, try_reserve_decode_elements, validate_roi, HtCodeBlockDecoder,
15};
16
17use super::native::{try_clone_color_space, NativeOutputBudget};
18use super::Image;
19
20impl<'a> Image<'a> {
21 pub fn decode_wavelets_with_context(
28 &self,
29 context: &mut DecoderContext<'a>,
30 selection: &crate::WaveletSelection,
31 ) -> Result<crate::WaveletImage> {
32 j2c::wavelets::extract(
33 self.codestream,
34 &self.header,
35 self.retained_metadata_bytes()?,
36 context,
37 selection,
38 )
39 }
40
41 pub fn decode_native(&self) -> Result<RawBitmap> {
54 let mut decoder_context = DecoderContext::default();
55 self.decode_native_with_context(&mut decoder_context)
56 }
57
58 #[doc(hidden)]
69 pub fn decode_native_with_retained_capacity(
70 &self,
71 retained_capacity: usize,
72 ) -> Result<RawBitmap> {
73 let retained_baseline_bytes = super::allocation::combine_retained_bytes(
74 retained_capacity,
75 self.retained_metadata_bytes()?,
76 )?;
77 let mut decoder_context = DecoderContext::default();
78 self.decode_native_with_context_and_retained_baseline(
79 &mut decoder_context,
80 retained_baseline_bytes,
81 )
82 }
83
84 #[doc(hidden)]
90 pub fn decode_reversible_53_coefficients(&self) -> Result<Reversible53CoefficientImage> {
91 let mut decoder_context = DecoderContext::default();
92 self.decode_reversible_53_coefficients_with_context(&mut decoder_context)
93 }
94
95 #[doc(hidden)]
98 pub fn decode_reversible_53_coefficients_with_context(
99 &self,
100 decoder_context: &mut DecoderContext<'a>,
101 ) -> Result<Reversible53CoefficientImage> {
102 j2c::recode::extract_reversible_53_coefficients(
103 self.codestream,
104 &self.header,
105 self.retained_metadata_bytes()?,
106 decoder_context,
107 )
108 }
109
110 pub fn decode_native_region(&self, roi: (u32, u32, u32, u32)) -> Result<RawBitmap> {
116 self.decode_native_region_with_context(roi, &mut DecoderContext::default())
117 }
118
119 pub fn decode_native_region_components(
126 &self,
127 roi: (u32, u32, u32, u32),
128 ) -> Result<DecodedNativeComponents> {
129 self.decode_native_region_components_with_context(roi, &mut DecoderContext::default())
130 }
131
132 pub fn decode_native_with_context(
139 &self,
140 decoder_context: &mut DecoderContext<'a>,
141 ) -> Result<RawBitmap> {
142 let retained_baseline_bytes = self.retained_metadata_bytes()?;
143 self.decode_native_with_context_and_retained_baseline(
144 decoder_context,
145 retained_baseline_bytes,
146 )
147 }
148
149 pub(crate) fn decode_native_with_context_and_retained_baseline(
150 &self,
151 decoder_context: &mut DecoderContext<'a>,
152 retained_baseline_bytes: usize,
153 ) -> Result<RawBitmap> {
154 let bit_depth = self.uniform_header_bit_depth()?;
155 let mut ht_decoder = None;
156 let parallel = decoder_context.cpu_decode_parallelism() == CpuDecodeParallelism::Auto;
157 decoder_context.set_output_region(None);
158 decoder_context.set_round_irreversible_output(true);
159 let decode_result = j2c::decode(
160 self.codestream,
161 &self.header,
162 retained_baseline_bytes,
163 decoder_context,
164 &mut ht_decoder,
165 );
166 decoder_context.set_output_region(None);
167 decoder_context.set_round_irreversible_output(false);
168 decode_result?;
169
170 let components = &decoder_context.tile_decode_context.channel_data;
171 let component_owner_capacity = components.capacity();
172 let num_components =
173 u16::try_from(components.len()).map_err(|_| ValidationError::TooManyChannels)?;
174 let width = self.width();
175 let height = self.height();
176 let pixel_count = checked_decode_sample_count(width, height)?;
177 let bytes_per_sample = native_bytes_per_sample(bit_depth)?;
178 let capacity =
179 checked_decode_byte_len3(pixel_count, usize::from(num_components), bytes_per_sample)?;
180 let mut budget = NativeOutputBudget::for_decoded_channels(
181 retained_baseline_bytes,
182 components,
183 component_owner_capacity,
184 )?;
185 budget.include_bit_capacity(components.len())?;
186 budget.include_elements::<u8>(capacity)?;
187 let component_signed = Self::try_component_signedness(components)?;
188 budget.include_bit_capacity_overage(components.len(), component_signed.capacity())?;
189 let signed = component_signed.iter().all(|signed| *signed);
190 let mut data = Vec::new();
191 try_reserve_decode_elements(&mut data, capacity)?;
192 budget.include_capacity_overage::<u8>(capacity, data.capacity())?;
193 if let [component] = components.as_slice() {
194 Self::extend_component_native_sample_bytes(
195 &mut data,
196 component,
197 0..pixel_count,
198 bit_depth,
199 parallel,
200 );
201 } else {
202 for index in 0..pixel_count {
203 for component in components {
204 Self::push_component_native_sample_bytes(
205 &mut data, component, index, bit_depth,
206 );
207 }
208 }
209 }
210 if data.len() != capacity {
211 bail!(DecodingError::CodeBlockDecodeFailure);
212 }
213 let bitmap = RawBitmap {
214 data,
215 width,
216 height,
217 bit_depth,
218 signed,
219 component_signed,
220 num_components,
221 bytes_per_sample: u8::try_from(bytes_per_sample)
222 .map_err(|_| ValidationError::ImageTooLarge)?,
223 };
224 NativeOutputBudget::validate_raw_pack(
225 retained_baseline_bytes,
226 components,
227 component_owner_capacity,
228 &bitmap,
229 )?;
230 Ok(bitmap)
231 }
232
233 pub fn decode_native_region_with_context(
240 &self,
241 roi: (u32, u32, u32, u32),
242 decoder_context: &mut DecoderContext<'a>,
243 ) -> Result<RawBitmap> {
244 validate_roi((self.width(), self.height()), roi)?;
245 if self.requires_exact_integer_decode() {
246 return self.decode_native_region_via_full_decode(roi, decoder_context);
247 }
248 let bit_depth = self.uniform_header_bit_depth()?;
249 let retained_image_bytes = self.retained_metadata_bytes()?;
250 let mut ht_decoder = None;
251 let parallel = decoder_context.cpu_decode_parallelism() == CpuDecodeParallelism::Auto;
252 decoder_context.set_output_region(Some(roi));
253 decoder_context.set_round_irreversible_output(true);
254 decoder_context.permit_line_region_idwt(self.permits_line_region_idwt());
255 let decode_result = j2c::decode(
256 self.codestream,
257 &self.header,
258 retained_image_bytes,
259 decoder_context,
260 &mut ht_decoder,
261 );
262 decoder_context.set_output_region(None);
263 decoder_context.set_round_irreversible_output(false);
264 decoder_context.permit_line_region_idwt(false);
265 decode_result?;
266
267 let components = &decoder_context.tile_decode_context.channel_data;
268 let component_owner_capacity = components.capacity();
269 let num_components =
270 u16::try_from(components.len()).map_err(|_| ValidationError::TooManyChannels)?;
271 let bytes_per_sample = native_bytes_per_sample(bit_depth)?;
272 let (_x, _y, width, height) = roi;
273 let capacity = checked_decode_byte_len4(
274 width as usize,
275 height as usize,
276 usize::from(num_components),
277 bytes_per_sample,
278 )?;
279 let mut budget = NativeOutputBudget::for_decoded_channels(
280 retained_image_bytes,
281 components,
282 component_owner_capacity,
283 )?;
284 budget.include_bit_capacity(components.len())?;
285 budget.include_elements::<u8>(capacity)?;
286 let mut data = Vec::new();
287 let component_signed = Self::try_component_signedness(components)?;
288 budget.include_bit_capacity_overage(components.len(), component_signed.capacity())?;
289 try_reserve_decode_elements(&mut data, capacity)?;
290 budget.include_capacity_overage::<u8>(capacity, data.capacity())?;
291 let signed = component_signed.iter().all(|signed| *signed);
292
293 let pixel_count = width as usize * height as usize;
294 if let [component] = components.as_slice() {
295 Self::extend_component_native_sample_bytes(
296 &mut data,
297 component,
298 0..pixel_count,
299 bit_depth,
300 parallel,
301 );
302 } else {
303 for index in 0..pixel_count {
304 for component in components {
305 Self::push_component_native_sample_bytes(
306 &mut data, component, index, bit_depth,
307 );
308 }
309 }
310 }
311 if data.len() != capacity {
312 bail!(DecodingError::CodeBlockDecodeFailure);
313 }
314
315 let bitmap = RawBitmap {
316 data,
317 width,
318 height,
319 bit_depth,
320 signed,
321 component_signed,
322 num_components,
323 bytes_per_sample: u8::try_from(bytes_per_sample)
324 .map_err(|_| ValidationError::ImageTooLarge)?,
325 };
326 NativeOutputBudget::validate_raw_pack(
327 retained_image_bytes,
328 components,
329 component_owner_capacity,
330 &bitmap,
331 )?;
332 Ok(bitmap)
333 }
334
335 fn try_component_signedness(components: &[ComponentData]) -> Result<Vec<bool>> {
336 let mut signedness = Vec::new();
337 try_reserve_decode_elements(&mut signedness, components.len())?;
338 signedness.extend(components.iter().map(|component| component.signed));
339 Ok(signedness)
340 }
341
342 pub(super) fn component_plane_sampling_at(&self, component_idx: usize) -> (u8, u8) {
343 if self.settings.resolve_palette_indices && self.boxes.palette.is_some() {
344 return (1, 1);
345 }
346 self.header
347 .component_infos
348 .get(component_idx)
349 .map_or((1, 1), |component| {
350 (
351 component.size_info.horizontal_resolution,
352 component.size_info.vertical_resolution,
353 )
354 })
355 }
356
357 pub(super) fn try_borrow_component_planes<'ctx>(
358 &self,
359 components: &'ctx [ComponentData],
360 component_owner_capacity: usize,
361 dimensions: (u32, u32),
362 ) -> Result<DecodedComponents<'ctx>> {
363 let retained_image_bytes = self.retained_metadata_bytes()?;
364 self.try_borrow_component_planes_with_retained_baseline(
365 components,
366 component_owner_capacity,
367 dimensions,
368 retained_image_bytes,
369 )
370 }
371
372 pub(super) fn try_borrow_component_planes_with_retained_baseline<'ctx>(
373 &self,
374 components: &'ctx [ComponentData],
375 component_owner_capacity: usize,
376 dimensions: (u32, u32),
377 retained_image_bytes: usize,
378 ) -> Result<DecodedComponents<'ctx>> {
379 let mut budget = NativeOutputBudget::for_decoded_channels(
380 retained_image_bytes,
381 components,
382 component_owner_capacity,
383 )?;
384 budget.include_elements::<ComponentPlane<'_>>(components.len())?;
385 budget.include_color_space_clone(&self.color_space)?;
386 let color_space = try_clone_color_space(&self.color_space)?;
387 budget.include_color_space_clone_overage(&self.color_space, &color_space)?;
388 let mut planes = Vec::new();
389 try_reserve_decode_elements(&mut planes, components.len())?;
390 budget
391 .include_capacity_overage::<ComponentPlane<'_>>(components.len(), planes.capacity())?;
392 for (component_idx, component) in components.iter().enumerate() {
393 planes.push(ComponentPlane {
394 samples: component.container.truncated(),
395 dimensions,
396 bit_depth: component.bit_depth,
397 signed: component.signed,
398 sampling: self.component_plane_sampling_at(component_idx),
399 });
400 }
401
402 let mut packed = DecodedComponents {
403 dimensions,
404 color_space,
405 has_alpha: self.has_alpha,
406 planes,
407 live_bytes: 0,
408 };
409 packed.live_bytes = NativeOutputBudget::validate_borrowed_pack(
410 retained_image_bytes,
411 components,
412 component_owner_capacity,
413 &packed,
414 )?;
415 Ok(packed)
416 }
417
418 fn uniform_header_bit_depth(&self) -> Result<u8> {
419 let Some(first) = self.header.component_infos.first() else {
420 bail!(DecodingError::CodeBlockDecodeFailure);
421 };
422 if self
423 .header
424 .component_infos
425 .iter()
426 .any(|component| component.size_info.precision != first.size_info.precision)
427 {
428 bail!(DecodingError::UnsupportedFeature(
429 "decode_native requires uniform component bit depths; use decode_components for mixed-depth images"
430 ));
431 }
432 if first.size_info.precision > 38 {
433 bail!(DecodingError::UnsupportedFeature(
434 "decode_native supports JPEG 2000 Part 1 component precision up to 38 bits"
435 ));
436 }
437 Ok(first.size_info.precision)
438 }
439
440 pub(super) fn validate_component_plane_precision(&self) -> Result<()> {
441 if self
442 .header
443 .component_infos
444 .iter()
445 .any(|component| component.size_info.precision > 24)
446 {
447 bail!(DecodingError::UnsupportedFeature(
448 "decode_components currently supports component planes up to 24 bits per component"
449 ));
450 }
451 Ok(())
452 }
453}
454
455impl<'a> Image<'a> {
465 #[doc(hidden)]
472 pub fn decode_components_for_integer_output_with_context<'ctx>(
473 &self,
474 decoder_context: &'ctx mut DecoderContext<'a>,
475 ) -> Result<DecodedComponents<'ctx>> {
476 self.decode_borrowed_component_planes(decoder_context, None, None, true)
477 }
478
479 #[doc(hidden)]
486 pub fn decode_region_components_for_integer_output_with_context<'ctx>(
487 &self,
488 roi: (u32, u32, u32, u32),
489 decoder_context: &'ctx mut DecoderContext<'a>,
490 ) -> Result<DecodedComponents<'ctx>> {
491 self.decode_borrowed_component_planes(decoder_context, Some(roi), None, true)
492 }
493
494 #[doc(hidden)]
501 pub fn decode_components_for_integer_output_with_ht_decoder<'ctx>(
502 &self,
503 decoder_context: &'ctx mut DecoderContext<'a>,
504 ht_decoder: &mut dyn HtCodeBlockDecoder,
505 ) -> Result<DecodedComponents<'ctx>> {
506 self.decode_borrowed_component_planes(decoder_context, None, Some(ht_decoder), true)
507 }
508
509 #[doc(hidden)]
516 pub fn decode_region_components_for_integer_output_with_ht_decoder<'ctx>(
517 &self,
518 decoder_context: &'ctx mut DecoderContext<'a>,
519 roi: (u32, u32, u32, u32),
520 ht_decoder: &mut dyn HtCodeBlockDecoder,
521 ) -> Result<DecodedComponents<'ctx>> {
522 self.decode_borrowed_component_planes(decoder_context, Some(roi), Some(ht_decoder), true)
523 }
524
525 pub(super) fn decode_borrowed_component_planes<'ctx>(
526 &self,
527 decoder_context: &'ctx mut DecoderContext<'a>,
528 roi: Option<(u32, u32, u32, u32)>,
529 ht_decoder: Option<&mut dyn HtCodeBlockDecoder>,
530 round_irreversible_output: bool,
531 ) -> Result<DecodedComponents<'ctx>> {
532 let dimensions = match roi {
533 Some(roi) => {
534 validate_roi((self.width(), self.height()), roi)?;
535 (roi.2, roi.3)
536 }
537 None => (self.width(), self.height()),
538 };
539 self.validate_component_plane_precision()?;
540 let decoded_image = self.decode_image(
541 decoder_context,
542 roi,
543 ht_decoder,
544 round_irreversible_output,
545 self.retained_metadata_bytes()?,
546 )?;
547 let DecodedImage {
548 decoded_components,
549 boxes: _,
550 } = decoded_image;
551 self.try_borrow_component_planes(
552 decoded_components.as_slice(),
553 decoded_components.capacity(),
554 dimensions,
555 )
556 }
557}