1use alloc::boxed::Box;
8use alloc::vec::Vec;
9
10use super::bitplane::{BitPlaneDecodeBuffers, BitPlaneDecodeContext};
11use super::build::{CodeBlock, Decomposition, Layer, Precinct, Segment, SubBand, SubBandType};
12use super::codestream::{
13 ComponentInfo, Header, ProgressionOrder, QuantizationStyle, WaveletTransform,
14};
15use super::idwt::IDWTOutput;
16use super::progression::{
17 IteratorInput, ProgressionData, component_position_resolution_layer_progression,
18 layer_resolution_component_position_progression,
19 position_component_resolution_layer_progression,
20 resolution_layer_component_position_progression,
21 resolution_position_component_layer_progression,
22};
23use super::tag_tree::TagNode;
24use super::tile::{ComponentTile, ResolutionTile, Tile};
25use super::{ComponentData, bitplane, build, idwt, mct, segment, tile};
26use crate::error::{DecodingError, Result, TileError, ValidationError, bail};
27use crate::j2c::segment::MAX_BITPLANE_COUNT;
28use crate::math::SimdBuffer;
29use crate::reader::BitReader;
30use core::ops::Range;
31
32pub(crate) fn decode<'a>(
33 data: &'a [u8],
34 header: &'a Header<'a>,
35 ctx: &mut DecoderContext<'a>,
36) -> Result<()> {
37 let mut reader = BitReader::new(data);
38 let tiles = tile::parse(&mut reader, header)?;
39
40 if tiles.is_empty() {
41 bail!(TileError::Invalid);
42 }
43
44 ctx.reset(header, &tiles[0])?;
45
46 for tile in &tiles {
47 trace!(
48 "tile {} rect [{},{} {}x{}]",
49 tile.idx,
50 tile.rect.x0,
51 tile.rect.y0,
52 tile.rect.width(),
53 tile.rect.height(),
54 );
55
56 let iter_input = IteratorInput::new(tile);
57
58 let progression_iterator: Box<dyn Iterator<Item = ProgressionData>> =
59 match tile.progression_order {
60 ProgressionOrder::LayerResolutionComponentPosition => {
61 Box::new(layer_resolution_component_position_progression(iter_input))
62 }
63 ProgressionOrder::ResolutionLayerComponentPosition => {
64 Box::new(resolution_layer_component_position_progression(iter_input))
65 }
66 ProgressionOrder::ResolutionPositionComponentLayer => Box::new(
67 resolution_position_component_layer_progression(iter_input)
68 .ok_or(DecodingError::InvalidProgressionIterator)?,
69 ),
70 ProgressionOrder::PositionComponentResolutionLayer => Box::new(
71 position_component_resolution_layer_progression(iter_input)
72 .ok_or(DecodingError::InvalidProgressionIterator)?,
73 ),
74 ProgressionOrder::ComponentPositionResolutionLayer => Box::new(
75 component_position_resolution_layer_progression(iter_input)
76 .ok_or(DecodingError::InvalidProgressionIterator)?,
77 ),
78 };
79
80 decode_tile(
81 tile,
82 header,
83 progression_iterator,
84 &mut ctx.tile_decode_context,
85 &mut ctx.channel_data,
86 &mut ctx.storage,
87 )?;
88 }
89
90 if tiles[0].mct {
94 mct::apply_inverse(&mut ctx.channel_data, &tiles[0].component_infos, header)?;
95 }
96
97 apply_sign_shift(&mut ctx.channel_data, &header.component_infos);
98
99 Ok(())
100}
101
102#[derive(Default)]
104pub struct DecoderContext<'a> {
105 tile_decode_context: TileDecodeContext,
106 pub(crate) channel_data: Vec<ComponentData>,
108 storage: DecompositionStorage<'a>,
109}
110
111impl DecoderContext<'_> {
112 fn reset(&mut self, header: &Header<'_>, initial_tile: &Tile<'_>) -> Result<()> {
113 self.tile_decode_context.reset();
114 self.storage.reset();
115
116 self.channel_data.clear();
117 let sample_count = (header.size_data.image_width() as usize)
118 .checked_mul(header.size_data.image_height() as usize)
119 .ok_or(ValidationError::ImageTooLarge)?;
120 for info in &initial_tile.component_infos {
122 self.channel_data.push(ComponentData {
123 container: SimdBuffer::zeros(sample_count),
124 bit_depth: info.size_info.precision,
125 });
126 }
127
128 Ok(())
129 }
130}
131
132fn decode_tile<'a, 'b>(
133 tile: &'b Tile<'a>,
134 header: &Header<'_>,
135 progression_iterator: Box<dyn Iterator<Item = ProgressionData> + '_>,
136 tile_ctx: &mut TileDecodeContext,
137 channel_data: &mut [ComponentData],
138 storage: &mut DecompositionStorage<'a>,
139) -> Result<()> {
140 storage.reset();
141
142 build::build(tile, storage, header.skipped_resolution_levels)?;
147 segment::parse(tile, progression_iterator, header, storage)?;
149 decode_component_tile_bit_planes(tile, tile_ctx, storage, header)?;
152
153 for (idx, component_info) in header.component_infos.iter().enumerate() {
156 idwt::apply(
158 storage,
159 tile_ctx,
160 idx,
161 header,
162 component_info.wavelet_transform(),
163 );
164 store(
175 tile,
176 header,
177 tile_ctx,
178 &mut channel_data[idx],
179 component_info,
180 );
181 }
182
183 Ok(())
184}
185
186#[derive(Clone)]
188pub(crate) struct TileDecompositions {
189 pub(crate) first_ll_sub_band: usize,
190 pub(crate) decompositions: Range<usize>,
191}
192
193impl TileDecompositions {
194 pub(crate) fn sub_band_iter(
195 &self,
196 resolution: u8,
197 decompositions: &[Decomposition],
198 ) -> SubBandIter {
199 let indices = if resolution == 0 {
200 [
201 self.first_ll_sub_band,
202 self.first_ll_sub_band,
203 self.first_ll_sub_band,
204 ]
205 } else {
206 decompositions[self.decompositions.clone()][resolution as usize - 1].sub_bands
207 };
208
209 SubBandIter {
210 next_idx: 0,
211 indices,
212 resolution,
213 }
214 }
215}
216
217#[derive(Clone)]
218pub(crate) struct SubBandIter {
219 resolution: u8,
220 next_idx: usize,
221 indices: [usize; 3],
222}
223
224impl Iterator for SubBandIter {
225 type Item = usize;
226
227 fn next(&mut self) -> Option<Self::Item> {
228 let value = if self.resolution == 0 {
229 if self.next_idx > 0 {
230 None
231 } else {
232 Some(self.indices[0])
233 }
234 } else if self.next_idx >= self.indices.len() {
235 None
236 } else {
237 Some(self.indices[self.next_idx])
238 };
239
240 self.next_idx += 1;
241
242 value
243 }
244}
245
246#[derive(Default)]
249pub(crate) struct DecompositionStorage<'a> {
250 pub(crate) segments: Vec<Segment<'a>>,
251 pub(crate) layers: Vec<Layer>,
252 pub(crate) code_blocks: Vec<CodeBlock>,
253 pub(crate) precincts: Vec<Precinct>,
254 pub(crate) tag_tree_nodes: Vec<TagNode>,
255 pub(crate) coefficients: Vec<f32>,
256 pub(crate) sub_bands: Vec<SubBand>,
257 pub(crate) decompositions: Vec<Decomposition>,
258 pub(crate) tile_decompositions: Vec<TileDecompositions>,
259}
260
261impl DecompositionStorage<'_> {
262 fn reset(&mut self) {
263 self.segments.clear();
264 self.layers.clear();
265 self.code_blocks.clear();
266 self.precincts.clear();
270 self.sub_bands.clear();
271 self.decompositions.clear();
272 self.tile_decompositions.clear();
273 self.tag_tree_nodes.clear();
274 }
275}
276
277#[derive(Default)]
282pub(crate) struct TileDecodeContext {
283 pub(crate) idwt_output: IDWTOutput,
285 pub(crate) idwt_scratch_buffer: Vec<f32>,
287 pub(crate) bit_plane_decode_context: BitPlaneDecodeContext,
289 pub(crate) bit_plane_decode_buffers: BitPlaneDecodeBuffers,
291}
292
293impl TileDecodeContext {
294 fn reset(&mut self) {
295 }
301}
302
303fn decode_component_tile_bit_planes<'a>(
304 tile: &Tile<'a>,
305 tile_ctx: &mut TileDecodeContext,
306 storage: &mut DecompositionStorage<'a>,
307 header: &Header<'_>,
308) -> Result<()> {
309 for (tile_decompositions_idx, component_info) in tile.component_infos.iter().enumerate() {
310 for resolution in
312 0..component_info.num_resolution_levels() - header.skipped_resolution_levels
313 {
314 let tile_composition = &storage.tile_decompositions[tile_decompositions_idx];
315 let sub_band_iter = tile_composition.sub_band_iter(resolution, &storage.decompositions);
316
317 for sub_band_idx in sub_band_iter {
318 decode_sub_band_bitplanes(
319 sub_band_idx,
320 resolution,
321 component_info,
322 tile_ctx,
323 storage,
324 header,
325 )?;
326 }
327 }
328 }
329
330 Ok(())
331}
332
333fn decode_sub_band_bitplanes(
334 sub_band_idx: usize,
335 resolution: u8,
336 component_info: &ComponentInfo,
337 tile_ctx: &mut TileDecodeContext,
338 storage: &mut DecompositionStorage<'_>,
339 header: &Header<'_>,
340) -> Result<()> {
341 let sub_band = &storage.sub_bands[sub_band_idx];
342
343 let quantised =
344 component_info.quantization_info.quantization_style != QuantizationStyle::NoQuantization;
345 let irreversible = component_info.wavelet_transform() == WaveletTransform::Irreversible97;
346 let dequantization_step = {
347 if !quantised {
348 1.0
349 } else {
350 let (exponent, mantissa) =
351 component_info.exponent_mantissa(sub_band.sub_band_type, resolution)?;
352
353 let r_b = {
354 let log_gain = match sub_band.sub_band_type {
355 SubBandType::LowLow => 0,
356 SubBandType::LowHigh => 1,
357 SubBandType::HighLow => 1,
358 SubBandType::HighHigh => 2,
359 };
360
361 component_info.size_info.precision as u16 + log_gain
362 };
363
364 crate::math::pow2i(r_b as i32 - exponent as i32) * (1.0 + (mantissa as f32) / 2048.0)
365 }
366 };
367
368 let num_bitplanes = {
369 let (exponent, _) = component_info.exponent_mantissa(sub_band.sub_band_type, resolution)?;
370 let num_bitplanes = (component_info.quantization_info.guard_bits as u16)
372 .checked_add(exponent)
373 .and_then(|x| x.checked_sub(1))
374 .ok_or(DecodingError::InvalidBitplaneCount)?;
375
376 if num_bitplanes > MAX_BITPLANE_COUNT as u16 {
377 bail!(DecodingError::TooManyBitplanes);
378 }
379
380 num_bitplanes as u8
381 };
382
383 for precinct in sub_band
384 .precincts
385 .clone()
386 .map(|idx| &storage.precincts[idx])
387 {
388 for code_block in precinct
389 .code_blocks
390 .clone()
391 .map(|idx| &storage.code_blocks[idx])
392 {
393 bitplane::decode(
394 code_block,
395 sub_band.sub_band_type,
396 num_bitplanes,
397 &component_info.coding_style.parameters.code_block_style,
398 tile_ctx,
399 storage,
400 header.strict,
401 )?;
402
403 let x_offset = code_block.rect.x0 - sub_band.rect.x0;
407 let y_offset = code_block.rect.y0 - sub_band.rect.y0;
408
409 let base_store = &mut storage.coefficients[sub_band.coefficients.clone()];
410 let mut base_idx = (y_offset * sub_band.rect.width()) as usize + x_offset as usize;
411
412 for (coefficients, coefficient_states) in
413 tile_ctx.bit_plane_decode_context.coefficient_rows()
414 {
415 let out_row = &mut base_store[base_idx..];
416
417 for ((output, coefficient), coefficient_state) in
418 out_row.iter_mut().zip(coefficients).zip(coefficient_states)
419 {
420 *output = coefficient.reconstructed(coefficient_state, irreversible);
421 *output *= dequantization_step;
422 }
423
424 base_idx += sub_band.rect.width() as usize;
425 }
426 }
427 }
428
429 Ok(())
430}
431
432fn apply_sign_shift(channel_data: &mut [ComponentData], component_infos: &[ComponentInfo]) {
433 use crate::math::{Level, dispatch, f32x8};
434
435 for (channel, component_info) in channel_data.iter_mut().zip(component_infos.iter()) {
436 let offset = (1_u32 << (component_info.size_info.precision - 1)) as f32;
437 dispatch!(Level::new(), simd => {
438 let offset_v = f32x8::splat(simd, offset);
439 for chunk in channel.container.chunks_exact_mut(8) {
440 let v = f32x8::from_slice(simd, chunk);
441 (v + offset_v).store(chunk);
442 }
443 });
444 }
445}
446
447fn store<'a>(
448 tile: &'a Tile<'a>,
449 header: &Header<'_>,
450 tile_ctx: &mut TileDecodeContext,
451 channel_data: &mut ComponentData,
452 component_info: &ComponentInfo,
453) {
454 let idwt_output = &mut tile_ctx.idwt_output;
455
456 let component_tile = ComponentTile::new(tile, component_info);
457 let resolution_tile = ResolutionTile::new(
458 component_tile,
459 component_info.num_resolution_levels() - 1 - header.skipped_resolution_levels,
460 );
461
462 let (scale_x, scale_y) = (
463 component_info.size_info.horizontal_resolution,
464 component_info.size_info.vertical_resolution,
465 );
466
467 let (image_x_offset, image_y_offset) = (
468 header.size_data.image_area_x_offset,
469 header.size_data.image_area_y_offset,
470 );
471
472 if scale_x == 1 && scale_y == 1 {
473 let skip_x = image_x_offset.saturating_sub(idwt_output.rect.x0);
482 let skip_y = image_y_offset.saturating_sub(idwt_output.rect.y0);
483
484 let input_row_iter = idwt_output
485 .coefficients
486 .chunks_exact(idwt_output.rect.width() as usize)
487 .skip(skip_y as usize)
488 .take(idwt_output.rect.height() as usize);
489
490 let output_row_iter = channel_data
491 .container
492 .chunks_exact_mut(header.size_data.image_width() as usize)
493 .skip(resolution_tile.rect.y0.saturating_sub(image_y_offset) as usize);
494
495 for (input_row, output_row) in input_row_iter.zip(output_row_iter) {
496 let input_row = &input_row[skip_x as usize..];
497 let output_row = &mut output_row
498 [resolution_tile.rect.x0.saturating_sub(image_x_offset) as usize..]
499 [..input_row.len()];
500
501 output_row.copy_from_slice(input_row);
502 }
503 } else {
504 let image_width = header.size_data.image_width();
505 let image_height = header.size_data.image_height();
506
507 let x_shrink_factor = header.size_data.x_shrink_factor;
508 let y_shrink_factor = header.size_data.y_shrink_factor;
509
510 let x_offset = header
511 .size_data
512 .image_area_x_offset
513 .div_ceil(x_shrink_factor);
514 let y_offset = header
515 .size_data
516 .image_area_y_offset
517 .div_ceil(y_shrink_factor);
518
519 for y in resolution_tile.rect.y0..resolution_tile.rect.y1 {
521 let relative_y = (y - component_tile.rect.y0) as usize;
522 let reference_grid_y = (scale_y as u32 * y) / y_shrink_factor;
523
524 for x in resolution_tile.rect.x0..resolution_tile.rect.x1 {
525 let relative_x = (x - component_tile.rect.x0) as usize;
526 let reference_grid_x = (scale_x as u32 * x) / x_shrink_factor;
527
528 let sample = idwt_output.coefficients
529 [relative_y * idwt_output.rect.width() as usize + relative_x];
530
531 for x_position in u32::max(reference_grid_x, x_offset)
532 ..u32::min(reference_grid_x + scale_x as u32, image_width + x_offset)
533 {
534 for y_position in u32::max(reference_grid_y, y_offset)
535 ..u32::min(reference_grid_y + scale_y as u32, image_height + y_offset)
536 {
537 let pos = (y_position - y_offset) as usize * image_width as usize
538 + (x_position - x_offset) as usize;
539
540 channel_data.container[pos] = sample;
541 }
542 }
543 }
544 }
545 }
546}