use std::path::Path;
use std::fs::File;
use std::io::BufWriter;
use gif;
use png;
use error::{RasterError, RasterResult};
use Image;
use ImageFormat;
pub fn decode_gif(image_file: &File) -> RasterResult<Image>{
let mut decoder = gif::Decoder::new(image_file);
gif::SetParameter::set(&mut decoder, gif::ColorOutput::RGBA);
let mut reader = try!(decoder.read_info());
if let Some(_) = try!(reader.next_frame_info()) {
let mut bytes = vec![0; reader.buffer_size()];
try!(reader.read_into_buffer(&mut bytes));
Ok(
Image {
width: reader.width() as i32,
height: reader.height() as i32,
bytes: bytes
}
)
} else {
Err(RasterError::Decode(ImageFormat::Gif, "Error getting frame info".to_string()))
}
}
pub fn encode_gif(image: &Image, path: &Path) -> RasterResult<()> {
let file = try!(File::create(path));
let writer = BufWriter::new(file);
let frame = gif::Frame::from_rgba(image.width as u16, image.height as u16, &mut image.bytes.clone()); let mut encoder = try!(
gif::Encoder::new(writer, frame.width, frame.height, &[])
);
try!(encoder.write_frame(&frame).map_err(RasterError::Io));
Ok(())
}
pub fn decode_png(image_file: &File) -> RasterResult<Image>{
let decoder = png::Decoder::new(image_file);
let (info, mut reader) = try!(decoder.read_info());
let mut bytes = vec![0; info.buffer_size()];
try!(reader.next_frame(&mut bytes));
if info.color_type == png::ColorType::RGB {
let mut insert_count = 0;
let len = (info.width * info.height) as usize;
for i in 0..len { let insert_pos = 3 * (i+1) + insert_count;
bytes.insert(insert_pos, 255);
insert_count+=1;
}
} Ok(
Image {
width: info.width as i32,
height: info.height as i32,
bytes: bytes
}
)
}
pub fn encode_png(image: &Image, path: &Path) -> RasterResult<()>{
let file = try!(File::create(path));
let ref mut w = BufWriter::new(file);
let mut encoder = png::Encoder::new(w, image.width as u32, image.height as u32);
png::HasParameters::set(&mut encoder, png::ColorType::RGBA);
png::HasParameters::set(&mut encoder, png::BitDepth::Eight);
let mut writer = try!(encoder.write_header());
Ok(try!(writer.write_image_data(&image.bytes)))
}