More Reductions (#468)

* Add test for issue 195

* Reduce grayscale alpha to palette

* Black alpha before color type reductions
This commit is contained in:
andrews05 2022-12-08 07:22:13 +13:00 committed by GitHub
parent 1934587253
commit bd5a0b526b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 6 deletions

View file

@ -726,6 +726,13 @@ fn perform_reductions(
}
if opts.color_type_reduction {
// Perform a black alpha reduction before color type reductions
// This can allow reductions from alpha to indexed which may not have been possible otherwise
if !opts.alphas.is_empty() {
if let Some(reduced) = filtered_alpha_channel(&png, AlphaOptim::Black) {
png = Arc::new(reduced);
}
}
if let Some(reduced) = reduce_color_type(&png, opts.grayscale_reduction) {
png = Arc::new(reduced);
eval.try_image(png.clone());

View file

@ -3,7 +3,7 @@ use crate::headers::IhdrData;
use crate::png::PngImage;
use indexmap::IndexMap;
use itertools::Itertools;
use rgb::{FromSlice, RGB8, RGBA8};
use rgb::{FromSlice, RGB8, RGBA, RGBA8};
use rustc_hash::FxHasher;
use std::hash::{BuildHasherDefault, Hash};
@ -105,7 +105,7 @@ where
}
#[must_use]
pub fn reduced_color_to_palette(png: &PngImage) -> Option<PngImage> {
pub fn reduce_to_palette(png: &PngImage) -> Option<PngImage> {
if png.ihdr.bit_depth != BitDepth::Eight {
return None;
}
@ -131,6 +131,17 @@ pub fn reduced_color_to_palette(png: &PngImage) -> Option<PngImage> {
&mut palette,
&mut raw_data,
)
} else if png.ihdr.color_type == ColorType::GrayscaleAlpha {
reduce_scanline_to_palette(
line.data.as_gray_alpha().iter().cloned().map(|px| RGBA {
r: px.0,
g: px.0,
b: px.0,
a: px.1,
}),
&mut palette,
&mut raw_data,
)
} else {
debug_assert_eq!(png.ihdr.color_type, ColorType::RGBA);
reduce_scanline_to_palette(

View file

@ -12,7 +12,7 @@ use crate::bit_depth::reduce_bit_depth_8_or_less;
pub mod color;
use crate::color::*;
pub(crate) use crate::alpha::try_alpha_reductions;
pub(crate) use crate::alpha::{filtered_alpha_channel, try_alpha_reductions};
pub(crate) use crate::bit_depth::reduce_bit_depth;
/// Attempt to reduce the number of colors in the palette
@ -206,14 +206,14 @@ pub fn reduce_color_type(png: &PngImage, grayscale_reduction: bool) -> Option<Pn
.or_else(|| reduced_alpha_channel(&reduced))
{
reduced = Cow::Owned(r);
} else if let Some(r) = reduced_color_to_palette(&reduced) {
} else if let Some(r) = reduce_to_palette(&reduced) {
reduced = Cow::Owned(r);
should_reduce_bit_depth = true;
}
}
if reduced.ihdr.color_type == ColorType::GrayscaleAlpha {
if let Some(r) = reduced_alpha_channel(&reduced) {
if let Some(r) = reduced_alpha_channel(&reduced).or_else(|| reduce_to_palette(&reduced)) {
reduced = Cow::Owned(r);
should_reduce_bit_depth = true;
}
@ -225,7 +225,7 @@ pub fn reduce_color_type(png: &PngImage, grayscale_reduction: bool) -> Option<Pn
} else {
None
}
.or_else(|| reduced_color_to_palette(&reduced))
.or_else(|| reduce_to_palette(&reduced))
{
reduced = Cow::Owned(r);
should_reduce_bit_depth = true;

BIN
tests/files/issue-195.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -630,3 +630,15 @@ fn issue_182() {
BitDepth::One,
);
}
#[test]
fn issue_195() {
test_it_converts(
"tests/files/issue-195.png",
None,
ColorType::RGBA,
BitDepth::Eight,
ColorType::Indexed,
BitDepth::Eight,
);
}