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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use std::io;

use ffimage::color::{Bgra, Rgb, Rgba};
use ffimage::core::{Pixel, TryConvert};
use ffimage::packed::{DynamicImageBuffer, DynamicImageView, GenericImageBuffer, GenericImageView};

use crate::format::PixelFormat;

fn _convert<DP: Pixel + From<Rgb<u8>>>(
    src: &DynamicImageView,
    dst: &mut GenericImageBuffer<DP>,
) -> io::Result<()> {
    let data = src.raw().as_slice();
    if data.is_none() {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "failed to get raw [u8] data",
        ));
    }
    let data = data.unwrap();

    let rgb = GenericImageView::<Rgb<u8>>::new(data, src.width(), src.height());
    if rgb.is_none() {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "failed to create RGB view",
        ));
    }
    let rgb = rgb.unwrap();

    let res = rgb.try_convert(dst);
    if res.is_err() {
        return Err(io::Error::new(
            io::ErrorKind::Other,
            "failed to convert RGB",
        ));
    }

    Ok(())
}

pub fn convert_to_rgba(src: &DynamicImageView, dst: &mut DynamicImageBuffer) -> io::Result<()> {
    let mut rgba = GenericImageBuffer::<Rgba<u8>>::new(src.width(), src.height());
    let res = _convert(src, &mut rgba);
    if res.is_err() {
        return Err(io::Error::new(
            io::ErrorKind::Other,
            "failed to convert RGB to RGBA",
        ));
    }

    *dst = DynamicImageBuffer::from_raw(src.width(), src.height(), rgba.into()).unwrap();
    Ok(())
}

pub fn convert_to_bgra(src: &DynamicImageView, dst: &mut DynamicImageBuffer) -> io::Result<()> {
    let mut bgra = GenericImageBuffer::<Bgra<u8>>::new(src.width(), src.height());
    let res = _convert(src, &mut bgra);
    if res.is_err() {
        return Err(io::Error::new(
            io::ErrorKind::Other,
            "failed to convert RGB to BGRA",
        ));
    }

    *dst = DynamicImageBuffer::from_raw(src.width(), src.height(), bgra.into()).unwrap();
    Ok(())
}

pub fn convert(
    src: &DynamicImageView,
    dst: &mut DynamicImageBuffer,
    dst_fmt: PixelFormat,
) -> io::Result<()> {
    match dst_fmt {
        PixelFormat::Bgra(32) => return convert_to_bgra(src, dst),
        PixelFormat::Rgba(32) => return convert_to_rgba(src, dst),
        _ => {}
    }

    Err(io::Error::new(
        io::ErrorKind::InvalidInput,
        "cannot handle target format",
    ))
}