use crate::{
allocation::HostPhaseBudget,
error::CudaError,
execution::CudaExecutionStats,
htj2k_encode::{
htj2k_encoded_cleanup_length, htj2k_encoded_num_coding_passes,
htj2k_encoded_num_zero_bitplanes, htj2k_encoded_refinement_length,
CudaHtj2kEncodeStageTimings, CudaHtj2kEncodeStatus, CudaHtj2kEncodedCodeBlock,
CudaHtj2kEncodedCodeBlocks,
},
};
#[doc(hidden)]
#[derive(Debug)]
pub struct CudaHtj2kCompactEncodedCodeBlock {
pub(crate) payload_range: std::ops::Range<usize>,
pub(crate) status: CudaHtj2kEncodeStatus,
pub(crate) execution: CudaExecutionStats,
pub(crate) stage_timings: CudaHtj2kEncodeStageTimings,
}
impl CudaHtj2kCompactEncodedCodeBlock {
pub fn payload_range(&self) -> std::ops::Range<usize> {
self.payload_range.clone()
}
impl_cuda_htj2k_encoded_status_accessors!();
pub fn into_parts(self) -> (std::ops::Range<usize>, u32, u32, u8, u8) {
(
self.payload_range,
htj2k_encoded_cleanup_length(self.status),
htj2k_encoded_refinement_length(self.status),
htj2k_encoded_num_coding_passes(self.status),
htj2k_encoded_num_zero_bitplanes(self.status),
)
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct CudaHtj2kCompactEncodedCodeBlocks {
pub(crate) payload: Vec<u8>,
pub(crate) code_blocks: Vec<CudaHtj2kCompactEncodedCodeBlock>,
pub(crate) execution: CudaExecutionStats,
pub(crate) stage_timings: CudaHtj2kEncodeStageTimings,
}
impl CudaHtj2kCompactEncodedCodeBlocks {
pub fn payload(&self) -> &[u8] {
&self.payload
}
pub fn code_blocks(&self) -> &[CudaHtj2kCompactEncodedCodeBlock] {
&self.code_blocks
}
pub fn into_payload_and_code_blocks(self) -> (Vec<u8>, Vec<CudaHtj2kCompactEncodedCodeBlock>) {
(self.payload, self.code_blocks)
}
pub fn execution(&self) -> CudaExecutionStats {
self.execution
}
pub fn stage_timings(&self) -> CudaHtj2kEncodeStageTimings {
self.stage_timings
}
pub(crate) fn into_owned_code_blocks_with_live_host_bytes(
self,
live_host_bytes: usize,
) -> Result<CudaHtj2kEncodedCodeBlocks, CudaError> {
let Self {
payload,
code_blocks,
execution,
stage_timings,
} = self;
let mut host_budget = HostPhaseBudget::with_live_bytes(
"CUDA compact HTJ2K code-block expansion",
live_host_bytes,
)?;
host_budget.account_vec(&payload)?;
host_budget.account_vec(&code_blocks)?;
let mut owned_code_blocks = host_budget.try_vec_with_capacity(code_blocks.len())?;
for block in code_blocks {
let CudaHtj2kCompactEncodedCodeBlock {
payload_range,
status,
execution,
stage_timings,
} = block;
if payload_range.start > payload_range.end || payload_range.end > payload.len() {
return Err(CudaError::LengthTooLarge {
len: payload_range.end,
});
}
let data = host_budget.try_vec_from_slice(&payload[payload_range])?;
owned_code_blocks.push(CudaHtj2kEncodedCodeBlock {
data,
status,
execution,
stage_timings,
});
}
Ok(CudaHtj2kEncodedCodeBlocks {
code_blocks: owned_code_blocks,
execution,
stage_timings,
})
}
}
pub(crate) const HTJ2K_UVLC_ENCODE_TABLE_BYTES: usize = 75 * 6;