Clippy
This commit is contained in:
parent
8270c6a034
commit
a72bc945fc
18 changed files with 148 additions and 208 deletions
|
|
@ -5,7 +5,8 @@ extern crate test;
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use oxipng::{internal_tests::*, *};
|
||||
use oxipng::internal_tests::*;
|
||||
use oxipng::*;
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
|
|
@ -13,9 +14,7 @@ fn filters_16_bits_filter_0(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::None, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -23,9 +22,7 @@ fn filters_8_bits_filter_0(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::None, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -35,9 +32,7 @@ fn filters_4_bits_filter_0(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::None, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -47,9 +42,7 @@ fn filters_2_bits_filter_0(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::None, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -59,9 +52,7 @@ fn filters_1_bits_filter_0(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::None, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::None, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -69,9 +60,7 @@ fn filters_16_bits_filter_1(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Sub, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -79,9 +68,7 @@ fn filters_8_bits_filter_1(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Sub, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -91,9 +78,7 @@ fn filters_4_bits_filter_1(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Sub, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -103,9 +88,7 @@ fn filters_2_bits_filter_1(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Sub, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -115,9 +98,7 @@ fn filters_1_bits_filter_1(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Sub, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Sub, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -125,9 +106,7 @@ fn filters_16_bits_filter_2(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Up, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -135,9 +114,7 @@ fn filters_8_bits_filter_2(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Up, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -147,9 +124,7 @@ fn filters_4_bits_filter_2(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Up, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -159,9 +134,7 @@ fn filters_2_bits_filter_2(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Up, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -171,9 +144,7 @@ fn filters_1_bits_filter_2(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Up, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Up, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -181,9 +152,7 @@ fn filters_16_bits_filter_3(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Average, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -191,9 +160,7 @@ fn filters_8_bits_filter_3(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Average, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -203,9 +170,7 @@ fn filters_4_bits_filter_3(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Average, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -215,9 +180,7 @@ fn filters_2_bits_filter_3(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Average, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -227,9 +190,7 @@ fn filters_1_bits_filter_3(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Average, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Average, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -237,9 +198,7 @@ fn filters_16_bits_filter_4(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Paeth, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -247,9 +206,7 @@ fn filters_8_bits_filter_4(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Paeth, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -259,9 +216,7 @@ fn filters_4_bits_filter_4(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Paeth, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -271,9 +226,7 @@ fn filters_2_bits_filter_4(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Paeth, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -283,9 +236,7 @@ fn filters_1_bits_filter_4(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Paeth, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Paeth, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -293,9 +244,7 @@ fn filters_16_bits_filter_5(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::MinSum, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -303,9 +252,7 @@ fn filters_8_bits_filter_5(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::MinSum, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -315,9 +262,7 @@ fn filters_4_bits_filter_5(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::MinSum, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -327,9 +272,7 @@ fn filters_2_bits_filter_5(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::MinSum, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -339,7 +282,5 @@ fn filters_1_bits_filter_5(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::MinSum, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ fn filters_minsum(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::MinSum, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::MinSum, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -23,9 +21,7 @@ fn filters_entropy(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Entropy, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Entropy, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -33,9 +29,7 @@ fn filters_bigrams(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Bigrams, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Bigrams, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -43,9 +37,7 @@ fn filters_bigent(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::BigEnt, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::BigEnt, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -53,7 +45,5 @@ fn filters_brute(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, &Options::default()).unwrap();
|
||||
|
||||
b.iter(|| {
|
||||
png.raw.filter_image(RowFilter::Brute, false);
|
||||
});
|
||||
b.iter(|| png.raw.filter_image(RowFilter::Brute, false));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ pub struct AtomicMin {
|
|||
}
|
||||
|
||||
impl AtomicMin {
|
||||
#[must_use]
|
||||
pub fn new(init: Option<usize>) -> Self {
|
||||
Self {
|
||||
val: AtomicUsize::new(init.unwrap_or(usize::MAX)),
|
||||
|
|
@ -21,8 +22,8 @@ impl AtomicMin {
|
|||
}
|
||||
}
|
||||
|
||||
/// Unset value is usize_max
|
||||
pub fn as_atomic_usize(&self) -> &AtomicUsize {
|
||||
/// Unset value is `usize_max`
|
||||
pub const fn as_atomic_usize(&self) -> &AtomicUsize {
|
||||
&self.val
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ impl Display for ColorType {
|
|||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ColorType::Grayscale { .. } => Display::fmt("Grayscale", f),
|
||||
ColorType::RGB { .. } => Display::fmt("RGB", f),
|
||||
ColorType::Indexed { palette } => {
|
||||
Self::Grayscale { .. } => Display::fmt("Grayscale", f),
|
||||
Self::RGB { .. } => Display::fmt("RGB", f),
|
||||
Self::Indexed { palette } => {
|
||||
Display::fmt(&format!("Indexed ({} colors)", palette.len()), f)
|
||||
}
|
||||
ColorType::GrayscaleAlpha => Display::fmt("Grayscale + Alpha", f),
|
||||
ColorType::RGBA => Display::fmt("RGB + Alpha", f),
|
||||
Self::GrayscaleAlpha => Display::fmt("Grayscale + Alpha", f),
|
||||
Self::RGBA => Display::fmt("RGB + Alpha", f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,49 +46,47 @@ impl Display for ColorType {
|
|||
impl ColorType {
|
||||
/// Get the code used by the PNG specification to denote this color type
|
||||
#[inline]
|
||||
pub fn png_header_code(&self) -> u8 {
|
||||
#[must_use]
|
||||
pub const fn png_header_code(&self) -> u8 {
|
||||
match self {
|
||||
ColorType::Grayscale { .. } => 0,
|
||||
ColorType::RGB { .. } => 2,
|
||||
ColorType::Indexed { .. } => 3,
|
||||
ColorType::GrayscaleAlpha => 4,
|
||||
ColorType::RGBA => 6,
|
||||
Self::Grayscale { .. } => 0,
|
||||
Self::RGB { .. } => 2,
|
||||
Self::Indexed { .. } => 3,
|
||||
Self::GrayscaleAlpha => 4,
|
||||
Self::RGBA => 6,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn channels_per_pixel(&self) -> u8 {
|
||||
pub(crate) const fn channels_per_pixel(&self) -> u8 {
|
||||
match self {
|
||||
ColorType::Grayscale { .. } | ColorType::Indexed { .. } => 1,
|
||||
ColorType::GrayscaleAlpha => 2,
|
||||
ColorType::RGB { .. } => 3,
|
||||
ColorType::RGBA => 4,
|
||||
Self::Grayscale { .. } | Self::Indexed { .. } => 1,
|
||||
Self::GrayscaleAlpha => 2,
|
||||
Self::RGB { .. } => 3,
|
||||
Self::RGBA => 4,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_rgb(&self) -> bool {
|
||||
matches!(self, ColorType::RGB { .. } | ColorType::RGBA)
|
||||
pub(crate) const fn is_rgb(&self) -> bool {
|
||||
matches!(self, Self::RGB { .. } | Self::RGBA)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn is_gray(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
ColorType::Grayscale { .. } | ColorType::GrayscaleAlpha
|
||||
)
|
||||
pub(crate) const fn is_gray(&self) -> bool {
|
||||
matches!(self, Self::Grayscale { .. } | Self::GrayscaleAlpha)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn has_alpha(&self) -> bool {
|
||||
matches!(self, ColorType::GrayscaleAlpha | ColorType::RGBA)
|
||||
pub(crate) const fn has_alpha(&self) -> bool {
|
||||
matches!(self, Self::GrayscaleAlpha | Self::RGBA)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn has_trns(&self) -> bool {
|
||||
pub(crate) const fn has_trns(&self) -> bool {
|
||||
match self {
|
||||
ColorType::Grayscale { transparent_shade } => transparent_shade.is_some(),
|
||||
ColorType::RGB { transparent_color } => transparent_color.is_some(),
|
||||
Self::Grayscale { transparent_shade } => transparent_shade.is_some(),
|
||||
Self::RGB { transparent_color } => transparent_color.is_some(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub fn inflate(data: &[u8], out_size: usize) -> PngResult<Vec<u8>> {
|
|||
Ok(dest)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn crc32(data: &[u8]) -> u32 {
|
||||
let mut crc = Crc::new();
|
||||
crc.update(data);
|
||||
|
|
|
|||
|
|
@ -33,14 +33,13 @@ impl fmt::Display for PngError {
|
|||
f.write_str("Missing data in the file; the file is truncated")
|
||||
}
|
||||
PngError::APNGNotSupported => f.write_str("APNG files are not (yet) supported"),
|
||||
PngError::ChunkMissing(s) => write!(f, "Chunk {} missing or empty", s),
|
||||
PngError::ChunkMissing(s) => write!(f, "Chunk {s} missing or empty"),
|
||||
PngError::InvalidDepthForType(d, ref c) => {
|
||||
write!(f, "Invalid bit depth {} for color type {}", d, c)
|
||||
write!(f, "Invalid bit depth {d} for color type {c}")
|
||||
}
|
||||
PngError::IncorrectDataLength(l1, l2) => write!(
|
||||
f,
|
||||
"Data length {} does not match the expected length {}",
|
||||
l1, l2
|
||||
"Data length {l1} does not match the expected length {l2}"
|
||||
),
|
||||
PngError::C2PAMetadataPreventsChanges => f.write_str(
|
||||
"The image contains C2PA manifest that would be invalidated by any file changes",
|
||||
|
|
@ -52,6 +51,7 @@ impl fmt::Display for PngError {
|
|||
|
||||
impl PngError {
|
||||
#[cold]
|
||||
#[must_use]
|
||||
pub fn new(description: &str) -> PngError {
|
||||
PngError::Other(description.into())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use rayon::prelude::*;
|
|||
use crate::rayon;
|
||||
use crate::{atomicmin::AtomicMin, deflate, filters::RowFilter, png::PngImage, Deadline, PngError};
|
||||
|
||||
pub struct Candidate {
|
||||
pub(crate) struct Candidate {
|
||||
pub image: Arc<PngImage>,
|
||||
pub idat_data: Vec<u8>,
|
||||
pub filtered: Vec<u8>,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ impl IhdrData {
|
|||
/// Bits per pixel
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn bpp(&self) -> usize {
|
||||
pub const fn bpp(&self) -> usize {
|
||||
self.bit_depth as usize * self.color_type.channels_per_pixel() as usize
|
||||
}
|
||||
|
||||
|
|
@ -91,11 +91,11 @@ pub enum StripChunks {
|
|||
impl StripChunks {
|
||||
pub(crate) fn keep(&self, name: &[u8; 4]) -> bool {
|
||||
match &self {
|
||||
StripChunks::None => true,
|
||||
StripChunks::Keep(names) => names.contains(name),
|
||||
StripChunks::Strip(names) => !names.contains(name),
|
||||
StripChunks::Safe => DISPLAY_CHUNKS.contains(name),
|
||||
StripChunks::All => false,
|
||||
Self::None => true,
|
||||
Self::Keep(names) => names.contains(name),
|
||||
Self::Strip(names) => !names.contains(name),
|
||||
Self::Safe => DISPLAY_CHUNKS.contains(name),
|
||||
Self::All => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
src/lib.rs
18
src/lib.rs
|
|
@ -195,8 +195,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
.map_err(|err| {
|
||||
// Fail if metadata cannot be preserved
|
||||
PngError::new(&format!(
|
||||
"Unable to read metadata from input file {:?}: {}",
|
||||
input_path, err
|
||||
"Unable to read metadata from input file {input_path:?}: {err}"
|
||||
))
|
||||
})
|
||||
.map(Some)?;
|
||||
|
|
@ -211,7 +210,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
let mut data = Vec::new();
|
||||
stdin()
|
||||
.read_to_end(&mut data)
|
||||
.map_err(|e| PngError::new(&format!("Error reading stdin: {}", e)))?;
|
||||
.map_err(|e| PngError::new(&format!("Error reading stdin: {e}")))?;
|
||||
data
|
||||
}
|
||||
};
|
||||
|
|
@ -260,7 +259,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
let mut buffer = BufWriter::new(stdout());
|
||||
buffer
|
||||
.write_all(&optimized_output)
|
||||
.map_err(|e| PngError::new(&format!("Unable to write to stdout: {}", e)))?;
|
||||
.map_err(|e| PngError::new(&format!("Unable to write to stdout: {e}")))?;
|
||||
}
|
||||
(OutFile::Path { path, .. }, _) => {
|
||||
let output_path = path
|
||||
|
|
@ -460,7 +459,7 @@ fn optimize_raw(
|
|||
|
||||
if eval_result.is_some() {
|
||||
// Some filters have already been evaluated, we don't need to try them again
|
||||
filters = filters.difference(&eval_filters).cloned().collect();
|
||||
filters = filters.difference(&eval_filters).copied().collect();
|
||||
}
|
||||
|
||||
if !filters.is_empty() {
|
||||
|
|
@ -609,6 +608,7 @@ pub struct Deadline {
|
|||
}
|
||||
|
||||
impl Deadline {
|
||||
#[must_use]
|
||||
pub fn new(timeout: Option<Duration>) -> Self {
|
||||
Self {
|
||||
imp: timeout.map(|timeout| DeadlineImp {
|
||||
|
|
@ -742,7 +742,7 @@ fn postprocess_chunks(
|
|||
c.data.truncate(4);
|
||||
c.data.append(&mut data);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -756,8 +756,7 @@ fn copy_permissions(metadata_input: &Metadata, out_file: &File) -> PngResult<()>
|
|||
.set_permissions(metadata_input.permissions())
|
||||
.map_err(|err_io| {
|
||||
PngError::new(&format!(
|
||||
"unable to set permissions for output file: {}",
|
||||
err_io
|
||||
"unable to set permissions for output file: {err_io}"
|
||||
))
|
||||
})
|
||||
}
|
||||
|
|
@ -778,8 +777,7 @@ fn copy_times(input_path_meta: &Metadata, out_path: &Path) -> PngResult<()> {
|
|||
);
|
||||
filetime::set_file_times(out_path, atime, mtime).map_err(|err_io| {
|
||||
PngError::new(&format!(
|
||||
"unable to set file times on {:?}: {}",
|
||||
out_path, err_io
|
||||
"unable to set file times on {out_path:?}: {err_io}"
|
||||
))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
12
src/main.rs
12
src/main.rs
|
|
@ -228,8 +228,8 @@ fn parse_opts_into_struct(
|
|||
let out_dir = if let Some(path) = matches.get_one::<PathBuf>("output_dir") {
|
||||
if !path.exists() {
|
||||
match DirBuilder::new().recursive(true).create(path) {
|
||||
Ok(_) => (),
|
||||
Err(x) => return Err(format!("Could not create output directory {}", x)),
|
||||
Ok(()) => (),
|
||||
Err(x) => return Err(format!("Could not create output directory {x}")),
|
||||
};
|
||||
} else if !path.is_dir() {
|
||||
return Err(format!(
|
||||
|
|
@ -305,9 +305,9 @@ fn parse_opts_into_struct(
|
|||
})
|
||||
.collect::<Result<IndexSet<_>, _>>()?;
|
||||
if keep_display {
|
||||
names.extend(DISPLAY_CHUNKS.iter().cloned());
|
||||
names.extend(DISPLAY_CHUNKS.iter().copied());
|
||||
}
|
||||
opts.strip = StripChunks::Keep(names)
|
||||
opts.strip = StripChunks::Keep(names);
|
||||
}
|
||||
|
||||
if let Some(strip) = matches.get_one::<String>("strip") {
|
||||
|
|
@ -329,7 +329,7 @@ fn parse_opts_into_struct(
|
|||
}
|
||||
let name = parse_chunk_name(x)?;
|
||||
if FORBIDDEN_CHUNKS.contains(&name) {
|
||||
return Err(format!("{} chunk is not allowed to be stripped", x));
|
||||
return Err(format!("{x} chunk is not allowed to be stripped"));
|
||||
}
|
||||
Ok(name)
|
||||
})
|
||||
|
|
@ -370,7 +370,7 @@ fn parse_chunk_name(name: &str) -> Result<[u8; 4], String> {
|
|||
name.trim()
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.map_err(|_| format!("Invalid chunk name {}", name))
|
||||
.map_err(|_| format!("Invalid chunk name {name}"))
|
||||
}
|
||||
|
||||
fn parse_numeric_range_opts(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ impl OutFile {
|
|||
/// Construct a new `OutFile` with the given path.
|
||||
///
|
||||
/// This is a convenience method for `OutFile::Path { path: Some(path), preserve_attrs: false }`.
|
||||
#[must_use]
|
||||
pub fn from_path(path: PathBuf) -> Self {
|
||||
OutFile::Path {
|
||||
path: Some(path),
|
||||
|
|
@ -38,9 +39,10 @@ impl OutFile {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn path(&self) -> Option<&Path> {
|
||||
match *self {
|
||||
OutFile::Path {
|
||||
Self::Path {
|
||||
path: Some(ref p), ..
|
||||
} => Some(p.as_path()),
|
||||
_ => None,
|
||||
|
|
@ -57,10 +59,11 @@ pub enum InFile {
|
|||
}
|
||||
|
||||
impl InFile {
|
||||
#[must_use]
|
||||
pub fn path(&self) -> Option<&Path> {
|
||||
match *self {
|
||||
InFile::Path(ref p) => Some(p.as_path()),
|
||||
InFile::StdIn => None,
|
||||
Self::Path(ref p) => Some(p.as_path()),
|
||||
Self::StdIn => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,15 +71,15 @@ impl InFile {
|
|||
impl fmt::Display for InFile {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
InFile::Path(ref p) => write!(f, "{}", p.display()),
|
||||
InFile::StdIn => f.write_str("stdin"),
|
||||
Self::Path(ref p) => write!(f, "{}", p.display()),
|
||||
Self::StdIn => f.write_str("stdin"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<PathBuf>> From<T> for InFile {
|
||||
fn from(s: T) -> Self {
|
||||
InFile::Path(s.into())
|
||||
Self::Path(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +94,7 @@ pub struct Options {
|
|||
///
|
||||
/// Default: `false`
|
||||
pub force: bool,
|
||||
/// Which RowFilters to try on the file
|
||||
/// Which `RowFilters` to try on the file
|
||||
///
|
||||
/// Default: `None,Sub,Entropy,Bigrams`
|
||||
pub filter: IndexSet<RowFilter>,
|
||||
|
|
@ -156,8 +159,9 @@ pub struct Options {
|
|||
}
|
||||
|
||||
impl Options {
|
||||
pub fn from_preset(level: u8) -> Options {
|
||||
let opts = Options::default();
|
||||
#[must_use]
|
||||
pub fn from_preset(level: u8) -> Self {
|
||||
let opts = Self::default();
|
||||
match level {
|
||||
0 => opts.apply_preset_0(),
|
||||
1 => opts.apply_preset_1(),
|
||||
|
|
@ -173,8 +177,9 @@ impl Options {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn max_compression() -> Options {
|
||||
Options::from_preset(6)
|
||||
#[must_use]
|
||||
pub fn max_compression() -> Self {
|
||||
Self::from_preset(6)
|
||||
}
|
||||
|
||||
// The following methods make assumptions that they are operating
|
||||
|
|
@ -237,9 +242,9 @@ impl Options {
|
|||
}
|
||||
|
||||
impl Default for Options {
|
||||
fn default() -> Options {
|
||||
fn default() -> Self {
|
||||
// Default settings based on -o 2 from the CLI interface
|
||||
Options {
|
||||
Self {
|
||||
fix_errors: false,
|
||||
force: false,
|
||||
filter: indexset! {RowFilter::None, RowFilter::Sub, RowFilter::Entropy, RowFilter::Bigrams},
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ impl PngData {
|
|||
aux_chunks.push(Chunk {
|
||||
name: chunk.name,
|
||||
data: Vec::new(),
|
||||
})
|
||||
});
|
||||
}
|
||||
idat_data.extend_from_slice(chunk.data);
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ impl PngData {
|
|||
aux_chunks.push(Chunk {
|
||||
name: chunk.name,
|
||||
data: chunk.data.to_owned(),
|
||||
})
|
||||
});
|
||||
} else if chunk.name == *b"acTL" {
|
||||
warn!(
|
||||
"Stripping animation data from APNG - image will become standard PNG"
|
||||
|
|
@ -170,11 +170,13 @@ impl PngData {
|
|||
}
|
||||
|
||||
/// Return an estimate of the output size which can help with evaluation of very small data
|
||||
#[must_use]
|
||||
pub fn estimated_output_size(&self) -> usize {
|
||||
self.idat_data.len() + self.raw.key_chunks_size()
|
||||
}
|
||||
|
||||
/// Format the `PngData` struct into a valid PNG bytestream
|
||||
#[must_use]
|
||||
pub fn output(&self) -> Vec<u8> {
|
||||
// PNG header
|
||||
let mut output = vec![0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
|
||||
|
|
@ -227,7 +229,7 @@ impl PngData {
|
|||
transparent_color: Some(trns),
|
||||
} => {
|
||||
// Transparency pixel - 6 byte RGB16
|
||||
let trns_data: Vec<_> = trns.iter().flat_map(|c| c.to_be_bytes()).collect();
|
||||
let trns_data: Vec<_> = trns.iter().flat_map(u16::to_be_bytes).collect();
|
||||
write_png_block(b"tRNS", &trns_data, &mut output);
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -261,7 +263,7 @@ impl PngImage {
|
|||
/// Assumes that the data has already been de-filtered
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn change_interlacing(&self, interlace: Interlacing) -> Option<PngImage> {
|
||||
pub fn change_interlacing(&self, interlace: Interlacing) -> Option<Self> {
|
||||
if interlace == self.ihdr.interlaced {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -277,13 +279,15 @@ impl PngImage {
|
|||
|
||||
/// Return the number of channels in the image, based on color type
|
||||
#[inline]
|
||||
pub fn channels_per_pixel(&self) -> usize {
|
||||
#[must_use]
|
||||
pub const fn channels_per_pixel(&self) -> usize {
|
||||
self.ihdr.color_type.channels_per_pixel() as usize
|
||||
}
|
||||
|
||||
/// Return the number of bytes per channel in the image
|
||||
#[inline]
|
||||
pub fn bytes_per_channel(&self) -> usize {
|
||||
#[must_use]
|
||||
pub const fn bytes_per_channel(&self) -> usize {
|
||||
match self.ihdr.bit_depth {
|
||||
BitDepth::Sixteen => 2,
|
||||
// Depths lower than 8 will round up to 1 byte
|
||||
|
|
@ -292,6 +296,7 @@ impl PngImage {
|
|||
}
|
||||
|
||||
/// Calculate the size of the PLTE and tRNS chunks
|
||||
#[must_use]
|
||||
pub fn key_chunks_size(&self) -> usize {
|
||||
match &self.ihdr.color_type {
|
||||
ColorType::Indexed { palette } => {
|
||||
|
|
@ -310,6 +315,7 @@ impl PngImage {
|
|||
|
||||
/// Return an iterator over the scanlines of the image
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn scan_lines(&self, has_filter: bool) -> ScanLines<'_> {
|
||||
ScanLines::new(self, has_filter)
|
||||
}
|
||||
|
|
@ -337,6 +343,7 @@ impl PngImage {
|
|||
}
|
||||
|
||||
/// Apply the specified filter type to all rows in the image
|
||||
#[must_use]
|
||||
pub fn filter_image(&self, filter: RowFilter, optimize_alpha: bool) -> Vec<u8> {
|
||||
let mut filtered = Vec::with_capacity(self.data.len());
|
||||
let bpp = self.bytes_per_channel() * self.channels_per_pixel();
|
||||
|
|
@ -411,7 +418,7 @@ impl PngImage {
|
|||
for f in try_filters {
|
||||
f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes);
|
||||
let mut counts = vec![0; 0x100];
|
||||
for &i in f_buf.iter() {
|
||||
for &i in &f_buf {
|
||||
counts[i as usize] += 1;
|
||||
}
|
||||
let size = counts.into_iter().fold(0, |acc, x| {
|
||||
|
|
@ -435,7 +442,7 @@ impl PngImage {
|
|||
f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes);
|
||||
let mut set = bitarr![0; 0x10000];
|
||||
for pair in f_buf.windows(2) {
|
||||
let bigram = (pair[0] as usize) << 8 | pair[1] as usize;
|
||||
let bigram = ((pair[0] as usize) << 8) | pair[1] as usize;
|
||||
set.set(bigram, true);
|
||||
}
|
||||
let size = set.count_ones();
|
||||
|
|
@ -455,7 +462,7 @@ impl PngImage {
|
|||
f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes);
|
||||
counts.clear();
|
||||
for pair in f_buf.windows(2) {
|
||||
let bigram = (pair[0] as u16) << 8 | pair[1] as u16;
|
||||
let bigram = (u16::from(pair[0]) << 8) | u16::from(pair[1]);
|
||||
counts.entry(bigram).and_modify(|e| *e += 1).or_insert(1);
|
||||
}
|
||||
let size = counts.values().fold(0, |acc, &x| acc + ilog2i(x)) as i32;
|
||||
|
|
@ -516,7 +523,7 @@ fn write_png_block(key: &[u8], chunk: &[u8], output: &mut Vec<u8>) {
|
|||
}
|
||||
|
||||
// Integer approximation for i * log2(i) - much faster than float calculations
|
||||
fn ilog2i(i: u32) -> u32 {
|
||||
const fn ilog2i(i: u32) -> u32 {
|
||||
let log = 32 - i.leading_zeros() - 1;
|
||||
i * log + ((i - (1 << log)) << 1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ pub struct ScanLines<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ScanLines<'a> {
|
||||
#[must_use]
|
||||
pub fn new(png: &'a PngImage, has_filter: bool) -> Self {
|
||||
Self {
|
||||
iter: ScanLineRanges::new(png, has_filter),
|
||||
|
|
@ -22,6 +23,7 @@ impl<'a> ScanLines<'a> {
|
|||
|
||||
impl<'a> Iterator for ScanLines<'a> {
|
||||
type Item = ScanLine<'a>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (len, pass, num_pixels) = self.iter.next()?;
|
||||
|
|
@ -79,6 +81,7 @@ impl ScanLineRanges {
|
|||
|
||||
impl Iterator for ScanLineRanges {
|
||||
type Item = (usize, Option<u8>, usize);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.left == 0 {
|
||||
return None;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use crate::{
|
|||
};
|
||||
|
||||
/// Clean the alpha channel by setting the color of all fully transparent pixels to black
|
||||
#[must_use]
|
||||
pub fn cleaned_alpha_channel(png: &PngImage) -> Option<PngImage> {
|
||||
if !png.ihdr.color_type.has_alpha() {
|
||||
return None;
|
||||
|
|
@ -85,8 +86,8 @@ pub fn reduced_alpha_channel(png: &PngImage, optimize_alpha: bool) -> Option<Png
|
|||
|
||||
// Construct the color type with appropriate transparency data
|
||||
let transparent = transparency_pixel.map(|trns| match png.ihdr.bit_depth {
|
||||
BitDepth::Sixteen => (trns as u16) << 8 | trns as u16,
|
||||
_ => trns as u16,
|
||||
BitDepth::Sixteen => (u16::from(trns) << 8) | u16::from(trns),
|
||||
_ => u16::from(trns),
|
||||
});
|
||||
let target_color_type = match png.ihdr.color_type {
|
||||
ColorType::GrayscaleAlpha => ColorType::Grayscale {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub fn reduced_bit_depth_16_to_8(png: &PngImage, force_scale: bool) -> Option<Pn
|
|||
}
|
||||
|
||||
Some(PngImage {
|
||||
data: png.data.iter().step_by(2).cloned().collect(),
|
||||
data: png.data.iter().step_by(2).copied().collect(),
|
||||
ihdr: IhdrData {
|
||||
color_type: png.ihdr.color_type.clone(),
|
||||
bit_depth: BitDepth::Eight,
|
||||
|
|
@ -48,8 +48,8 @@ pub fn scaled_bit_depth_16_to_8(png: &PngImage) -> Option<PngImage> {
|
|||
}
|
||||
// See: http://www.libpng.org/pub/png/spec/1.2/PNG-Decoders.html#D.Sample-depth-rescaling
|
||||
// This allows values such as 0x00FF to be rounded to 0x01 rather than truncated to 0x00
|
||||
let val = u16::from_be_bytes([pair[0], pair[1]]) as f64;
|
||||
(val * 255.0 / 65535.0).round() as u8
|
||||
let val = f32::from(u16::from_be_bytes([pair[0], pair[1]]));
|
||||
(val * (255.0 / 65535.0)).round() as u8
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ pub fn reduced_bit_depth_8_or_less(png: &PngImage) -> Option<PngImage> {
|
|||
let mut check = reduced_trans;
|
||||
let mut bits = minimum_bits;
|
||||
while bits < 8 {
|
||||
check = check << bits | check;
|
||||
check = (check << bits) | check;
|
||||
bits <<= 1;
|
||||
}
|
||||
// If the transparency doesn't fit the new bit depth it is therefore unused - set it to None
|
||||
|
|
@ -188,7 +188,7 @@ pub fn expanded_bit_depth_to_8(png: &PngImage) -> Option<PngImage> {
|
|||
// Expand gray by repeating the bits
|
||||
let mut bits = bit_depth;
|
||||
while bits < 8 {
|
||||
val = val << bits | val;
|
||||
val = (val << bits) | val;
|
||||
bits <<= 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ pub fn expanded_bit_depth_to_8(png: &PngImage) -> Option<PngImage> {
|
|||
{
|
||||
let mut bits = bit_depth;
|
||||
while bits < 8 {
|
||||
trans = trans << bits | trans;
|
||||
trans = (trans << bits) | trans;
|
||||
bits <<= 1;
|
||||
}
|
||||
ColorType::Grayscale {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option<PngIm
|
|||
let mut raw_data = Vec::with_capacity(png.data.len() / png.channels_per_pixel());
|
||||
let palette: Vec<_> = match png.ihdr.color_type {
|
||||
ColorType::Grayscale { transparent_shade } => {
|
||||
let pmap = build_palette(png.data.as_gray().iter().cloned(), &mut raw_data)?;
|
||||
let pmap = build_palette(png.data.as_gray().iter().copied(), &mut raw_data)?;
|
||||
// Convert the Gray16 transparency to Gray8
|
||||
let transparency_pixel = transparent_shade.map(|t| Gray::from(t as u8));
|
||||
pmap.into_iter()
|
||||
|
|
@ -63,7 +63,7 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option<PngIm
|
|||
.collect()
|
||||
}
|
||||
ColorType::RGB { transparent_color } => {
|
||||
let pmap = build_palette(png.data.as_rgb().iter().cloned(), &mut raw_data)?;
|
||||
let pmap = build_palette(png.data.as_rgb().iter().copied(), &mut raw_data)?;
|
||||
// Convert the RGB16 transparency to RGB8
|
||||
let transparency_pixel = transparent_color.map(|t| t.map(|c| c as u8));
|
||||
pmap.into_iter()
|
||||
|
|
@ -77,11 +77,11 @@ pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option<PngIm
|
|||
.collect()
|
||||
}
|
||||
ColorType::GrayscaleAlpha => {
|
||||
let pmap = build_palette(png.data.as_gray_alpha().iter().cloned(), &mut raw_data)?;
|
||||
let pmap = build_palette(png.data.as_gray_alpha().iter().copied(), &mut raw_data)?;
|
||||
pmap.into_iter().map(RGBA::from).collect()
|
||||
}
|
||||
ColorType::RGBA => {
|
||||
let pmap = build_palette(png.data.as_rgba().iter().cloned(), &mut raw_data)?;
|
||||
let pmap = build_palette(png.data.as_rgba().iter().copied(), &mut raw_data)?;
|
||||
pmap.into_iter().collect()
|
||||
}
|
||||
_ => return None,
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ fn co_occurrence_matrix(num_colors: usize, png: &PngImage) -> Vec<Vec<u32>> {
|
|||
matrix[val][prev_val] += 1;
|
||||
}
|
||||
}
|
||||
prev = Some(line)
|
||||
prev = Some(line);
|
||||
}
|
||||
matrix
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
use std::cell::RefCell;
|
||||
#[cfg(feature = "zopfli")]
|
||||
use std::num::NonZeroU8;
|
||||
#[cfg(feature = "filetime")]
|
||||
use std::ops::Deref;
|
||||
use std::{
|
||||
fs::remove_file,
|
||||
path::{Path, PathBuf},
|
||||
|
|
@ -94,7 +92,7 @@ fn test_it_converts(
|
|||
bit_depth_out,
|
||||
|_| {},
|
||||
|_| {},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -194,10 +192,7 @@ fn verbose_mode() {
|
|||
let expected_prefix = expected_prefixes[i];
|
||||
assert!(
|
||||
log.starts_with(expected_prefix),
|
||||
"logs[{}] = {:?} doesn't start with {:?}",
|
||||
i,
|
||||
log,
|
||||
expected_prefix
|
||||
"logs[{i}] = {log:?} doesn't start with {expected_prefix:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -540,8 +535,8 @@ fn preserve_attrs() {
|
|||
|
||||
let cellref_atime_canon = atime_canon.borrow();
|
||||
let cellref_mtime_canon = mtime_canon.borrow();
|
||||
let ref_atime_canon: &filetime::FileTime = cellref_atime_canon.deref();
|
||||
let ref_mtime_canon: &filetime::FileTime = cellref_mtime_canon.deref();
|
||||
let ref_atime_canon: &filetime::FileTime = &cellref_atime_canon;
|
||||
let ref_mtime_canon: &filetime::FileTime = &cellref_mtime_canon;
|
||||
|
||||
assert_eq!(
|
||||
ref_atime_canon,
|
||||
|
|
|
|||
Loading…
Reference in a new issue