From 7f9ad263ecb168d37a354510e319d2193f6f736f Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Thu, 14 Jul 2016 11:10:10 -0400 Subject: [PATCH] Refactor code into modules --- .editorconfig | 10 + CHANGELOG.md | 5 +- Cargo.lock | 65 +++ Cargo.toml | 8 + src/colors.rs | 96 +++++ src/filters.rs | 162 ++++++++ src/headers.rs | 120 ++++++ src/interlace.rs | 211 ++++++++++ src/lib.rs | 20 +- src/main.rs | 10 +- src/png.rs | 938 +------------------------------------------- src/reduction.rs | 339 ++++++++++++++++ tests/filters.rs | 545 ++++++++++++------------- tests/flags.rs | 66 ++-- tests/interlaced.rs | 649 +++++++++++++++--------------- tests/reduction.rs | 665 +++++++++++++++---------------- 16 files changed, 2014 insertions(+), 1895 deletions(-) create mode 100644 .editorconfig create mode 100644 src/colors.rs create mode 100644 src/filters.rs create mode 100644 src/headers.rs create mode 100644 src/interlace.rs create mode 100644 src/reduction.rs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..a50e07fb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.rs] +charset = utf-8 +indent_style = space +indent_size = 4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 59531d52..dfeba9b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -**Version 0.8.3** - - Significant refactoring +**Version 0.9.0 (unreleased)** + - [SEMVER_MAJOR] Significant refactoring of modules + - Use `itertools` to cleanup areas of code **Version 0.8.2** - Fix issue where images smaller than 4px width would crash on interlacing ([#42](https://github.com/shssoichiro/oxipng/issues/42)) diff --git a/Cargo.lock b/Cargo.lock index 104dd1c6..4f4ec5ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -68,6 +69,28 @@ dependencies = [ "vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "clippy" +version = "0.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clippy_lints 0.0.79 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clippy_lints" +version = "0.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quine-mc_cluskey 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crc" version = "1.3.0" @@ -159,6 +182,11 @@ dependencies = [ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matches" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memchr" version = "0.1.11" @@ -176,6 +204,11 @@ dependencies = [ "libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nom" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "num" version = "0.1.34" @@ -267,6 +300,11 @@ dependencies = [ "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quine-mc_cluskey" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rand" version = "0.3.14" @@ -283,6 +321,7 @@ dependencies = [ "aho-corasick 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -312,6 +351,19 @@ name = "scopeguard" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "semver" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "simd" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.4.1" @@ -342,6 +394,19 @@ dependencies = [ "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "toml" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index 43c3bc2f..9512f1f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,15 @@ num_cpus = "^0.2.11" regex = "^0.1.63" scoped-pool = "^0.1.8" +[dependencies.clippy] +optional = true +version = "*" + [dev-dependencies.image] version = "^0.8.0" default-features = false features = ["png_codec"] + +[features] +default = [] +nightly = ["clippy", "regex/simd-accel"] diff --git a/src/colors.rs b/src/colors.rs new file mode 100644 index 00000000..40aee6ea --- /dev/null +++ b/src/colors.rs @@ -0,0 +1,96 @@ +use std::fmt; + +#[derive(Debug,PartialEq,Clone,Copy)] +/// The color type used to represent this image +pub enum ColorType { + /// Grayscale, with one color channel + Grayscale, + /// RGB, with three color channels + RGB, + /// Indexed, with one byte per pixel representing one of up to 256 colors in the image + Indexed, + /// Grayscale + Alpha, with two color channels + GrayscaleAlpha, + /// RGBA, with four color channels + RGBA, +} + +impl fmt::Display for ColorType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, + "{}", + match *self { + ColorType::Grayscale => "Grayscale", + ColorType::RGB => "RGB", + ColorType::Indexed => "Indexed", + ColorType::GrayscaleAlpha => "Grayscale + Alpha", + ColorType::RGBA => "RGB + Alpha", + }) + } +} + +impl ColorType { + /// Get the code used by the PNG specification to denote this color type + pub fn png_header_code(&self) -> u8 { + match *self { + ColorType::Grayscale => 0, + ColorType::RGB => 2, + ColorType::Indexed => 3, + ColorType::GrayscaleAlpha => 4, + ColorType::RGBA => 6, + } + } +} + +#[derive(Debug,PartialEq,Clone,Copy)] +/// The number of bits to be used per channel per pixel +pub enum BitDepth { + /// One bit per channel per pixel + One, + /// Two bits per channel per pixel + Two, + /// Four bits per channel per pixel + Four, + /// Eight bits per channel per pixel + Eight, + /// Sixteen bits per channel per pixel + Sixteen, +} + +impl fmt::Display for BitDepth { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, + "{}", + match *self { + BitDepth::One => "1", + BitDepth::Two => "2", + BitDepth::Four => "4", + BitDepth::Eight => "8", + BitDepth::Sixteen => "16", + }) + } +} + +impl BitDepth { + /// Retrieve the number of bits per channel per pixel as a `u8` + pub fn as_u8(&self) -> u8 { + match *self { + BitDepth::One => 1, + BitDepth::Two => 2, + BitDepth::Four => 4, + BitDepth::Eight => 8, + BitDepth::Sixteen => 16, + } + } + /// Parse a number of bits per channel per pixel into a `BitDepth` + pub fn from_u8(depth: u8) -> BitDepth { + match depth { + 1 => BitDepth::One, + 2 => BitDepth::Two, + 4 => BitDepth::Four, + 8 => BitDepth::Eight, + 16 => BitDepth::Sixteen, + _ => panic!("Unsupported bit depth"), + } + } +} diff --git a/src/filters.rs b/src/filters.rs new file mode 100644 index 00000000..7bc06fe4 --- /dev/null +++ b/src/filters.rs @@ -0,0 +1,162 @@ +pub fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec { + let mut filtered = Vec::with_capacity(data.len()); + match filter { + 0 => { + filtered.extend_from_slice(data); + } + 1 => { + filtered.extend_from_slice(&data[0..bpp]); + filtered.extend_from_slice(&data.iter() + .skip(bpp) + .zip(data.iter()) + .map(|(cur, last)| cur.wrapping_sub(*last)) + .collect::>()); + } + 2 => { + if last_line.is_empty() { + filtered.extend_from_slice(data); + } else { + filtered.extend_from_slice(&data.iter() + .zip(last_line.iter()) + .map(|(cur, last)| cur.wrapping_sub(*last)) + .collect::>()); + }; + } + 3 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + filtered.push(match i.checked_sub(bpp) { + Some(x) => byte.wrapping_sub(data[x] >> 1), + None => *byte, + }); + } else { + filtered.push(match i.checked_sub(bpp) { + Some(x) => { + byte.wrapping_sub(((data[x] as u16 + last_line[i] as u16) >> 1) as u8) + } + None => byte.wrapping_sub(last_line[i] >> 1), + }); + }; + } + } + 4 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + filtered.push(match i.checked_sub(bpp) { + Some(x) => byte.wrapping_sub(data[x]), + None => *byte, + }); + } else { + filtered.push(match i.checked_sub(bpp) { + Some(x) => { + byte.wrapping_sub(paeth_predictor(data[x], last_line[i], last_line[x])) + } + None => byte.wrapping_sub(last_line[i]), + }); + }; + } + } + _ => unreachable!(), + } + filtered +} + +pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec { + let mut unfiltered = Vec::with_capacity(data.len()); + match filter { + 0 => { + unfiltered.extend_from_slice(data); + } + 1 => { + for (i, byte) in data.iter().enumerate() { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(b)); + } + None => { + unfiltered.push(*byte); + } + }; + } + } + 2 => { + if last_line.is_empty() { + unfiltered.extend_from_slice(data); + } else { + unfiltered.extend_from_slice(&data.iter() + .zip(last_line.iter()) + .map(|(cur, last)| cur.wrapping_add(*last)) + .collect::>()); + }; + } + 3 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(b >> 1)); + } + None => { + unfiltered.push(*byte); + } + }; + } else { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(((b as u16 + last_line[i] as u16) >> 1) as u8)); + } + None => { + unfiltered.push(byte.wrapping_add(last_line[i] >> 1)); + } + }; + }; + } + } + 4 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(b)); + } + None => { + unfiltered.push(*byte); + } + }; + } else { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(paeth_predictor(b, + last_line[i], + last_line[x]))); + } + None => { + unfiltered.push(byte.wrapping_add(last_line[i])); + } + }; + }; + } + } + _ => unreachable!(), + } + unfiltered +} + +fn paeth_predictor(a: u8, b: u8, c: u8) -> u8 { + let p = a as i32 + b as i32 - c as i32; + let pa = (p - a as i32).abs(); + let pb = (p - b as i32).abs(); + let pc = (p - c as i32).abs(); + if pa <= pb && pa <= pc { + a + } else if pb <= pc { + b + } else { + c + } +} diff --git a/src/headers.rs b/src/headers.rs new file mode 100644 index 00000000..9e870ca2 --- /dev/null +++ b/src/headers.rs @@ -0,0 +1,120 @@ +use byteorder::{BigEndian, ReadBytesExt}; +use colors::{BitDepth, ColorType}; +use crc::crc32; +use std::io::Cursor; + +#[derive(Debug, Clone, Copy)] +/// Headers from the IHDR chunk of the image +pub struct IhdrData { + /// The width of the image in pixels + pub width: u32, + /// The height of the image in pixels + pub height: u32, + /// The color type of the image + pub color_type: ColorType, + /// The bit depth of the image + pub bit_depth: BitDepth, + /// The compression method used for this image (0 for DEFLATE) + pub compression: u8, + /// The filter mode used for this image (currently only 0 is valid) + pub filter: u8, + /// The interlacing mode of the image (0 = None, 1 = Adam7) + pub interlaced: u8, +} + +#[derive(Debug, PartialEq, Clone)] +/// Options to use for performing operations on headers (such as stripping) +pub enum Headers { + /// None + None, + /// Some, with a list of 4-character chunk codes + Some(Vec), + /// Headers that won't affect rendering (all but cHRM, gAMA, iCCP, sBIT, sRGB, bKGD, hIST, pHYs, sPLT) + Safe, + /// All non-critical headers + All, +} + +pub fn file_header_is_valid(bytes: &[u8]) -> bool { + let expected_header: [u8; 8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]; + + bytes.iter().zip(expected_header.iter()).all(|x| x.0 == x.1) +} + +pub fn parse_next_header(byte_data: &[u8], + byte_offset: &mut usize, + fix_errors: bool) + -> Result)>, String> { + let mut rdr = Cursor::new(byte_data.iter() + .skip(*byte_offset) + .take(4) + .cloned() + .collect::>()); + let length: u32 = match rdr.read_u32::() { + Ok(x) => x, + Err(_) => return Err("Invalid data found--unable to read PNG file".to_owned()), + }; + *byte_offset += 4; + + let mut header_bytes: Vec = byte_data.iter().skip(*byte_offset).take(4).cloned().collect(); + let header = match String::from_utf8(header_bytes.clone()) { + Ok(x) => x, + Err(_) => return Err("Invalid data found--unable to read PNG file".to_owned()), + }; + if header == "IEND" { + // End of data + return Ok(None); + } + *byte_offset += 4; + + let data: Vec = byte_data.iter() + .skip(*byte_offset) + .take(length as usize) + .cloned() + .collect(); + *byte_offset += length as usize; + let mut rdr = Cursor::new(byte_data.iter() + .skip(*byte_offset) + .take(4) + .cloned() + .collect::>()); + let crc: u32 = match rdr.read_u32::() { + Ok(x) => x, + Err(_) => return Err("Invalid data found--unable to read PNG file".to_owned()), + }; + *byte_offset += 4; + header_bytes.extend(data.clone()); + if !fix_errors && crc32::checksum_ieee(header_bytes.as_ref()) != crc { + return Err(format!("Corrupt data chunk found--CRC Mismatch in {}\nThis may be recoverable by using --fix", + header)); + } + + Ok(Some((header, data))) +} + +pub fn parse_ihdr_header(byte_data: &[u8]) -> Result { + let mut rdr = Cursor::new(&byte_data[0..8]); + Ok(IhdrData { + color_type: match byte_data[9] { + 0 => ColorType::Grayscale, + 2 => ColorType::RGB, + 3 => ColorType::Indexed, + 4 => ColorType::GrayscaleAlpha, + 6 => ColorType::RGBA, + _ => return Err("Unexpected color type in header".to_owned()), + }, + bit_depth: match byte_data[8] { + 1 => BitDepth::One, + 2 => BitDepth::Two, + 4 => BitDepth::Four, + 8 => BitDepth::Eight, + 16 => BitDepth::Sixteen, + _ => return Err("Unexpected bit depth in header".to_owned()), + }, + width: rdr.read_u32::().unwrap(), + height: rdr.read_u32::().unwrap(), + compression: byte_data[10], + filter: byte_data[11], + interlaced: byte_data[12], + }) +} diff --git a/src/interlace.rs b/src/interlace.rs new file mode 100644 index 00000000..a87c0d8f --- /dev/null +++ b/src/interlace.rs @@ -0,0 +1,211 @@ +use bit_vec::BitVec; +use png::PngData; + +pub fn interlace_image(png: &mut PngData) { + let mut passes: Vec = vec![BitVec::new(); 7]; + let bits_per_pixel = png.ihdr_data.bit_depth.as_u8() * png.channels_per_pixel(); + for (index, line) in png.scan_lines().enumerate() { + match index % 8 { + // Add filter bytes to passes that will be in the output image + 0 => { + passes[0].extend(BitVec::from_elem(8, false)); + if png.ihdr_data.width >= 5 { + passes[1].extend(BitVec::from_elem(8, false)); + } + if png.ihdr_data.width >= 3 { + passes[3].extend(BitVec::from_elem(8, false)); + } + if png.ihdr_data.width >= 2 { + passes[5].extend(BitVec::from_elem(8, false)); + } + } + 4 => { + passes[2].extend(BitVec::from_elem(8, false)); + if png.ihdr_data.width >= 3 { + passes[3].extend(BitVec::from_elem(8, false)); + } + if png.ihdr_data.width >= 2 { + passes[5].extend(BitVec::from_elem(8, false)); + } + } + 2 | 6 => { + passes[4].extend(BitVec::from_elem(8, false)); + if png.ihdr_data.width >= 2 { + passes[5].extend(BitVec::from_elem(8, false)); + } + } + _ => { + passes[6].extend(BitVec::from_elem(8, false)); + } + } + let bit_vec = BitVec::from_bytes(&line.data); + for (i, bit) in bit_vec.iter().enumerate() { + // Avoid moving padded 0's into new image + if i >= (png.ihdr_data.width * bits_per_pixel as u32) as usize { + break; + } + // Copy pixels into interlaced passes + let pix_modulo = (i / bits_per_pixel as usize) % 8; + match index % 8 { + 0 => { + match pix_modulo { + 0 => passes[0].push(bit), + 4 => passes[1].push(bit), + 2 | 6 => passes[3].push(bit), + _ => passes[5].push(bit), + } + } + 4 => { + match pix_modulo { + 0 | 4 => passes[2].push(bit), + 2 | 6 => passes[3].push(bit), + _ => passes[5].push(bit), + } + } + 2 | 6 => { + match pix_modulo % 2 { + 0 => passes[4].push(bit), + _ => passes[5].push(bit), + } + } + _ => { + passes[6].push(bit); + } + } + } + // Pad end of line on each pass to get 8 bits per byte + for pass in &mut passes { + while pass.len() % 8 != 0 { + pass.push(false); + } + } + } + let mut output = Vec::new(); + for pass in &passes { + output.extend(pass.to_bytes()); + } + png.raw_data = output; +} + +pub fn deinterlace_image(png: &mut PngData) { + let bits_per_pixel = png.ihdr_data.bit_depth.as_u8() * png.channels_per_pixel(); + let bits_per_line = 8 + bits_per_pixel as usize * png.ihdr_data.width as usize; + // Initialize each output line with a starting filter byte of 0 + // as well as some blank data + let mut lines: Vec = + vec![BitVec::from_elem(bits_per_line, false); png.ihdr_data.height as usize]; + let mut current_pass = 1; + let mut pass_constants = interlaced_constants(current_pass); + let mut current_y: usize = pass_constants.y_shift as usize; + for line in png.scan_lines() { + let bit_vec = BitVec::from_bytes(&line.data); + let bits_in_line = ((png.ihdr_data.width - pass_constants.x_shift as u32) as f32 / + pass_constants.x_step as f32) + .ceil() as usize * bits_per_pixel as usize; + for (i, bit) in bit_vec.iter().enumerate() { + // Avoid moving padded 0's into new image + if i >= bits_in_line { + break; + } + let current_x: usize = pass_constants.x_shift as usize + + (i / bits_per_pixel as usize) * pass_constants.x_step as usize; + // Copy this bit into the output line, offset by 8 because of filter byte + let index = 8 + (i % bits_per_pixel as usize) + current_x * bits_per_pixel as usize; + lines[current_y].set(index, bit); + } + // Calculate the next line and move to next pass if necessary + current_y += pass_constants.y_step as usize; + if current_y >= png.ihdr_data.height as usize { + if current_pass == 7 { + break; + } + current_pass += 1; + if current_pass == 2 && png.ihdr_data.width <= 4 { + current_pass += 1; + } + if current_pass == 3 && png.ihdr_data.height <= 4 { + current_pass += 1; + } + pass_constants = interlaced_constants(current_pass); + current_y = pass_constants.y_shift as usize; + } + } + let mut output = Vec::new(); + for line in &mut lines { + while line.len() % 8 != 0 { + line.push(false); + } + output.extend(line.to_bytes()); + } + png.raw_data = output; +} + +#[derive(Clone, Copy)] +struct InterlacedConstants { + x_shift: u8, + y_shift: u8, + x_step: u8, + y_step: u8, +} + +fn interlaced_constants(pass: u8) -> InterlacedConstants { + match pass { + 1 => { + InterlacedConstants { + x_shift: 0, + y_shift: 0, + x_step: 8, + y_step: 8, + } + } + 2 => { + InterlacedConstants { + x_shift: 4, + y_shift: 0, + x_step: 8, + y_step: 8, + } + } + 3 => { + InterlacedConstants { + x_shift: 0, + y_shift: 4, + x_step: 4, + y_step: 8, + } + } + 4 => { + InterlacedConstants { + x_shift: 2, + y_shift: 0, + x_step: 4, + y_step: 4, + } + } + 5 => { + InterlacedConstants { + x_shift: 0, + y_shift: 2, + x_step: 2, + y_step: 4, + } + } + 6 => { + InterlacedConstants { + x_shift: 1, + y_shift: 0, + x_step: 2, + y_step: 2, + } + } + 7 => { + InterlacedConstants { + x_shift: 0, + y_shift: 1, + x_step: 1, + y_step: 2, + } + } + _ => unreachable!(), + } +} diff --git a/src/lib.rs b/src/lib.rs index 7b3496af..67e2da6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ extern crate miniz_sys; extern crate num_cpus; extern crate scoped_pool; +use headers::Headers; use scoped_pool::Pool; use std::collections::{HashMap, HashSet}; use std::fs::{File, copy}; @@ -15,12 +16,17 @@ use std::io::{BufWriter, Write, stderr, stdout}; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; +pub mod colors; pub mod deflate { pub mod deflate; pub mod libz_stream; pub mod miniz_stream; } +mod filters; +pub mod headers; +mod interlace; pub mod png; +mod reduction; #[derive(Clone,Debug)] /// Options controlling the output of the `optimize` function @@ -96,7 +102,7 @@ pub struct Options { pub idat_recoding: bool, /// Which headers to strip from the PNG file, if any /// Default: `None` - pub strip: png::Headers, + pub strip: Headers, /// Whether to use heuristics to pick the best filter and compression /// Intended for use with `-o 1` from the CLI interface /// Default: `false` @@ -148,7 +154,7 @@ impl Default for Options { color_type_reduction: true, palette_reduction: true, idat_recoding: true, - strip: png::Headers::None, + strip: Headers::None, use_heuristics: false, threads: thread_count, } @@ -339,7 +345,7 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op if opts.use_heuristics { // Heuristically determine which set of options to use if png.ihdr_data.bit_depth.as_u8() >= 8 && - png.ihdr_data.color_type != png::ColorType::Indexed { + png.ihdr_data.color_type != colors::ColorType::Indexed { if filter.is_empty() { filter.insert(5); } @@ -540,13 +546,13 @@ fn report_reduction(png: &png::PngData) { fn perform_strip(png: &mut png::PngData, opts: &Options) { match opts.strip.clone() { // Strip headers - png::Headers::None => (), - png::Headers::Some(hdrs) => { + Headers::None => (), + Headers::Some(hdrs) => { for hdr in &hdrs { png.aux_headers.remove(hdr); } } - png::Headers::Safe => { + Headers::Safe => { const PRESERVED_HEADERS: [&'static str; 9] = ["cHRM", "gAMA", "iCCP", "sBIT", "sRGB", "bKGD", "hIST", "pHYs", "sPLT"]; let mut preserved = HashMap::new(); @@ -557,7 +563,7 @@ fn perform_strip(png: &mut png::PngData, opts: &Options) { } png.aux_headers = preserved; } - png::Headers::All => { + Headers::All => { png.aux_headers = HashMap::new(); } } diff --git a/src/main.rs b/src/main.rs index 097acc77..2ee3d996 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ extern crate clap; extern crate regex; use clap::{App, Arg, ArgMatches}; -use oxipng::png; +use oxipng::headers::Headers; use regex::Regex; use std::collections::HashSet; use std::fs::DirBuilder; @@ -475,9 +475,9 @@ fn parse_opts_into_struct(matches: &ArgMatches, opts: &mut oxipng::Options) -> R .to_owned()); } if hdrs[0] == "safe" { - opts.strip = png::Headers::Safe; + opts.strip = Headers::Safe; } else { - opts.strip = png::Headers::All; + opts.strip = Headers::All; } } else { const FORBIDDEN_CHUNKS: [&'static str; 5] = ["IHDR", "IDAT", "tRNS", "PLTE", "IEND"]; @@ -486,12 +486,12 @@ fn parse_opts_into_struct(matches: &ArgMatches, opts: &mut oxipng::Options) -> R return Err(format!("{} chunk is not allowed to be stripped", i)); } } - opts.strip = png::Headers::Some(hdrs); + opts.strip = Headers::Some(hdrs); } } if matches.is_present("strip-safe") { - opts.strip = png::Headers::Safe; + opts.strip = Headers::Safe; } if let Some(x) = matches.value_of("threads") { diff --git a/src/png.rs b/src/png.rs index a671d563..c0fec9bf 100644 --- a/src/png.rs +++ b/src/png.rs @@ -1,122 +1,18 @@ use bit_vec::BitVec; -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use byteorder::{BigEndian, WriteBytesExt}; +use colors::{BitDepth, ColorType}; use crc::crc32; +use filters::*; +use headers::*; +use interlace::{interlace_image, deinterlace_image}; use itertools::Itertools; +use reduction::*; use std::collections::{HashMap, HashSet}; -use std::fmt; use std::fs::File; -use std::io::{Cursor, Read}; +use std::io::Read; use std::iter::Iterator; use std::path::Path; -#[derive(Debug,PartialEq,Clone,Copy)] -/// The color type used to represent this image -pub enum ColorType { - /// Grayscale, with one color channel - Grayscale, - /// RGB, with three color channels - RGB, - /// Indexed, with one byte per pixel representing one of up to 256 colors in the image - Indexed, - /// Grayscale + Alpha, with two color channels - GrayscaleAlpha, - /// RGBA, with four color channels - RGBA, -} - -impl fmt::Display for ColorType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, - "{}", - match *self { - ColorType::Grayscale => "Grayscale", - ColorType::RGB => "RGB", - ColorType::Indexed => "Indexed", - ColorType::GrayscaleAlpha => "Grayscale + Alpha", - ColorType::RGBA => "RGB + Alpha", - }) - } -} - -impl ColorType { - /// Get the code used by the PNG specification to denote this color type - fn png_header_code(&self) -> u8 { - match *self { - ColorType::Grayscale => 0, - ColorType::RGB => 2, - ColorType::Indexed => 3, - ColorType::GrayscaleAlpha => 4, - ColorType::RGBA => 6, - } - } -} - -#[derive(Debug,PartialEq,Clone,Copy)] -/// The number of bits to be used per channel per pixel -pub enum BitDepth { - /// One bit per channel per pixel - One, - /// Two bits per channel per pixel - Two, - /// Four bits per channel per pixel - Four, - /// Eight bits per channel per pixel - Eight, - /// Sixteen bits per channel per pixel - Sixteen, -} - -impl fmt::Display for BitDepth { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, - "{}", - match *self { - BitDepth::One => "1", - BitDepth::Two => "2", - BitDepth::Four => "4", - BitDepth::Eight => "8", - BitDepth::Sixteen => "16", - }) - } -} - -impl BitDepth { - /// Retrieve the number of bits per channel per pixel as a `u8` - pub fn as_u8(&self) -> u8 { - match *self { - BitDepth::One => 1, - BitDepth::Two => 2, - BitDepth::Four => 4, - BitDepth::Eight => 8, - BitDepth::Sixteen => 16, - } - } - /// Parse a number of bits per channel per pixel into a `BitDepth` - pub fn from_u8(depth: u8) -> BitDepth { - match depth { - 1 => BitDepth::One, - 2 => BitDepth::Two, - 4 => BitDepth::Four, - 8 => BitDepth::Eight, - 16 => BitDepth::Sixteen, - _ => panic!("Unsupported bit depth"), - } - } -} - -#[derive(Debug,PartialEq,Clone)] -/// Options to use for performing operations on headers (such as stripping) -pub enum Headers { - /// None - None, - /// Some, with a list of 4-character chunk codes - Some(Vec), - /// Headers that won't affect rendering (all but cHRM, gAMA, iCCP, sBIT, sRGB, bKGD, hIST, pHYs, sPLT) - Safe, - /// All non-critical headers - All, -} - #[derive(Debug,Clone)] /// An iterator over the scan lines of a PNG image pub struct ScanLines<'a> { @@ -283,25 +179,6 @@ pub struct PngData { pub aux_headers: HashMap>, } -#[derive(Debug,Clone,Copy)] -/// Headers from the IHDR chunk of the image -pub struct IhdrData { - /// The width of the image in pixels - pub width: u32, - /// The height of the image in pixels - pub height: u32, - /// The color type of the image - pub color_type: ColorType, - /// The bit depth of the image - pub bit_depth: BitDepth, - /// The compression method used for this image (0 for DEFLATE) - pub compression: u8, - /// The filter mode used for this image (currently only 0 is valid) - pub filter: u8, - /// The interlacing mode of the image (0 = None, 1 = Adam7) - pub interlaced: u8, -} - impl PngData { /// Create a new `PngData` struct by opening a file pub fn new(filepath: &Path, fix_errors: bool) -> Result { @@ -393,6 +270,7 @@ impl PngData { // Return the PngData Ok(png_data) } + /// Return the number of channels in the image, based on color type pub fn channels_per_pixel(&self) -> u8 { match self.ihdr_data.color_type { @@ -402,6 +280,7 @@ impl PngData { ColorType::RGBA => 4, } } + /// Format the `PngData` struct into a valid PNG bytestream pub fn output(&self) -> Vec { // PNG header @@ -446,6 +325,7 @@ impl PngData { output } + /// Return an iterator over the scanlines of the image pub fn scan_lines(&self) -> ScanLines { ScanLines { @@ -455,6 +335,7 @@ impl PngData { pass: None, } } + /// Reverse all filters applied on the image, returning an unfiltered IDAT bytestream pub fn unfilter_image(&self) -> Vec { let mut unfiltered = Vec::with_capacity(self.raw_data.len()); @@ -470,6 +351,7 @@ impl PngData { } unfiltered } + /// Apply the specified filter type to all rows in the image /// 0: None /// 1: Sub @@ -530,6 +412,7 @@ impl PngData { } filtered } + /// Attempt to reduce the bit depth of the image /// Returns true if the bit depth was reduced, false otherwise pub fn reduce_bit_depth(&mut self) -> bool { @@ -576,6 +459,7 @@ impl PngData { self.raw_data = reduced; true } + /// Attempt to reduce the number of colors in the palette /// Returns true if the palette was reduced, false otherwise pub fn reduce_palette(&mut self) -> bool { @@ -672,6 +556,7 @@ impl PngData { true } + fn do_palette_reduction(&mut self, indices: &[u8], index_map: &mut HashMap, @@ -766,6 +651,7 @@ impl PngData { let new_palette = indexed_palette.iter().cloned().flatten().cloned().collect::>(); self.palette = Some(new_palette); } + /// Attempt to reduce the color type of the image /// Returns true if the color type was reduced, false otherwise pub fn reduce_color_type(&mut self) -> bool { @@ -851,6 +737,7 @@ impl PngData { changed } + /// Convert the image to the specified interlacing type /// Returns true if the interlacing was changed, false otherwise /// The `interlace` parameter specifies the *new* interlacing mode @@ -871,797 +758,6 @@ impl PngData { } } -fn interlace_image(png: &mut PngData) { - let mut passes: Vec = vec![BitVec::new(); 7]; - let bits_per_pixel = png.ihdr_data.bit_depth.as_u8() * png.channels_per_pixel(); - for (index, line) in png.scan_lines().enumerate() { - match index % 8 { - // Add filter bytes to passes that will be in the output image - 0 => { - passes[0].extend(BitVec::from_elem(8, false)); - if png.ihdr_data.width >= 5 { - passes[1].extend(BitVec::from_elem(8, false)); - } - if png.ihdr_data.width >= 3 { - passes[3].extend(BitVec::from_elem(8, false)); - } - if png.ihdr_data.width >= 2 { - passes[5].extend(BitVec::from_elem(8, false)); - } - } - 4 => { - passes[2].extend(BitVec::from_elem(8, false)); - if png.ihdr_data.width >= 3 { - passes[3].extend(BitVec::from_elem(8, false)); - } - if png.ihdr_data.width >= 2 { - passes[5].extend(BitVec::from_elem(8, false)); - } - } - 2 | 6 => { - passes[4].extend(BitVec::from_elem(8, false)); - if png.ihdr_data.width >= 2 { - passes[5].extend(BitVec::from_elem(8, false)); - } - } - _ => { - passes[6].extend(BitVec::from_elem(8, false)); - } - } - let bit_vec = BitVec::from_bytes(&line.data); - for (i, bit) in bit_vec.iter().enumerate() { - // Avoid moving padded 0's into new image - if i >= (png.ihdr_data.width * bits_per_pixel as u32) as usize { - break; - } - // Copy pixels into interlaced passes - let pix_modulo = (i / bits_per_pixel as usize) % 8; - match index % 8 { - 0 => { - match pix_modulo { - 0 => passes[0].push(bit), - 4 => passes[1].push(bit), - 2 | 6 => passes[3].push(bit), - _ => passes[5].push(bit), - } - } - 4 => { - match pix_modulo { - 0 | 4 => passes[2].push(bit), - 2 | 6 => passes[3].push(bit), - _ => passes[5].push(bit), - } - } - 2 | 6 => { - match pix_modulo % 2 { - 0 => passes[4].push(bit), - _ => passes[5].push(bit), - } - } - _ => { - passes[6].push(bit); - } - } - } - // Pad end of line on each pass to get 8 bits per byte - for pass in &mut passes { - while pass.len() % 8 != 0 { - pass.push(false); - } - } - } - let mut output = Vec::new(); - for pass in &passes { - output.extend(pass.to_bytes()); - } - png.raw_data = output; -} - -fn deinterlace_image(png: &mut PngData) { - let bits_per_pixel = png.ihdr_data.bit_depth.as_u8() * png.channels_per_pixel(); - let bits_per_line = 8 + bits_per_pixel as usize * png.ihdr_data.width as usize; - // Initialize each output line with a starting filter byte of 0 - // as well as some blank data - let mut lines: Vec = - vec![BitVec::from_elem(bits_per_line, false); png.ihdr_data.height as usize]; - let mut current_pass = 1; - let mut pass_constants = interlaced_constants(current_pass); - let mut current_y: usize = pass_constants.y_shift as usize; - for line in png.scan_lines() { - let bit_vec = BitVec::from_bytes(&line.data); - let bits_in_line = ((png.ihdr_data.width - pass_constants.x_shift as u32) as f32 / - pass_constants.x_step as f32) - .ceil() as usize * bits_per_pixel as usize; - for (i, bit) in bit_vec.iter().enumerate() { - // Avoid moving padded 0's into new image - if i >= bits_in_line { - break; - } - let current_x: usize = pass_constants.x_shift as usize + - (i / bits_per_pixel as usize) * pass_constants.x_step as usize; - // Copy this bit into the output line, offset by 8 because of filter byte - let index = 8 + (i % bits_per_pixel as usize) + current_x * bits_per_pixel as usize; - lines[current_y].set(index, bit); - } - // Calculate the next line and move to next pass if necessary - current_y += pass_constants.y_step as usize; - if current_y >= png.ihdr_data.height as usize { - if current_pass == 7 { - break; - } - current_pass += 1; - if current_pass == 2 && png.ihdr_data.width <= 4 { - current_pass += 1; - } - if current_pass == 3 && png.ihdr_data.height <= 4 { - current_pass += 1; - } - pass_constants = interlaced_constants(current_pass); - current_y = pass_constants.y_shift as usize; - } - } - let mut output = Vec::new(); - for line in &mut lines { - while line.len() % 8 != 0 { - line.push(false); - } - output.extend(line.to_bytes()); - } - png.raw_data = output; -} - -#[derive(Clone, Copy)] -struct InterlacedConstants { - x_shift: u8, - y_shift: u8, - x_step: u8, - y_step: u8, -} - -fn interlaced_constants(pass: u8) -> InterlacedConstants { - match pass { - 1 => { - InterlacedConstants { - x_shift: 0, - y_shift: 0, - x_step: 8, - y_step: 8, - } - } - 2 => { - InterlacedConstants { - x_shift: 4, - y_shift: 0, - x_step: 8, - y_step: 8, - } - } - 3 => { - InterlacedConstants { - x_shift: 0, - y_shift: 4, - x_step: 4, - y_step: 8, - } - } - 4 => { - InterlacedConstants { - x_shift: 2, - y_shift: 0, - x_step: 4, - y_step: 4, - } - } - 5 => { - InterlacedConstants { - x_shift: 0, - y_shift: 2, - x_step: 2, - y_step: 4, - } - } - 6 => { - InterlacedConstants { - x_shift: 1, - y_shift: 0, - x_step: 2, - y_step: 2, - } - } - 7 => { - InterlacedConstants { - x_shift: 0, - y_shift: 1, - x_step: 1, - y_step: 2, - } - } - _ => unreachable!(), - } -} - -fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec { - let mut filtered = Vec::with_capacity(data.len()); - match filter { - 0 => { - filtered.extend_from_slice(data); - } - 1 => { - filtered.extend_from_slice(&data[0..bpp]); - filtered.extend_from_slice(&data.iter() - .skip(bpp) - .zip(data.iter()) - .map(|(cur, last)| cur.wrapping_sub(*last)) - .collect::>()); - } - 2 => { - if last_line.is_empty() { - filtered.extend_from_slice(data); - } else { - filtered.extend_from_slice(&data.iter() - .zip(last_line.iter()) - .map(|(cur, last)| cur.wrapping_sub(*last)) - .collect::>()); - }; - } - 3 => { - for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - filtered.push(match i.checked_sub(bpp) { - Some(x) => byte.wrapping_sub(data[x] >> 1), - None => *byte, - }); - } else { - filtered.push(match i.checked_sub(bpp) { - Some(x) => { - byte.wrapping_sub(((data[x] as u16 + last_line[i] as u16) >> 1) as u8) - } - None => byte.wrapping_sub(last_line[i] >> 1), - }); - }; - } - } - 4 => { - for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - filtered.push(match i.checked_sub(bpp) { - Some(x) => byte.wrapping_sub(data[x]), - None => *byte, - }); - } else { - filtered.push(match i.checked_sub(bpp) { - Some(x) => { - byte.wrapping_sub(paeth_predictor(data[x], last_line[i], last_line[x])) - } - None => byte.wrapping_sub(last_line[i]), - }); - }; - } - } - _ => unreachable!(), - } - filtered -} - -fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec { - let mut unfiltered = Vec::with_capacity(data.len()); - match filter { - 0 => { - unfiltered.extend_from_slice(data); - } - 1 => { - for (i, byte) in data.iter().enumerate() { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(b)); - } - None => { - unfiltered.push(*byte); - } - }; - } - } - 2 => { - if last_line.is_empty() { - unfiltered.extend_from_slice(data); - } else { - unfiltered.extend_from_slice(&data.iter() - .zip(last_line.iter()) - .map(|(cur, last)| cur.wrapping_add(*last)) - .collect::>()); - }; - } - 3 => { - for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(b >> 1)); - } - None => { - unfiltered.push(*byte); - } - }; - } else { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(((b as u16 + last_line[i] as u16) >> 1) as u8)); - } - None => { - unfiltered.push(byte.wrapping_add(last_line[i] >> 1)); - } - }; - }; - } - } - 4 => { - for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(b)); - } - None => { - unfiltered.push(*byte); - } - }; - } else { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(paeth_predictor(b, - last_line[i], - last_line[x]))); - } - None => { - unfiltered.push(byte.wrapping_add(last_line[i])); - } - }; - }; - } - } - _ => unreachable!(), - } - unfiltered -} - -fn reduce_bit_depth_8_or_less(png: &PngData) -> Option<(Vec, u8)> { - let mut reduced = BitVec::with_capacity(png.raw_data.len() * 8); - let bit_depth: usize = png.ihdr_data.bit_depth.as_u8() as usize; - let mut allowed_bits = 1; - for line in png.scan_lines() { - let bit_vec = BitVec::from_bytes(&line.data); - for (i, bit) in bit_vec.iter().enumerate() { - let bit_index = bit_depth - (i % bit_depth); - if bit && bit_index > allowed_bits { - allowed_bits = bit_index.next_power_of_two(); - if allowed_bits == bit_depth { - // Not reducable - return None; - } - } - } - } - - for line in png.scan_lines() { - reduced.extend(BitVec::from_bytes(&[line.filter])); - let bit_vec = BitVec::from_bytes(&line.data); - for (i, bit) in bit_vec.iter().enumerate() { - let bit_index = bit_depth - (i % bit_depth); - if bit_index <= allowed_bits { - reduced.push(bit); - } - } - // Pad end of line to get 8 bits per byte - while reduced.len() % 8 != 0 { - reduced.push(false); - } - } - - Some((reduced.to_bytes(), allowed_bits as u8)) -} - -fn reduce_rgba_to_rgb(png: &PngData) -> Option> { - let mut reduced = Vec::with_capacity(png.raw_data.len()); - let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3; - let bpp: usize = 4 * byte_depth as usize; - let colored_bytes = bpp - byte_depth as usize; - for line in png.scan_lines() { - reduced.push(line.filter); - for (i, byte) in line.data.iter().enumerate() { - if i % bpp >= colored_bytes { - if *byte != 255 { - return None; - } - } else { - reduced.push(*byte); - } - } - } - - Some(reduced) -} - -fn reduce_rgba_to_grayscale_alpha(png: &PngData) -> Option> { - let mut reduced = Vec::with_capacity(png.raw_data.len()); - let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3; - let bpp: usize = 4 * byte_depth as usize; - let colored_bytes = bpp - byte_depth as usize; - for line in png.scan_lines() { - reduced.push(line.filter); - let mut low_bytes = Vec::with_capacity(4); - let mut high_bytes = Vec::with_capacity(4); - let mut trans_bytes = Vec::with_capacity(byte_depth as usize); - for (i, byte) in line.data.iter().enumerate() { - if i % bpp < colored_bytes { - if byte_depth == 1 || i % 2 == 1 { - low_bytes.push(*byte); - } else { - high_bytes.push(*byte); - } - } else { - trans_bytes.push(*byte); - } - - if i % bpp == bpp - 1 { - if low_bytes.iter().unique().count() > 1 { - return None; - } - if byte_depth == 2 { - if high_bytes.iter().unique().count() > 1 { - return None; - } - reduced.push(high_bytes[0]); - high_bytes.clear(); - } - reduced.push(low_bytes[0]); - low_bytes.clear(); - reduced.extend_from_slice(&trans_bytes); - trans_bytes.clear(); - } - } - } - - Some(reduced) -} - -fn reduce_rgba_to_palette(png: &PngData) -> Option<(Vec, Vec, Vec)> { - if png.ihdr_data.bit_depth != BitDepth::Eight { - return None; - } - let mut reduced = Vec::with_capacity(png.raw_data.len()); - let mut palette = Vec::with_capacity(256); - let bpp: usize = (4 * png.ihdr_data.bit_depth.as_u8() as usize) >> 3; - for line in png.scan_lines() { - reduced.push(line.filter); - let mut cur_pixel = Vec::with_capacity(bpp); - for (i, byte) in line.data.iter().enumerate() { - cur_pixel.push(*byte); - if i % bpp == bpp - 1 { - if let Some(idx) = palette.iter().position(|x| x == &cur_pixel) { - reduced.push(idx as u8); - } else { - let len = palette.len(); - if len == 256 { - return None; - } - palette.push(cur_pixel.clone()); - reduced.push(len as u8); - } - cur_pixel.clear(); - } - } - } - - let mut color_palette = Vec::with_capacity(palette.len() * 3); - let mut trans_palette = Vec::with_capacity(palette.len()); - for color in &palette { - for (i, byte) in color.iter().enumerate() { - if i < 3 { - color_palette.push(*byte); - } else { - trans_palette.push(*byte); - } - } - } - - Some((reduced, color_palette, trans_palette)) -} - -fn reduce_rgb_to_palette(png: &PngData) -> Option<(Vec, Vec)> { - if png.ihdr_data.bit_depth != BitDepth::Eight { - return None; - } - let mut reduced = Vec::with_capacity(png.raw_data.len()); - let mut palette = Vec::with_capacity(256); - let bpp: usize = (3 * png.ihdr_data.bit_depth.as_u8() as usize) >> 3; - for line in png.scan_lines() { - reduced.push(line.filter); - let mut cur_pixel = Vec::with_capacity(bpp); - for (i, byte) in line.data.iter().enumerate() { - cur_pixel.push(*byte); - if i % bpp == bpp - 1 { - if let Some(idx) = palette.iter().position(|x| x == &cur_pixel) { - reduced.push(idx as u8); - } else { - let len = palette.len(); - if len == 256 { - return None; - } - palette.push(cur_pixel.clone()); - reduced.push(len as u8); - } - cur_pixel.clear(); - } - } - } - - let mut color_palette = Vec::with_capacity(palette.len() * 3); - for color in &palette { - color_palette.extend_from_slice(color); - } - - Some((reduced, color_palette)) -} - -fn reduce_grayscale_to_palette(png: &PngData) -> Option<(Vec, Vec)> { - if png.ihdr_data.bit_depth == BitDepth::Sixteen { - return None; - } - 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 None; - } - palette.push(pix_slice.clone()); - 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); - } - - Some((reduced.to_bytes(), color_palette)) -} - -fn reduce_palette_to_grayscale(png: &PngData) -> Option> { - let mut reduced = BitVec::with_capacity(png.raw_data.len() * 8); - let mut cur_pixel = Vec::with_capacity(3); - let palette = png.palette.clone().unwrap(); - // Iterate through palette and determine if all colors are grayscale - for byte in &palette { - cur_pixel.push(*byte); - if cur_pixel.len() == 3 { - if cur_pixel.iter().unique().count() > 1 { - return None; - } - cur_pixel.clear(); - } - } - - // Iterate through scanlines and assign grayscale value to each pixel - let bit_depth: usize = png.ihdr_data.bit_depth.as_u8() as usize; - let bit_depth_inverse = 8 - bit_depth; - 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(bit_depth); - for bit in bit_vec { - // Handle bit depths less than 8-bits - // At the end of each pixel, push its grayscale value onto the reduced image - cur_pixel.push(bit); - if cur_pixel.len() == bit_depth { - // `to_bytes` gives us e.g. 10000000 for a 1-bit pixel, when we would want 00000001 - let padded_pixel = cur_pixel.to_bytes()[0] >> bit_depth_inverse; - let palette_idx: usize = padded_pixel as usize * 3; - reduced.extend(BitVec::from_bytes(&[palette[palette_idx]])); - // BitVec's clear function doesn't set len to 0 - cur_pixel = BitVec::with_capacity(bit_depth); - } - } - // Pad end of line to get 8 bits per byte - while reduced.len() % 8 != 0 { - reduced.push(false); - } - } - - Some(reduced.to_bytes()) -} - -fn reduce_rgb_to_grayscale(png: &PngData) -> Option> { - let mut reduced = Vec::with_capacity(png.raw_data.len()); - let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3; - let bpp: usize = 3 * byte_depth as usize; - let mut cur_pixel = Vec::with_capacity(bpp); - for line in png.scan_lines() { - reduced.push(line.filter); - for (i, byte) in line.data.iter().enumerate() { - cur_pixel.push(*byte); - if i % bpp == bpp - 1 { - if bpp == 3 { - if cur_pixel.iter().unique().count() > 1 { - return None; - } - reduced.push(cur_pixel[0]); - } else { - let pixel_bytes = cur_pixel.iter() - .step(2) - .cloned() - .zip(cur_pixel.iter() - .skip(1) - .step(2) - .cloned()) - .unique() - .collect::>(); - if pixel_bytes.len() > 1 { - return None; - } - reduced.push(pixel_bytes[0].0); - reduced.push(pixel_bytes[0].1); - } - cur_pixel.clear(); - } - } - } - - Some(reduced) -} - -fn reduce_grayscale_alpha_to_grayscale(png: &PngData) -> Option> { - let mut reduced = Vec::with_capacity(png.raw_data.len()); - let byte_depth = png.ihdr_data.bit_depth.as_u8() >> 3; - let bpp: usize = 2 * byte_depth as usize; - let colored_bytes = bpp - byte_depth as usize; - for line in png.scan_lines() { - reduced.push(line.filter); - for (i, byte) in line.data.iter().enumerate() { - if i % bpp >= colored_bytes { - if *byte != 255 { - return None; - } - } else { - reduced.push(*byte); - } - } - } - - Some(reduced) -} - -fn paeth_predictor(a: u8, b: u8, c: u8) -> u8 { - let p = a as i32 + b as i32 - c as i32; - let pa = (p - a as i32).abs(); - let pb = (p - b as i32).abs(); - let pc = (p - c as i32).abs(); - if pa <= pb && pa <= pc { - a - } else if pb <= pc { - b - } else { - c - } -} - -fn file_header_is_valid(bytes: &[u8]) -> bool { - let expected_header: [u8; 8] = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]; - - bytes.iter().zip(expected_header.iter()).all(|x| x.0 == x.1) -} - -fn parse_next_header(byte_data: &[u8], - byte_offset: &mut usize, - fix_errors: bool) - -> Result)>, String> { - let mut rdr = Cursor::new(byte_data.iter() - .skip(*byte_offset) - .take(4) - .cloned() - .collect::>()); - let length: u32 = match rdr.read_u32::() { - Ok(x) => x, - Err(_) => return Err("Invalid data found--unable to read PNG file".to_owned()), - }; - *byte_offset += 4; - - let mut header_bytes: Vec = byte_data.iter().skip(*byte_offset).take(4).cloned().collect(); - let header = match String::from_utf8(header_bytes.clone()) { - Ok(x) => x, - Err(_) => return Err("Invalid data found--unable to read PNG file".to_owned()), - }; - if header == "IEND" { - // End of data - return Ok(None); - } - *byte_offset += 4; - - let data: Vec = byte_data.iter() - .skip(*byte_offset) - .take(length as usize) - .cloned() - .collect(); - *byte_offset += length as usize; - let mut rdr = Cursor::new(byte_data.iter() - .skip(*byte_offset) - .take(4) - .cloned() - .collect::>()); - let crc: u32 = match rdr.read_u32::() { - Ok(x) => x, - Err(_) => return Err("Invalid data found--unable to read PNG file".to_owned()), - }; - *byte_offset += 4; - header_bytes.extend(data.clone()); - if !fix_errors && crc32::checksum_ieee(header_bytes.as_ref()) != crc { - return Err(format!("Corrupt data chunk found--CRC Mismatch in {}\nThis may be recoverable by using --fix", - header)); - } - - Ok(Some((header, data))) -} - -fn parse_ihdr_header(byte_data: &[u8]) -> Result { - let mut rdr = Cursor::new(&byte_data[0..8]); - Ok(IhdrData { - color_type: match byte_data[9] { - 0 => ColorType::Grayscale, - 2 => ColorType::RGB, - 3 => ColorType::Indexed, - 4 => ColorType::GrayscaleAlpha, - 6 => ColorType::RGBA, - _ => return Err("Unexpected color type in header".to_owned()), - }, - bit_depth: match byte_data[8] { - 1 => BitDepth::One, - 2 => BitDepth::Two, - 4 => BitDepth::Four, - 8 => BitDepth::Eight, - 16 => BitDepth::Sixteen, - _ => return Err("Unexpected bit depth in header".to_owned()), - }, - width: rdr.read_u32::().unwrap(), - height: rdr.read_u32::().unwrap(), - compression: byte_data[10], - filter: byte_data[11], - interlaced: byte_data[12], - }) -} - fn write_png_block(key: &[u8], header: &[u8], output: &mut Vec) { let mut header_data = Vec::with_capacity(header.len() + 4); header_data.extend_from_slice(key); diff --git a/src/reduction.rs b/src/reduction.rs new file mode 100644 index 00000000..0afff2ef --- /dev/null +++ b/src/reduction.rs @@ -0,0 +1,339 @@ +use bit_vec::BitVec; +use colors::BitDepth; +use itertools::Itertools; +use png::PngData; + +pub fn reduce_bit_depth_8_or_less(png: &PngData) -> Option<(Vec, u8)> { + let mut reduced = BitVec::with_capacity(png.raw_data.len() * 8); + let bit_depth: usize = png.ihdr_data.bit_depth.as_u8() as usize; + let mut allowed_bits = 1; + for line in png.scan_lines() { + let bit_vec = BitVec::from_bytes(&line.data); + for (i, bit) in bit_vec.iter().enumerate() { + let bit_index = bit_depth - (i % bit_depth); + if bit && bit_index > allowed_bits { + allowed_bits = bit_index.next_power_of_two(); + if allowed_bits == bit_depth { + // Not reducable + return None; + } + } + } + } + + for line in png.scan_lines() { + reduced.extend(BitVec::from_bytes(&[line.filter])); + let bit_vec = BitVec::from_bytes(&line.data); + for (i, bit) in bit_vec.iter().enumerate() { + let bit_index = bit_depth - (i % bit_depth); + if bit_index <= allowed_bits { + reduced.push(bit); + } + } + // Pad end of line to get 8 bits per byte + while reduced.len() % 8 != 0 { + reduced.push(false); + } + } + + Some((reduced.to_bytes(), allowed_bits as u8)) +} + +pub fn reduce_rgba_to_rgb(png: &PngData) -> Option> { + let mut reduced = Vec::with_capacity(png.raw_data.len()); + let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3; + let bpp: usize = 4 * byte_depth as usize; + let colored_bytes = bpp - byte_depth as usize; + for line in png.scan_lines() { + reduced.push(line.filter); + for (i, byte) in line.data.iter().enumerate() { + if i % bpp >= colored_bytes { + if *byte != 255 { + return None; + } + } else { + reduced.push(*byte); + } + } + } + + Some(reduced) +} + +pub fn reduce_rgba_to_grayscale_alpha(png: &PngData) -> Option> { + let mut reduced = Vec::with_capacity(png.raw_data.len()); + let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3; + let bpp: usize = 4 * byte_depth as usize; + let colored_bytes = bpp - byte_depth as usize; + for line in png.scan_lines() { + reduced.push(line.filter); + let mut low_bytes = Vec::with_capacity(4); + let mut high_bytes = Vec::with_capacity(4); + let mut trans_bytes = Vec::with_capacity(byte_depth as usize); + for (i, byte) in line.data.iter().enumerate() { + if i % bpp < colored_bytes { + if byte_depth == 1 || i % 2 == 1 { + low_bytes.push(*byte); + } else { + high_bytes.push(*byte); + } + } else { + trans_bytes.push(*byte); + } + + if i % bpp == bpp - 1 { + if low_bytes.iter().unique().count() > 1 { + return None; + } + if byte_depth == 2 { + if high_bytes.iter().unique().count() > 1 { + return None; + } + reduced.push(high_bytes[0]); + high_bytes.clear(); + } + reduced.push(low_bytes[0]); + low_bytes.clear(); + reduced.extend_from_slice(&trans_bytes); + trans_bytes.clear(); + } + } + } + + Some(reduced) +} + +pub fn reduce_rgba_to_palette(png: &PngData) -> Option<(Vec, Vec, Vec)> { + if png.ihdr_data.bit_depth != BitDepth::Eight { + return None; + } + let mut reduced = Vec::with_capacity(png.raw_data.len()); + let mut palette = Vec::with_capacity(256); + let bpp: usize = (4 * png.ihdr_data.bit_depth.as_u8() as usize) >> 3; + for line in png.scan_lines() { + reduced.push(line.filter); + let mut cur_pixel = Vec::with_capacity(bpp); + for (i, byte) in line.data.iter().enumerate() { + cur_pixel.push(*byte); + if i % bpp == bpp - 1 { + if let Some(idx) = palette.iter().position(|x| x == &cur_pixel) { + reduced.push(idx as u8); + } else { + let len = palette.len(); + if len == 256 { + return None; + } + palette.push(cur_pixel.clone()); + reduced.push(len as u8); + } + cur_pixel.clear(); + } + } + } + + let mut color_palette = Vec::with_capacity(palette.len() * 3); + let mut trans_palette = Vec::with_capacity(palette.len()); + for color in &palette { + for (i, byte) in color.iter().enumerate() { + if i < 3 { + color_palette.push(*byte); + } else { + trans_palette.push(*byte); + } + } + } + + Some((reduced, color_palette, trans_palette)) +} + +pub fn reduce_rgb_to_palette(png: &PngData) -> Option<(Vec, Vec)> { + if png.ihdr_data.bit_depth != BitDepth::Eight { + return None; + } + let mut reduced = Vec::with_capacity(png.raw_data.len()); + let mut palette = Vec::with_capacity(256); + let bpp: usize = (3 * png.ihdr_data.bit_depth.as_u8() as usize) >> 3; + for line in png.scan_lines() { + reduced.push(line.filter); + let mut cur_pixel = Vec::with_capacity(bpp); + for (i, byte) in line.data.iter().enumerate() { + cur_pixel.push(*byte); + if i % bpp == bpp - 1 { + if let Some(idx) = palette.iter().position(|x| x == &cur_pixel) { + reduced.push(idx as u8); + } else { + let len = palette.len(); + if len == 256 { + return None; + } + palette.push(cur_pixel.clone()); + reduced.push(len as u8); + } + cur_pixel.clear(); + } + } + } + + let mut color_palette = Vec::with_capacity(palette.len() * 3); + for color in &palette { + color_palette.extend_from_slice(color); + } + + Some((reduced, color_palette)) +} + +pub fn reduce_grayscale_to_palette(png: &PngData) -> Option<(Vec, Vec)> { + if png.ihdr_data.bit_depth == BitDepth::Sixteen { + return None; + } + 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 None; + } + palette.push(pix_slice.clone()); + 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); + } + + Some((reduced.to_bytes(), color_palette)) +} + +pub fn reduce_palette_to_grayscale(png: &PngData) -> Option> { + let mut reduced = BitVec::with_capacity(png.raw_data.len() * 8); + let mut cur_pixel = Vec::with_capacity(3); + let palette = png.palette.clone().unwrap(); + // Iterate through palette and determine if all colors are grayscale + for byte in &palette { + cur_pixel.push(*byte); + if cur_pixel.len() == 3 { + if cur_pixel.iter().unique().count() > 1 { + return None; + } + cur_pixel.clear(); + } + } + + // Iterate through scanlines and assign grayscale value to each pixel + let bit_depth: usize = png.ihdr_data.bit_depth.as_u8() as usize; + let bit_depth_inverse = 8 - bit_depth; + 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(bit_depth); + for bit in bit_vec { + // Handle bit depths less than 8-bits + // At the end of each pixel, push its grayscale value onto the reduced image + cur_pixel.push(bit); + if cur_pixel.len() == bit_depth { + // `to_bytes` gives us e.g. 10000000 for a 1-bit pixel, when we would want 00000001 + let padded_pixel = cur_pixel.to_bytes()[0] >> bit_depth_inverse; + let palette_idx: usize = padded_pixel as usize * 3; + reduced.extend(BitVec::from_bytes(&[palette[palette_idx]])); + // BitVec's clear function doesn't set len to 0 + cur_pixel = BitVec::with_capacity(bit_depth); + } + } + // Pad end of line to get 8 bits per byte + while reduced.len() % 8 != 0 { + reduced.push(false); + } + } + + Some(reduced.to_bytes()) +} + +pub fn reduce_rgb_to_grayscale(png: &PngData) -> Option> { + let mut reduced = Vec::with_capacity(png.raw_data.len()); + let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3; + let bpp: usize = 3 * byte_depth as usize; + let mut cur_pixel = Vec::with_capacity(bpp); + for line in png.scan_lines() { + reduced.push(line.filter); + for (i, byte) in line.data.iter().enumerate() { + cur_pixel.push(*byte); + if i % bpp == bpp - 1 { + if bpp == 3 { + if cur_pixel.iter().unique().count() > 1 { + return None; + } + reduced.push(cur_pixel[0]); + } else { + let pixel_bytes = cur_pixel.iter() + .step(2) + .cloned() + .zip(cur_pixel.iter() + .skip(1) + .step(2) + .cloned()) + .unique() + .collect::>(); + if pixel_bytes.len() > 1 { + return None; + } + reduced.push(pixel_bytes[0].0); + reduced.push(pixel_bytes[0].1); + } + cur_pixel.clear(); + } + } + } + + Some(reduced) +} + +pub fn reduce_grayscale_alpha_to_grayscale(png: &PngData) -> Option> { + let mut reduced = Vec::with_capacity(png.raw_data.len()); + let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3; + let bpp: usize = 2 * byte_depth as usize; + let colored_bytes = bpp - byte_depth as usize; + for line in png.scan_lines() { + reduced.push(line.filter); + for (i, byte) in line.data.iter().enumerate() { + if i % bpp >= colored_bytes { + if *byte != 255 { + return None; + } + } else { + reduced.push(*byte); + } + } + } + + Some(reduced) +} diff --git a/tests/filters.rs b/tests/filters.rs index 1a3d578b..dcc0ae38 100644 --- a/tests/filters.rs +++ b/tests/filters.rs @@ -3,6 +3,7 @@ extern crate oxipng; use image::GenericImage; use image::Pixel; +use oxipng::colors::{BitDepth, ColorType}; use oxipng::png; use std::collections::HashSet; use std::fs::remove_file; @@ -24,10 +25,10 @@ fn get_opts(input: &Path) -> oxipng::Options { 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) { + color_type_in: ColorType, + bit_depth_in: BitDepth, + color_type_out: ColorType, + bit_depth_out: BitDepth) { let png = png::PngData::new(input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.color_type, color_type_in); @@ -71,10 +72,10 @@ fn filter_0_for_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -88,10 +89,10 @@ fn filter_1_for_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -105,10 +106,10 @@ fn filter_2_for_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -122,10 +123,10 @@ fn filter_3_for_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -139,10 +140,10 @@ fn filter_4_for_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -156,10 +157,10 @@ fn filter_5_for_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -173,10 +174,10 @@ fn filter_0_for_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -190,10 +191,10 @@ fn filter_1_for_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -207,10 +208,10 @@ fn filter_2_for_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -224,10 +225,10 @@ fn filter_3_for_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -241,10 +242,10 @@ fn filter_4_for_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -258,10 +259,10 @@ fn filter_5_for_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -275,10 +276,10 @@ fn filter_0_for_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -292,10 +293,10 @@ fn filter_1_for_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -309,10 +310,10 @@ fn filter_2_for_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -326,10 +327,10 @@ fn filter_3_for_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -343,10 +344,10 @@ fn filter_4_for_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -360,10 +361,10 @@ fn filter_5_for_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -377,10 +378,10 @@ fn filter_0_for_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -394,10 +395,10 @@ fn filter_1_for_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -411,10 +412,10 @@ fn filter_2_for_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -428,10 +429,10 @@ fn filter_3_for_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -445,10 +446,10 @@ fn filter_4_for_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -462,10 +463,10 @@ fn filter_5_for_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -479,10 +480,10 @@ fn filter_0_for_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -496,10 +497,10 @@ fn filter_1_for_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -513,10 +514,10 @@ fn filter_2_for_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -530,10 +531,10 @@ fn filter_3_for_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -547,10 +548,10 @@ fn filter_4_for_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -564,10 +565,10 @@ fn filter_5_for_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -581,10 +582,10 @@ fn filter_0_for_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -598,10 +599,10 @@ fn filter_1_for_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -615,10 +616,10 @@ fn filter_2_for_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -632,10 +633,10 @@ fn filter_3_for_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -649,10 +650,10 @@ fn filter_4_for_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -666,10 +667,10 @@ fn filter_5_for_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -683,10 +684,10 @@ fn filter_0_for_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -700,10 +701,10 @@ fn filter_1_for_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -717,10 +718,10 @@ fn filter_2_for_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -734,10 +735,10 @@ fn filter_3_for_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -751,10 +752,10 @@ fn filter_4_for_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -768,10 +769,10 @@ fn filter_5_for_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -785,10 +786,10 @@ fn filter_0_for_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -802,10 +803,10 @@ fn filter_1_for_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -819,10 +820,10 @@ fn filter_2_for_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -836,10 +837,10 @@ fn filter_3_for_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -853,10 +854,10 @@ fn filter_4_for_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -870,10 +871,10 @@ fn filter_5_for_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -887,10 +888,10 @@ fn filter_0_for_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -904,10 +905,10 @@ fn filter_1_for_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -921,10 +922,10 @@ fn filter_2_for_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -938,10 +939,10 @@ fn filter_3_for_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -955,10 +956,10 @@ fn filter_4_for_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -972,10 +973,10 @@ fn filter_5_for_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -989,10 +990,10 @@ fn filter_0_for_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1006,10 +1007,10 @@ fn filter_1_for_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1023,10 +1024,10 @@ fn filter_2_for_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1040,10 +1041,10 @@ fn filter_3_for_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1057,10 +1058,10 @@ fn filter_4_for_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1074,10 +1075,10 @@ fn filter_5_for_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1091,10 +1092,10 @@ fn filter_0_for_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1108,10 +1109,10 @@ fn filter_1_for_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1125,10 +1126,10 @@ fn filter_2_for_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1142,10 +1143,10 @@ fn filter_3_for_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1159,10 +1160,10 @@ fn filter_4_for_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1176,10 +1177,10 @@ fn filter_5_for_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1193,8 +1194,8 @@ fn issue_29() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } diff --git a/tests/flags.rs b/tests/flags.rs index 39adf274..0d6d0c8e 100644 --- a/tests/flags.rs +++ b/tests/flags.rs @@ -3,6 +3,8 @@ extern crate oxipng; use image::GenericImage; use image::Pixel; +use oxipng::colors::{BitDepth, ColorType}; +use oxipng::headers::Headers; use oxipng::png; use std::collections::HashSet; use std::fs::remove_file; @@ -24,10 +26,10 @@ fn get_opts(input: &Path) -> oxipng::Options { 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) { + color_type_in: ColorType, + bit_depth_in: BitDepth, + color_type_out: ColorType, + bit_depth_out: BitDepth) { let png = png::PngData::new(input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.color_type, color_type_in); @@ -70,17 +72,17 @@ fn verbose_mode() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] fn strip_headers_list() { let input = PathBuf::from("tests/files/strip_headers_list.png"); let mut opts = get_opts(&input); - opts.strip = png::Headers::Some(vec!["iCCP".to_owned(), "tEXt".to_owned()]); + opts.strip = Headers::Some(vec!["iCCP".to_owned(), "tEXt".to_owned()]); let output = opts.out_file.clone(); let png = png::PngData::new(&input, opts.fix_errors).unwrap(); @@ -121,7 +123,7 @@ fn strip_headers_list() { fn strip_headers_safe() { let input = PathBuf::from("tests/files/strip_headers_safe.png"); let mut opts = get_opts(&input); - opts.strip = png::Headers::Safe; + opts.strip = Headers::Safe; let output = opts.out_file.clone(); let png = png::PngData::new(&input, opts.fix_errors).unwrap(); @@ -162,7 +164,7 @@ fn strip_headers_safe() { fn strip_headers_all() { let input = PathBuf::from("tests/files/strip_headers_all.png"); let mut opts = get_opts(&input); - opts.strip = png::Headers::All; + opts.strip = Headers::All; let output = opts.out_file.clone(); let png = png::PngData::new(&input, opts.fix_errors).unwrap(); @@ -203,7 +205,7 @@ fn strip_headers_all() { fn strip_headers_none() { let input = PathBuf::from("tests/files/strip_headers_none.png"); let mut opts = get_opts(&input); - opts.strip = png::Headers::None; + opts.strip = Headers::None; let output = opts.out_file.clone(); let png = png::PngData::new(&input, opts.fix_errors).unwrap(); @@ -324,8 +326,8 @@ fn interlacing_0_to_1_small_files() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.interlaced, 0); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); match oxipng::optimize(&input, &opts) { Ok(_) => (), @@ -342,8 +344,8 @@ fn interlacing_0_to_1_small_files() { }; assert_eq!(png.ihdr_data.interlaced, 1); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::One); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::One); let old_png = image::open(&input).unwrap(); let new_png = image::open(&output).unwrap(); @@ -365,8 +367,8 @@ fn interlacing_1_to_0_small_files() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.interlaced, 1); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); match oxipng::optimize(&input, &opts) { Ok(_) => (), @@ -383,8 +385,8 @@ fn interlacing_1_to_0_small_files() { }; assert_eq!(png.ihdr_data.interlaced, 0); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::One); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::One); let old_png = image::open(&input).unwrap(); let new_png = image::open(&output).unwrap(); @@ -446,10 +448,10 @@ fn preserve_attrs() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); // TODO: Actually check permissions } @@ -463,8 +465,8 @@ fn fix_errors() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); - assert_eq!(png.ihdr_data.color_type, png::ColorType::RGBA); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::RGBA); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); match oxipng::optimize(&input, &opts) { Ok(_) => (), @@ -480,8 +482,8 @@ fn fix_errors() { } }; - assert_eq!(png.ihdr_data.color_type, png::ColorType::Grayscale); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Grayscale); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); // Cannot check if pixels are equal because image crate cannot read corrupt (input) PNGs remove_file(output).ok(); @@ -497,8 +499,8 @@ fn issue_42() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.interlaced, 0); - assert_eq!(png.ihdr_data.color_type, png::ColorType::GrayscaleAlpha); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::GrayscaleAlpha); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); match oxipng::optimize(&input, &opts) { Ok(_) => (), @@ -515,8 +517,8 @@ fn issue_42() { }; assert_eq!(png.ihdr_data.interlaced, 1); - assert_eq!(png.ihdr_data.color_type, png::ColorType::GrayscaleAlpha); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::GrayscaleAlpha); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); let old_png = image::open(&input).unwrap(); let new_png = image::open(&output).unwrap(); diff --git a/tests/interlaced.rs b/tests/interlaced.rs index 686cea05..3056b511 100644 --- a/tests/interlaced.rs +++ b/tests/interlaced.rs @@ -3,6 +3,7 @@ extern crate oxipng; use image::GenericImage; use image::Pixel; +use oxipng::colors::{BitDepth, ColorType}; use oxipng::png; use std::collections::HashSet; use std::fs::remove_file; @@ -24,10 +25,10 @@ fn get_opts(input: &Path) -> oxipng::Options { 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) { + color_type_in: ColorType, + bit_depth_in: BitDepth, + color_type_out: ColorType, + bit_depth_out: BitDepth) { let png = png::PngData::new(input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.color_type, color_type_in); @@ -71,10 +72,10 @@ fn interlaced_rgba_16_should_be_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -86,10 +87,10 @@ fn interlaced_rgba_16_should_be_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -101,10 +102,10 @@ fn interlaced_rgba_8_should_be_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -116,10 +117,10 @@ fn interlaced_rgba_16_should_be_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -131,10 +132,10 @@ fn interlaced_rgba_16_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -146,10 +147,10 @@ fn interlaced_rgba_8_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -161,10 +162,10 @@ fn interlaced_rgba_16_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -176,10 +177,10 @@ fn interlaced_rgba_8_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -191,10 +192,10 @@ fn interlaced_rgba_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -206,10 +207,10 @@ fn interlaced_rgba_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -221,10 +222,10 @@ fn interlaced_rgba_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -236,10 +237,10 @@ fn interlaced_rgba_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -251,10 +252,10 @@ fn interlaced_rgba_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -266,10 +267,10 @@ fn interlaced_rgba_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -281,10 +282,10 @@ fn interlaced_rgba_16_should_be_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -296,10 +297,10 @@ fn interlaced_rgba_16_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -311,10 +312,10 @@ fn interlaced_rgba_8_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -326,10 +327,10 @@ fn interlaced_rgba_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -341,10 +342,10 @@ fn interlaced_rgba_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -356,10 +357,10 @@ fn interlaced_rgba_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -371,10 +372,10 @@ fn interlaced_rgba_16_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -386,10 +387,10 @@ fn interlaced_rgba_8_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -401,10 +402,10 @@ fn interlaced_rgba_16_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -416,10 +417,10 @@ fn interlaced_rgba_8_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -431,10 +432,10 @@ fn interlaced_rgba_16_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -446,10 +447,10 @@ fn interlaced_rgba_8_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -461,10 +462,10 @@ fn interlaced_rgb_16_should_be_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -476,10 +477,10 @@ fn interlaced_rgb_16_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -491,10 +492,10 @@ fn interlaced_rgb_8_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -506,10 +507,10 @@ fn interlaced_rgb_16_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -521,10 +522,10 @@ fn interlaced_rgb_8_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -536,10 +537,10 @@ fn interlaced_rgb_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -551,10 +552,10 @@ fn interlaced_rgb_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -566,10 +567,10 @@ fn interlaced_rgb_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -581,10 +582,10 @@ fn interlaced_rgb_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -596,10 +597,10 @@ fn interlaced_rgb_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -611,10 +612,10 @@ fn interlaced_rgb_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -626,10 +627,10 @@ fn interlaced_rgb_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -641,10 +642,10 @@ fn interlaced_rgb_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -656,10 +657,10 @@ fn interlaced_rgb_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -671,10 +672,10 @@ fn interlaced_rgb_16_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -686,10 +687,10 @@ fn interlaced_rgb_8_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -701,10 +702,10 @@ fn interlaced_rgb_16_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -716,10 +717,10 @@ fn interlaced_rgb_8_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -731,10 +732,10 @@ fn interlaced_rgb_16_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -746,10 +747,10 @@ fn interlaced_rgb_8_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -761,10 +762,10 @@ fn interlaced_palette_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -776,10 +777,10 @@ fn interlaced_palette_8_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -791,10 +792,10 @@ fn interlaced_palette_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -806,10 +807,10 @@ fn interlaced_palette_4_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -821,10 +822,10 @@ fn interlaced_palette_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -836,10 +837,10 @@ fn interlaced_palette_4_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -851,10 +852,10 @@ fn interlaced_palette_2_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -866,10 +867,10 @@ fn interlaced_palette_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -881,10 +882,10 @@ fn interlaced_palette_4_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -896,10 +897,10 @@ fn interlaced_palette_2_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -911,10 +912,10 @@ fn interlaced_palette_1_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -926,10 +927,10 @@ fn interlaced_grayscale_alpha_16_should_be_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -941,10 +942,10 @@ fn interlaced_grayscale_alpha_16_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -956,10 +957,10 @@ fn interlaced_grayscale_alpha_8_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -971,10 +972,10 @@ fn interlaced_grayscale_alpha_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -986,10 +987,10 @@ fn interlaced_grayscale_alpha_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1001,10 +1002,10 @@ fn interlaced_grayscale_alpha_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1016,10 +1017,10 @@ fn interlaced_grayscale_alpha_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1031,10 +1032,10 @@ fn interlaced_grayscale_alpha_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1046,10 +1047,10 @@ fn interlaced_grayscale_alpha_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1061,10 +1062,10 @@ fn interlaced_grayscale_alpha_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1076,10 +1077,10 @@ fn interlaced_grayscale_alpha_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1091,10 +1092,10 @@ fn interlaced_grayscale_alpha_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1106,10 +1107,10 @@ fn interlaced_grayscale_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -1121,10 +1122,10 @@ fn interlaced_grayscale_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1136,10 +1137,10 @@ fn interlaced_grayscale_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1151,10 +1152,10 @@ fn interlaced_grayscale_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1166,10 +1167,10 @@ fn interlaced_grayscale_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1181,10 +1182,10 @@ fn interlaced_grayscale_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1196,10 +1197,10 @@ fn interlaced_grayscale_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1211,10 +1212,10 @@ fn interlaced_grayscale_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1226,10 +1227,10 @@ fn interlaced_grayscale_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1241,10 +1242,10 @@ fn interlaced_small_files() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1256,8 +1257,8 @@ fn interlaced_odd_width() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } diff --git a/tests/reduction.rs b/tests/reduction.rs index 10f9fbb5..9595bd17 100644 --- a/tests/reduction.rs +++ b/tests/reduction.rs @@ -3,6 +3,7 @@ extern crate oxipng; use image::GenericImage; use image::Pixel; +use oxipng::colors::{BitDepth, ColorType}; use oxipng::png; use std::collections::HashSet; use std::fs::remove_file; @@ -24,10 +25,10 @@ fn get_opts(input: &Path) -> oxipng::Options { 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) { + color_type_in: ColorType, + bit_depth_in: BitDepth, + color_type_out: ColorType, + bit_depth_out: BitDepth) { let png = png::PngData::new(input, opts.fix_errors).unwrap(); assert_eq!(png.ihdr_data.color_type, color_type_in); @@ -71,10 +72,10 @@ fn rgba_16_should_be_rgba_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Sixteen); } #[test] @@ -86,10 +87,10 @@ fn rgba_16_should_be_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -101,10 +102,10 @@ fn rgba_8_should_be_rgba_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGBA, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGBA, + BitDepth::Eight); } #[test] @@ -116,10 +117,10 @@ fn rgba_16_should_be_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -131,10 +132,10 @@ fn rgba_16_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -146,10 +147,10 @@ fn rgba_8_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -161,10 +162,10 @@ fn rgba_16_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -176,10 +177,10 @@ fn rgba_8_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -191,10 +192,10 @@ fn rgba_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -206,10 +207,10 @@ fn rgba_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -221,10 +222,10 @@ fn rgba_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -236,10 +237,10 @@ fn rgba_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -251,10 +252,10 @@ fn rgba_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -266,10 +267,10 @@ fn rgba_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -281,10 +282,10 @@ fn rgba_16_should_be_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -296,10 +297,10 @@ fn rgba_16_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -311,10 +312,10 @@ fn rgba_8_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -326,10 +327,10 @@ fn rgba_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -341,10 +342,10 @@ fn rgba_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -356,10 +357,10 @@ fn rgba_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -371,10 +372,10 @@ fn rgba_16_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -386,10 +387,10 @@ fn rgba_8_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -401,10 +402,10 @@ fn rgba_16_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -416,10 +417,10 @@ fn rgba_8_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -431,10 +432,10 @@ fn rgba_16_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -446,10 +447,10 @@ fn rgba_8_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGBA, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGBA, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -461,10 +462,10 @@ fn rgb_16_should_be_rgb_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Sixteen); } #[test] @@ -476,10 +477,10 @@ fn rgb_16_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -491,10 +492,10 @@ fn rgb_8_should_be_rgb_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::RGB, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::RGB, + BitDepth::Eight); } #[test] @@ -506,10 +507,10 @@ fn rgb_16_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -521,10 +522,10 @@ fn rgb_8_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -536,10 +537,10 @@ fn rgb_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -551,10 +552,10 @@ fn rgb_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -566,10 +567,10 @@ fn rgb_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -581,10 +582,10 @@ fn rgb_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -596,10 +597,10 @@ fn rgb_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -611,10 +612,10 @@ fn rgb_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -626,10 +627,10 @@ fn rgb_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -641,10 +642,10 @@ fn rgb_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -656,10 +657,10 @@ fn rgb_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::RGB, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -671,10 +672,10 @@ fn rgb_16_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -686,10 +687,10 @@ fn rgb_8_should_be_palette_4_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -701,10 +702,10 @@ fn rgb_16_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -716,10 +717,10 @@ fn rgb_8_should_be_palette_2_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -731,10 +732,10 @@ fn rgb_16_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -746,10 +747,10 @@ fn rgb_8_should_be_palette_1_grayscale() { test_it_converts(&input, &output, &opts, - png::ColorType::RGB, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::RGB, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -761,10 +762,10 @@ fn palette_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -776,10 +777,10 @@ fn palette_8_should_be_palette_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Eight); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Eight); } #[test] @@ -791,10 +792,10 @@ fn palette_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -806,10 +807,10 @@ fn palette_4_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -821,10 +822,10 @@ fn palette_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -836,10 +837,10 @@ fn palette_4_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -851,10 +852,10 @@ fn palette_2_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -866,10 +867,10 @@ fn palette_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -881,10 +882,10 @@ fn palette_4_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Four, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -896,10 +897,10 @@ fn palette_2_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Two, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Two, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -911,10 +912,10 @@ fn palette_1_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::One, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -926,10 +927,10 @@ fn grayscale_alpha_16_should_be_grayscale_alpha_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Sixteen); } #[test] @@ -941,10 +942,10 @@ fn grayscale_alpha_16_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -956,10 +957,10 @@ fn grayscale_alpha_8_should_be_grayscale_alpha_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::GrayscaleAlpha, + BitDepth::Eight); } #[test] @@ -971,10 +972,10 @@ fn grayscale_alpha_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -986,10 +987,10 @@ fn grayscale_alpha_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1001,10 +1002,10 @@ fn grayscale_alpha_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1016,10 +1017,10 @@ fn grayscale_alpha_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1031,10 +1032,10 @@ fn grayscale_alpha_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1046,10 +1047,10 @@ fn grayscale_alpha_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1061,10 +1062,10 @@ fn grayscale_alpha_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1076,10 +1077,10 @@ fn grayscale_alpha_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::GrayscaleAlpha, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1091,10 +1092,10 @@ fn grayscale_alpha_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::GrayscaleAlpha, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::GrayscaleAlpha, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1106,10 +1107,10 @@ fn grayscale_16_should_be_grayscale_16() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Sixteen); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Sixteen); } #[test] @@ -1121,10 +1122,10 @@ fn grayscale_16_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1136,10 +1137,10 @@ fn grayscale_16_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1151,10 +1152,10 @@ fn grayscale_16_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1166,10 +1167,10 @@ fn grayscale_16_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Sixteen, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Grayscale, + BitDepth::Sixteen, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1181,10 +1182,10 @@ fn grayscale_8_should_be_grayscale_8() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Grayscale, - png::BitDepth::Eight); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Grayscale, + BitDepth::Eight); } #[test] @@ -1196,10 +1197,10 @@ fn grayscale_8_should_be_palette_4() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Four); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Four); } #[test] @@ -1211,10 +1212,10 @@ fn grayscale_8_should_be_palette_2() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::Two); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::Two); } #[test] @@ -1226,10 +1227,10 @@ fn grayscale_8_should_be_palette_1() { test_it_converts(&input, &output, &opts, - png::ColorType::Grayscale, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Grayscale, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1241,10 +1242,10 @@ fn small_files() { test_it_converts(&input, &output, &opts, - png::ColorType::Indexed, - png::BitDepth::Eight, - png::ColorType::Indexed, - png::BitDepth::One); + ColorType::Indexed, + BitDepth::Eight, + ColorType::Indexed, + BitDepth::One); } #[test] @@ -1255,8 +1256,8 @@ fn palette_should_be_reduced_with_dupes() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); assert_eq!(png.palette.unwrap().len(), 43 * 3); match oxipng::optimize(&input, &opts) { @@ -1273,8 +1274,8 @@ fn palette_should_be_reduced_with_dupes() { } }; - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); assert_eq!(png.palette.unwrap().len(), 35 * 3); let old_png = image::open(&input).unwrap(); @@ -1295,8 +1296,8 @@ fn palette_should_be_reduced_with_unused() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); assert_eq!(png.palette.unwrap().len(), 35 * 3); match oxipng::optimize(&input, &opts) { @@ -1313,8 +1314,8 @@ fn palette_should_be_reduced_with_unused() { } }; - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); assert_eq!(png.palette.unwrap().len(), 33 * 3); let old_png = image::open(&input).unwrap(); @@ -1335,8 +1336,8 @@ fn palette_should_be_reduced_with_both() { let png = png::PngData::new(&input, opts.fix_errors).unwrap(); - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); assert_eq!(png.palette.unwrap().len(), 43 * 3); match oxipng::optimize(&input, &opts) { @@ -1353,8 +1354,8 @@ fn palette_should_be_reduced_with_both() { } }; - assert_eq!(png.ihdr_data.color_type, png::ColorType::Indexed); - assert_eq!(png.ihdr_data.bit_depth, png::BitDepth::Eight); + assert_eq!(png.ihdr_data.color_type, ColorType::Indexed); + assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight); assert_eq!(png.palette.unwrap().len(), 33 * 3); let old_png = image::open(&input).unwrap();