1use alloc::vec;
4use alloc::vec::Vec;
5
6use super::bitplane::BITPLANE_BIT_SIZE;
7use super::build::SubBandType;
8use super::DecodeSettings;
9use crate::error::{bail, err, DecodingError, MarkerError, Result, ValidationError};
10use crate::reader::BitReader;
11use crate::{MAX_J2K_SPEC_COMPONENTS, MAX_NATIVE_DECODE_COMPONENTS};
12
13const MAX_LAYER_COUNT: u8 = 32;
14const MAX_RESOLUTION_COUNT: u8 = 32;
15const MAX_PRECINCT_EXPONENT: u8 = 31;
16
17#[derive(Debug)]
18pub(crate) struct Header<'a> {
19 pub(crate) size_data: SizeData,
20 pub(crate) global_coding_style: CodingStyleDefault,
21 pub(crate) component_infos: Vec<ComponentInfo>,
22 pub(crate) progression_changes: Vec<ProgressionChange>,
23 pub(crate) plm_packet_lengths: Vec<u32>,
24 pub(crate) ppm_packets: Vec<PpmPacket<'a>>,
25 pub(crate) skipped_resolution_levels: u8,
26 pub(crate) strict: bool,
28}
29
30#[derive(Debug, Clone)]
31pub(crate) struct PpmMarkerData<'a> {
32 pub(crate) sequence_idx: u8,
33 pub(crate) packets: Vec<PpmPacket<'a>>,
34}
35
36#[derive(Debug, Clone)]
37pub(crate) struct PpmPacket<'a> {
38 pub(crate) data: &'a [u8],
39}
40
41#[derive(Debug, Clone)]
42pub(crate) struct PacketLengthMarker {
43 pub(crate) sequence_idx: u8,
44 pub(crate) packet_lengths: Vec<u32>,
45}
46
47pub(crate) fn read_header<'a>(
48 reader: &mut BitReader<'a>,
49 settings: &DecodeSettings,
50) -> Result<Header<'a>> {
51 if reader.read_marker()? != markers::SIZ {
52 bail!(MarkerError::Expected("SIZ"));
53 }
54
55 let mut size_data = size_marker(reader)?;
56
57 let mut cod = None;
58 let mut qcd = None;
59
60 let num_components = size_data.component_sizes.len() as u16;
61 let mut cod_components = vec![None; num_components as usize];
62 let mut qcd_components = vec![None; num_components as usize];
63 let mut rgn_components = vec![None; num_components as usize];
64 let mut progression_changes = vec![];
65 let mut plm_markers = vec![];
66 let mut ppm_markers = vec![];
67
68 loop {
69 match reader.peek_marker().ok_or(MarkerError::Invalid)? {
70 markers::SOT => break,
71 markers::CAP | markers::CPF => {
72 reader.read_marker()?;
73 skip_marker_segment(reader).ok_or(MarkerError::ParseFailure("CAP/CPF"))?;
74 }
75 markers::COD => {
76 reader.read_marker()?;
77 cod = Some(cod_marker(reader).ok_or(MarkerError::ParseFailure("COD"))?);
78 }
79 markers::COC => {
80 reader.read_marker()?;
81 let (component_index, coc) =
82 coc_marker(reader, num_components).ok_or(MarkerError::ParseFailure("COC"))?;
83 *cod_components
84 .get_mut(component_index as usize)
85 .ok_or(MarkerError::ParseFailure("COC"))? = Some(coc);
86 }
87 markers::QCD => {
88 reader.read_marker()?;
89 qcd = Some(qcd_marker(reader).ok_or(MarkerError::ParseFailure("QCD"))?);
90 }
91 markers::QCC => {
92 reader.read_marker()?;
93 let (component_index, qcc) =
94 qcc_marker(reader, num_components).ok_or(MarkerError::ParseFailure("QCC"))?;
95 *qcd_components
96 .get_mut(component_index as usize)
97 .ok_or(MarkerError::ParseFailure("QCC"))? = Some(qcc);
98 }
99 markers::POC => {
100 reader.read_marker()?;
101 let num_layers = cod
102 .as_ref()
103 .ok_or(MarkerError::ParseFailure("POC"))?
104 .num_layers;
105 progression_changes.extend(
106 poc_marker(reader, num_components, num_layers)
107 .ok_or(MarkerError::ParseFailure("POC"))?,
108 );
109 }
110 markers::RGN => {
111 reader.read_marker()?;
112 let rgn =
113 rgn_marker(reader, num_components).ok_or(MarkerError::ParseFailure("RGN"))?;
114 if rgn.style != 0 {
115 bail!(DecodingError::UnsupportedFeature("explicit ROI coding"));
116 }
117 *rgn_components
118 .get_mut(rgn.component_index as usize)
119 .ok_or(MarkerError::ParseFailure("RGN"))? = Some(rgn.shift);
120 }
121 markers::TLM => {
122 reader.read_marker()?;
123 tlm_marker(reader).ok_or(MarkerError::ParseFailure("TLM"))?;
124 }
125 markers::PLM => {
126 reader.read_marker()?;
127 plm_markers.push(plm_marker(reader).ok_or(MarkerError::ParseFailure("PLM"))?);
128 }
129 markers::COM => {
130 reader.read_marker()?;
131 com_marker(reader).ok_or(MarkerError::ParseFailure("COM"))?;
132 }
133 markers::PPM => {
134 reader.read_marker()?;
135 ppm_markers.push(ppm_marker(reader).ok_or(MarkerError::ParseFailure("PPM"))?);
136 }
137 markers::CRG => {
138 reader.read_marker()?;
139 skip_marker_segment(reader);
140 }
141 (0x30..=0x3F) => {
142 reader.read_marker()?;
146 }
148 _ => {
149 bail!(MarkerError::Unsupported);
150 }
151 }
152 }
153
154 let cod = cod.ok_or(MarkerError::Missing("COD"))?;
155 let qcd = qcd.ok_or(MarkerError::Missing("QCD"))?;
156
157 let component_infos: Vec<ComponentInfo> = size_data
158 .component_sizes
159 .iter()
160 .enumerate()
161 .map(|(idx, csi)| ComponentInfo {
162 size_info: *csi,
163 coding_style: cod_components[idx]
164 .clone()
165 .map(|mut c| {
166 c.flags.raw |= cod.component_parameters.flags.raw;
167
168 c
169 })
170 .unwrap_or(cod.component_parameters.clone()),
171 quantization_info: qcd_components[idx].clone().unwrap_or(qcd.clone()),
172 roi_shift: rgn_components[idx].unwrap_or(0),
173 })
174 .collect();
175
176 let min_num_resolution_levels = component_infos
180 .iter()
181 .map(|c| c.num_resolution_levels())
182 .min()
183 .ok_or(ValidationError::InvalidComponentMetadata)?;
184 let skipped_resolution_levels =
185 if let Some((target_width, target_height)) = settings.target_resolution {
186 if target_width == 0 || target_height == 0 {
187 bail!(ValidationError::InvalidDimensions);
188 }
189 let width_log = (size_data.image_width() / target_width)
190 .checked_ilog2()
191 .unwrap_or(0);
192 let height_log = (size_data.image_height() / target_height)
193 .checked_ilog2()
194 .unwrap_or(0);
195
196 width_log.min(height_log) as u8
197 } else {
198 0
199 }
200 .min(min_num_resolution_levels - 1);
201
202 size_data.x_resolution_shrink_factor *= 1 << skipped_resolution_levels;
205 size_data.y_resolution_shrink_factor *= 1 << skipped_resolution_levels;
206
207 ppm_markers.sort_by_key(|ppm_marker| ppm_marker.sequence_idx);
208 plm_markers.sort_by_key(|plm_marker| plm_marker.sequence_idx);
209
210 let header = Header {
211 size_data,
212 global_coding_style: cod.clone(),
213 component_infos,
214 progression_changes,
215 plm_packet_lengths: plm_markers
216 .into_iter()
217 .flat_map(|marker| marker.packet_lengths)
218 .collect(),
219 ppm_packets: ppm_markers
220 .into_iter()
221 .flat_map(|i| i.packets)
222 .filter_map(|p| if p.data.is_empty() { None } else { Some(p) })
223 .collect(),
224 skipped_resolution_levels,
225 strict: settings.strict,
226 };
227
228 validate(&header)?;
229
230 Ok(header)
231}
232
233fn validate(header: &Header<'_>) -> Result<()> {
234 for info in &header.component_infos {
235 let max_resolution_idx = info.coding_style.parameters.num_resolution_levels - 1;
236 let quantization_style = info.quantization_info.quantization_style;
237 let num_precinct_exponents = info.quantization_info.step_sizes.len();
238
239 if num_precinct_exponents == 0 {
240 bail!(ValidationError::MissingPrecinctExponents);
241 } else if matches!(
242 quantization_style,
243 QuantizationStyle::NoQuantization | QuantizationStyle::ScalarExpounded
244 ) {
245 if max_resolution_idx == 0 {
249 if num_precinct_exponents == 0 {
250 bail!(ValidationError::InsufficientExponents);
251 }
252 } else if 1 + (max_resolution_idx as usize - 1) * 3 + 2 >= num_precinct_exponents {
253 bail!(ValidationError::InsufficientExponents);
254 }
255 }
256 }
257
258 Ok(())
259}
260
261#[derive(Debug, Clone)]
262pub(crate) struct ComponentInfo {
263 pub(crate) size_info: ComponentSizeInfo,
264 pub(crate) coding_style: CodingStyleComponent,
265 pub(crate) quantization_info: QuantizationInfo,
266 pub(crate) roi_shift: u8,
267}
268
269impl ComponentInfo {
270 pub(crate) fn exponent_mantissa(
271 &self,
272 sub_band_type: SubBandType,
273 resolution: u8,
274 ) -> Result<(u16, u16)> {
275 let n_ll = self.coding_style.parameters.num_decomposition_levels;
276
277 let sb_index = match sub_band_type {
278 SubBandType::LowLow => u16::MAX,
281 SubBandType::HighLow => 0,
282 SubBandType::LowHigh => 1,
283 SubBandType::HighHigh => 2,
284 };
285
286 let step_sizes = &self.quantization_info.step_sizes;
287 match self.quantization_info.quantization_style {
288 QuantizationStyle::NoQuantization | QuantizationStyle::ScalarExpounded => {
289 let entry = if resolution == 0 {
290 step_sizes.first()
291 } else {
292 step_sizes.get(1 + (resolution as usize - 1) * 3 + sb_index as usize)
293 };
294
295 Ok(entry
296 .map(|s| (s.exponent, s.mantissa))
297 .ok_or(ValidationError::MissingStepSize)?)
298 }
299 QuantizationStyle::ScalarDerived => {
300 let (e_0, mantissa) = step_sizes
301 .first()
302 .map(|s| (s.exponent, s.mantissa))
303 .ok_or(ValidationError::MissingStepSize)?;
304 let n_b = if resolution == 0 {
305 n_ll as u16
306 } else {
307 n_ll as u16 + 1 - resolution as u16
308 };
309
310 let exponent = e_0
311 .checked_sub(n_ll as u16)
312 .and_then(|e| e.checked_add(n_b))
313 .ok_or(ValidationError::InvalidExponents)?;
314
315 Ok((exponent, mantissa))
316 }
317 }
318 }
319
320 pub(crate) fn wavelet_transform(&self) -> WaveletTransform {
321 self.coding_style.parameters.transformation
322 }
323
324 pub(crate) fn num_resolution_levels(&self) -> u8 {
325 self.coding_style.parameters.num_resolution_levels
326 }
327
328 pub(crate) fn num_decomposition_levels(&self) -> u8 {
329 self.coding_style.parameters.num_decomposition_levels
330 }
331
332 pub(crate) fn code_block_style(&self) -> CodeBlockStyle {
333 self.coding_style.parameters.code_block_style
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340 use crate::J2kWaveletTransform;
341
342 #[test]
343 fn wavelet_transform_converts_to_external_selector() {
344 assert_eq!(
345 J2kWaveletTransform::from(WaveletTransform::Reversible53),
346 J2kWaveletTransform::Reversible53
347 );
348 assert_eq!(
349 J2kWaveletTransform::from(WaveletTransform::Irreversible97),
350 J2kWaveletTransform::Irreversible97
351 );
352 }
353}
354
355#[derive(Debug, Clone, Copy)]
357pub(crate) enum ProgressionOrder {
358 LayerResolutionComponentPosition,
359 ResolutionLayerComponentPosition,
360 ResolutionPositionComponentLayer,
361 PositionComponentResolutionLayer,
362 ComponentPositionResolutionLayer,
363}
364
365#[derive(Debug, Clone)]
366pub(crate) struct ProgressionChange {
367 pub(crate) resolution_start: u8,
368 pub(crate) component_start: u8,
369 pub(crate) layer_end: u8,
370 pub(crate) resolution_end: u8,
371 pub(crate) component_end: u8,
372 pub(crate) progression_order: ProgressionOrder,
373}
374
375impl ProgressionOrder {
376 fn from_u8(value: u8) -> Result<Self> {
377 match value {
378 0 => Ok(Self::LayerResolutionComponentPosition),
379 1 => Ok(Self::ResolutionLayerComponentPosition),
380 2 => Ok(Self::ResolutionPositionComponentLayer),
381 3 => Ok(Self::PositionComponentResolutionLayer),
382 4 => Ok(Self::ComponentPositionResolutionLayer),
383 _ => err!(ValidationError::InvalidProgressionOrder),
384 }
385 }
386}
387
388#[derive(Debug, Clone, Copy, PartialEq, Eq)]
390pub(crate) enum WaveletTransform {
391 Irreversible97,
392 Reversible53,
393}
394
395impl WaveletTransform {
396 fn from_u8(value: u8) -> Result<Self> {
397 match value {
398 0 => Ok(Self::Irreversible97),
399 1 => Ok(Self::Reversible53),
400 _ => err!(ValidationError::InvalidTransformation),
401 }
402 }
403}
404
405impl From<WaveletTransform> for crate::J2kWaveletTransform {
406 fn from(transform: WaveletTransform) -> Self {
407 match transform {
408 WaveletTransform::Reversible53 => Self::Reversible53,
409 WaveletTransform::Irreversible97 => Self::Irreversible97,
410 }
411 }
412}
413
414#[derive(Debug, Clone, Copy, Default)]
416pub(crate) struct CodingStyleFlags {
417 pub(crate) raw: u8,
418}
419
420impl CodingStyleFlags {
421 fn from_u8(value: u8) -> Self {
422 Self { raw: value }
423 }
424
425 pub(crate) fn has_precincts(&self) -> bool {
426 (self.raw & 0x01) != 0
427 }
428
429 pub(crate) fn may_use_sop_markers(&self) -> bool {
430 (self.raw & 0x02) != 0
431 }
432
433 pub(crate) fn uses_eph_marker(&self) -> bool {
434 (self.raw & 0x04) != 0
435 }
436}
437
438#[derive(Debug, Clone, Copy, Default)]
440pub(crate) struct CodeBlockStyle {
441 pub(crate) selective_arithmetic_coding_bypass: bool,
442 pub(crate) reset_context_probabilities: bool,
443 pub(crate) termination_on_each_pass: bool,
444 pub(crate) vertically_causal_context: bool,
445 pub(crate) segmentation_symbols: bool,
446 pub(crate) high_throughput_block_coding: bool,
447}
448
449impl CodeBlockStyle {
450 fn from_u8(value: u8) -> Self {
451 Self {
452 selective_arithmetic_coding_bypass: (value & 0x01) != 0,
453 reset_context_probabilities: (value & 0x02) != 0,
454 termination_on_each_pass: (value & 0x04) != 0,
455 vertically_causal_context: (value & 0x08) != 0,
456 segmentation_symbols: (value & 0x20) != 0,
459 high_throughput_block_coding: (value & 0x40) != 0,
460 }
461 }
462
463 pub(crate) fn uses_high_throughput_block_coding(&self) -> bool {
464 self.high_throughput_block_coding
465 }
466}
467
468#[derive(Debug, Clone, Copy, PartialEq, Eq)]
470pub(crate) enum QuantizationStyle {
471 NoQuantization,
472 ScalarDerived,
473 ScalarExpounded,
474}
475
476impl QuantizationStyle {
477 fn from_u8(value: u8) -> Result<Self> {
478 match value & 0x1F {
479 0 => Ok(Self::NoQuantization),
480 1 => Ok(Self::ScalarDerived),
481 2 => Ok(Self::ScalarExpounded),
482 _ => err!(ValidationError::InvalidQuantizationStyle),
483 }
484 }
485}
486
487#[derive(Clone, Copy, Debug)]
488pub(crate) struct StepSize {
489 pub(crate) mantissa: u16,
490 pub(crate) exponent: u16,
491}
492
493#[derive(Clone, Debug)]
495pub(crate) struct QuantizationInfo {
496 pub(crate) quantization_style: QuantizationStyle,
497 pub(crate) guard_bits: u8,
498 pub(crate) step_sizes: Vec<StepSize>,
499}
500
501#[derive(Debug, Clone)]
503pub(crate) struct CodingStyleDefault {
504 pub(crate) progression_order: ProgressionOrder,
505 pub(crate) num_layers: u8,
506 pub(crate) mct: bool,
507 pub(crate) component_parameters: CodingStyleComponent,
509}
510
511#[derive(Clone, Debug)]
513pub(crate) struct CodingStyleComponent {
514 pub(crate) flags: CodingStyleFlags,
515 pub(crate) parameters: CodingStyleParameters,
516}
517
518#[derive(Clone, Debug)]
520pub(crate) struct CodingStyleParameters {
521 pub(crate) num_decomposition_levels: u8,
522 pub(crate) num_resolution_levels: u8,
523 pub(crate) code_block_width: u8,
524 pub(crate) code_block_height: u8,
525 pub(crate) code_block_style: CodeBlockStyle,
526 pub(crate) transformation: WaveletTransform,
527 pub(crate) precinct_exponents: Vec<(u8, u8)>,
528}
529
530#[derive(Debug)]
531pub(crate) struct SizeData {
532 pub(crate) reference_grid_width: u32,
534 pub(crate) reference_grid_height: u32,
536 pub(crate) image_area_x_offset: u32,
539 pub(crate) image_area_y_offset: u32,
541 pub(crate) tile_width: u32,
543 pub(crate) tile_height: u32,
545 pub(crate) tile_x_offset: u32,
547 pub(crate) tile_y_offset: u32,
549 pub(crate) component_sizes: Vec<ComponentSizeInfo>,
551 pub(crate) x_shrink_factor: u32,
553 pub(crate) y_shrink_factor: u32,
555 pub(crate) x_resolution_shrink_factor: u32,
557 pub(crate) y_resolution_shrink_factor: u32,
559}
560
561impl SizeData {
562 pub(crate) fn tile_x_coord(&self, idx: u32) -> u32 {
563 idx % self.num_x_tiles()
565 }
566
567 pub(crate) fn tile_y_coord(&self, idx: u32) -> u32 {
568 idx / self.num_x_tiles()
570 }
571}
572
573#[derive(Debug, Clone, Copy)]
575pub(crate) struct ComponentSizeInfo {
576 pub(crate) precision: u8,
577 pub(crate) horizontal_resolution: u8,
578 pub(crate) vertical_resolution: u8,
579}
580
581impl SizeData {
582 pub(crate) fn num_x_tiles(&self) -> u32 {
584 (self.reference_grid_width - self.tile_x_offset).div_ceil(self.tile_width)
586 }
587
588 pub(crate) fn num_y_tiles(&self) -> u32 {
590 (self.reference_grid_height - self.tile_y_offset).div_ceil(self.tile_height)
592 }
593
594 pub(crate) fn num_tiles(&self) -> u32 {
600 self.num_x_tiles().saturating_mul(self.num_y_tiles())
601 }
602
603 pub(crate) fn image_width(&self) -> u32 {
605 (self.reference_grid_width - self.image_area_x_offset)
606 .div_ceil(self.x_shrink_factor * self.x_resolution_shrink_factor)
607 }
608
609 pub(crate) fn image_height(&self) -> u32 {
611 (self.reference_grid_height - self.image_area_y_offset)
612 .div_ceil(self.y_shrink_factor * self.y_resolution_shrink_factor)
613 }
614}
615
616fn size_marker(reader: &mut BitReader<'_>) -> Result<SizeData> {
618 let size_data = size_marker_inner(reader)?;
619
620 if size_data.tile_width == 0
621 || size_data.tile_height == 0
622 || size_data.reference_grid_width == 0
623 || size_data.reference_grid_height == 0
624 {
625 bail!(ValidationError::InvalidDimensions);
626 }
627
628 if size_data.tile_x_offset >= size_data.reference_grid_width
629 || size_data.tile_y_offset >= size_data.reference_grid_height
630 {
631 bail!(ValidationError::InvalidDimensions);
632 }
633
634 if size_data.tile_x_offset > size_data.image_area_x_offset
637 || size_data.tile_y_offset > size_data.image_area_y_offset
638 {
639 bail!(crate::TileError::InvalidOffsets);
640 }
641
642 if size_data
646 .tile_x_offset
647 .checked_add(size_data.tile_width)
648 .ok_or(crate::TileError::InvalidOffsets)?
649 <= size_data.image_area_x_offset
650 || size_data
651 .tile_y_offset
652 .checked_add(size_data.tile_height)
653 .ok_or(crate::TileError::InvalidOffsets)?
654 <= size_data.image_area_y_offset
655 {
656 bail!(crate::TileError::InvalidOffsets);
657 }
658
659 for comp in &size_data.component_sizes {
660 if comp.precision == 0 || comp.vertical_resolution == 0 || comp.horizontal_resolution == 0 {
661 bail!(ValidationError::InvalidComponentMetadata);
662 }
663 }
664
665 if size_data.image_width() > crate::MAX_J2K_IMAGE_DIMENSION
666 || size_data.image_height() > crate::MAX_J2K_IMAGE_DIMENSION
667 {
668 bail!(ValidationError::ImageTooLarge);
669 }
670
671 let num_tiles = u64::from(size_data.num_x_tiles()) * u64::from(size_data.num_y_tiles());
676 if num_tiles > crate::MAX_J2K_TILE_COUNT {
677 bail!(ValidationError::TooManyTiles);
678 }
679
680 Ok(size_data)
681}
682
683fn read_siz_byte(reader: &mut BitReader<'_>) -> Result<u8> {
684 reader
685 .read_byte()
686 .ok_or(MarkerError::ParseFailure("SIZ").into())
687}
688
689fn read_siz_u16(reader: &mut BitReader<'_>) -> Result<u16> {
690 reader
691 .read_u16()
692 .ok_or(MarkerError::ParseFailure("SIZ").into())
693}
694
695fn read_siz_u32(reader: &mut BitReader<'_>) -> Result<u32> {
696 reader
697 .read_u32()
698 .ok_or(MarkerError::ParseFailure("SIZ").into())
699}
700
701fn size_marker_inner(reader: &mut BitReader<'_>) -> Result<SizeData> {
702 let _ = read_siz_u16(reader)?;
704 let _ = read_siz_u16(reader)?;
706
707 let xsiz = read_siz_u32(reader)?;
708 let ysiz = read_siz_u32(reader)?;
709 let x_osiz = read_siz_u32(reader)?;
710 let y_osiz = read_siz_u32(reader)?;
711 let xt_siz = read_siz_u32(reader)?;
712 let yt_siz = read_siz_u32(reader)?;
713 let xto_siz = read_siz_u32(reader)?;
714 let yto_siz = read_siz_u32(reader)?;
715 let csiz = read_siz_u16(reader)?;
716
717 if x_osiz >= xsiz || y_osiz >= ysiz {
718 bail!(ValidationError::InvalidDimensions);
719 }
720
721 if csiz == 0 {
722 bail!(ValidationError::InvalidComponentMetadata);
723 }
724
725 if csiz > MAX_J2K_SPEC_COMPONENTS || csiz > MAX_NATIVE_DECODE_COMPONENTS {
726 bail!(ValidationError::TooManyChannels);
727 }
728
729 let mut components = Vec::with_capacity(csiz as usize);
730 for _ in 0..csiz {
731 let ssiz = read_siz_byte(reader)?;
732 let x_rsiz = read_siz_byte(reader)?;
733 let y_rsiz = read_siz_byte(reader)?;
734
735 let precision = (ssiz & 0x7F) + 1;
736 let _is_signed = (ssiz & 0x80) != 0;
739
740 if precision as u32 > BITPLANE_BIT_SIZE {
742 bail!(ValidationError::InvalidComponentMetadata);
743 }
744
745 components.push(ComponentSizeInfo {
746 precision,
747 horizontal_resolution: x_rsiz,
748 vertical_resolution: y_rsiz,
749 });
750 }
751
752 let mut x_shrink_factor = 1;
758 let mut y_shrink_factor = 1;
759
760 let hr = components[0].horizontal_resolution;
761 let vr = components[0].vertical_resolution;
762 let mut same_resolution = true;
763
764 for component in &components[1..] {
765 same_resolution &= component.horizontal_resolution == hr;
766 same_resolution &= component.vertical_resolution == vr;
767 }
768
769 if same_resolution {
770 x_shrink_factor = hr as u32;
771 y_shrink_factor = vr as u32;
772 }
773
774 Ok(SizeData {
775 reference_grid_width: xsiz,
776 reference_grid_height: ysiz,
777 image_area_x_offset: x_osiz,
778 image_area_y_offset: y_osiz,
779 tile_width: xt_siz,
780 tile_height: yt_siz,
781 tile_x_offset: xto_siz,
782 tile_y_offset: yto_siz,
783 component_sizes: components,
784 x_shrink_factor,
785 y_shrink_factor,
786 x_resolution_shrink_factor: 1,
787 y_resolution_shrink_factor: 1,
788 })
789}
790
791fn coding_style_parameters(
792 reader: &mut BitReader<'_>,
793 coding_style: &CodingStyleFlags,
794) -> Option<CodingStyleParameters> {
795 let num_decomposition_levels = reader.read_byte()?;
796
797 if num_decomposition_levels > MAX_RESOLUTION_COUNT {
798 return None;
799 }
800
801 let num_resolution_levels = num_decomposition_levels.checked_add(1)?;
802 let code_block_width = reader.read_byte()?.checked_add(2)?;
803 let code_block_height = reader.read_byte()?.checked_add(2)?;
804 let code_block_style = CodeBlockStyle::from_u8(reader.read_byte()?);
805 let transformation = WaveletTransform::from_u8(reader.read_byte()?).ok()?;
806
807 let mut precinct_exponents = Vec::new();
808 if coding_style.has_precincts() {
809 for _ in 0..num_resolution_levels {
811 let precinct_size = reader.read_byte()?;
813 let width_exp = precinct_size & 0xF;
814 let height_exp = precinct_size >> 4;
815
816 if width_exp > MAX_PRECINCT_EXPONENT || height_exp > MAX_PRECINCT_EXPONENT {
817 return None;
818 }
819
820 precinct_exponents.push((width_exp, height_exp));
821 }
822 } else {
823 for _ in 0..num_resolution_levels {
825 precinct_exponents.push((15, 15));
826 }
827 }
828
829 Some(CodingStyleParameters {
830 num_decomposition_levels,
831 num_resolution_levels,
832 code_block_width,
833 code_block_height,
834 code_block_style,
835 transformation,
836 precinct_exponents,
837 })
838}
839
840fn com_marker(reader: &mut BitReader<'_>) -> Option<()> {
842 skip_marker_segment(reader)
843}
844
845fn tlm_marker(reader: &mut BitReader<'_>) -> Option<()> {
847 skip_marker_segment(reader)
848}
849
850fn plm_marker(reader: &mut BitReader<'_>) -> Option<PacketLengthMarker> {
852 let segment_len = reader.read_u16()?.checked_sub(2)? as usize;
853 let segment = reader.read_bytes(segment_len)?;
854 let mut reader = BitReader::new(segment);
855
856 let sequence_idx = reader.read_byte()?;
857 let mut packet_lengths = vec![];
858
859 while !reader.at_end() {
860 let length_data_len = reader.read_u32()? as usize;
861 let length_data = reader.read_bytes(length_data_len)?;
862 packet_lengths.extend(decode_packet_lengths(length_data)?);
863 }
864
865 Some(PacketLengthMarker {
866 sequence_idx,
867 packet_lengths,
868 })
869}
870
871pub(crate) fn plt_marker(reader: &mut BitReader<'_>) -> Option<PacketLengthMarker> {
873 let segment_len = reader.read_u16()?.checked_sub(2)? as usize;
874 let segment = reader.read_bytes(segment_len)?;
875 let mut reader = BitReader::new(segment);
876
877 let sequence_idx = reader.read_byte()?;
878 let packet_lengths = decode_packet_lengths(reader.tail()?)?;
879
880 Some(PacketLengthMarker {
881 sequence_idx,
882 packet_lengths,
883 })
884}
885
886pub(crate) fn decode_packet_lengths(data: &[u8]) -> Option<Vec<u32>> {
887 let mut packet_lengths = vec![];
888 let mut value = 0_u32;
889 let mut in_progress = false;
890
891 for byte in data {
892 value = value.checked_shl(7)?.checked_add(u32::from(byte & 0x7F))?;
893 in_progress = true;
894
895 if byte & 0x80 == 0 {
896 packet_lengths.push(value);
897 value = 0;
898 in_progress = false;
899 }
900 }
901
902 if in_progress {
903 return None;
904 }
905
906 Some(packet_lengths)
907}
908
909fn ppm_marker<'a>(reader: &mut BitReader<'a>) -> Option<PpmMarkerData<'a>> {
911 let segment_len = reader.read_u16()?.checked_sub(2)? as usize;
912 let ppm_data = reader.read_bytes(segment_len)?;
913 let mut packets = vec![];
914
915 let mut reader = BitReader::new(ppm_data);
916 let sequence_idx = reader.read_byte()?;
917
918 while !reader.at_end() {
922 let packet_len = reader.read_u16()? as usize;
923 let data = reader.read_bytes(packet_len)?;
924
925 packets.push(PpmPacket { data });
926 }
927
928 Some(PpmMarkerData {
929 sequence_idx,
930 packets,
931 })
932}
933
934pub(crate) fn rgn_marker(reader: &mut BitReader<'_>, csiz: u16) -> Option<RgnMarkerData> {
936 let length = reader.read_u16()?;
937 let component_index_bytes = if csiz < 257 { 1 } else { 2 };
938 if length != 4 + component_index_bytes {
939 return None;
940 }
941
942 let component_index = read_component_index(reader, csiz)?;
943 if component_index >= csiz {
944 return None;
945 }
946
947 let style = reader.read_byte()?;
948 let shift = reader.read_byte()?;
949
950 Some(RgnMarkerData {
951 component_index,
952 style,
953 shift,
954 })
955}
956
957#[derive(Debug, Clone, Copy, PartialEq, Eq)]
958pub(crate) struct RgnMarkerData {
959 pub(crate) component_index: u16,
960 pub(crate) style: u8,
961 pub(crate) shift: u8,
962}
963
964pub(crate) fn skip_marker_segment(reader: &mut BitReader<'_>) -> Option<()> {
965 let length = reader.read_u16()?.checked_sub(2)?;
966 reader.skip_bytes(length as usize)?;
967
968 Some(())
969}
970
971pub(crate) fn cod_marker(reader: &mut BitReader<'_>) -> Option<CodingStyleDefault> {
973 let _ = reader.read_u16()?;
975
976 let coding_style_flags = CodingStyleFlags::from_u8(reader.read_byte()?);
977 let progression_order = ProgressionOrder::from_u8(reader.read_byte()?).ok()?;
978
979 let num_layers = reader.read_u16()?;
980
981 if num_layers == 0 || num_layers > MAX_LAYER_COUNT as u16 {
983 return None;
984 }
985
986 let mct = reader.read_byte()? == 1;
987
988 let coding_style_parameters = coding_style_parameters(reader, &coding_style_flags)?;
989
990 Some(CodingStyleDefault {
991 progression_order,
992 num_layers: num_layers as u8,
993 mct,
994 component_parameters: CodingStyleComponent {
995 flags: coding_style_flags,
996 parameters: coding_style_parameters,
997 },
998 })
999}
1000
1001pub(crate) fn coc_marker(
1003 reader: &mut BitReader<'_>,
1004 csiz: u16,
1005) -> Option<(u16, CodingStyleComponent)> {
1006 let _ = reader.read_u16()?;
1008
1009 let component_index = if csiz < 257 {
1010 reader.read_byte()? as u16
1011 } else {
1012 reader.read_u16()?
1013 };
1014 let coding_style = CodingStyleFlags::from_u8(reader.read_byte()?);
1015
1016 let parameters = coding_style_parameters(reader, &coding_style)?;
1017
1018 let coc = CodingStyleComponent {
1019 flags: coding_style,
1020 parameters,
1021 };
1022
1023 Some((component_index, coc))
1024}
1025
1026pub(crate) fn qcd_marker(reader: &mut BitReader<'_>) -> Option<QuantizationInfo> {
1028 let length = reader.read_u16()?;
1030
1031 let sqcd_val = reader.read_byte()?;
1032 let quantization_style = QuantizationStyle::from_u8(sqcd_val & 0x1F).ok()?;
1033 let guard_bits = (sqcd_val >> 5) & 0x07;
1034
1035 let remaining_bytes = length.checked_sub(3)? as usize;
1036
1037 let mut parameters = quantization_parameters(reader, quantization_style, remaining_bytes)?;
1038 parameters.guard_bits = guard_bits;
1039
1040 Some(parameters)
1041}
1042
1043pub(crate) fn qcc_marker(reader: &mut BitReader<'_>, csiz: u16) -> Option<(u16, QuantizationInfo)> {
1045 let length = reader.read_u16()?;
1046
1047 let component_index = if csiz < 257 {
1048 reader.read_byte()? as u16
1049 } else {
1050 reader.read_u16()?
1051 };
1052
1053 let sqcc_val = reader.read_byte()?;
1054 let quantization_style = QuantizationStyle::from_u8(sqcc_val & 0x1F).ok()?;
1055 let guard_bits = (sqcc_val >> 5) & 0x07;
1056
1057 let component_index_size = if csiz < 257 { 1 } else { 2 };
1058 let remaining_bytes = length
1059 .checked_sub(2)?
1060 .checked_sub(component_index_size)?
1061 .checked_sub(1)? as usize;
1062
1063 let mut parameters = quantization_parameters(reader, quantization_style, remaining_bytes)?;
1064 parameters.guard_bits = guard_bits;
1065
1066 Some((component_index, parameters))
1067}
1068
1069pub(crate) fn poc_marker(
1071 reader: &mut BitReader<'_>,
1072 csiz: u16,
1073 _num_layers: u8,
1074) -> Option<Vec<ProgressionChange>> {
1075 let length = reader.read_u16()?;
1076 let remaining_bytes = length.checked_sub(2)?;
1077 let component_index_size = if csiz < 257 { 1u16 } else { 2u16 };
1078 let change_size = 1 + component_index_size + 2 + 1 + component_index_size + 1;
1079 if remaining_bytes == 0 || remaining_bytes % change_size != 0 {
1080 return None;
1081 }
1082
1083 let change_count = remaining_bytes / change_size;
1084 let mut changes = Vec::with_capacity(change_count as usize);
1085 for _ in 0..change_count {
1086 let resolution_start = reader.read_byte()?;
1087 let component_start = read_component_index(reader, csiz)?;
1088 let layer_end = reader.read_u16()?;
1089 let resolution_end = reader.read_byte()?;
1090 let component_end = read_component_index(reader, csiz)?;
1091 let progression_order = ProgressionOrder::from_u8(reader.read_byte()?).ok()?;
1092
1093 if resolution_start >= resolution_end
1094 || component_start >= component_end
1095 || component_start >= csiz
1096 || layer_end == 0
1097 || layer_end > u16::from(u8::MAX)
1098 || component_end > u16::from(u8::MAX)
1099 {
1100 return None;
1101 }
1102
1103 changes.push(ProgressionChange {
1104 resolution_start,
1105 component_start: component_start as u8,
1106 layer_end: layer_end as u8,
1107 resolution_end,
1108 component_end: component_end as u8,
1109 progression_order,
1110 });
1111 }
1112
1113 Some(changes)
1114}
1115
1116fn read_component_index(reader: &mut BitReader<'_>, csiz: u16) -> Option<u16> {
1117 if csiz < 257 {
1118 Some(u16::from(reader.read_byte()?))
1119 } else {
1120 reader.read_u16()
1121 }
1122}
1123
1124fn quantization_parameters(
1125 reader: &mut BitReader<'_>,
1126 quantization_style: QuantizationStyle,
1127 remaining_bytes: usize,
1128) -> Option<QuantizationInfo> {
1129 let mut step_sizes = Vec::new();
1130
1131 let irreversible = |val: u16| {
1132 let exponent = val >> 11;
1133 let mantissa = val & ((1 << 11) - 1);
1134
1135 StepSize { exponent, mantissa }
1136 };
1137
1138 match quantization_style {
1139 QuantizationStyle::NoQuantization => {
1140 for _ in 0..remaining_bytes {
1142 let value = reader.read_byte()? as u16;
1143 step_sizes.push(StepSize {
1144 mantissa: 0,
1146 exponent: (value >> 3),
1147 });
1148 }
1149 }
1150 QuantizationStyle::ScalarDerived => {
1151 let value = reader.read_u16()?;
1152 step_sizes.push(irreversible(value));
1153 }
1154 QuantizationStyle::ScalarExpounded => {
1155 let num_bands = remaining_bytes / 2;
1156 for _ in 0..num_bands {
1157 let value = reader.read_u16()?;
1158
1159 step_sizes.push(irreversible(value));
1160 }
1161 }
1162 }
1163
1164 Some(QuantizationInfo {
1165 quantization_style,
1166 guard_bits: 0,
1167 step_sizes,
1168 })
1169}
1170
1171#[allow(
1172 unused,
1173 reason = "Not all marker codes are used in every decoding path yet"
1174)]
1175pub(crate) mod markers {
1177 pub(crate) const SOC: u8 = 0x4F;
1179 pub(crate) const SOT: u8 = 0x90;
1181 pub(crate) const SOD: u8 = 0x93;
1183 pub(crate) const EOC: u8 = 0xD9;
1185
1186 pub(crate) const CAP: u8 = 0x50;
1188 pub(crate) const SIZ: u8 = 0x51;
1190
1191 pub(crate) const COD: u8 = 0x52;
1193 pub(crate) const COC: u8 = 0x53;
1195 pub(crate) const RGN: u8 = 0x5E;
1197 pub(crate) const QCD: u8 = 0x5C;
1199 pub(crate) const QCC: u8 = 0x5D;
1201 pub(crate) const POC: u8 = 0x5F;
1203
1204 pub(crate) const TLM: u8 = 0x55;
1206 pub(crate) const PLM: u8 = 0x57;
1208 pub(crate) const PLT: u8 = 0x58;
1210 pub(crate) const CPF: u8 = 0x59;
1212 pub(crate) const PPM: u8 = 0x60;
1214 pub(crate) const PPT: u8 = 0x61;
1216
1217 pub(crate) const SOP: u8 = 0x91;
1219 pub(crate) const EPH: u8 = 0x92;
1221
1222 pub(crate) const CRG: u8 = 0x63;
1224 pub(crate) const COM: u8 = 0x64;
1226
1227 pub(crate) fn to_string(marker: u8) -> &'static str {
1228 match marker {
1229 SOC => "SOC",
1231 SOT => "SOT",
1232 SOD => "SOD",
1233 EOC => "EOC",
1234
1235 CAP => "CAP",
1237 SIZ => "SIZ",
1238
1239 COD => "COD",
1241 COC => "COC",
1242 RGN => "RGN",
1243 QCD => "QCD",
1244 QCC => "QCC",
1245 POC => "POC",
1246
1247 TLM => "TLM",
1249 PLM => "PLM",
1250 PLT => "PLT",
1251 CPF => "CPF",
1252 PPM => "PPM",
1253 PPT => "PPT",
1254
1255 SOP => "SOP",
1257 EPH => "EPH",
1258
1259 CRG => "CRG",
1261 COM => "COM",
1262
1263 _ => "UNKNOWN",
1264 }
1265 }
1266}