1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

use std::io::{BufRead, BufReader, Seek, SeekFrom};
use std::fs::File;
use std::path::Path;

mod riff;
pub mod bmp;
pub mod gif;
pub mod jpeg;
pub mod png;
pub mod webp;

use crate::errors::ImageError::InvalidSignature;
use crate::errors::{ImageError, ImageResult};
use crate::types::{Format, ImageMeta};



macro_rules! try_to_load {
    ($image_type:ident, $image:ident) => {
        match $image_type::load($image) {
            Ok(meta) => return Ok(meta),
            Err(InvalidSignature) => {
                $image.seek(SeekFrom::Start(0))?;
            },
            otherwise => return otherwise,
        }
    }
}

pub fn load<R: ?Sized + BufRead + Seek>(image: &mut R) -> ImageResult<ImageMeta> {
    try_to_load!(jpeg, image);
    try_to_load!(gif, image);
    try_to_load!(png, image);
    try_to_load!(bmp, image);
    try_to_load!(webp, image);
    Err(ImageError::Unsupported)
}

pub fn load_from_buf(buffer: &[u8]) -> ImageResult<ImageMeta> {
    let mut buffer = std::io::Cursor::new(buffer);
    load(&mut buffer)
}

pub fn load_from_file<T: ?Sized + AsRef<Path>>(file: &T) -> ImageResult<ImageMeta> {
    let file = File::open(file.as_ref())?;
    let mut file = BufReader::new(file);
    load(&mut file)
}

pub fn load_with_format<R: ?Sized + BufRead + Seek>(image: &mut R, format: Format) -> ImageResult<ImageMeta> {
    use Format::*;

    match format {
        Bmp => bmp::load(image),
        Gif => gif::load(image),
        Jpeg => jpeg::load(image),
        Png => png::load(image),
        Webp => webp::load(image),
    }
}