use alloc::sync::Arc;
use core::any::Any;
pub use j2k_types::{
HtCodeBlockPayloadRanges as Htj2kPayloadRanges,
J2kClassicCodeBlockPayload as ClassicCodeBlockPayload, J2kCodestreamRange,
};
#[derive(Debug, Clone)]
pub struct PreparedClassicPlan {
plan: Arc<j2k_native::J2kReferencedClassicPlan>,
}
impl PreparedClassicPlan {
pub(super) fn from_native(plan: j2k_native::J2kReferencedClassicPlan) -> Self {
Self {
plan: Arc::new(plan),
}
}
pub(crate) fn native_plan(&self) -> &j2k_native::J2kReferencedClassicPlan {
&self.plan
}
#[must_use]
pub fn is_grayscale(&self) -> bool {
!self.plan.tiles().is_empty()
&& self
.plan
.tiles()
.iter()
.all(|tile| tile.grayscale_geometry().is_some())
}
#[must_use]
pub fn is_color(&self) -> bool {
!self.plan.tiles().is_empty()
&& self
.plan
.tiles()
.iter()
.all(|tile| tile.color_geometry().is_some())
}
#[must_use]
pub fn is_rgba(&self) -> bool {
!self.plan.tiles().is_empty()
&& self
.plan
.tiles()
.iter()
.all(|tile| tile.rgba_geometry().is_some())
}
#[must_use]
pub fn payload_count(&self) -> usize {
self.plan.payloads().len()
}
#[must_use]
pub fn range_count(&self) -> usize {
self.plan.ranges().len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.plan.payloads().is_empty()
}
pub(super) fn uniform_wavelet_transform(&self) -> Option<j2k_native::J2kWaveletTransform> {
uniform_wavelet_transform(self.plan.tiles())
}
#[must_use]
pub fn payload(&self, index: usize) -> Option<ClassicCodeBlockPayload> {
self.plan.payloads().get(index).copied()
}
pub fn payloads(&self) -> impl ExactSizeIterator<Item = ClassicCodeBlockPayload> + '_ {
self.plan.payloads().iter().copied()
}
#[must_use]
pub fn range(&self, index: usize) -> Option<J2kCodestreamRange> {
self.plan.ranges().get(index).copied()
}
pub fn ranges(&self) -> impl ExactSizeIterator<Item = J2kCodestreamRange> + '_ {
self.plan.ranges().iter().copied()
}
#[doc(hidden)]
#[must_use]
pub fn adapter_view(&self) -> &(dyn Any + Send + Sync) {
self.plan.as_ref()
}
}
#[derive(Debug, Clone)]
pub struct PreparedHtj2kPlan {
plan: Arc<j2k_native::J2kReferencedHtj2kPlan>,
}
impl PreparedHtj2kPlan {
pub(super) fn from_native(plan: j2k_native::J2kReferencedHtj2kPlan) -> Self {
Self {
plan: Arc::new(plan),
}
}
pub(crate) fn native_plan(&self) -> &j2k_native::J2kReferencedHtj2kPlan {
&self.plan
}
#[must_use]
pub fn is_grayscale(&self) -> bool {
!self.plan.tiles().is_empty()
&& self
.plan
.tiles()
.iter()
.all(|tile| tile.grayscale_geometry().is_some())
}
#[must_use]
pub fn is_color(&self) -> bool {
!self.plan.tiles().is_empty()
&& self
.plan
.tiles()
.iter()
.all(|tile| tile.color_geometry().is_some())
}
#[must_use]
pub fn is_rgba(&self) -> bool {
!self.plan.tiles().is_empty()
&& self
.plan
.tiles()
.iter()
.all(|tile| tile.rgba_geometry().is_some())
}
#[must_use]
pub fn payload_count(&self) -> usize {
self.plan.payloads().len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.plan.payloads().is_empty()
}
pub(super) fn uniform_wavelet_transform(&self) -> Option<j2k_native::J2kWaveletTransform> {
uniform_wavelet_transform(self.plan.tiles())
}
#[must_use]
pub fn payload(&self, index: usize) -> Option<Htj2kPayloadRanges> {
self.plan.payloads().get(index).copied()
}
pub fn payloads(&self) -> impl ExactSizeIterator<Item = Htj2kPayloadRanges> + '_ {
self.plan.payloads().iter().copied()
}
#[doc(hidden)]
#[must_use]
pub fn adapter_view(&self) -> &(dyn Any + Send + Sync) {
self.plan.as_ref()
}
}
fn uniform_wavelet_transform(
tiles: &[j2k_native::J2kReferencedTilePlan],
) -> Option<j2k_native::J2kWaveletTransform> {
let first = tiles.first()?.wavelet_transform();
tiles
.iter()
.all(|tile| tile.wavelet_transform() == first)
.then_some(first)
}