1use std::io;
2
3use io::Cursor;
4use io::Seek;
5use io::Write;
6
7use io::Read;
8
9use image::DynamicImage;
10use image::ImageFormat;
11
12pub struct Image {
13 pub img: DynamicImage,
14}
15
16impl Image {
17 pub fn to_writer<W>(&self, mut wtr: W) -> Result<W, io::Error>
18 where
19 W: Write + Seek,
20 {
21 let fmt: ImageFormat = ImageFormat::Png;
22 self.img.write_to(&mut wtr, fmt).map_err(io::Error::other)?;
23 wtr.flush()?;
24 Ok(wtr)
25 }
26}
27
28impl Image {
29 pub fn from_bytes(bytes: &[u8], ifmt: Option<ImageFormat>) -> Result<Self, io::Error> {
30 match ifmt {
31 None => image::load_from_memory(bytes),
32 Some(f) => image::load_from_memory_with_format(bytes, f),
33 }
34 .map_err(io::Error::other)
35 .map(|img| Self { img })
36 }
37}
38
39impl Image {
40 pub fn from_reader<R>(rdr: R, limit: u64, ifmt: Option<ImageFormat>) -> Result<Self, io::Error>
41 where
42 R: Read,
43 {
44 let mut taken = rdr.take(limit);
45 let mut buf: Vec<u8> = vec![];
46 taken.read_to_end(&mut buf)?;
47 Self::from_bytes(&buf, ifmt)
48 }
49}
50
51pub const INPUT_BYTES_MAX: u64 = 16777216;
52
53impl Image {
54 pub fn stdin2stdout(limit: u64, ifmt: Option<ImageFormat>) -> Result<(), io::Error> {
55 let img: Self = Self::from_reader(io::stdin().lock(), limit, ifmt)?;
56 let buf: Vec<u8> = vec![];
57 let cur = Cursor::new(buf);
58 let wtr: Cursor<_> = img.to_writer(cur)?;
59 let buf: Vec<u8> = wtr.into_inner();
60 let o = io::stdout();
61 let mut ol = o.lock();
62 ol.write_all(&buf)?;
63 ol.flush()
64 }
65
66 pub fn stdin2stdout_default() -> Result<(), io::Error> {
67 Self::stdin2stdout(INPUT_BYTES_MAX, None)
68 }
69}
70
71pub fn str2image_format(s: &str) -> Option<ImageFormat> {
72 ImageFormat::from_extension(s)
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_str2image_format() {
81 assert_eq!(str2image_format("png"), Some(ImageFormat::Png));
82 assert_eq!(str2image_format("jpeg"), Some(ImageFormat::Jpeg));
83 assert_eq!(str2image_format("jpg"), Some(ImageFormat::Jpeg)); assert_eq!(str2image_format("webp"), Some(ImageFormat::WebP));
85 assert_eq!(str2image_format("xyz"), None); assert_eq!(str2image_format(""), None); }
88}