Change interlacing to bool
This commit is contained in:
parent
fafe3707be
commit
7a3de278f8
15 changed files with 84 additions and 131 deletions
|
|
@ -13,7 +13,7 @@ fn interlacing_16_bits(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::Adam7));
|
b.iter(|| png.raw.change_interlacing(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -21,7 +21,7 @@ fn interlacing_8_bits(b: &mut Bencher) {
|
||||||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::Adam7));
|
b.iter(|| png.raw.change_interlacing(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -31,7 +31,7 @@ fn interlacing_4_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::Adam7));
|
b.iter(|| png.raw.change_interlacing(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -41,7 +41,7 @@ fn interlacing_2_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::Adam7));
|
b.iter(|| png.raw.change_interlacing(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -51,7 +51,7 @@ fn interlacing_1_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::Adam7));
|
b.iter(|| png.raw.change_interlacing(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -61,7 +61,7 @@ fn deinterlacing_16_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::None));
|
b.iter(|| png.raw.change_interlacing(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -71,7 +71,7 @@ fn deinterlacing_8_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::None));
|
b.iter(|| png.raw.change_interlacing(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -81,7 +81,7 @@ fn deinterlacing_4_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::None));
|
b.iter(|| png.raw.change_interlacing(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -91,7 +91,7 @@ fn deinterlacing_2_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::None));
|
b.iter(|| png.raw.change_interlacing(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
|
|
@ -101,5 +101,5 @@ fn deinterlacing_1_bits(b: &mut Bencher) {
|
||||||
));
|
));
|
||||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||||
|
|
||||||
b.iter(|| png.raw.change_interlacing(Interlacing::None));
|
b.iter(|| png.raw.change_interlacing(false));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
src/cli.rs
11
src/cli.rs
|
|
@ -1,6 +1,6 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{Arg, ArgAction, Command, value_parser};
|
use clap::{Arg, ArgAction, Command, builder::ArgPredicate, value_parser};
|
||||||
|
|
||||||
include!("display_chunks.rs");
|
include!("display_chunks.rs");
|
||||||
|
|
||||||
|
|
@ -163,9 +163,8 @@ transformation and may be unsuitable for some applications.")
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
// Note: The default value is not explicitly set here, as it is dependant on the `--nx` flag.
|
|
||||||
Arg::new("interlace")
|
Arg::new("interlace")
|
||||||
.help("Set PNG interlacing type (0, 1, keep) [default: 0]")
|
.help("Set PNG interlacing type (0, 1, keep)")
|
||||||
.long_help("\
|
.long_help("\
|
||||||
Set the PNG interlacing type, where <type> is one of:
|
Set the PNG interlacing type, where <type> is one of:
|
||||||
|
|
||||||
|
|
@ -174,13 +173,13 @@ Set the PNG interlacing type, where <type> is one of:
|
||||||
keep => Keep the existing interlacing type of each image
|
keep => Keep the existing interlacing type of each image
|
||||||
|
|
||||||
Note that interlacing can add 25-50% to the size of an optimized image. Only use it if you \
|
Note that interlacing can add 25-50% to the size of an optimized image. Only use it if you \
|
||||||
believe the benefits outweigh the costs for your use case.
|
believe the benefits outweigh the costs for your use case.")
|
||||||
|
|
||||||
[default: 0]")
|
|
||||||
.short('i')
|
.short('i')
|
||||||
.long("interlace")
|
.long("interlace")
|
||||||
.value_name("type")
|
.value_name("type")
|
||||||
.value_parser(["0", "1", "keep"])
|
.value_parser(["0", "1", "keep"])
|
||||||
|
.default_value("0")
|
||||||
|
.default_value_if("no-reductions", ArgPredicate::IsPresent, "keep")
|
||||||
.hide_possible_values(true),
|
.hide_possible_values(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ use crate::{
|
||||||
deflate::{crc32, inflate},
|
deflate::{crc32, inflate},
|
||||||
display_chunks::DISPLAY_CHUNKS,
|
display_chunks::DISPLAY_CHUNKS,
|
||||||
error::PngError,
|
error::PngError,
|
||||||
interlace::Interlacing,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -22,8 +21,8 @@ pub struct IhdrData {
|
||||||
pub color_type: ColorType,
|
pub color_type: ColorType,
|
||||||
/// The bit depth of the image
|
/// The bit depth of the image
|
||||||
pub bit_depth: BitDepth,
|
pub bit_depth: BitDepth,
|
||||||
/// The interlacing mode of the image
|
/// Whether the image is interlaced
|
||||||
pub interlaced: Interlacing,
|
pub interlaced: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IhdrData {
|
impl IhdrData {
|
||||||
|
|
@ -45,7 +44,7 @@ impl IhdrData {
|
||||||
(w * bpp).div_ceil(8) * h
|
(w * bpp).div_ceil(8) * h
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.interlaced == Interlacing::None {
|
if !self.interlaced {
|
||||||
bitmap_size(bpp, w, h) + h
|
bitmap_size(bpp, w, h) + h
|
||||||
} else {
|
} else {
|
||||||
let mut size = bitmap_size(bpp, (w + 7) >> 3, (h + 7) >> 3) + ((h + 7) >> 3);
|
let mut size = bitmap_size(bpp, (w + 7) >> 3, (h + 7) >> 3) + ((h + 7) >> 3);
|
||||||
|
|
@ -214,7 +213,11 @@ pub fn parse_ihdr_chunk(
|
||||||
bit_depth: byte_data[8].try_into()?,
|
bit_depth: byte_data[8].try_into()?,
|
||||||
width: read_be_u32(&byte_data[0..4]),
|
width: read_be_u32(&byte_data[0..4]),
|
||||||
height: read_be_u32(&byte_data[4..8]),
|
height: read_be_u32(&byte_data[4..8]),
|
||||||
interlaced: interlaced.try_into()?,
|
interlaced: match interlaced {
|
||||||
|
0 => false,
|
||||||
|
1 => true,
|
||||||
|
_ => return Err(PngError::new("Unexpected interlacing in header")),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,6 @@
|
||||||
use std::{fmt, fmt::Display};
|
|
||||||
|
|
||||||
use bitvec::prelude::*;
|
use bitvec::prelude::*;
|
||||||
|
|
||||||
use crate::{PngError, headers::IhdrData, png::PngImage};
|
use crate::{headers::IhdrData, png::PngImage};
|
||||||
|
|
||||||
/// Whether to enable progressive rendering. See [`Options`][crate::Options])
|
|
||||||
#[repr(u8)]
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
||||||
pub enum Interlacing {
|
|
||||||
/// Makes images load top to bottom.
|
|
||||||
None,
|
|
||||||
/// Makes it possible to render partially-loaded images at lower resolution. Usually increases file sizes.
|
|
||||||
Adam7,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<u8> for Interlacing {
|
|
||||||
type Error = PngError;
|
|
||||||
|
|
||||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
|
||||||
match value {
|
|
||||||
0 => Ok(Self::None),
|
|
||||||
1 => Ok(Self::Adam7),
|
|
||||||
_ => Err(PngError::new("Unexpected interlacing in header")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Interlacing {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
Display::fmt(
|
|
||||||
match self {
|
|
||||||
Self::None => "non-interlaced",
|
|
||||||
Self::Adam7 => "interlaced",
|
|
||||||
},
|
|
||||||
f,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn interlace_image(png: &PngImage) -> PngImage {
|
pub fn interlace_image(png: &PngImage) -> PngImage {
|
||||||
|
|
@ -89,7 +53,7 @@ pub fn interlace_image(png: &PngImage) -> PngImage {
|
||||||
data: output,
|
data: output,
|
||||||
ihdr: IhdrData {
|
ihdr: IhdrData {
|
||||||
color_type: png.ihdr.color_type.clone(),
|
color_type: png.ihdr.color_type.clone(),
|
||||||
interlaced: Interlacing::Adam7,
|
interlaced: true,
|
||||||
..png.ihdr
|
..png.ihdr
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +67,7 @@ pub fn deinterlace_image(png: &PngImage) -> PngImage {
|
||||||
},
|
},
|
||||||
ihdr: IhdrData {
|
ihdr: IhdrData {
|
||||||
color_type: png.ihdr.color_type.clone(),
|
color_type: png.ihdr.color_type.clone(),
|
||||||
interlaced: Interlacing::None,
|
interlaced: false,
|
||||||
..png.ihdr
|
..png.ihdr
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/lib.rs
12
src/lib.rs
|
|
@ -47,7 +47,6 @@ pub use crate::{
|
||||||
error::PngError,
|
error::PngError,
|
||||||
filters::{FilterStrategy, RowFilter},
|
filters::{FilterStrategy, RowFilter},
|
||||||
headers::StripChunks,
|
headers::StripChunks,
|
||||||
interlace::Interlacing,
|
|
||||||
options::{InFile, Options, OutFile},
|
options::{InFile, Options, OutFile},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -130,7 +129,7 @@ impl RawImage {
|
||||||
height,
|
height,
|
||||||
color_type,
|
color_type,
|
||||||
bit_depth,
|
bit_depth,
|
||||||
interlaced: Interlacing::None,
|
interlaced: false,
|
||||||
},
|
},
|
||||||
data,
|
data,
|
||||||
}),
|
}),
|
||||||
|
|
@ -397,7 +396,7 @@ fn optimize_png(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.interlace == Some(Interlacing::Adam7) && png.raw.ihdr.interlaced != Interlacing::Adam7 {
|
if opts.interlace == Some(true) && !png.raw.ihdr.interlaced {
|
||||||
warn!(
|
warn!(
|
||||||
"Interlacing was not enabled as it would result in a larger file. To override this, use `--force`."
|
"Interlacing was not enabled as it would result in a larger file. To override this, use `--force`."
|
||||||
);
|
);
|
||||||
|
|
@ -618,9 +617,14 @@ impl Deadline {
|
||||||
|
|
||||||
/// Display the format of the image data
|
/// Display the format of the image data
|
||||||
fn report_format(prefix: &str, png: &PngImage) {
|
fn report_format(prefix: &str, png: &PngImage) {
|
||||||
|
let interlaced = if png.ihdr.interlaced {
|
||||||
|
"interlaced"
|
||||||
|
} else {
|
||||||
|
"non-interlaced"
|
||||||
|
};
|
||||||
debug!(
|
debug!(
|
||||||
"{}{}-bit {}, {}",
|
"{}{}-bit {}, {}",
|
||||||
prefix, png.ihdr.bit_depth, png.ihdr.color_type, png.ihdr.interlaced
|
prefix, png.ihdr.bit_depth, png.ihdr.color_type, interlaced
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -276,11 +276,7 @@ fn parse_opts_into_struct(
|
||||||
opts.idat_recoding = !matches.get_flag("no-recoding");
|
opts.idat_recoding = !matches.get_flag("no-recoding");
|
||||||
|
|
||||||
if let Some(x) = matches.get_one::<String>("interlace") {
|
if let Some(x) = matches.get_one::<String>("interlace") {
|
||||||
opts.interlace = if x == "keep" {
|
opts.interlace = if x == "keep" { None } else { Some(x == "1") };
|
||||||
None
|
|
||||||
} else {
|
|
||||||
x.parse::<u8>().unwrap().try_into().ok()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(keep) = matches.get_one::<String>("keep") {
|
if let Some(keep) = matches.get_one::<String>("keep") {
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@ use std::{
|
||||||
use indexmap::{IndexSet, indexset};
|
use indexmap::{IndexSet, indexset};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{deflate::Deflater, filters::FilterStrategy, headers::StripChunks};
|
||||||
deflate::Deflater, filters::FilterStrategy, headers::StripChunks, interlace::Interlacing,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Write destination for [`optimize`][crate::optimize].
|
/// Write destination for [`optimize`][crate::optimize].
|
||||||
/// You can use [`optimize_from_memory`](crate::optimize_from_memory) to avoid external I/O.
|
/// You can use [`optimize_from_memory`](crate::optimize_from_memory) to avoid external I/O.
|
||||||
|
|
@ -100,15 +98,13 @@ pub struct Options {
|
||||||
///
|
///
|
||||||
/// Default: `None,Sub,Entropy,Bigrams`
|
/// Default: `None,Sub,Entropy,Bigrams`
|
||||||
pub filters: IndexSet<FilterStrategy>,
|
pub filters: IndexSet<FilterStrategy>,
|
||||||
/// Whether to change the interlacing type of the file.
|
/// Whether to change the interlacing of the file.
|
||||||
///
|
///
|
||||||
/// These are the interlacing types avaliable:
|
/// - `None` will not change the current interlacing.
|
||||||
/// - `None` will not change the current interlacing type.
|
/// - `Some(x)` will turn interlacing on or off.
|
||||||
/// - `Some(x)` will change the file to interlacing mode `x`.
|
|
||||||
/// See [`Interlacing`] for the possible interlacing types.
|
|
||||||
///
|
///
|
||||||
/// Default: `Some(Interlacing::None)`
|
/// Default: `Some(false)`
|
||||||
pub interlace: Option<Interlacing>,
|
pub interlace: Option<bool>,
|
||||||
/// Whether to allow transparent pixels to be altered to improve compression.
|
/// Whether to allow transparent pixels to be altered to improve compression.
|
||||||
///
|
///
|
||||||
/// Default: `false`
|
/// Default: `false`
|
||||||
|
|
@ -255,7 +251,7 @@ impl Default for Options {
|
||||||
FilterStrategy::Entropy,
|
FilterStrategy::Entropy,
|
||||||
FilterStrategy::Bigrams
|
FilterStrategy::Bigrams
|
||||||
},
|
},
|
||||||
interlace: Some(Interlacing::None),
|
interlace: Some(false),
|
||||||
optimize_alpha: false,
|
optimize_alpha: false,
|
||||||
bit_depth_reduction: true,
|
bit_depth_reduction: true,
|
||||||
color_type_reduction: true,
|
color_type_reduction: true,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use crate::{
|
||||||
error::PngError,
|
error::PngError,
|
||||||
filters::*,
|
filters::*,
|
||||||
headers::*,
|
headers::*,
|
||||||
interlace::{Interlacing, deinterlace_image, interlace_image},
|
interlace::{deinterlace_image, interlace_image},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod scan_lines;
|
pub(crate) mod scan_lines;
|
||||||
|
|
@ -293,18 +293,17 @@ impl PngImage {
|
||||||
Ok(image)
|
Ok(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the image to the specified interlacing type
|
/// Enable or disable interlacing
|
||||||
/// Returns true if the interlacing was changed, false otherwise
|
/// Returns the new image if the interlacing was changed, None otherwise
|
||||||
/// The `interlace` parameter specifies the *new* interlacing mode
|
|
||||||
/// Assumes that the data has already been de-filtered
|
/// Assumes that the data has already been de-filtered
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn change_interlacing(&self, interlace: Interlacing) -> Option<Self> {
|
pub fn change_interlacing(&self, interlace: bool) -> Option<Self> {
|
||||||
if interlace == self.ihdr.interlaced {
|
if interlace == self.ihdr.interlaced {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(if interlace == Interlacing::Adam7 {
|
Some(if interlace {
|
||||||
// Convert progressive to interlaced data
|
// Convert progressive to interlaced data
|
||||||
interlace_image(self)
|
interlace_image(self)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{interlace::Interlacing, png::PngImage};
|
use crate::png::PngImage;
|
||||||
|
|
||||||
/// An iterator over the scan lines of a PNG image
|
/// An iterator over the scan lines of a PNG image
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -69,7 +69,7 @@ impl ScanLineRanges {
|
||||||
width: png.ihdr.width,
|
width: png.ihdr.width,
|
||||||
height: png.ihdr.height,
|
height: png.ihdr.height,
|
||||||
left: png.data.len(),
|
left: png.data.len(),
|
||||||
pass: if png.ihdr.interlaced == Interlacing::Adam7 {
|
pass: if png.ihdr.interlaced {
|
||||||
Some((1, 0))
|
Some((1, 0))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use indexmap::IndexSet;
|
||||||
use rgb::RGBA8;
|
use rgb::RGBA8;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Interlacing,
|
|
||||||
colors::{BitDepth, ColorType},
|
colors::{BitDepth, ColorType},
|
||||||
headers::IhdrData,
|
headers::IhdrData,
|
||||||
png::{PngImage, scan_lines::ScanLine},
|
png::{PngImage, scan_lines::ScanLine},
|
||||||
|
|
@ -134,7 +133,7 @@ pub fn sorted_palette(png: &PngImage) -> Option<PngImage> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn sorted_palette_mzeng(png: &PngImage) -> Option<PngImage> {
|
pub fn sorted_palette_mzeng(png: &PngImage) -> Option<PngImage> {
|
||||||
// Interlacing not currently supported
|
// Interlacing not currently supported
|
||||||
if png.ihdr.bit_depth != BitDepth::Eight || png.ihdr.interlaced != Interlacing::None {
|
if png.ihdr.bit_depth != BitDepth::Eight || png.ihdr.interlaced {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let palette = match &png.ihdr.color_type {
|
let palette = match &png.ihdr.color_type {
|
||||||
|
|
@ -156,7 +155,7 @@ pub fn sorted_palette_mzeng(png: &PngImage) -> Option<PngImage> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn sorted_palette_battiato(png: &PngImage) -> Option<PngImage> {
|
pub fn sorted_palette_battiato(png: &PngImage) -> Option<PngImage> {
|
||||||
// Interlacing not currently supported
|
// Interlacing not currently supported
|
||||||
if png.ihdr.bit_depth != BitDepth::Eight || png.ihdr.interlaced != Interlacing::None {
|
if png.ihdr.bit_depth != BitDepth::Eight || png.ihdr.interlaced {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let palette = match &png.ihdr.color_type {
|
let palette = match &png.ihdr.color_type {
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ fn strip_chunks_none() {
|
||||||
fn interlacing_0_to_1() {
|
fn interlacing_0_to_1() {
|
||||||
let input = PathBuf::from("tests/files/interlacing_0_to_1.png");
|
let input = PathBuf::from("tests/files/interlacing_0_to_1.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(true);
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
input,
|
input,
|
||||||
|
|
@ -327,10 +327,10 @@ fn interlacing_0_to_1() {
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::None);
|
assert!(!png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::Adam7);
|
assert!(png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -339,7 +339,7 @@ fn interlacing_0_to_1() {
|
||||||
fn interlacing_1_to_0() {
|
fn interlacing_1_to_0() {
|
||||||
let input = PathBuf::from("tests/files/interlacing_1_to_0.png");
|
let input = PathBuf::from("tests/files/interlacing_1_to_0.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::None);
|
opts.interlace = Some(false);
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
input,
|
input,
|
||||||
|
|
@ -350,10 +350,10 @@ fn interlacing_1_to_0() {
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::Adam7);
|
assert!(png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::None);
|
assert!(!png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -362,7 +362,7 @@ fn interlacing_1_to_0() {
|
||||||
fn interlacing_0_to_1_small_files() {
|
fn interlacing_0_to_1_small_files() {
|
||||||
let input = PathBuf::from("tests/files/interlacing_0_to_1_small_files.png");
|
let input = PathBuf::from("tests/files/interlacing_0_to_1_small_files.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(true);
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
input,
|
input,
|
||||||
|
|
@ -373,10 +373,10 @@ fn interlacing_0_to_1_small_files() {
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::None);
|
assert!(!png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::Adam7);
|
assert!(png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -385,7 +385,7 @@ fn interlacing_0_to_1_small_files() {
|
||||||
fn interlacing_1_to_0_small_files() {
|
fn interlacing_1_to_0_small_files() {
|
||||||
let input = PathBuf::from("tests/files/interlacing_1_to_0_small_files.png");
|
let input = PathBuf::from("tests/files/interlacing_1_to_0_small_files.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::None);
|
opts.interlace = Some(false);
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
input,
|
input,
|
||||||
|
|
@ -396,10 +396,10 @@ fn interlacing_1_to_0_small_files() {
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::Adam7);
|
assert!(png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::None);
|
assert!(!png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -408,7 +408,7 @@ fn interlacing_1_to_0_small_files() {
|
||||||
fn interlaced_0_to_1_other_filter_mode() {
|
fn interlaced_0_to_1_other_filter_mode() {
|
||||||
let input = PathBuf::from("tests/files/interlaced_0_to_1_other_filter_mode.png");
|
let input = PathBuf::from("tests/files/interlaced_0_to_1_other_filter_mode.png");
|
||||||
let (output, mut opts) = get_opts(&input);
|
let (output, mut opts) = get_opts(&input);
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(true);
|
||||||
opts.filters = indexset! {FilterStrategy::PAETH};
|
opts.filters = indexset! {FilterStrategy::PAETH};
|
||||||
|
|
||||||
test_it_converts_callbacks(
|
test_it_converts_callbacks(
|
||||||
|
|
@ -420,10 +420,10 @@ fn interlaced_0_to_1_other_filter_mode() {
|
||||||
GRAY,
|
GRAY,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::None);
|
assert!(!png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
|png| {
|
|png| {
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::Adam7);
|
assert!(png.raw.ihdr.interlaced);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ fn test_it_converts(
|
||||||
|
|
||||||
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
||||||
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::Adam7);
|
assert!(png.raw.ihdr.interlaced);
|
||||||
|
|
||||||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ fn get_opts(input: &Path) -> (OutFile, oxipng::Options) {
|
||||||
|
|
||||||
fn test_it_converts(
|
fn test_it_converts(
|
||||||
input: &str,
|
input: &str,
|
||||||
interlace: Interlacing,
|
interlace: bool,
|
||||||
color_type_in: u8,
|
color_type_in: u8,
|
||||||
bit_depth_in: BitDepth,
|
bit_depth_in: BitDepth,
|
||||||
color_type_out: u8,
|
color_type_out: u8,
|
||||||
|
|
@ -31,14 +31,7 @@ fn test_it_converts(
|
||||||
opts.interlace = Some(interlace);
|
opts.interlace = Some(interlace);
|
||||||
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
||||||
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in);
|
||||||
assert_eq!(
|
assert_eq!(png.raw.ihdr.interlaced, !interlace);
|
||||||
png.raw.ihdr.interlaced,
|
|
||||||
if interlace == Interlacing::Adam7 {
|
|
||||||
Interlacing::None
|
|
||||||
} else {
|
|
||||||
Interlacing::Adam7
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
|
@ -65,7 +58,7 @@ fn test_it_converts(
|
||||||
fn deinterlace_rgb_16() {
|
fn deinterlace_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/interlaced_rgb_16_should_be_rgb_16.png",
|
"tests/files/interlaced_rgb_16_should_be_rgb_16.png",
|
||||||
Interlacing::None,
|
false,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -77,7 +70,7 @@ fn deinterlace_rgb_16() {
|
||||||
fn deinterlace_rgb_8() {
|
fn deinterlace_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/interlaced_rgb_8_should_be_rgb_8.png",
|
"tests/files/interlaced_rgb_8_should_be_rgb_8.png",
|
||||||
Interlacing::None,
|
false,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -89,7 +82,7 @@ fn deinterlace_rgb_8() {
|
||||||
fn deinterlace_palette_8() {
|
fn deinterlace_palette_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/interlaced_palette_8_should_be_palette_8.png",
|
"tests/files/interlaced_palette_8_should_be_palette_8.png",
|
||||||
Interlacing::None,
|
false,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -101,7 +94,7 @@ fn deinterlace_palette_8() {
|
||||||
fn deinterlace_palette_4() {
|
fn deinterlace_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/interlaced_palette_4_should_be_palette_4.png",
|
"tests/files/interlaced_palette_4_should_be_palette_4.png",
|
||||||
Interlacing::None,
|
false,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -113,7 +106,7 @@ fn deinterlace_palette_4() {
|
||||||
fn deinterlace_palette_2() {
|
fn deinterlace_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/interlaced_palette_2_should_be_palette_2.png",
|
"tests/files/interlaced_palette_2_should_be_palette_2.png",
|
||||||
Interlacing::None,
|
false,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -125,7 +118,7 @@ fn deinterlace_palette_2() {
|
||||||
fn deinterlace_palette_1() {
|
fn deinterlace_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/interlaced_palette_1_should_be_palette_1.png",
|
"tests/files/interlaced_palette_1_should_be_palette_1.png",
|
||||||
Interlacing::None,
|
false,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -137,7 +130,7 @@ fn deinterlace_palette_1() {
|
||||||
fn interlace_rgb_16() {
|
fn interlace_rgb_16() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/rgb_16_should_be_rgb_16.png",
|
"tests/files/rgb_16_should_be_rgb_16.png",
|
||||||
Interlacing::Adam7,
|
true,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Sixteen,
|
BitDepth::Sixteen,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -149,7 +142,7 @@ fn interlace_rgb_16() {
|
||||||
fn interlace_rgb_8() {
|
fn interlace_rgb_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/rgb_8_should_be_rgb_8.png",
|
"tests/files/rgb_8_should_be_rgb_8.png",
|
||||||
Interlacing::Adam7,
|
true,
|
||||||
RGB,
|
RGB,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
RGB,
|
RGB,
|
||||||
|
|
@ -161,7 +154,7 @@ fn interlace_rgb_8() {
|
||||||
fn interlace_palette_8() {
|
fn interlace_palette_8() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/palette_8_should_be_palette_8.png",
|
"tests/files/palette_8_should_be_palette_8.png",
|
||||||
Interlacing::Adam7,
|
true,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Eight,
|
BitDepth::Eight,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -173,7 +166,7 @@ fn interlace_palette_8() {
|
||||||
fn interlace_palette_4() {
|
fn interlace_palette_4() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/palette_4_should_be_palette_4.png",
|
"tests/files/palette_4_should_be_palette_4.png",
|
||||||
Interlacing::Adam7,
|
true,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Four,
|
BitDepth::Four,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -185,7 +178,7 @@ fn interlace_palette_4() {
|
||||||
fn interlace_palette_2() {
|
fn interlace_palette_2() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/palette_2_should_be_palette_2.png",
|
"tests/files/palette_2_should_be_palette_2.png",
|
||||||
Interlacing::Adam7,
|
true,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::Two,
|
BitDepth::Two,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
@ -197,7 +190,7 @@ fn interlace_palette_2() {
|
||||||
fn interlace_palette_1() {
|
fn interlace_palette_1() {
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
"tests/files/palette_1_should_be_palette_1.png",
|
"tests/files/palette_1_should_be_palette_1.png",
|
||||||
Interlacing::Adam7,
|
true,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
BitDepth::One,
|
BitDepth::One,
|
||||||
INDEXED,
|
INDEXED,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ fn test_it_converts(
|
||||||
|
|
||||||
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
assert_eq!(png.raw.ihdr.color_type.png_header_code(), color_type_in);
|
||||||
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in, "test file is broken");
|
assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in, "test file is broken");
|
||||||
assert_eq!(png.raw.ihdr.interlaced, Interlacing::None);
|
assert!(!png.raw.ihdr.interlaced);
|
||||||
|
|
||||||
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
match oxipng::optimize(&InFile::Path(input), &output, &opts) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ fn test_it_converts(
|
||||||
fn issue_42() {
|
fn issue_42() {
|
||||||
let input = "tests/files/issue-42.png";
|
let input = "tests/files/issue-42.png";
|
||||||
let (output, mut opts) = get_opts(Path::new(input));
|
let (output, mut opts) = get_opts(Path::new(input));
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(true);
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
input,
|
input,
|
||||||
Some((output, opts)),
|
Some((output, opts)),
|
||||||
|
|
@ -186,7 +186,7 @@ fn issue_175() {
|
||||||
fn issue_182() {
|
fn issue_182() {
|
||||||
let input = "tests/files/issue-182.png";
|
let input = "tests/files/issue-182.png";
|
||||||
let (output, mut opts) = get_opts(Path::new(input));
|
let (output, mut opts) = get_opts(Path::new(input));
|
||||||
opts.interlace = Some(Interlacing::Adam7);
|
opts.interlace = Some(true);
|
||||||
|
|
||||||
test_it_converts(
|
test_it_converts(
|
||||||
input,
|
input,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue