use std::{
fs::File,
io::{BufReader, Cursor, Read, Seek},
path::Path,
};
use crate::{
buffer::Buffer,
color,
decoder::{self, Decoder},
error::{self, Error},
format::{self, Format},
pixel,
};
pub fn from<P, C, R>(mut input: R) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
R: Read + Seek,
{
let format = format::guess(input.by_ref()).ok_or(Error::Format("unsupported image format".into()))?;
with_format(input, format)
}
pub fn from_memory<P, C, R>(input: R) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
R: AsRef<[u8]>,
{
from(Cursor::new(input))
}
pub fn from_path<P, C, R>(path: R) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
R: AsRef<Path>,
{
from(BufReader::new(File::open(path)?))
}
pub fn with_format<P, C, R>(input: R, format: Format) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
R: Read + Seek,
{
match format {
#[cfg(feature = "png")]
Format::Png => png(input, |_| {}),
#[cfg(feature = "jpeg")]
Format::Jpeg => jpeg(input, |_| {}),
#[cfg(feature = "bmp")]
Format::Bmp => bmp(input, |_| {}),
#[cfg(feature = "tga")]
Format::Tga => tga(input, |_| {}),
#[cfg(feature = "gif")]
Format::Gif => gif(input, |_| {}),
#[cfg(feature = "xyz")]
Format::Xyz => xyz(input, |_| {}),
_ => Err(Error::Unsupported("unsupported image format".into())),
}
}
#[cfg(feature = "png")]
#[inline]
pub fn png<P, C, F, R>(input: R, func: F) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
F: FnOnce(&mut decoder::png::Decoder<R>),
R: Read,
{
let mut decoder = decoder::png::Decoder::new(input);
func(&mut decoder);
decoder.frame()
}
#[cfg(feature = "jpeg")]
#[inline]
pub fn jpeg<P, C, F, R>(input: R, func: F) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Luma>,
P: pixel::Write<C>,
C: pixel::Channel,
F: FnOnce(&mut decoder::jpeg::Decoder<R>),
R: Read,
{
let mut decoder = decoder::jpeg::Decoder::new(input);
func(&mut decoder);
decoder.frame()
}
#[cfg(feature = "bmp")]
#[inline]
pub fn bmp<P, C, F, R>(input: R, func: F) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba>,
P: pixel::Write<C>,
C: pixel::Channel,
F: FnOnce(&mut decoder::bmp::Decoder<R>),
R: Read + Seek,
{
let mut decoder = decoder::bmp::Decoder::new(input);
func(&mut decoder);
decoder.frame()
}
#[cfg(feature = "tga")]
#[inline]
pub fn tga<P, C, F, R>(input: R, func: F) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
F: FnOnce(&mut decoder::tga::Decoder<R>),
R: Read + Seek,
{
let mut decoder = decoder::tga::Decoder::new(input);
func(&mut decoder);
decoder.frame()
}
#[cfg(feature = "gif")]
#[inline]
pub fn gif<P, C, F, R>(input: R, func: F) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba> + From<color::Luma> + From<color::Lumaa>,
P: pixel::Write<C>,
C: pixel::Channel,
F: FnOnce(&mut decoder::gif::Decoder<R>),
R: Read,
{
let mut decoder = decoder::gif::Decoder::new(input);
func(&mut decoder);
decoder.frame()
}
#[cfg(feature = "xyz")]
#[inline]
pub fn xyz<P, C, F, R>(input: R, func: F) -> error::Result<Buffer<P, C, Vec<C>>>
where
P: From<color::Rgb> + From<color::Rgba>,
P: pixel::Write<C>,
C: pixel::Channel,
F: FnOnce(&mut decoder::xyz::Decoder<R>),
R: Read,
{
let mut decoder = decoder::xyz::Decoder::new(input);
func(&mut decoder);
decoder.frame()
}