Skip to main content

j2k_types/dispatch/
accelerator.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! Low-level encode-stage accelerator integration contract.
4
5use alloc::vec::Vec;
6
7use super::{J2kEncodeDispatchReport, J2kEncodeStageResult};
8use crate::{
9    EncodedHtJ2kCodeBlock, EncodedJ2kCodeBlock, J2kForwardDwt53Job, J2kForwardDwt53Output,
10    J2kForwardDwt97Job, J2kForwardDwt97Output, J2kForwardIctJob, J2kForwardRctJob,
11    J2kHtCodeBlockEncodeJob, J2kHtSubbandEncodeJob, J2kPacketizationEncodeJob,
12    J2kPacketizationProgressionOrder, J2kQuantizeSubbandJob, J2kResidentHtj2kTileEncodeJob,
13    J2kTier1CodeBlockEncodeJob,
14};
15
16/// Pixel deinterleave and level-shift job supplied to an accelerator.
17#[derive(Debug, Clone, Copy)]
18pub struct J2kDeinterleaveToF32Job<'a> {
19    /// Interleaved source pixel bytes.
20    pub pixels: &'a [u8],
21    /// Number of pixels to convert.
22    pub num_pixels: usize,
23    /// Number of interleaved components per pixel.
24    pub num_components: u16,
25    /// Source sample bit depth.
26    pub bit_depth: u8,
27    /// Whether source samples are signed.
28    pub signed: bool,
29}
30
31/// Combined pixel deinterleave, level-shift, and forward MCT job supplied to an accelerator.
32///
33/// The native encoder only offers this job for three-component inputs with MCT enabled.
34#[derive(Debug, Clone, Copy)]
35pub struct J2kDeinterleaveMctToF32Job<'a> {
36    /// Interleaved source pixel bytes.
37    pub pixels: &'a [u8],
38    /// Number of pixels to convert.
39    pub num_pixels: usize,
40    /// Source sample bit depth.
41    pub bit_depth: u8,
42    /// Whether source samples are signed.
43    pub signed: bool,
44    /// Whether to apply the reversible RCT (`true`) or irreversible ICT (`false`).
45    pub reversible: bool,
46}
47
48/// Validated image and coding context supplied before encode-stage dispatch.
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub struct J2kEncodeContext {
51    /// Number of pixels in the encoded image or tile.
52    pub num_pixels: usize,
53    /// Number of interleaved source components.
54    pub num_components: u16,
55    /// Source sample bit depth.
56    pub bit_depth: u8,
57    /// Whether source samples are signed.
58    pub signed: bool,
59    /// Whether the codestream uses reversible coding.
60    pub reversible: bool,
61}
62
63/// HTJ2K tile-body encode job for a backend-resident full-tile path.
64#[derive(Debug, Clone, Copy)]
65pub struct J2kHtj2kTileEncodeJob<'a> {
66    /// Interleaved source pixel bytes.
67    pub pixels: &'a [u8],
68    /// Tile/image width in samples.
69    pub width: u32,
70    /// Tile/image height in samples.
71    pub height: u32,
72    /// Number of interleaved image components.
73    pub num_components: u16,
74    /// Source component bit depth.
75    pub bit_depth: u8,
76    /// Whether source samples are signed.
77    pub signed: bool,
78    /// Number of DWT decomposition levels.
79    pub num_decomposition_levels: u8,
80    /// Whether the codestream uses reversible coding.
81    pub reversible: bool,
82    /// Whether a multi-component transform should be applied.
83    pub use_mct: bool,
84    /// JPEG 2000 guard bits used to derive total coded bitplanes.
85    pub guard_bits: u8,
86    /// Code-block width in samples.
87    pub code_block_width: u32,
88    /// Code-block height in samples.
89    pub code_block_height: u32,
90    /// Packet progression order to emit.
91    pub progression_order: J2kPacketizationProgressionOrder,
92    /// Per-component sampling factors, as `(x_rsiz, y_rsiz)`.
93    pub component_sampling: &'a [(u8, u8)],
94    /// Quantization step sizes, as `(exponent, mantissa)`, in codestream order.
95    pub quantization_steps: &'a [(u16, u16)],
96}
97
98/// CPU-only encode accelerator that always falls back to native stages.
99#[derive(Debug, Default, Clone, Copy)]
100pub struct CpuOnlyJ2kEncodeStageAccelerator;
101
102/// Low-level JPEG 2000 encode-stage accelerator integration contract.
103pub trait J2kEncodeStageAccelerator {
104    /// Supply validated context before any encode-stage hook is invoked.
105    fn begin_encode(&mut self, _context: J2kEncodeContext) -> J2kEncodeStageResult<()> {
106        Ok(())
107    }
108
109    /// Report cumulative backend dispatches completed by this accelerator.
110    fn dispatch_report(&self) -> J2kEncodeDispatchReport {
111        J2kEncodeDispatchReport::default()
112    }
113
114    /// Report the exact maximum cleanup magnitude from the latest fused HT subband encode.
115    fn ht_subband_maximum_cleanup_magnitude(&self) -> Option<u64> {
116        None
117    }
118
119    /// Report the exact Part 15 magnitude bound from the latest complete HT tile encode.
120    fn ht_tile_required_magnitude_bound(&self) -> Option<u8> {
121        None
122    }
123
124    /// Optionally deinterleave interleaved pixel bytes into f32 component planes.
125    fn encode_deinterleave(
126        &mut self,
127        _job: J2kDeinterleaveToF32Job<'_>,
128    ) -> J2kEncodeStageResult<Option<Vec<Vec<f32>>>> {
129        Ok(None)
130    }
131
132    /// Optionally combine three-component deinterleave, level shift, and forward MCT.
133    fn encode_deinterleave_mct(
134        &mut self,
135        _job: J2kDeinterleaveMctToF32Job<'_>,
136    ) -> J2kEncodeStageResult<Option<Vec<Vec<f32>>>> {
137        Ok(None)
138    }
139
140    /// Optionally apply forward RCT in place.
141    fn encode_forward_rct(&mut self, _job: J2kForwardRctJob<'_>) -> J2kEncodeStageResult<bool> {
142        Ok(false)
143    }
144
145    /// Optionally apply forward ICT in place.
146    fn encode_forward_ict(&mut self, _job: J2kForwardIctJob<'_>) -> J2kEncodeStageResult<bool> {
147        Ok(false)
148    }
149
150    /// Optionally run a forward reversible 5/3 DWT.
151    fn encode_forward_dwt53(
152        &mut self,
153        _job: J2kForwardDwt53Job<'_>,
154    ) -> J2kEncodeStageResult<Option<J2kForwardDwt53Output>> {
155        Ok(None)
156    }
157
158    /// Optionally run a forward irreversible 9/7 DWT.
159    fn encode_forward_dwt97(
160        &mut self,
161        _job: J2kForwardDwt97Job<'_>,
162    ) -> J2kEncodeStageResult<Option<J2kForwardDwt97Output>> {
163        Ok(None)
164    }
165
166    /// Optionally quantize one subband.
167    fn encode_quantize_subband(
168        &mut self,
169        _job: J2kQuantizeSubbandJob<'_>,
170    ) -> J2kEncodeStageResult<Option<Vec<i32>>> {
171        Ok(None)
172    }
173
174    /// Optionally encode one classic Tier-1 code block.
175    fn encode_tier1_code_block(
176        &mut self,
177        _job: J2kTier1CodeBlockEncodeJob<'_>,
178    ) -> J2kEncodeStageResult<Option<EncodedJ2kCodeBlock>> {
179        Ok(None)
180    }
181
182    /// Optionally encode multiple classic Tier-1 code blocks in one backend dispatch.
183    fn encode_tier1_code_blocks(
184        &mut self,
185        _jobs: &[J2kTier1CodeBlockEncodeJob<'_>],
186    ) -> J2kEncodeStageResult<Option<Vec<EncodedJ2kCodeBlock>>> {
187        Ok(None)
188    }
189
190    /// Optionally encode one HTJ2K code block.
191    fn encode_ht_code_block(
192        &mut self,
193        _job: J2kHtCodeBlockEncodeJob<'_>,
194    ) -> J2kEncodeStageResult<Option<EncodedHtJ2kCodeBlock>> {
195        Ok(None)
196    }
197
198    /// Optionally encode multiple HTJ2K code blocks in one backend dispatch.
199    fn encode_ht_code_blocks(
200        &mut self,
201        _jobs: &[J2kHtCodeBlockEncodeJob<'_>],
202    ) -> J2kEncodeStageResult<Option<Vec<EncodedHtJ2kCodeBlock>>> {
203        Ok(None)
204    }
205
206    /// Optionally quantize and encode one HTJ2K cleanup/refinement subband.
207    fn encode_ht_subband(
208        &mut self,
209        _job: J2kHtSubbandEncodeJob<'_>,
210    ) -> J2kEncodeStageResult<Option<Vec<EncodedHtJ2kCodeBlock>>> {
211        Ok(None)
212    }
213
214    /// Optionally encode the complete HTJ2K tile packet body.
215    fn encode_htj2k_tile(
216        &mut self,
217        _job: J2kHtj2kTileEncodeJob<'_>,
218    ) -> J2kEncodeStageResult<Option<Vec<u8>>> {
219        Ok(None)
220    }
221
222    /// Optionally encode a complete HTJ2K tile whose pixels remain backend-resident.
223    fn encode_resident_htj2k_tile(
224        &mut self,
225        _job: J2kResidentHtj2kTileEncodeJob<'_>,
226    ) -> J2kEncodeStageResult<Option<Vec<u8>>> {
227        Ok(None)
228    }
229
230    /// Return whether CPU code-block fallback should use internal rayon parallelism.
231    fn prefer_parallel_cpu_code_block_fallback(&self) -> bool {
232        false
233    }
234
235    /// Return whether callers may parallelize whole-tile CPU-only batch encode.
236    fn prefer_parallel_cpu_tile_encode(&self) -> bool {
237        false
238    }
239
240    /// Optionally packetize prepared packet contributions.
241    fn encode_packetization(
242        &mut self,
243        _job: J2kPacketizationEncodeJob<'_>,
244    ) -> J2kEncodeStageResult<Option<Vec<u8>>> {
245        Ok(None)
246    }
247}
248
249#[doc(hidden)]
250impl J2kEncodeStageAccelerator for CpuOnlyJ2kEncodeStageAccelerator {
251    fn prefer_parallel_cpu_code_block_fallback(&self) -> bool {
252        true
253    }
254
255    fn prefer_parallel_cpu_tile_encode(&self) -> bool {
256        true
257    }
258}