use super::{
EncodedImageError, EncodedImageView, RawImageView, RawImageViewError, SurfaceDescriptor,
SurfaceView,
};
use crate::media::{MediaPayload, MediaPayloadError, MediaSectionKind};
use crate::palette::ColorTableView;
#[cfg(test)]
mod tests;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ImageRef<'a> {
Raw(SurfaceView<'a>),
Encoded(EncodedImageView<'a>),
}
impl<'a> ImageRef<'a> {
pub fn open(payload: &'a [u8]) -> Result<Self, ImageReadError> {
Self::from_payload(payload, None)
}
pub fn open_at(payload: &'a [u8], file_offset: u32) -> Result<Self, ImageReadError> {
Self::from_payload(payload, Some(file_offset))
}
pub const fn surface(self) -> SurfaceDescriptor {
match self {
Self::Raw(image) => image.surface(),
Self::Encoded(image) => image.surface(),
}
}
pub const fn color_table(self) -> Option<ColorTableView<'a>> {
match self {
Self::Raw(image) => image.color_table(),
Self::Encoded(image) => image.color_table(),
}
}
pub const fn raw(self) -> Option<SurfaceView<'a>> {
match self {
Self::Raw(image) => Some(image),
Self::Encoded(_) => None,
}
}
pub const fn encoded(self) -> Option<EncodedImageView<'a>> {
match self {
Self::Raw(_) => None,
Self::Encoded(image) => Some(image),
}
}
fn from_payload(payload: &'a [u8], file_offset: Option<u32>) -> Result<Self, ImageReadError> {
let media = MediaPayload::open(payload).map_err(ImageReadError::Media)?;
if media.section(MediaSectionKind::CODINGS).is_some() {
EncodedImageView::from_media(media, file_offset)
.map(Self::Encoded)
.map_err(ImageReadError::Encoded)
} else {
RawImageView::from_media(media, file_offset)
.map(|image| Self::Raw(image.view()))
.map_err(ImageReadError::Raw)
}
}
}
impl<'a> From<SurfaceView<'a>> for ImageRef<'a> {
fn from(image: SurfaceView<'a>) -> Self {
Self::Raw(image)
}
}
impl<'a> From<EncodedImageView<'a>> for ImageRef<'a> {
fn from(image: EncodedImageView<'a>) -> Self {
Self::Encoded(image)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ImageReadError {
Media(MediaPayloadError),
Raw(RawImageViewError),
Encoded(EncodedImageError),
}