j2k_types/lib.rs
1// j2k-coverage: shared-accelerator-host
2//! Shared JPEG 2000 and HTJ2K encode-stage contracts and helpers for j2k.
3//!
4//! This crate is the neutral public contract between the `j2k` facade, the
5//! `j2k-native` codec engine, and device adapters. It defines encode-stage
6//! jobs, outputs, dispatch reports, progression-order helpers, the shared
7//! accelerator trait, and its default CPU-only implementation.
8
9#![no_std]
10#![forbid(unsafe_code)]
11#![forbid(missing_docs)]
12
13extern crate alloc;
14
15use alloc::vec::Vec;
16use core::ops::Range;
17
18mod decode_payload;
19pub use decode_payload::{
20 HtCodeBlockPayloadRanges, J2kClassicCodeBlockPayload, J2kCodestreamRange,
21};
22mod limits;
23#[doc(hidden)]
24pub use limits::{MAX_JPEG2000_PART1_COMPONENTS, MAX_JPEG2000_PART1_SAMPLE_BIT_DEPTH};
25mod resident;
26#[doc(hidden)]
27pub use resident::{
28 J2kResidentEncodeInput, J2kResidentEncodeInputError, J2kResidentHtj2kTileEncodeJob,
29};
30mod stage_error;
31pub use stage_error::{J2kEncodeStageError, J2kEncodeStageErrorKind, J2kEncodeStageResult};
32
33/// Adapter classic J2K sub-band kind for backend experimentation.
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum J2kSubBandType {
36 /// Low-low sub-band.
37 LowLow,
38 /// High-low sub-band.
39 HighLow,
40 /// Low-high sub-band.
41 LowHigh,
42 /// High-high sub-band.
43 HighHigh,
44}
45
46/// Adapter classic J2K code-block style for backend experimentation.
47#[derive(Debug, Clone, Copy)]
48#[expect(
49 clippy::struct_excessive_bools,
50 reason = "the five booleans model independent JPEG 2000 COD code-block style flags"
51)]
52pub struct J2kCodeBlockStyle {
53 /// Selective arithmetic coding bypass was enabled.
54 pub selective_arithmetic_coding_bypass: bool,
55 /// Context probabilities reset after each pass.
56 pub reset_context_probabilities: bool,
57 /// Coding terminated after each pass.
58 pub termination_on_each_pass: bool,
59 /// Vertically causal context was enabled.
60 pub vertically_causal_context: bool,
61 /// Segmentation symbols were enabled.
62 pub segmentation_symbols: bool,
63}
64
65/// Adapter classic J2K coded segment for backend experimentation.
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub struct J2kCodeBlockSegment {
68 /// Byte offset of this segment within the combined payload.
69 pub data_offset: u32,
70 /// Segment payload length in bytes.
71 pub data_length: u32,
72 /// First coding pass covered by this segment.
73 pub start_coding_pass: u8,
74 /// One-past-last coding pass covered by this segment.
75 pub end_coding_pass: u8,
76 /// Whether this segment is decoded through the arithmetic path.
77 pub use_arithmetic: bool,
78}
79
80/// Adapter encoded classic J2K code-block payload for backend experimentation.
81#[derive(Debug)]
82pub struct EncodedJ2kCodeBlock {
83 /// Combined payload bytes for all coded segments in this code block.
84 pub data: Vec<u8>,
85 /// Coded segments for the code block.
86 pub segments: Vec<J2kCodeBlockSegment>,
87 /// Number of coding passes present for this code block.
88 pub number_of_coding_passes: u8,
89 /// Missing most-significant bit planes for this code block.
90 pub missing_bit_planes: u8,
91}
92
93/// Adapter encoded HTJ2K cleanup/refinement code-block payload for backend experimentation.
94#[derive(Debug)]
95pub struct EncodedHtJ2kCodeBlock {
96 /// Combined cleanup/refinement bytes for this code block.
97 pub data: Vec<u8>,
98 /// Cleanup segment length in bytes.
99 pub cleanup_length: u32,
100 /// Refinement segment length in bytes.
101 pub refinement_length: u32,
102 /// Number of coding passes present for this code block.
103 pub num_coding_passes: u8,
104 /// Number of zero most-significant bitplanes before first inclusion.
105 pub num_zero_bitplanes: u8,
106}
107
108/// Adapter pixel deinterleave/level-shift job for backend experimentation.
109#[derive(Debug, Clone, Copy)]
110pub struct J2kDeinterleaveToF32Job<'a> {
111 /// Interleaved source pixel bytes.
112 pub pixels: &'a [u8],
113 /// Number of pixels to convert.
114 pub num_pixels: usize,
115 /// Number of interleaved components per pixel.
116 pub num_components: u16,
117 /// Source sample bit depth.
118 pub bit_depth: u8,
119 /// Whether source samples are signed.
120 pub signed: bool,
121}
122
123/// Adapter forward RCT job for backend experimentation.
124#[derive(Debug)]
125pub struct J2kForwardRctJob<'a> {
126 /// First component plane, updated in place.
127 pub plane0: &'a mut [f32],
128 /// Second component plane, updated in place.
129 pub plane1: &'a mut [f32],
130 /// Third component plane, updated in place.
131 pub plane2: &'a mut [f32],
132}
133
134/// Adapter forward ICT job for backend experimentation.
135#[derive(Debug)]
136pub struct J2kForwardIctJob<'a> {
137 /// First component plane, updated in place.
138 pub plane0: &'a mut [f32],
139 /// Second component plane, updated in place.
140 pub plane1: &'a mut [f32],
141 /// Third component plane, updated in place.
142 pub plane2: &'a mut [f32],
143}
144
145/// Adapter forward 5/3 DWT job for backend experimentation.
146#[derive(Debug, Clone, Copy)]
147pub struct J2kForwardDwt53Job<'a> {
148 /// Source samples in row-major order.
149 pub samples: &'a [f32],
150 /// Source width in samples.
151 pub width: u32,
152 /// Source height in samples.
153 pub height: u32,
154 /// Number of decomposition levels requested.
155 pub num_levels: u8,
156}
157
158/// Adapter forward 5/3 DWT output for backend experimentation.
159#[derive(Debug)]
160pub struct J2kForwardDwt53Output {
161 /// LL subband coefficients from the lowest decomposition level.
162 pub ll: Vec<f32>,
163 /// LL subband width.
164 pub ll_width: u32,
165 /// LL subband height.
166 pub ll_height: u32,
167 /// Higher resolution detail levels, ordered from lowest to highest.
168 pub levels: Vec<J2kForwardDwt53Level>,
169}
170
171/// Adapter forward 5/3 DWT detail level for backend experimentation.
172#[derive(Debug)]
173pub struct J2kForwardDwt53Level {
174 /// HL subband coefficients.
175 pub hl: Vec<f32>,
176 /// LH subband coefficients.
177 pub lh: Vec<f32>,
178 /// HH subband coefficients.
179 pub hh: Vec<f32>,
180 /// Full-resolution width represented by this level.
181 pub width: u32,
182 /// Full-resolution height represented by this level.
183 pub height: u32,
184 /// Low-pass width at this level.
185 pub low_width: u32,
186 /// Low-pass height at this level.
187 pub low_height: u32,
188 /// High-pass width at this level.
189 pub high_width: u32,
190 /// High-pass height at this level.
191 pub high_height: u32,
192}
193
194/// Adapter forward irreversible 9/7 DWT job for backend experimentation.
195#[derive(Debug, Clone, Copy)]
196pub struct J2kForwardDwt97Job<'a> {
197 /// Source samples in row-major order.
198 pub samples: &'a [f32],
199 /// Source width in samples.
200 pub width: u32,
201 /// Source height in samples.
202 pub height: u32,
203 /// Number of decomposition levels requested.
204 pub num_levels: u8,
205}
206
207/// Adapter forward 9/7 DWT output for backend experimentation.
208#[derive(Debug)]
209pub struct J2kForwardDwt97Output {
210 /// LL subband coefficients from the lowest decomposition level.
211 pub ll: Vec<f32>,
212 /// LL subband width.
213 pub ll_width: u32,
214 /// LL subband height.
215 pub ll_height: u32,
216 /// Higher resolution detail levels, ordered from lowest to highest.
217 pub levels: Vec<J2kForwardDwt97Level>,
218}
219
220/// Adapter forward 9/7 DWT detail level for backend experimentation.
221#[derive(Debug)]
222pub struct J2kForwardDwt97Level {
223 /// HL subband coefficients.
224 pub hl: Vec<f32>,
225 /// LH subband coefficients.
226 pub lh: Vec<f32>,
227 /// HH subband coefficients.
228 pub hh: Vec<f32>,
229 /// Full-resolution width represented by this level.
230 pub width: u32,
231 /// Full-resolution height represented by this level.
232 pub height: u32,
233 /// Low-pass width at this level.
234 pub low_width: u32,
235 /// Low-pass height at this level.
236 pub low_height: u32,
237 /// High-pass width at this level.
238 pub high_width: u32,
239 /// High-pass height at this level.
240 pub high_height: u32,
241}
242
243/// Adapter sub-band quantization job for backend experimentation.
244#[derive(Debug, Clone, Copy)]
245pub struct J2kQuantizeSubbandJob<'a> {
246 /// Source sub-band coefficients in row-major order.
247 pub coefficients: &'a [f32],
248 /// Quantization step-size exponent.
249 pub step_exponent: u16,
250 /// Quantization step-size mantissa.
251 pub step_mantissa: u16,
252 /// Nominal range bits for this sub-band.
253 pub range_bits: u8,
254 /// Whether to use reversible integer quantization.
255 pub reversible: bool,
256}
257
258/// Adapter Tier-1 classic J2K code-block encode job for backend experimentation.
259#[derive(Debug, Clone, Copy)]
260pub struct J2kTier1CodeBlockEncodeJob<'a> {
261 /// Quantized coefficients in row-major order.
262 pub coefficients: &'a [i32],
263 /// Code-block width in samples.
264 pub width: u32,
265 /// Code-block height in samples.
266 pub height: u32,
267 /// Subband kind containing this code-block.
268 pub sub_band_type: J2kSubBandType,
269 /// Total bitplanes for this subband/code-block.
270 pub total_bitplanes: u8,
271 /// Classic J2K code-block style flags.
272 pub style: J2kCodeBlockStyle,
273}
274
275/// Adapter HTJ2K code-block encode job for backend experimentation.
276#[derive(Debug, Clone, Copy)]
277pub struct J2kHtCodeBlockEncodeJob<'a> {
278 /// Quantized coefficients in row-major order.
279 pub coefficients: &'a [i32],
280 /// Code-block width in samples.
281 pub width: u32,
282 /// Code-block height in samples.
283 pub height: u32,
284 /// Total bitplanes for this subband/code-block.
285 pub total_bitplanes: u8,
286 /// Requested HT coding passes for this contribution.
287 ///
288 /// `1` is cleanup-only. `2` requests cleanup plus significance-propagation
289 /// refinement on the native CPU path. `3` additionally requests one
290 /// magnitude-refinement pass. Higher values require an accelerator and
291 /// must not be silently reduced by CPU fallback.
292 pub target_coding_passes: u8,
293}
294
295/// Adapter HTJ2K cleanup/refinement encode job for one unquantized sub-band.
296#[derive(Debug, Clone, Copy)]
297pub struct J2kHtSubbandEncodeJob<'a> {
298 /// Source sub-band coefficients in row-major order.
299 pub coefficients: &'a [f32],
300 /// Sub-band width in samples.
301 pub width: u32,
302 /// Sub-band height in samples.
303 pub height: u32,
304 /// Quantization step-size exponent.
305 pub step_exponent: u16,
306 /// Quantization step-size mantissa.
307 pub step_mantissa: u16,
308 /// Nominal range bits for this sub-band.
309 pub range_bits: u8,
310 /// Whether to use reversible integer quantization.
311 pub reversible: bool,
312 /// Code-block width in samples.
313 pub code_block_width: u32,
314 /// Code-block height in samples.
315 pub code_block_height: u32,
316 /// Total coded bitplanes for this sub-band.
317 pub total_bitplanes: u8,
318}
319
320/// Adapter HTJ2K tile-body encode job for backend-resident full-tile paths.
321#[derive(Debug, Clone, Copy)]
322pub struct J2kHtj2kTileEncodeJob<'a> {
323 /// Interleaved source pixel bytes.
324 pub pixels: &'a [u8],
325 /// Tile/image width in samples.
326 pub width: u32,
327 /// Tile/image height in samples.
328 pub height: u32,
329 /// Number of interleaved image components.
330 pub num_components: u16,
331 /// Source component bit depth.
332 pub bit_depth: u8,
333 /// Whether source samples are signed.
334 pub signed: bool,
335 /// Number of DWT decomposition levels.
336 pub num_decomposition_levels: u8,
337 /// Whether the codestream uses reversible coding.
338 pub reversible: bool,
339 /// Whether a multi-component transform should be applied.
340 pub use_mct: bool,
341 /// JPEG 2000 guard bits used to derive total coded bitplanes.
342 pub guard_bits: u8,
343 /// Code-block width in samples.
344 pub code_block_width: u32,
345 /// Code-block height in samples.
346 pub code_block_height: u32,
347 /// Packet progression order to emit.
348 pub progression_order: J2kPacketizationProgressionOrder,
349 /// Per-component sampling factors, as `(x_rsiz, y_rsiz)`.
350 pub component_sampling: &'a [(u8, u8)],
351 /// Quantization step sizes, as `(exponent, mantissa)`, in codestream order.
352 pub quantization_steps: &'a [(u16, u16)],
353}
354
355/// Adapter LRCP packetization code-block contribution for backend experimentation.
356#[derive(Debug, Clone, Copy, PartialEq, Eq)]
357pub struct J2kPacketizationCodeBlock<'a> {
358 /// Encoded Tier-1 bitstream bytes for this packet contribution.
359 pub data: &'a [u8],
360 /// HTJ2K cleanup segment length in bytes when using high-throughput coding.
361 pub ht_cleanup_length: u32,
362 /// HTJ2K refinement segment length in bytes when using high-throughput coding.
363 pub ht_refinement_length: u32,
364 /// Number of coding passes in this contribution.
365 pub num_coding_passes: u8,
366 /// Number of zero most-significant bitplanes before first inclusion.
367 pub num_zero_bitplanes: u8,
368 /// Whether this code-block was included in a previous packet.
369 pub previously_included: bool,
370 /// L-block value used for segment length coding.
371 pub l_block: u32,
372 /// Block coder used for this contribution.
373 pub block_coding_mode: J2kPacketizationBlockCodingMode,
374}
375
376/// Adapter packetization block coding mode for backend experimentation.
377#[derive(Debug, Clone, Copy, PartialEq, Eq)]
378pub enum J2kPacketizationBlockCodingMode {
379 /// Classic JPEG 2000 Part 1 EBCOT block coding.
380 Classic,
381 /// High-throughput JPEG 2000 Part 15 block coding.
382 HighThroughput,
383}
384
385/// Adapter packet progression order for backend packetization experimentation.
386#[derive(Debug, Clone, Copy, PartialEq, Eq)]
387pub enum J2kPacketizationProgressionOrder {
388 /// Layer-resolution-component-position progression.
389 Lrcp,
390 /// Resolution-layer-component-position progression.
391 Rlcp,
392 /// Resolution-position-component-layer progression.
393 Rpcl,
394 /// Position-component-resolution-layer progression.
395 Pcrl,
396 /// Component-position-resolution-layer progression.
397 Cprl,
398}
399
400impl J2kPacketizationProgressionOrder {
401 /// Return the JPEG 2000 COD progression-order byte for this order.
402 pub const fn codestream_order_code(self) -> u8 {
403 match self {
404 Self::Lrcp => 0x00,
405 Self::Rlcp => 0x01,
406 Self::Rpcl => 0x02,
407 Self::Pcrl => 0x03,
408 Self::Cprl => 0x04,
409 }
410 }
411}
412
413/// Adapter LRCP packetization subband precinct for backend experimentation.
414#[derive(Debug, PartialEq, Eq)]
415pub struct J2kPacketizationSubband<'a> {
416 /// Code-block contributions in row-major order.
417 pub code_blocks: Vec<J2kPacketizationCodeBlock<'a>>,
418 /// Number of code-blocks in the x direction.
419 pub num_cbs_x: u32,
420 /// Number of code-blocks in the y direction.
421 pub num_cbs_y: u32,
422}
423
424/// Adapter LRCP packetization resolution packet for backend experimentation.
425#[derive(Debug, PartialEq, Eq)]
426pub struct J2kPacketizationResolution<'a> {
427 /// Subbands in packet order: LL for resolution 0, then HL/LH/HH.
428 pub subbands: Vec<J2kPacketizationSubband<'a>>,
429}
430
431/// Adapter explicit packet descriptor for backend packetization experimentation.
432#[derive(Debug, Clone, Copy, PartialEq, Eq)]
433pub struct J2kPacketizationPacketDescriptor {
434 /// Index into the packet contribution array.
435 pub packet_index: u32,
436 /// Persistent packet-state index for repeated layer/precinct packets.
437 pub state_index: u32,
438 /// Quality layer for inclusion tag-tree thresholds.
439 pub layer: u8,
440 /// Resolution index in the output progression.
441 pub resolution: u32,
442 /// Component index in the output progression.
443 pub component: u16,
444 /// Precinct index in the output progression.
445 pub precinct: u64,
446}
447
448/// Sort explicit packet descriptors according to a JPEG 2000 progression order.
449pub fn sort_packet_descriptors_for_progression(
450 descriptors: &mut [J2kPacketizationPacketDescriptor],
451 progression_order: J2kPacketizationProgressionOrder,
452) {
453 match progression_order {
454 J2kPacketizationProgressionOrder::Lrcp => descriptors.sort_by_key(|descriptor| {
455 (
456 descriptor.layer,
457 descriptor.resolution,
458 descriptor.component,
459 descriptor.precinct,
460 )
461 }),
462 J2kPacketizationProgressionOrder::Rlcp => descriptors.sort_by_key(|descriptor| {
463 (
464 descriptor.resolution,
465 descriptor.layer,
466 descriptor.component,
467 descriptor.precinct,
468 )
469 }),
470 J2kPacketizationProgressionOrder::Rpcl => descriptors.sort_by_key(|descriptor| {
471 (
472 descriptor.resolution,
473 descriptor.precinct,
474 descriptor.component,
475 descriptor.layer,
476 )
477 }),
478 J2kPacketizationProgressionOrder::Pcrl => descriptors.sort_by_key(|descriptor| {
479 (
480 descriptor.precinct,
481 descriptor.component,
482 descriptor.resolution,
483 descriptor.layer,
484 )
485 }),
486 J2kPacketizationProgressionOrder::Cprl => descriptors.sort_by_key(|descriptor| {
487 (
488 descriptor.component,
489 descriptor.precinct,
490 descriptor.resolution,
491 descriptor.layer,
492 )
493 }),
494 }
495}
496
497/// Adapter LRCP packetization job for backend experimentation.
498#[derive(Debug, Clone, Copy, PartialEq, Eq)]
499pub struct J2kPacketizationEncodeJob<'a> {
500 /// Number of resolution packets prepared for packetization.
501 pub resolution_count: u32,
502 /// Number of layers to write.
503 pub num_layers: u8,
504 /// Number of image components.
505 pub num_components: u16,
506 /// Total number of code-block contributions.
507 pub code_block_count: u32,
508 /// Packet progression order to emit.
509 pub progression_order: J2kPacketizationProgressionOrder,
510 /// Explicit packet descriptors in output progression order.
511 pub packet_descriptors: &'a [J2kPacketizationPacketDescriptor],
512 /// Packet payload prepared by Tier-1, in LRCP packet order.
513 pub resolutions: &'a [J2kPacketizationResolution<'a>],
514}
515
516#[cfg(test)]
517mod packet_order_tests {
518 use super::{
519 sort_packet_descriptors_for_progression, J2kPacketizationPacketDescriptor,
520 J2kPacketizationProgressionOrder,
521 };
522
523 fn descriptors() -> [J2kPacketizationPacketDescriptor; 3] {
524 [
525 J2kPacketizationPacketDescriptor {
526 packet_index: 0,
527 state_index: 0,
528 layer: 1,
529 resolution: 0,
530 component: 2,
531 precinct: 1,
532 },
533 J2kPacketizationPacketDescriptor {
534 packet_index: 1,
535 state_index: 1,
536 layer: 0,
537 resolution: 1,
538 component: 1,
539 precinct: 0,
540 },
541 J2kPacketizationPacketDescriptor {
542 packet_index: 2,
543 state_index: 2,
544 layer: 0,
545 resolution: 0,
546 component: 0,
547 precinct: 2,
548 },
549 ]
550 }
551
552 #[test]
553 fn progression_order_codes_match_codestream_values() {
554 assert_eq!(
555 J2kPacketizationProgressionOrder::Lrcp.codestream_order_code(),
556 0
557 );
558 assert_eq!(
559 J2kPacketizationProgressionOrder::Rlcp.codestream_order_code(),
560 1
561 );
562 assert_eq!(
563 J2kPacketizationProgressionOrder::Rpcl.codestream_order_code(),
564 2
565 );
566 assert_eq!(
567 J2kPacketizationProgressionOrder::Pcrl.codestream_order_code(),
568 3
569 );
570 assert_eq!(
571 J2kPacketizationProgressionOrder::Cprl.codestream_order_code(),
572 4
573 );
574 }
575
576 #[test]
577 fn packet_descriptor_sort_uses_requested_progression_order() {
578 let mut lrcp = descriptors();
579 sort_packet_descriptors_for_progression(&mut lrcp, J2kPacketizationProgressionOrder::Lrcp);
580 assert_eq!(lrcp.map(|descriptor| descriptor.packet_index), [2, 1, 0]);
581
582 let mut pcrl = descriptors();
583 sort_packet_descriptors_for_progression(&mut pcrl, J2kPacketizationProgressionOrder::Pcrl);
584 assert_eq!(pcrl.map(|descriptor| descriptor.packet_index), [1, 0, 2]);
585 }
586}
587
588/// Adapter encode-stage dispatch counters for backend experimentation.
589#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
590pub struct J2kEncodeDispatchReport {
591 /// Pixel deinterleave/level-shift dispatch count.
592 pub deinterleave: usize,
593 /// Forward RCT kernel dispatch count.
594 pub forward_rct: usize,
595 /// Forward ICT kernel dispatch count.
596 pub forward_ict: usize,
597 /// Forward reversible 5/3 DWT kernel dispatch count.
598 pub forward_dwt53: usize,
599 /// Forward irreversible 9/7 DWT kernel dispatch count.
600 pub forward_dwt97: usize,
601 /// Sub-band quantization dispatch count.
602 pub quantize_subband: usize,
603 /// Tier-1 code-block encode dispatch count.
604 pub tier1_code_block: usize,
605 /// HTJ2K code-block encode dispatch count.
606 pub ht_code_block: usize,
607 /// Packetization dispatch count.
608 pub packetization: usize,
609}
610
611impl J2kEncodeDispatchReport {
612 /// Return the saturating per-stage delta from `before` to `self`.
613 #[must_use]
614 pub fn saturating_delta(self, before: Self) -> Self {
615 Self {
616 deinterleave: self.deinterleave.saturating_sub(before.deinterleave),
617 forward_rct: self.forward_rct.saturating_sub(before.forward_rct),
618 forward_ict: self.forward_ict.saturating_sub(before.forward_ict),
619 forward_dwt53: self.forward_dwt53.saturating_sub(before.forward_dwt53),
620 forward_dwt97: self.forward_dwt97.saturating_sub(before.forward_dwt97),
621 quantize_subband: self
622 .quantize_subband
623 .saturating_sub(before.quantize_subband),
624 tier1_code_block: self
625 .tier1_code_block
626 .saturating_sub(before.tier1_code_block),
627 ht_code_block: self.ht_code_block.saturating_sub(before.ht_code_block),
628 packetization: self.packetization.saturating_sub(before.packetization),
629 }
630 }
631
632 /// Return total dispatches across all encode stages.
633 #[must_use]
634 pub fn total(self) -> usize {
635 self.forward_rct
636 .saturating_add(self.deinterleave)
637 .saturating_add(self.forward_ict)
638 .saturating_add(self.forward_dwt53)
639 .saturating_add(self.forward_dwt97)
640 .saturating_add(self.quantize_subband)
641 .saturating_add(self.tier1_code_block)
642 .saturating_add(self.ht_code_block)
643 .saturating_add(self.packetization)
644 }
645
646 /// Return whether at least one encode stage dispatched.
647 #[must_use]
648 pub fn any(self) -> bool {
649 self.total() > 0
650 }
651}
652
653/// Adapter CPU-only encode accelerator that always falls back to native stages.
654#[derive(Debug, Default, Clone, Copy)]
655pub struct CpuOnlyJ2kEncodeStageAccelerator;
656
657/// Adapter JPEG 2000 encode-stage accelerator for backend experimentation.
658pub trait J2kEncodeStageAccelerator {
659 /// Report cumulative backend dispatches completed by this accelerator.
660 fn dispatch_report(&self) -> J2kEncodeDispatchReport {
661 J2kEncodeDispatchReport::default()
662 }
663
664 /// Optionally deinterleave interleaved pixel bytes into f32 component planes.
665 ///
666 /// Return `Ok(Some(components))` with one plane per component. Return
667 /// `Ok(None)` to use the CPU fallback.
668 fn encode_deinterleave(
669 &mut self,
670 _job: J2kDeinterleaveToF32Job<'_>,
671 ) -> J2kEncodeStageResult<Option<Vec<Vec<f32>>>> {
672 Ok(None)
673 }
674
675 /// Optionally apply forward RCT in place.
676 ///
677 /// Return `Ok(true)` after writing transformed planes. Return `Ok(false)`
678 /// to use the CPU fallback.
679 fn encode_forward_rct(&mut self, _job: J2kForwardRctJob<'_>) -> J2kEncodeStageResult<bool> {
680 Ok(false)
681 }
682
683 /// Optionally apply forward ICT in place.
684 ///
685 /// Return `Ok(true)` after writing transformed planes. Return `Ok(false)`
686 /// to use the CPU fallback.
687 fn encode_forward_ict(&mut self, _job: J2kForwardIctJob<'_>) -> J2kEncodeStageResult<bool> {
688 Ok(false)
689 }
690
691 /// Optionally run a forward reversible 5/3 DWT.
692 ///
693 /// Return `Ok(Some(output))` with all subbands populated. Return
694 /// `Ok(None)` to use the CPU fallback.
695 fn encode_forward_dwt53(
696 &mut self,
697 _job: J2kForwardDwt53Job<'_>,
698 ) -> J2kEncodeStageResult<Option<J2kForwardDwt53Output>> {
699 Ok(None)
700 }
701
702 /// Optionally run a forward irreversible 9/7 DWT.
703 ///
704 /// Return `Ok(Some(output))` with all subbands populated. Return
705 /// `Ok(None)` to use the CPU fallback.
706 fn encode_forward_dwt97(
707 &mut self,
708 _job: J2kForwardDwt97Job<'_>,
709 ) -> J2kEncodeStageResult<Option<J2kForwardDwt97Output>> {
710 Ok(None)
711 }
712
713 /// Optionally quantize one sub-band.
714 ///
715 /// Return `Ok(Some(coefficients))` with one quantized coefficient for each
716 /// input coefficient. Return `Ok(None)` to use the CPU fallback.
717 fn encode_quantize_subband(
718 &mut self,
719 _job: J2kQuantizeSubbandJob<'_>,
720 ) -> J2kEncodeStageResult<Option<Vec<i32>>> {
721 Ok(None)
722 }
723
724 /// Optionally encode one classic Tier-1 code-block.
725 ///
726 /// Return `Ok(Some(output))` with encoded bytes and pass metadata. Return
727 /// `Ok(None)` to use the CPU fallback.
728 fn encode_tier1_code_block(
729 &mut self,
730 _job: J2kTier1CodeBlockEncodeJob<'_>,
731 ) -> J2kEncodeStageResult<Option<EncodedJ2kCodeBlock>> {
732 Ok(None)
733 }
734
735 /// Optionally encode multiple classic Tier-1 code-blocks in one backend dispatch.
736 ///
737 /// Return `Ok(Some(outputs))` with one encoded output per input job. Return
738 /// `Ok(None)` to use the per-block hook or CPU fallback.
739 fn encode_tier1_code_blocks(
740 &mut self,
741 _jobs: &[J2kTier1CodeBlockEncodeJob<'_>],
742 ) -> J2kEncodeStageResult<Option<Vec<EncodedJ2kCodeBlock>>> {
743 Ok(None)
744 }
745
746 /// Optionally encode one HTJ2K code-block.
747 ///
748 /// Return `Ok(Some(output))` with encoded bytes and pass metadata. Return
749 /// `Ok(None)` to use the CPU fallback.
750 fn encode_ht_code_block(
751 &mut self,
752 _job: J2kHtCodeBlockEncodeJob<'_>,
753 ) -> J2kEncodeStageResult<Option<EncodedHtJ2kCodeBlock>> {
754 Ok(None)
755 }
756
757 /// Optionally encode multiple HTJ2K code-blocks in one backend dispatch.
758 ///
759 /// Return `Ok(Some(outputs))` with one encoded output per input job. Return
760 /// `Ok(None)` to use the per-block hook or CPU fallback.
761 fn encode_ht_code_blocks(
762 &mut self,
763 _jobs: &[J2kHtCodeBlockEncodeJob<'_>],
764 ) -> J2kEncodeStageResult<Option<Vec<EncodedHtJ2kCodeBlock>>> {
765 Ok(None)
766 }
767
768 /// Optionally quantize and encode one HTJ2K cleanup/refinement sub-band.
769 ///
770 /// Return `Ok(Some(outputs))` with one encoded output per code block in
771 /// raster code-block order. Return `Ok(None)` to use the separate
772 /// quantization and code-block hooks or CPU fallback.
773 fn encode_ht_subband(
774 &mut self,
775 _job: J2kHtSubbandEncodeJob<'_>,
776 ) -> J2kEncodeStageResult<Option<Vec<EncodedHtJ2kCodeBlock>>> {
777 Ok(None)
778 }
779
780 /// Optionally encode the complete HTJ2K tile packet body.
781 ///
782 /// Return `Ok(Some(bytes))` with the complete tile bitstream body. CPU
783 /// marker/header writing remains outside this hook. Return `Ok(None)` to
784 /// use the normal staged encode pipeline.
785 fn encode_htj2k_tile(
786 &mut self,
787 _job: J2kHtj2kTileEncodeJob<'_>,
788 ) -> J2kEncodeStageResult<Option<Vec<u8>>> {
789 Ok(None)
790 }
791
792 /// Optionally encode a complete HTJ2K tile whose pixels remain backend-resident.
793 ///
794 /// Unlike [`Self::encode_htj2k_tile`], this hook has no host sample slice.
795 /// A resident-input facade must treat `Ok(None)` as a hard decline because
796 /// there are no host pixels from which to run the CPU fallback pipeline.
797 fn encode_resident_htj2k_tile(
798 &mut self,
799 _job: J2kResidentHtj2kTileEncodeJob<'_>,
800 ) -> J2kEncodeStageResult<Option<Vec<u8>>> {
801 Ok(None)
802 }
803
804 /// Return whether native CPU code-block fallback should use internal rayon parallelism.
805 ///
806 /// External accelerators keep serial per-block fallback so their hooks still
807 /// observe every fallback block after a declined batch hook.
808 fn prefer_parallel_cpu_code_block_fallback(&self) -> bool {
809 false
810 }
811
812 /// Return whether whole-tile CPU-only batch encode may be parallelized by callers.
813 ///
814 /// This is narrower than [`Self::prefer_parallel_cpu_code_block_fallback`]:
815 /// callers must only bypass the supplied accelerator when it is known to
816 /// have no observable hooks.
817 fn prefer_parallel_cpu_tile_encode(&self) -> bool {
818 false
819 }
820
821 /// Optionally packetize prepared packet contributions.
822 ///
823 /// Return `Ok(Some(bytes))` with the complete tile bitstream. Return
824 /// `Ok(None)` to use the CPU fallback.
825 fn encode_packetization(
826 &mut self,
827 _job: J2kPacketizationEncodeJob<'_>,
828 ) -> J2kEncodeStageResult<Option<Vec<u8>>> {
829 Ok(None)
830 }
831}
832
833#[doc(hidden)]
834impl J2kEncodeStageAccelerator for CpuOnlyJ2kEncodeStageAccelerator {
835 fn prefer_parallel_cpu_code_block_fallback(&self) -> bool {
836 true
837 }
838
839 fn prefer_parallel_cpu_tile_encode(&self) -> bool {
840 true
841 }
842}
843
844/// Multipliers applied to irreversible 9/7 quantization step sizes by subband.
845#[derive(Debug, Clone, Copy, PartialEq)]
846pub struct IrreversibleQuantizationSubbandScales {
847 /// Multiplier for the LL subband.
848 pub low_low: f32,
849 /// Multiplier for HL subbands.
850 pub high_low: f32,
851 /// Multiplier for LH subbands.
852 pub low_high: f32,
853 /// Multiplier for HH subbands.
854 pub high_high: f32,
855}
856
857/// Public JPEG 2000 irreversible quantization step-size tuple.
858#[derive(Debug, Clone, Copy, PartialEq, Eq)]
859pub struct IrreversibleQuantizationStep {
860 /// Quantization step-size exponent.
861 pub exponent: u8,
862 /// Quantization step-size mantissa.
863 pub mantissa: u16,
864}
865
866impl Default for IrreversibleQuantizationSubbandScales {
867 fn default() -> Self {
868 Self {
869 low_low: 1.0,
870 high_low: 1.0,
871 low_high: 1.0,
872 high_high: 1.0,
873 }
874 }
875}
876
877/// Precomputed reversible 5/3 wavelet coefficients for one component.
878#[derive(Debug)]
879pub struct PrecomputedHtj2k53Component {
880 /// Horizontal SIZ sampling factor (`XRsiz`).
881 pub x_rsiz: u8,
882 /// Vertical SIZ sampling factor (`YRsiz`).
883 pub y_rsiz: u8,
884 /// Forward 5/3 DWT output, ordered as the encoder expects.
885 pub dwt: J2kForwardDwt53Output,
886}
887
888/// Precomputed reversible 5/3 wavelet image.
889#[derive(Debug)]
890pub struct PrecomputedHtj2k53Image {
891 /// Reference-grid image width.
892 pub width: u32,
893 /// Reference-grid image height.
894 pub height: u32,
895 /// Component precision in bits.
896 pub bit_depth: u8,
897 /// Whether component samples are signed.
898 pub signed: bool,
899 /// Components at their native resolution.
900 pub components: Vec<PrecomputedHtj2k53Component>,
901}
902
903/// Precomputed irreversible 9/7 wavelet coefficients for one component.
904#[derive(Debug)]
905pub struct PrecomputedHtj2k97Component {
906 /// Horizontal SIZ sampling factor (`XRsiz`).
907 pub x_rsiz: u8,
908 /// Vertical SIZ sampling factor (`YRsiz`).
909 pub y_rsiz: u8,
910 /// Forward 9/7 DWT output, ordered as the encoder expects.
911 pub dwt: J2kForwardDwt97Output,
912}
913
914/// Precomputed irreversible 9/7 wavelet image.
915#[derive(Debug)]
916pub struct PrecomputedHtj2k97Image {
917 /// Reference-grid image width.
918 pub width: u32,
919 /// Reference-grid image height.
920 pub height: u32,
921 /// Component precision in bits.
922 pub bit_depth: u8,
923 /// Whether component samples are signed.
924 pub signed: bool,
925 /// Components at their native resolution.
926 pub components: Vec<PrecomputedHtj2k97Component>,
927}
928
929/// Prequantized irreversible 9/7 HTJ2K code-block image.
930#[derive(Debug)]
931pub struct PrequantizedHtj2k97Image {
932 /// Reference-grid image width.
933 pub width: u32,
934 /// Reference-grid image height.
935 pub height: u32,
936 /// Component precision in bits.
937 pub bit_depth: u8,
938 /// Whether component samples are signed.
939 pub signed: bool,
940 /// Components at their native resolution.
941 pub components: Vec<PrequantizedHtj2k97Component>,
942}
943
944/// Prequantized irreversible 9/7 HTJ2K component.
945#[derive(Debug)]
946pub struct PrequantizedHtj2k97Component {
947 /// Horizontal SIZ sampling factor (`XRsiz`).
948 pub x_rsiz: u8,
949 /// Vertical SIZ sampling factor (`YRsiz`).
950 pub y_rsiz: u8,
951 /// Resolution packets for this component, ordered from lowest to highest.
952 pub resolutions: Vec<PrequantizedHtj2k97Resolution>,
953}
954
955/// One component resolution's prequantized HTJ2K subbands.
956#[derive(Debug)]
957pub struct PrequantizedHtj2k97Resolution {
958 /// Subbands in packet order: LL for resolution 0, then HL/LH/HH.
959 pub subbands: Vec<PrequantizedHtj2k97Subband>,
960}
961
962/// One prequantized HTJ2K subband split into code-blocks.
963#[derive(Debug)]
964pub struct PrequantizedHtj2k97Subband {
965 /// Subband kind.
966 pub sub_band_type: J2kSubBandType,
967 /// Number of code-blocks in the x direction.
968 pub num_cbs_x: u32,
969 /// Number of code-blocks in the y direction.
970 pub num_cbs_y: u32,
971 /// Total bitplanes declared for every code-block in this subband.
972 pub total_bitplanes: u8,
973 /// Code-block coefficients in row-major code-block order.
974 pub code_blocks: Vec<PrequantizedHtj2k97CodeBlock>,
975}
976
977/// One prequantized HTJ2K code-block.
978#[derive(Debug)]
979pub struct PrequantizedHtj2k97CodeBlock {
980 /// Quantized coefficients in row-major order.
981 pub coefficients: Vec<i32>,
982 /// Code-block width in coefficients.
983 pub width: u32,
984 /// Code-block height in coefficients.
985 pub height: u32,
986}
987
988/// Preencoded irreversible 9/7 HTJ2K code-block image.
989#[derive(Debug)]
990pub struct PreencodedHtj2k97Image {
991 /// Reference-grid image width.
992 pub width: u32,
993 /// Reference-grid image height.
994 pub height: u32,
995 /// Component precision in bits.
996 pub bit_depth: u8,
997 /// Whether component samples are signed.
998 pub signed: bool,
999 /// Components at their native resolution.
1000 pub components: Vec<PreencodedHtj2k97Component>,
1001}
1002
1003/// Preencoded irreversible 9/7 HTJ2K component.
1004#[derive(Debug)]
1005pub struct PreencodedHtj2k97Component {
1006 /// Horizontal SIZ sampling factor (`XRsiz`).
1007 pub x_rsiz: u8,
1008 /// Vertical SIZ sampling factor (`YRsiz`).
1009 pub y_rsiz: u8,
1010 /// Resolution packets for this component, ordered from lowest to highest.
1011 pub resolutions: Vec<PreencodedHtj2k97Resolution>,
1012}
1013
1014/// One component resolution's preencoded HTJ2K subbands.
1015#[derive(Debug)]
1016pub struct PreencodedHtj2k97Resolution {
1017 /// Subbands in packet order: LL for resolution 0, then HL/LH/HH.
1018 pub subbands: Vec<PreencodedHtj2k97Subband>,
1019}
1020
1021/// One preencoded HTJ2K subband split into code-blocks.
1022#[derive(Debug)]
1023pub struct PreencodedHtj2k97Subband {
1024 /// Subband kind.
1025 pub sub_band_type: J2kSubBandType,
1026 /// Number of code-blocks in the x direction.
1027 pub num_cbs_x: u32,
1028 /// Number of code-blocks in the y direction.
1029 pub num_cbs_y: u32,
1030 /// Total bitplanes declared for every code-block in this subband.
1031 pub total_bitplanes: u8,
1032 /// Encoded code-block payloads in row-major code-block order.
1033 pub code_blocks: Vec<PreencodedHtj2k97CodeBlock>,
1034}
1035
1036/// One preencoded HTJ2K code-block.
1037#[derive(Debug)]
1038pub struct PreencodedHtj2k97CodeBlock {
1039 /// Code-block width in coefficients.
1040 pub width: u32,
1041 /// Code-block height in coefficients.
1042 pub height: u32,
1043 /// Encoded cleanup/refinement payload and packet metadata.
1044 pub encoded: EncodedHtJ2kCodeBlock,
1045}
1046
1047/// Preencoded irreversible 9/7 HTJ2K code-block image backed by one compact
1048/// payload buffer.
1049#[derive(Debug)]
1050pub struct PreencodedHtj2k97CompactImage {
1051 /// Reference-grid image width.
1052 pub width: u32,
1053 /// Reference-grid image height.
1054 pub height: u32,
1055 /// Component precision in bits.
1056 pub bit_depth: u8,
1057 /// Whether component samples are signed.
1058 pub signed: bool,
1059 /// Contiguous encoded code-block payload bytes.
1060 pub payload: Vec<u8>,
1061 /// Components at their native resolution.
1062 pub components: Vec<PreencodedHtj2k97CompactComponent>,
1063}
1064
1065/// Preencoded compact irreversible 9/7 HTJ2K component.
1066#[derive(Debug)]
1067pub struct PreencodedHtj2k97CompactComponent {
1068 /// Horizontal SIZ sampling factor (`XRsiz`).
1069 pub x_rsiz: u8,
1070 /// Vertical SIZ sampling factor (`YRsiz`).
1071 pub y_rsiz: u8,
1072 /// Resolution packets for this component, ordered from lowest to highest.
1073 pub resolutions: Vec<PreencodedHtj2k97CompactResolution>,
1074}
1075
1076/// One component resolution's compact preencoded HTJ2K subbands.
1077#[derive(Debug)]
1078pub struct PreencodedHtj2k97CompactResolution {
1079 /// Subbands in packet order: LL for resolution 0, then HL/LH/HH.
1080 pub subbands: Vec<PreencodedHtj2k97CompactSubband>,
1081}
1082
1083/// One compact preencoded HTJ2K subband split into code-blocks.
1084#[derive(Debug)]
1085pub struct PreencodedHtj2k97CompactSubband {
1086 /// Subband kind.
1087 pub sub_band_type: J2kSubBandType,
1088 /// Number of code-blocks in the x direction.
1089 pub num_cbs_x: u32,
1090 /// Number of code-blocks in the y direction.
1091 pub num_cbs_y: u32,
1092 /// Total bitplanes declared for every code-block in this subband.
1093 pub total_bitplanes: u8,
1094 /// Code-block metadata in row-major code-block order.
1095 pub code_blocks: Vec<PreencodedHtj2k97CompactCodeBlock>,
1096}
1097
1098/// One compact preencoded HTJ2K code-block.
1099#[derive(Debug)]
1100pub struct PreencodedHtj2k97CompactCodeBlock {
1101 /// Code-block width in coefficients.
1102 pub width: u32,
1103 /// Code-block height in coefficients.
1104 pub height: u32,
1105 /// Byte range into the image-level compact payload.
1106 pub payload_range: Range<usize>,
1107 /// HTJ2K cleanup segment length in bytes.
1108 pub cleanup_length: u32,
1109 /// HTJ2K refinement segment length in bytes.
1110 pub refinement_length: u32,
1111 /// Number of coding passes in the encoded payload.
1112 pub num_coding_passes: u8,
1113 /// Number of missing most-significant bitplanes.
1114 pub num_zero_bitplanes: u8,
1115}