mod accounting;
use alloc::sync::Arc;
use super::shared_allocation::{checked_live_bytes, shared_owner_bytes};
use super::JpegPlanCacheError;
use crate::adapter::fast_packet::{
JpegFast420PacketV1, JpegFast422PacketV1, JpegFast444PacketV1, JpegFastPacketFamily,
};
use accounting::color_packet_capacity_bytes;
#[derive(Debug)]
#[doc(hidden)]
pub enum JpegFastPacket {
Fast420(JpegFast420PacketV1),
Fast422(JpegFast422PacketV1),
Fast444(JpegFast444PacketV1),
}
impl JpegFastPacket {
#[must_use]
pub const fn family(&self) -> JpegFastPacketFamily {
match self {
Self::Fast420(_) => JpegFastPacketFamily::Fast420,
Self::Fast422(_) => JpegFastPacketFamily::Fast422,
Self::Fast444(_) => JpegFastPacketFamily::Fast444,
}
}
#[must_use]
pub const fn fast420(&self) -> Option<&JpegFast420PacketV1> {
match self {
Self::Fast420(packet) => Some(packet),
Self::Fast422(_) | Self::Fast444(_) => None,
}
}
#[must_use]
pub const fn fast422(&self) -> Option<&JpegFast422PacketV1> {
match self {
Self::Fast422(packet) => Some(packet),
Self::Fast420(_) | Self::Fast444(_) => None,
}
}
#[must_use]
pub const fn fast444(&self) -> Option<&JpegFast444PacketV1> {
match self {
Self::Fast444(packet) => Some(packet),
Self::Fast420(_) | Self::Fast422(_) => None,
}
}
fn nested_capacity_bytes(&self) -> Result<usize, JpegPlanCacheError> {
match self {
Self::Fast420(packet) => color_packet_capacity_bytes(
&packet.restart_offsets,
&packet.entropy_checkpoints,
&packet.entropy_bytes,
),
Self::Fast422(packet) => color_packet_capacity_bytes(
&packet.restart_offsets,
&packet.entropy_checkpoints,
&packet.entropy_bytes,
),
Self::Fast444(packet) => color_packet_capacity_bytes(
&packet.restart_offsets,
&packet.entropy_checkpoints,
&packet.entropy_bytes,
),
}
}
}
impl From<JpegFast420PacketV1> for JpegFastPacket {
fn from(packet: JpegFast420PacketV1) -> Self {
Self::Fast420(packet)
}
}
impl From<JpegFast422PacketV1> for JpegFastPacket {
fn from(packet: JpegFast422PacketV1) -> Self {
Self::Fast422(packet)
}
}
impl From<JpegFast444PacketV1> for JpegFastPacket {
fn from(packet: JpegFast444PacketV1) -> Self {
Self::Fast444(packet)
}
}
#[derive(Clone)]
#[doc(hidden)]
pub struct SharedJpegFastPacket(Arc<JpegFastPacket>);
impl SharedJpegFastPacket {
pub fn try_new(packet: JpegFastPacket) -> Result<Self, JpegPlanCacheError> {
Self::try_new_with_external_live(packet, 0)
}
#[doc(hidden)]
pub fn try_new_with_external_live(
packet: JpegFastPacket,
external_live_bytes: usize,
) -> Result<Self, JpegPlanCacheError> {
Self::try_new_with_external_live_and_cap(
packet,
external_live_bytes,
j2k_core::DEFAULT_MAX_HOST_ALLOCATION_BYTES,
)
}
fn try_new_with_external_live_and_cap(
packet: JpegFastPacket,
external_live_bytes: usize,
cap: usize,
) -> Result<Self, JpegPlanCacheError> {
checked_live_bytes(
"shared JPEG fast-packet owner graph",
external_live_bytes,
shared_owner_bytes::<JpegFastPacket>(packet.nested_capacity_bytes()?)?,
cap,
)?;
Ok(Self(Arc::new(packet)))
}
#[cfg(test)]
pub(in crate::adapter::fast_packet::cache) fn try_new_with_cap_for_test(
packet: JpegFastPacket,
external_live_bytes: usize,
cap: usize,
) -> Result<Self, JpegPlanCacheError> {
Self::try_new_with_external_live_and_cap(packet, external_live_bytes, cap)
}
#[must_use]
pub fn as_packet(&self) -> &JpegFastPacket {
self.0.as_ref()
}
#[must_use]
pub fn fast420(&self) -> Option<&JpegFast420PacketV1> {
self.as_packet().fast420()
}
#[must_use]
pub fn fast422(&self) -> Option<&JpegFast422PacketV1> {
self.as_packet().fast422()
}
#[must_use]
pub fn fast444(&self) -> Option<&JpegFast444PacketV1> {
self.as_packet().fast444()
}
#[must_use]
pub fn ptr_eq(left: &Self, right: &Self) -> bool {
Arc::ptr_eq(&left.0, &right.0)
}
pub fn retained_cache_bytes(&self) -> Result<usize, JpegPlanCacheError> {
shared_owner_bytes::<JpegFastPacket>(self.0.nested_capacity_bytes()?)
}
}
impl core::fmt::Debug for SharedJpegFastPacket {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
formatter
.debug_struct("SharedJpegFastPacket")
.field("family", &self.as_packet().family())
.finish_non_exhaustive()
}
}