From c71fd44454213469c7712036976bb4ffea152a86 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 30 May 2023 08:16:33 +1200 Subject: [PATCH] Prevent conversion from grayscale when disabled --- benches/reductions.rs | 6 +++--- src/colors.rs | 8 ++++++++ src/reduction/color.rs | 5 ++++- src/reduction/mod.rs | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/benches/reductions.rs b/benches/reductions.rs index 46fb8f49..a5a7b7d8 100644 --- a/benches/reductions.rs +++ b/benches/reductions.rs @@ -229,7 +229,7 @@ fn reductions_rgba_to_palette_8(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgba_8_should_be_palette_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| color::reduced_to_indexed(&png.raw)); + b.iter(|| color::reduced_to_indexed(&png.raw, true)); } #[bench] @@ -237,7 +237,7 @@ fn reductions_rgb_to_palette_8(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_palette_8.png")); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| color::reduced_to_indexed(&png.raw)); + b.iter(|| color::reduced_to_indexed(&png.raw, true)); } #[bench] @@ -247,7 +247,7 @@ fn reductions_grayscale_8_to_palette_8(b: &mut Bencher) { )); let png = PngData::new(&input, &Options::default()).unwrap(); - b.iter(|| color::reduced_to_indexed(&png.raw)); + b.iter(|| color::reduced_to_indexed(&png.raw, true)); } #[bench] diff --git a/src/colors.rs b/src/colors.rs index 744ec720..d81b1346 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -70,6 +70,14 @@ impl ColorType { matches!(self, ColorType::RGB { .. } | ColorType::RGBA) } + #[inline] + pub(crate) fn is_gray(&self) -> bool { + matches!( + self, + ColorType::Grayscale { .. } | ColorType::GrayscaleAlpha + ) + } + #[inline] pub(crate) fn has_alpha(&self) -> bool { matches!(self, ColorType::GrayscaleAlpha | ColorType::RGBA) diff --git a/src/reduction/color.rs b/src/reduction/color.rs index 457c4422..277902b1 100644 --- a/src/reduction/color.rs +++ b/src/reduction/color.rs @@ -32,13 +32,16 @@ where } #[must_use] -pub fn reduced_to_indexed(png: &PngImage) -> Option { +pub fn reduced_to_indexed(png: &PngImage, allow_grayscale: bool) -> Option { if png.ihdr.bit_depth != BitDepth::Eight { return None; } if matches!(png.ihdr.color_type, ColorType::Indexed { .. }) { return None; } + if !allow_grayscale && png.ihdr.color_type.is_gray() { + return None; + } let mut raw_data = Vec::with_capacity(png.data.len() / png.channels_per_pixel()); let palette: Vec<_> = match png.ihdr.color_type { diff --git a/src/reduction/mod.rs b/src/reduction/mod.rs index e07f57db..a5ea3c90 100644 --- a/src/reduction/mod.rs +++ b/src/reduction/mod.rs @@ -108,7 +108,7 @@ pub(crate) fn perform_reductions( // Attempt to reduce to indexed let mut indexed = None; if opts.color_type_reduction && !deadline.passed() { - if let Some(reduced) = reduced_to_indexed(&png) { + if let Some(reduced) = reduced_to_indexed(&png, opts.grayscale_reduction) { // Make sure the palette gets sorted (but don't bother evaluating both results) let new = Arc::new(sorted_palette(&reduced).unwrap_or(reduced)); // For relatively small differences, enter this into the evaluator