use qoicodec::DecodeError; use qoicodec::Decoder; use qoicodec::PixelRGBA; use std::io::BufWriter; use std::path::Path; use std::{fs::File, io::Read}; #[test] fn main() -> Result<(), DecodeError> { let file = File::open("qoi_test_images/dice.qoi").unwrap(); let mut bytes = file.bytes() .map(|maybe_bytes| { match maybe_bytes { Ok(byte) => byte, Err(oops) => panic!("Oops, the file failed to load: {}", oops) } }); let decoder = Decoder::try_new(bytes)?; let test_out_path = Path::new("test_output.png"); let file = File::create(test_out_path).unwrap(); let ref mut w = BufWriter::new(file); let mut encoder = png::Encoder::new(w, decoder.width, decoder.height); encoder.set_color(match decoder.channels { 3 => png::ColorType::Rgb, 4 => png::ColorType::Rgba, _ => panic!("Bad colorspace in qoicodec::Decoder!") }); encoder.set_depth(png::BitDepth::Eight); encoder.set_source_gamma(png::ScaledFloat::from_scaled(45455)); encoder.set_source_gamma(png::ScaledFloat::new(1.0 / 2.2)); let source_chromaticities = png::SourceChromaticities::new( (0.31270, 0.32900), (0.64000, 0.33000), (0.30000, 0.60000), (0.15000, 0.06000), ); encoder.set_source_chromaticities(source_chromaticities); let mut writer = encoder.write_header().unwrap(); let data: Vec = PixelIterExpander::try_new(decoder).unwrap().collect(); let result = writer.write_image_data(&data); if let Err(res) = result { eprintln!("{}", res); } return Ok(()) } struct PixelIterExpander > { wrapped_iterator: I, current_pixel: qoicodec::PixelRGBA, color_element_idx: u8, } impl > PixelIterExpander { fn try_new(mut pixels: I) -> Option { let px = pixels.next()?; Some(Self { wrapped_iterator: pixels, current_pixel: px, color_element_idx: 0, }) } } impl > Iterator for PixelIterExpander { type Item = u8; fn next(&mut self) -> Option { // at index 4, reset counter and get next pixel if self.color_element_idx == 4 { self.color_element_idx = 0; self.current_pixel = self.wrapped_iterator.next()?; } // increment pixel value, match over index and return that byte self.color_element_idx += 1; match self.color_element_idx { 1 => Some(self.current_pixel.r), 2 => Some(self.current_pixel.g), 3 => Some(self.current_pixel.b), 4 => Some(self.current_pixel.a), _ => None } } }