|
|
@ -1,3 +1,6 @@
|
|||
**Version 0.15.1 (unreleased)**
|
||||
- Ignore color reductions that would increase file size ([#61](https://github.com/shssoichiro/oxipng/issues/61))
|
||||
|
||||
**Version 0.15.0**
|
||||
- [SEMVER_MINOR] Check images for correctness before writing result ([#60](https://github.com/shssoichiro/oxipng/issues/60))
|
||||
- Fix invalid output when reducing image to a different color type but file size does not improve ([#60](https://github.com/shssoichiro/oxipng/issues/60))
|
||||
|
|
|
|||
|
|
@ -717,11 +717,6 @@ impl PngData {
|
|||
should_reduce_bit_depth = true;
|
||||
}
|
||||
|
||||
if self.ihdr_data.color_type == ColorType::Grayscale && reduce_grayscale_to_palette(self) {
|
||||
changed = true;
|
||||
should_reduce_bit_depth = true;
|
||||
}
|
||||
|
||||
if should_reduce_bit_depth {
|
||||
// Some conversions will allow us to perform bit depth reduction that
|
||||
// wasn't possible before
|
||||
|
|
|
|||
|
|
@ -152,6 +152,12 @@ pub fn reduce_rgba_to_palette(png: &mut PngData) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
let headers_size = color_palette.len() + trans_palette.len() + 8;
|
||||
if reduced.len() + headers_size > png.raw_data.len() * 4 {
|
||||
// Reduction would result in a larger image
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Some(bkgd_header) = png.aux_headers.get_mut(&"bKGD".to_string()) {
|
||||
assert_eq!(bkgd_header.len(), 6);
|
||||
let header_pixels = bkgd_header.iter().skip(1).step(2).cloned().collect::<Vec<u8>>();
|
||||
|
|
@ -217,6 +223,12 @@ pub fn reduce_rgb_to_palette(png: &mut PngData) -> bool {
|
|||
color_palette.extend_from_slice(color);
|
||||
}
|
||||
|
||||
let headers_size = color_palette.len() + 4;
|
||||
if reduced.len() + headers_size > png.raw_data.len() * 3 {
|
||||
// Reduction would result in a larger image
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Some(bkgd_header) = png.aux_headers.get_mut(&"bKGD".to_string()) {
|
||||
assert_eq!(bkgd_header.len(), 6);
|
||||
let header_pixels = bkgd_header.iter().skip(1).step(2).cloned().collect::<Vec<u8>>();
|
||||
|
|
@ -237,82 +249,6 @@ pub fn reduce_rgb_to_palette(png: &mut PngData) -> bool {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn reduce_grayscale_to_palette(png: &mut PngData) -> bool {
|
||||
if png.ihdr_data.bit_depth == BitDepth::Sixteen {
|
||||
return false;
|
||||
}
|
||||
let mut reduced = BitVec::with_capacity(png.raw_data.len() * 8);
|
||||
// Only perform reduction if we can get to 4-bits or less
|
||||
let mut palette = Vec::with_capacity(16);
|
||||
let bpp: usize = png.ihdr_data.bit_depth.as_u8() as usize;
|
||||
let bpp_inverse = 8 - bpp;
|
||||
for line in png.scan_lines() {
|
||||
reduced.extend(BitVec::from_bytes(&[line.filter]));
|
||||
let bit_vec = BitVec::from_bytes(&line.data);
|
||||
let mut cur_pixel = BitVec::with_capacity(bpp);
|
||||
for (i, bit) in bit_vec.iter().enumerate() {
|
||||
cur_pixel.push(bit);
|
||||
if i % bpp == bpp - 1 {
|
||||
let pix_value = cur_pixel.to_bytes()[0] >> bpp_inverse;
|
||||
let pix_slice = vec![pix_value, pix_value, pix_value];
|
||||
if palette.contains(&pix_slice) {
|
||||
let index = palette.iter().enumerate().find(|&x| x.1 == &pix_slice).unwrap().0;
|
||||
let idx = BitVec::from_bytes(&[(index as u8) << bpp_inverse]);
|
||||
for b in idx.iter().take(bpp) {
|
||||
reduced.push(b);
|
||||
}
|
||||
} else {
|
||||
let len = palette.len();
|
||||
if len == 16 {
|
||||
return false;
|
||||
}
|
||||
palette.push(pix_slice);
|
||||
let idx = BitVec::from_bytes(&[(len as u8) << bpp_inverse]);
|
||||
for b in idx.iter().take(bpp) {
|
||||
reduced.push(b);
|
||||
}
|
||||
}
|
||||
cur_pixel = BitVec::with_capacity(bpp);
|
||||
}
|
||||
}
|
||||
// Pad end of line to get 8 bits per byte
|
||||
while reduced.len() % 8 != 0 {
|
||||
reduced.push(false);
|
||||
}
|
||||
}
|
||||
|
||||
let mut color_palette = Vec::with_capacity(palette.len() * 3);
|
||||
for color in &palette {
|
||||
color_palette.extend_from_slice(color);
|
||||
}
|
||||
|
||||
if let Some(bkgd_header) = png.aux_headers.get_mut(&"bKGD".to_string()) {
|
||||
assert_eq!(bkgd_header.len(), 2);
|
||||
let header_pixels = [bkgd_header[1], bkgd_header[1], bkgd_header[1]];
|
||||
if let Some(entry) = color_palette.chunks(3).position(|x| *x == header_pixels) {
|
||||
*bkgd_header = vec![entry as u8];
|
||||
} else if color_palette.len() == 255 {
|
||||
return false;
|
||||
} else {
|
||||
let entry = color_palette.len() / 3;
|
||||
color_palette.extend_from_slice(&header_pixels);
|
||||
*bkgd_header = vec![entry as u8];
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(sbit_header) = png.aux_headers.get_mut(&"sBIT".to_string()) {
|
||||
assert_eq!(sbit_header.len(), 1);
|
||||
let byte = sbit_header[0];
|
||||
sbit_header.push(byte);
|
||||
sbit_header.push(byte);
|
||||
}
|
||||
|
||||
png.raw_data = reduced.to_bytes();
|
||||
png.palette = Some(color_palette);
|
||||
png.ihdr_data.color_type = ColorType::Indexed;
|
||||
true
|
||||
}
|
||||
|
||||
pub fn reduce_rgb_to_grayscale(png: &mut PngData) -> bool {
|
||||
let mut reduced = Vec::with_capacity(png.raw_data.len());
|
||||
let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3;
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
|
@ -354,96 +354,6 @@ fn interlaced_rgba_8_should_be_grayscale_8() {
|
|||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgba_16_should_be_palette_4_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgba_8_should_be_palette_4_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgba_16_should_be_palette_2_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgba_8_should_be_palette_2_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgba_16_should_be_palette_1_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgba_8_should_be_palette_1_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_16_should_be_rgb_16() {
|
||||
let input = PathBuf::from("tests/files/interlaced_rgb_16_should_be_rgb_16.png");
|
||||
|
|
@ -654,96 +564,6 @@ fn interlaced_rgb_8_should_be_grayscale_8() {
|
|||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_16_should_be_palette_4_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_8_should_be_palette_4_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_16_should_be_palette_2_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_8_should_be_palette_2_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_16_should_be_palette_1_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_rgb_8_should_be_palette_1_grayscale() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_palette_8_should_be_palette_8() {
|
||||
let input = PathBuf::from("tests/files/interlaced_palette_8_should_be_palette_8.png");
|
||||
|
|
@ -984,96 +804,6 @@ fn interlaced_grayscale_alpha_8_should_be_grayscale_8() {
|
|||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_alpha_16_should_be_palette_4() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_alpha_8_should_be_palette_4() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_alpha_16_should_be_palette_2() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_alpha_8_should_be_palette_2() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_alpha_16_should_be_palette_1() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_alpha_8_should_be_palette_1() {
|
||||
let input = PathBuf::from("tests/files/interlaced_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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_16_should_be_grayscale_16() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_16_should_be_grayscale_16.png");
|
||||
|
|
@ -1104,51 +834,6 @@ fn interlaced_grayscale_16_should_be_grayscale_8() {
|
|||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_16_should_be_palette_4() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_16_should_be_palette_4.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_16_should_be_palette_2() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_16_should_be_palette_2.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_16_should_be_palette_1() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_16_should_be_palette_1.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_8_should_be_grayscale_8() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_8_should_be_grayscale_8.png");
|
||||
|
|
@ -1164,51 +849,6 @@ fn interlaced_grayscale_8_should_be_grayscale_8() {
|
|||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_8_should_be_palette_4() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_8_should_be_palette_4.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Four);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_8_should_be_palette_2() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_8_should_be_palette_2.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_grayscale_8_should_be_palette_1() {
|
||||
let input = PathBuf::from("tests/files/interlaced_grayscale_8_should_be_palette_1.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_small_files() {
|
||||
let input = PathBuf::from("tests/files/interlaced_small_files.png");
|
||||
|
|
|
|||
|
|
@ -354,96 +354,6 @@ fn rgba_8_should_be_grayscale_8() {
|
|||
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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rgb_16_should_be_rgb_16() {
|
||||
let input = PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png");
|
||||
|
|
@ -654,96 +564,6 @@ fn rgb_8_should_be_grayscale_8() {
|
|||
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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::RGB,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn palette_8_should_be_palette_8() {
|
||||
let input = PathBuf::from("tests/files/palette_8_should_be_palette_8.png");
|
||||
|
|
@ -984,96 +804,6 @@ fn grayscale_alpha_8_should_be_grayscale_8() {
|
|||
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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grayscale_16_should_be_grayscale_16() {
|
||||
let input = PathBuf::from("tests/files/grayscale_16_should_be_grayscale_16.png");
|
||||
|
|
@ -1104,51 +834,6 @@ fn grayscale_16_should_be_grayscale_8() {
|
|||
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,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Sixteen,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grayscale_8_should_be_grayscale_8() {
|
||||
let input = PathBuf::from("tests/files/grayscale_8_should_be_grayscale_8.png");
|
||||
|
|
@ -1164,51 +849,6 @@ fn grayscale_8_should_be_grayscale_8() {
|
|||
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,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
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,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight,
|
||||
ColorType::Indexed,
|
||||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn small_files() {
|
||||
let input = PathBuf::from("tests/files/small_files.png");
|
||||
|
|
|
|||