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 png;
use std::io::{self, Read, Write};
use image::{Image, PixelFormat};
impl Image {
pub fn read_png<R: Read>(input: R) -> io::Result<Image> {
let decoder = png::Decoder::new(input);
let (info, mut reader) = decoder.read_info()?;
let pixel_format = match info.color_type {
png::ColorType::RGBA => PixelFormat::RGBA,
png::ColorType::RGB => PixelFormat::RGB,
png::ColorType::GrayscaleAlpha => PixelFormat::GrayAlpha,
png::ColorType::Grayscale => PixelFormat::Gray,
_ => {
return Err(io::Error::new(io::ErrorKind::InvalidData,
format!("unsupported PNG color \
type: {:?}",
info.color_type)));
}
};
if info.bit_depth != png::BitDepth::Eight {
return Err(io::Error::new(io::ErrorKind::InvalidData,
format!("unsupported PNG bit depth: \
{:?}",
info.bit_depth)));
}
let mut image = Image::new(pixel_format, info.width, info.height);
assert_eq!(image.data().len(), info.buffer_size());
reader.next_frame(image.data_mut())?;
Ok(image)
}
pub fn write_png<W: Write>(&self, output: W) -> io::Result<()> {
let color_type = match self.format {
PixelFormat::RGBA => png::ColorType::RGBA,
PixelFormat::RGB => png::ColorType::RGB,
PixelFormat::GrayAlpha => png::ColorType::GrayscaleAlpha,
PixelFormat::Gray => png::ColorType::Grayscale,
PixelFormat::Alpha => {
return self.convert_to(PixelFormat::GrayAlpha)
.write_png(output);
}
};
let mut encoder = png::Encoder::new(output, self.width, self.height);
encoder.set_color(color_type);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header()?;
writer.write_image_data(&self.data).map_err(|err| match err {
png::EncodingError::IoError(err) => err,
png::EncodingError::Format(msg) => {
io::Error::new(io::ErrorKind::InvalidData, msg.into_owned())
}
})
}
}