use super::{JpegPlanCacheError, SharedJpegFastPacket, SharedJpegInput};
use crate::adapter::device_plan::DeviceBatchSummary;
use crate::adapter::fast_packet::JpegFastPacketFamily;
use crate::ColorSpace;
#[derive(Clone, Debug)]
#[doc(hidden)]
pub enum JpegFastPacketState {
Unsupported,
Ready(SharedJpegFastPacket),
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct JpegCachedPlan {
input: SharedJpegInput,
summary: DeviceBatchSummary,
color_space: ColorSpace,
packet_state: JpegFastPacketState,
}
impl JpegCachedPlan {
pub fn try_new(
input: SharedJpegInput,
summary: DeviceBatchSummary,
color_space: ColorSpace,
packet_state: JpegFastPacketState,
) -> Result<Self, JpegPlanCacheError> {
let family_count = usize::from(summary.matches_fast_420)
+ usize::from(summary.matches_fast_422)
+ usize::from(summary.matches_fast_444);
match &packet_state {
JpegFastPacketState::Unsupported if family_count != 0 => {
return Err(JpegPlanCacheError::Invariant(
"unsupported JPEG packet has a fast-family device batch summary",
));
}
JpegFastPacketState::Ready(packet) => {
let (matches, color_matches) = match packet.as_packet().family() {
JpegFastPacketFamily::Fast420 => {
(summary.matches_fast_420, color_space == ColorSpace::YCbCr)
}
JpegFastPacketFamily::Fast422 => {
(summary.matches_fast_422, color_space == ColorSpace::YCbCr)
}
JpegFastPacketFamily::Fast444 => (
summary.matches_fast_444,
matches!(color_space, ColorSpace::YCbCr | ColorSpace::Rgb),
),
};
if family_count != 1 || !matches || !color_matches {
return Err(JpegPlanCacheError::Invariant(
"ready JPEG packet must match exactly one device family and color mode",
));
}
}
JpegFastPacketState::Unsupported => {}
}
Ok(Self {
input,
summary,
color_space,
packet_state,
})
}
#[must_use]
pub const fn input(&self) -> &SharedJpegInput {
&self.input
}
#[must_use]
pub const fn batch_summary(&self) -> DeviceBatchSummary {
self.summary
}
#[must_use]
pub const fn color_space(&self) -> ColorSpace {
self.color_space
}
#[must_use]
pub const fn packet_state(&self) -> &JpegFastPacketState {
&self.packet_state
}
#[must_use]
pub const fn fast_packet(&self) -> Option<&SharedJpegFastPacket> {
match &self.packet_state {
JpegFastPacketState::Unsupported => None,
JpegFastPacketState::Ready(packet) => Some(packet),
}
}
pub(super) fn retained_cache_bytes(&self) -> Result<usize, JpegPlanCacheError> {
let input_bytes = self.input.retained_cache_bytes()?;
let packet_bytes = match &self.packet_state {
JpegFastPacketState::Unsupported => 0,
JpegFastPacketState::Ready(packet) => packet.retained_cache_bytes()?,
};
input_bytes
.checked_add(packet_bytes)
.ok_or(JpegPlanCacheError::Invariant(
"cached JPEG plan retained-byte count overflow",
))
}
}