use super::*;
#[derive(Clone, Debug)]
pub enum DecodedImage {
RGBA(ImageRGBA),
RGB(ImageRGB),
Grey(Image<u8>),
GreyAlpha(Image<[u8; 2]>),
Indexed {
image: Image<u8>,
palette: Vec<[u8; 3]>,
}
}
impl From<ImageRGBA> for DecodedImage {
#[inline]
fn from(image: ImageRGBA) -> Self {
DecodedImage::RGBA(image)
}
}
impl From<ImageRGB> for DecodedImage {
#[inline]
fn from(image: ImageRGB) -> Self {
DecodedImage::RGB(image)
}
}
impl From<Image<u8>> for DecodedImage {
#[inline]
fn from(image: Image<u8>) -> Self {
DecodedImage::Grey(image)
}
}
impl From<Image<[u8; 2]>> for DecodedImage {
#[inline]
fn from(image: Image<[u8; 2]>) -> Self {
DecodedImage::GreyAlpha(image)
}
}
impl DecodedImage {
#[inline]
pub fn rgba(self) -> Option<ImageRGBA> {
match self {
DecodedImage::RGBA(image) => Some(image),
_ => None,
}
}
#[inline]
pub fn rgb(self) -> Option<ImageRGB> {
match self {
DecodedImage::RGB(image) => Some(image),
_ => None,
}
}
#[inline]
pub fn grey(self) -> Option<Image<u8>> {
match self {
DecodedImage::Grey(image) => Some(image),
_ => None,
}
}
#[inline]
pub fn grey_alpha(self) -> Option<Image<[u8; 2]>> {
match self {
DecodedImage::GreyAlpha(image) => Some(image),
_ => None,
}
}
#[inline]
pub fn indexed(self) -> Option<(Image<u8>, Vec<[u8; 3]>)> {
match self {
DecodedImage::Indexed { image, palette } => Some((image, palette)),
_ => None,
}
}
}
impl DecodedImage {
#[inline]
pub fn width(&self) -> i32 {
match self {
DecodedImage::RGBA(image) => image.width,
DecodedImage::RGB(image) => image.width,
DecodedImage::Grey(image) => image.width,
DecodedImage::GreyAlpha(image) => image.width,
DecodedImage::Indexed { image, .. } => image.width,
}
}
#[inline]
pub fn height(&self) -> i32 {
match self {
DecodedImage::RGBA(image) => image.height,
DecodedImage::RGB(image) => image.height,
DecodedImage::Grey(image) => image.height,
DecodedImage::GreyAlpha(image) => image.height,
DecodedImage::Indexed { image, .. } => image.height,
}
}
pub fn to_rgba(self) -> ImageRGBA {
match self {
DecodedImage::RGBA(image) => image,
DecodedImage::RGB(image) => image.map_colors(|[r, g, b]| [r, g, b, 255]),
DecodedImage::Grey(image) => image.map_colors(|v| [v, v, v, 255]),
DecodedImage::GreyAlpha(image) => image.map_colors(|[v, a]| [v, v, v, a]),
DecodedImage::Indexed { image, palette } => image.map_colors(|index| {
let [r, g, b] = palette[index as usize];
[r, g, b, 255]
}),
}
}
pub fn to_rgb(self) -> ImageRGB {
match self {
DecodedImage::RGBA(image) => image.map_colors(|[r, g, b, _a]| [r, g, b]),
DecodedImage::RGB(image) => image,
DecodedImage::Grey(image) => image.map_colors(|v| [v, v, v]),
DecodedImage::GreyAlpha(image) => image.map_colors(|[v, _a]| [v, v, v]),
DecodedImage::Indexed { image, palette } => image.map_colors(|index| palette[index as usize]),
}
}
}
impl From<DecodedImage> for ImageRGBA {
#[inline]
fn from(img: DecodedImage) -> Self {
img.to_rgba()
}
}
impl From<DecodedImage> for ImageRGB {
#[inline]
fn from(img: DecodedImage) -> Self {
img.to_rgb()
}
}
fn load_file(path: &path::Path) -> Result<DecodedImage, LoadImageError> {
#![allow(unused_variables)]
let ext = path.extension().and_then(|s| s.to_str());
#[cfg(feature = "png")]
if ext == Some("png") {
return DecodedImage::load_file_png(path).map_err(Into::into);
}
#[cfg(feature = "gif")]
if ext == Some("gif") {
return DecodedImage::load_file_gif(path).map_err(Into::into);
}
#[cfg(feature = "jpeg")]
if ext == Some("jpg") || ext == Some("jpeg") {
return DecodedImage::load_file_jpeg(path).map_err(Into::into);
}
Err(LoadImageError::UnsupportedFormat)
}
fn load_memory(data: &[u8]) -> Result<DecodedImage, LoadImageError> {
#![allow(unused_variables)]
#[cfg(feature = "png")]
if data.starts_with(io::png::PNG_SIGNATURE) {
return DecodedImage::load_memory_png(data).map_err(Into::into);
}
#[cfg(feature = "gif")]
if data.starts_with(io::gif::GIF_SIGNATURE_87A) || data.starts_with(io::gif::GIF_SIGNATURE_89A) {
return DecodedImage::load_memory_gif(data).map_err(Into::into);
}
#[cfg(feature = "jpeg")]
if data.starts_with(io::jpeg::JPEG_SIGNATURE) {
return DecodedImage::load_memory_jpeg(data).map_err(Into::into);
}
Err(LoadImageError::UnsupportedFormat)
}
impl DecodedImage {
#[inline]
pub fn load_file(path: impl AsRef<path::Path>) -> Result<Self, LoadImageError> {
load_file(path.as_ref())
}
#[inline]
pub fn load_memory(data: &[u8]) -> Result<Self, LoadImageError> {
load_memory(data)
}
}