diff --git a/src/png.rs b/src/png.rs index 02d71bc1..a3f73b74 100644 --- a/src/png.rs +++ b/src/png.rs @@ -343,8 +343,7 @@ impl PngData { pub fn unfilter_image(&self) -> Vec { let mut unfiltered = Vec::with_capacity(self.raw_data.len()); let tmp = self.ihdr_data.bit_depth.as_u8() * self.channels_per_pixel(); - // Round up without converting to float - let bpp = (tmp + tmp % 8) >> 3; + let bpp = ((tmp as f32) / 8f32).ceil() as usize; let mut last_line: Vec = vec![]; for line in self.scan_lines() { unfiltered.push(0); @@ -355,7 +354,7 @@ impl PngData { 1 => { let mut data = Vec::with_capacity(line.data.len()); for (i, byte) in line.data.iter().enumerate() { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { let b = data[x]; data.push(byte.wrapping_add(b)) @@ -382,7 +381,7 @@ impl PngData { let mut data = Vec::with_capacity(line.data.len()); for (i, byte) in line.data.iter().enumerate() { if last_line.is_empty() { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { let b = data[x]; data.push(byte.wrapping_add(b >> 1)) @@ -390,7 +389,7 @@ impl PngData { None => data.push(*byte), }; } else { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { let b = data[x]; data.push(byte.wrapping_add( @@ -408,7 +407,7 @@ impl PngData { let mut data = Vec::with_capacity(line.data.len()); for (i, byte) in line.data.iter().enumerate() { if last_line.is_empty() { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { let b = data[x]; data.push(byte.wrapping_add(b)) @@ -416,7 +415,7 @@ impl PngData { None => data.push(*byte), }; } else { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { let b = data[x]; data.push(byte.wrapping_add(paeth_predictor(b, @@ -438,8 +437,7 @@ impl PngData { pub fn filter_image(&self, filter: u8) -> Vec { let mut filtered = Vec::with_capacity(self.raw_data.len()); let tmp = self.ihdr_data.bit_depth.as_u8() * self.channels_per_pixel(); - // Round up without converting to float - let bpp = (tmp + tmp % 8) >> 3; + let bpp = ((tmp as f32) / 8f32).ceil() as usize; let mut last_line: Vec = vec![]; // We could try a different filter method for each line // But that would be prohibitively slow and probably not provide much benefit @@ -454,7 +452,7 @@ impl PngData { } 1 => { for (i, byte) in line.data.iter().enumerate() { - filtered.push(match i.checked_sub(bpp as usize) { + filtered.push(match i.checked_sub(bpp) { Some(x) => byte.wrapping_sub(line.data[x]), None => *byte, }); @@ -472,12 +470,12 @@ impl PngData { 3 => { for (i, byte) in line.data.iter().enumerate() { if last_line.is_empty() { - filtered.push(match i.checked_sub(bpp as usize) { + filtered.push(match i.checked_sub(bpp) { Some(x) => byte.wrapping_sub(line.data[x] >> 1), None => *byte, }); } else { - filtered.push(match i.checked_sub(bpp as usize) { + filtered.push(match i.checked_sub(bpp) { Some(x) => byte.wrapping_sub( ((line.data[x] as u16 + last_line[i] as u16) >> 1) as u8 ), @@ -489,12 +487,12 @@ impl PngData { 4 => { for (i, byte) in line.data.iter().enumerate() { if last_line.is_empty() { - filtered.push(match i.checked_sub(bpp as usize) { + filtered.push(match i.checked_sub(bpp) { Some(x) => byte.wrapping_sub(line.data[x]), None => *byte, }); } else { - filtered.push(match i.checked_sub(bpp as usize) { + filtered.push(match i.checked_sub(bpp) { Some(x) => { byte.wrapping_sub(paeth_predictor(line.data[x], last_line[i], @@ -520,7 +518,7 @@ impl PngData { let mut line_4 = Vec::with_capacity(line.data.len()); for (i, byte) in line.data.iter().enumerate() { if last_line.is_empty() { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { line_1.push(byte.wrapping_sub(line.data[x])); line_2.push(*byte); @@ -535,7 +533,7 @@ impl PngData { } } } else { - match i.checked_sub(bpp as usize) { + match i.checked_sub(bpp) { Some(x) => { line_1.push(byte.wrapping_sub(line.data[x])); line_2.push(byte.wrapping_sub(last_line[i])); diff --git a/tests/filters.rs b/tests/filters.rs new file mode 100644 index 00000000..125a2d9a --- /dev/null +++ b/tests/filters.rs @@ -0,0 +1,1210 @@ +extern crate image; +extern crate oxipng; + +use image::GenericImage; +use image::Pixel; +use oxipng::png; +use std::collections::HashSet; +use std::fs::remove_file; +use std::path::Path; +use std::path::PathBuf; + +fn get_opts(input: &Path) -> oxipng::Options { + let mut filter = HashSet::new(); + filter.insert(0); + let mut compression = HashSet::new(); + compression.insert(9); + let mut memory = HashSet::new(); + memory.insert(9); + let mut strategies = HashSet::new(); + for i in 0..4 { + strategies.insert(i); + } + + oxipng::Options { + backup: false, + out_file: input.with_extension("out.png").to_owned(), + out_dir: None, + stdout: false, + pretend: false, + recursive: false, + fix_errors: false, + force: true, + clobber: true, + create: true, + preserve_attrs: false, + verbosity: Some(0), + filter: filter, + interlace: None, + compression: compression, + memory: memory, + strategies: strategies, + window: 15, + bit_depth_reduction: true, + color_type_reduction: true, + palette_reduction: true, + idat_recoding: true, + strip: false, + } +} + +fn test_it_converts(input: &Path, + output: &Path, + opts: &oxipng::Options, + color_type_in: png::ColorType, + bit_depth_in: png::BitDepth, + color_type_out: png::ColorType, + bit_depth_out: png::BitDepth) { + let png = png::PngData::new(input).unwrap(); + + assert!(png.ihdr_data.color_type == color_type_in); + assert!(png.ihdr_data.bit_depth == bit_depth_in); + + match oxipng::optimize(input, opts) { + Ok(_) => (), + Err(x) => panic!(x.to_owned()), + }; + assert!(output.exists()); + + let png = match png::PngData::new(output) { + Ok(x) => x, + Err(x) => { + remove_file(output).ok(); + panic!(x.to_owned()) + } + }; + + assert!(png.ihdr_data.color_type == color_type_out); + assert!(png.ihdr_data.bit_depth == bit_depth_out); + + let old_png = image::open(input).unwrap(); + let new_png = image::open(output).unwrap(); + + // Conversion should be lossless + assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == + new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); + + remove_file(output).ok(); +} + +#[test] +fn filter_0_for_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_1_for_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_2_for_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_3_for_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_4_for_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_5_for_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_0_for_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn filter_1_for_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn filter_2_for_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn filter_3_for_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn filter_4_for_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn filter_5_for_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn filter_0_for_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_1_for_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_2_for_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_3_for_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_4_for_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_5_for_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_0_for_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn filter_1_for_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn filter_2_for_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn filter_3_for_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn filter_4_for_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn filter_5_for_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn filter_0_for_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_1_for_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_2_for_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_3_for_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_4_for_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_5_for_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_0_for_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn filter_1_for_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn filter_2_for_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn filter_3_for_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn filter_4_for_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn filter_5_for_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn filter_0_for_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_1_for_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_2_for_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_3_for_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_4_for_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_5_for_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn filter_0_for_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn filter_1_for_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn filter_2_for_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn filter_3_for_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn filter_4_for_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn filter_5_for_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn filter_0_for_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn filter_1_for_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn filter_2_for_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn filter_3_for_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn filter_4_for_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn filter_5_for_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn filter_0_for_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn filter_1_for_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn filter_2_for_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn filter_3_for_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn filter_4_for_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn filter_5_for_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn filter_0_for_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(0); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn filter_1_for_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(1); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn filter_2_for_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(2); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn filter_3_for_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(3); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn filter_4_for_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(4); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn filter_5_for_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let mut opts = get_opts(&input); + opts.filter = HashSet::new(); + opts.filter.insert(5); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} diff --git a/tests/flags.rs b/tests/flags.rs new file mode 100644 index 00000000..9d99839e --- /dev/null +++ b/tests/flags.rs @@ -0,0 +1,86 @@ +extern crate image; +extern crate oxipng; + +use image::GenericImage; +use image::Pixel; +use oxipng::png; +use std::collections::HashSet; +use std::fs::remove_file; +use std::path::Path; +use std::path::PathBuf; + +fn get_opts(input: &Path) -> oxipng::Options { + let mut filter = HashSet::new(); + filter.insert(0); + let mut compression = HashSet::new(); + compression.insert(9); + let mut memory = HashSet::new(); + memory.insert(9); + let mut strategies = HashSet::new(); + for i in 0..4 { + strategies.insert(i); + } + + oxipng::Options { + backup: false, + out_file: input.with_extension("out.png").to_owned(), + out_dir: None, + stdout: false, + pretend: false, + recursive: false, + fix_errors: false, + force: true, + clobber: true, + create: true, + preserve_attrs: false, + verbosity: Some(0), + filter: filter, + interlace: None, + compression: compression, + memory: memory, + strategies: strategies, + window: 15, + bit_depth_reduction: true, + color_type_reduction: true, + palette_reduction: true, + idat_recoding: true, + strip: false, + } +} + +#[test] +fn strip_headers() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let mut opts = get_opts(&input); + opts.strip = true; + let output = opts.out_file.clone(); + + let png = png::PngData::new(&input).unwrap(); + + assert!(png.aux_headers.contains_key("tEXt")); + + match oxipng::optimize(&input, &opts) { + Ok(_) => (), + Err(x) => panic!(x.to_owned()), + }; + assert!(output.exists()); + + let png = match png::PngData::new(&output) { + Ok(x) => x, + Err(x) => { + remove_file(output).ok(); + panic!(x.to_owned()) + } + }; + + assert!(!png.aux_headers.contains_key("tEXt")); + + let old_png = image::open(&input).unwrap(); + let new_png = image::open(&output).unwrap(); + + // Conversion should be lossless + assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == + new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); + + remove_file(output).ok(); +} diff --git a/tests/oxipng.rs b/tests/oxipng.rs deleted file mode 100644 index 6bef3c28..00000000 --- a/tests/oxipng.rs +++ /dev/null @@ -1,3012 +0,0 @@ -extern crate image; -extern crate oxipng; - -use image::GenericImage; -use image::Pixel; -use oxipng::png; -use std::collections::HashSet; -use std::fs::remove_file; -use std::path::Path; -use std::path::PathBuf; - -fn get_opts(input: &Path) -> oxipng::Options { - let mut filter = HashSet::new(); - filter.insert(0); - let mut compression = HashSet::new(); - compression.insert(9); - let mut memory = HashSet::new(); - memory.insert(9); - let mut strategies = HashSet::new(); - for i in 0..4 { - strategies.insert(i); - } - - oxipng::Options { - backup: false, - out_file: input.with_extension("out.png").to_owned(), - out_dir: None, - stdout: false, - pretend: false, - recursive: false, - fix_errors: false, - force: true, - clobber: true, - create: true, - preserve_attrs: false, - verbosity: Some(0), - filter: filter, - interlace: None, - compression: compression, - memory: memory, - strategies: strategies, - window: 15, - bit_depth_reduction: true, - color_type_reduction: true, - palette_reduction: true, - idat_recoding: true, - strip: false, - } -} - -#[test] -fn rgba_16_should_be_rgba_16() { - let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_rgba_8() { - let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_rgba_8() { - let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_rgb_16() { - let input = PathBuf::from("tests/files/rgba_16_should_be_rgb_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_rgb_8() { - let input = PathBuf::from("tests/files/rgba_16_should_be_rgb_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_rgb_8() { - let input = PathBuf::from("tests/files/rgba_8_should_be_rgb_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_8() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_8() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_4() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_4() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_2() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_2() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_1() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_1() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_grayscale_alpha_16() { - let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_alpha_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_grayscale_alpha_8() { - let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_alpha_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_grayscale_alpha_8() { - let input = PathBuf::from("tests/files/rgba_8_should_be_grayscale_alpha_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_grayscale_16() { - let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/rgba_8_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_4_grayscale() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_4_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_4_grayscale() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_4_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_2_grayscale() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_2_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_2_grayscale() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_2_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_16_should_be_palette_1_grayscale() { - let input = PathBuf::from("tests/files/rgba_16_should_be_palette_1_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgba_8_should_be_palette_1_grayscale() { - let input = PathBuf::from("tests/files/rgba_8_should_be_palette_1_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGBA); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_rgb_16() { - let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_rgb_8() { - let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_rgb_8() { - let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_8() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_8() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_4() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_4() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_2() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_2() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_1() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_1() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_grayscale_16() { - let input = PathBuf::from("tests/files/rgb_16_should_be_grayscale_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/rgb_16_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/rgb_8_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_4_grayscale() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_4_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_4_grayscale() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_4_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_2_grayscale() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_2_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_2_grayscale() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_2_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_16_should_be_palette_1_grayscale() { - let input = PathBuf::from("tests/files/rgb_16_should_be_palette_1_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn rgb_8_should_be_palette_1_grayscale() { - let input = PathBuf::from("tests/files/rgb_8_should_be_palette_1_grayscale.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::RGB); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_8_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/palette_8_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_8_should_be_palette_8() { - let input = PathBuf::from("tests/files/palette_8_should_be_palette_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_8_should_be_palette_4() { - let input = PathBuf::from("tests/files/palette_8_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_4_should_be_palette_4() { - let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_8_should_be_palette_2() { - let input = PathBuf::from("tests/files/palette_8_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_4_should_be_palette_2() { - let input = PathBuf::from("tests/files/palette_4_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_2_should_be_palette_2() { - let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_8_should_be_palette_1() { - let input = PathBuf::from("tests/files/palette_8_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_4_should_be_palette_1() { - let input = PathBuf::from("tests/files/palette_4_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_2_should_be_palette_1() { - let input = PathBuf::from("tests/files/palette_2_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn palette_1_should_be_palette_1() { - let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_grayscale_alpha_16() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_grayscale_alpha_8() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_8_should_be_grayscale_alpha_8() { - let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_grayscale_16() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_16.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_8_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_palette_4() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_8_should_be_palette_4() { - let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_palette_2() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_8_should_be_palette_2() { - let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_16_should_be_palette_1() { - let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_alpha_8_should_be_palette_1() { - let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::GrayscaleAlpha); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_16_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_16_should_be_palette_4() { - let input = PathBuf::from("tests/files/grayscale_16_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_16_should_be_palette_2() { - let input = PathBuf::from("tests/files/grayscale_16_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_16_should_be_palette_1() { - let input = PathBuf::from("tests/files/grayscale_16_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Sixteen); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_8_should_be_grayscale_8() { - let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_8_should_be_palette_4() { - let input = PathBuf::from("tests/files/grayscale_8_should_be_palette_4.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Four); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_8_should_be_palette_2() { - let input = PathBuf::from("tests/files/grayscale_8_should_be_palette_2.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Two); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn grayscale_8_should_be_palette_1() { - let input = PathBuf::from("tests/files/grayscale_8_should_be_palette_1.png"); - let opts = get_opts(&input); - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.ihdr_data.color_type == png::ColorType::Grayscale); - assert!(png.ihdr_data.bit_depth == png::BitDepth::Eight); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(png.ihdr_data.color_type == png::ColorType::Indexed); - assert!(png.ihdr_data.bit_depth == png::BitDepth::One); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} - -#[test] -fn strip_headers() { - let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); - let mut opts = get_opts(&input); - opts.strip = true; - let output = opts.out_file.clone(); - - let png = png::PngData::new(&input).unwrap(); - - assert!(png.aux_headers.contains_key("tEXt")); - - match oxipng::optimize(&input, &opts) { - Ok(_) => (), - Err(x) => panic!(x.to_owned()), - }; - assert!(output.exists()); - - let png = match png::PngData::new(&output) { - Ok(x) => x, - Err(x) => { - remove_file(output).ok(); - panic!(x.to_owned()) - } - }; - - assert!(!png.aux_headers.contains_key("tEXt")); - - let old_png = image::open(&input).unwrap(); - let new_png = image::open(&output).unwrap(); - - // Conversion should be lossless - assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == - new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); - - remove_file(output).ok(); -} diff --git a/tests/reduction.rs b/tests/reduction.rs new file mode 100644 index 00000000..3662302e --- /dev/null +++ b/tests/reduction.rs @@ -0,0 +1,1259 @@ +extern crate image; +extern crate oxipng; + +use image::GenericImage; +use image::Pixel; +use oxipng::png; +use std::collections::HashSet; +use std::fs::remove_file; +use std::path::Path; +use std::path::PathBuf; + +fn get_opts(input: &Path) -> oxipng::Options { + let mut filter = HashSet::new(); + filter.insert(0); + let mut compression = HashSet::new(); + compression.insert(9); + let mut memory = HashSet::new(); + memory.insert(9); + let mut strategies = HashSet::new(); + for i in 0..4 { + strategies.insert(i); + } + + oxipng::Options { + backup: false, + out_file: input.with_extension("out.png").to_owned(), + out_dir: None, + stdout: false, + pretend: false, + recursive: false, + fix_errors: false, + force: true, + clobber: true, + create: true, + preserve_attrs: false, + verbosity: Some(0), + filter: filter, + interlace: None, + compression: compression, + memory: memory, + strategies: strategies, + window: 15, + bit_depth_reduction: true, + color_type_reduction: true, + palette_reduction: true, + idat_recoding: true, + strip: false, + } +} + +fn test_it_converts(input: &Path, + output: &Path, + opts: &oxipng::Options, + color_type_in: png::ColorType, + bit_depth_in: png::BitDepth, + color_type_out: png::ColorType, + bit_depth_out: png::BitDepth) { + let png = png::PngData::new(input).unwrap(); + + assert!(png.ihdr_data.color_type == color_type_in); + assert!(png.ihdr_data.bit_depth == bit_depth_in); + + match oxipng::optimize(input, opts) { + Ok(_) => (), + Err(x) => panic!(x.to_owned()), + }; + assert!(output.exists()); + + let png = match png::PngData::new(output) { + Ok(x) => x, + Err(x) => { + remove_file(output).ok(); + panic!(x.to_owned()) + } + }; + + assert!(png.ihdr_data.color_type == color_type_out); + assert!(png.ihdr_data.bit_depth == bit_depth_out); + + let old_png = image::open(input).unwrap(); + let new_png = image::open(output).unwrap(); + + // Conversion should be lossless + assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>() == + new_png.pixels().map(|x| x.2.channels().to_owned()).collect::>>()); + + remove_file(output).ok(); +} + + +#[test] +fn rgba_16_should_be_rgba_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Sixteen); +} + +#[test] +fn rgba_16_should_be_rgba_8() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgba_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn rgba_8_should_be_rgba_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgba_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGBA, + png::BitDepth::Eight); +} + +#[test] +fn rgba_16_should_be_rgb_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgb_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn rgba_16_should_be_rgb_8() { + let input = PathBuf::from("tests/files/rgba_16_should_be_rgb_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn rgba_8_should_be_rgb_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_rgb_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn rgba_16_should_be_palette_8() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Eight); +} + +#[test] +fn rgba_8_should_be_palette_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Eight); +} + +#[test] +fn rgba_16_should_be_palette_4() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgba_8_should_be_palette_4() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgba_16_should_be_palette_2() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgba_8_should_be_palette_2() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgba_16_should_be_palette_1() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgba_8_should_be_palette_1() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgba_16_should_be_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_alpha_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn rgba_16_should_be_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_alpha_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn rgba_8_should_be_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_grayscale_alpha_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn rgba_16_should_be_grayscale_16() { + let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn rgba_16_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/rgba_16_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn rgba_8_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/rgba_8_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn rgba_16_should_be_palette_4_grayscale() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_4_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgba_8_should_be_palette_4_grayscale() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_4_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgba_16_should_be_palette_2_grayscale() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_2_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgba_8_should_be_palette_2_grayscale() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_2_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgba_16_should_be_palette_1_grayscale() { + let input = PathBuf::from("tests/files/rgba_16_should_be_palette_1_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgba_8_should_be_palette_1_grayscale() { + let input = PathBuf::from("tests/files/rgba_8_should_be_palette_1_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGBA, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgb_16_should_be_rgb_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Sixteen); +} + +#[test] +fn rgb_16_should_be_rgb_8() { + let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn rgb_8_should_be_rgb_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::RGB, + png::BitDepth::Eight); +} + +#[test] +fn rgb_16_should_be_palette_8() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Eight); +} + +#[test] +fn rgb_8_should_be_palette_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Eight); +} + +#[test] +fn rgb_16_should_be_palette_4() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgb_8_should_be_palette_4() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgb_16_should_be_palette_2() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgb_8_should_be_palette_2() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgb_16_should_be_palette_1() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgb_8_should_be_palette_1() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgb_16_should_be_grayscale_16() { + let input = PathBuf::from("tests/files/rgb_16_should_be_grayscale_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn rgb_16_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/rgb_16_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn rgb_8_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/rgb_8_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn rgb_16_should_be_palette_4_grayscale() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_4_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgb_8_should_be_palette_4_grayscale() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_4_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn rgb_16_should_be_palette_2_grayscale() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_2_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgb_8_should_be_palette_2_grayscale() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_2_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn rgb_16_should_be_palette_1_grayscale() { + let input = PathBuf::from("tests/files/rgb_16_should_be_palette_1_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn rgb_8_should_be_palette_1_grayscale() { + let input = PathBuf::from("tests/files/rgb_8_should_be_palette_1_grayscale.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::RGB, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn palette_8_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/palette_8_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn palette_8_should_be_palette_8() { + let input = PathBuf::from("tests/files/palette_8_should_be_palette_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Eight); +} + +#[test] +fn palette_8_should_be_palette_4() { + let input = PathBuf::from("tests/files/palette_8_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn palette_4_should_be_palette_4() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn palette_8_should_be_palette_2() { + let input = PathBuf::from("tests/files/palette_8_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn palette_4_should_be_palette_2() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn palette_2_should_be_palette_2() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn palette_8_should_be_palette_1() { + let input = PathBuf::from("tests/files/palette_8_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn palette_4_should_be_palette_1() { + let input = PathBuf::from("tests/files/palette_4_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Four, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn palette_2_should_be_palette_1() { + let input = PathBuf::from("tests/files/palette_2_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::Two, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn palette_1_should_be_palette_1() { + let input = PathBuf::from("tests/files/palette_1_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Indexed, + png::BitDepth::One, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn grayscale_alpha_16_should_be_grayscale_alpha_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen); +} + +#[test] +fn grayscale_alpha_16_should_be_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_alpha_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn grayscale_alpha_8_should_be_grayscale_alpha_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_alpha_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight); +} + +#[test] +fn grayscale_alpha_16_should_be_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn grayscale_alpha_16_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn grayscale_alpha_8_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn grayscale_alpha_16_should_be_palette_4() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn grayscale_alpha_8_should_be_palette_4() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn grayscale_alpha_16_should_be_palette_2() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn grayscale_alpha_8_should_be_palette_2() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn grayscale_alpha_16_should_be_palette_1() { + let input = PathBuf::from("tests/files/grayscale_alpha_16_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn grayscale_alpha_8_should_be_palette_1() { + let input = PathBuf::from("tests/files/grayscale_alpha_8_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::GrayscaleAlpha, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn grayscale_16_should_be_grayscale_16() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Sixteen); +} + +#[test] +fn grayscale_16_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn grayscale_16_should_be_palette_4() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn grayscale_16_should_be_palette_2() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn grayscale_16_should_be_palette_1() { + let input = PathBuf::from("tests/files/grayscale_16_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Sixteen, + png::ColorType::Indexed, + png::BitDepth::One); +} + +#[test] +fn grayscale_8_should_be_grayscale_8() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Grayscale, + png::BitDepth::Eight); +} + +#[test] +fn grayscale_8_should_be_palette_4() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_palette_4.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Four); +} + +#[test] +fn grayscale_8_should_be_palette_2() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_palette_2.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::Two); +} + +#[test] +fn grayscale_8_should_be_palette_1() { + let input = PathBuf::from("tests/files/grayscale_8_should_be_palette_1.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + png::ColorType::Grayscale, + png::BitDepth::Eight, + png::ColorType::Indexed, + png::BitDepth::One); +}