Reduce alpha in palette
This commit is contained in:
parent
93d48d64e6
commit
e842a0e2f3
3 changed files with 31 additions and 19 deletions
|
|
@ -80,7 +80,7 @@ fn reductions_rgba_to_rgb_16(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgba_16_should_be_rgb_16.png"));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -88,7 +88,7 @@ fn reductions_rgba_to_rgb_8(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgba_8_should_be_rgb_8.png"));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -98,7 +98,7 @@ fn reductions_rgba_to_grayscale_alpha_16(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -108,7 +108,7 @@ fn reductions_rgba_to_grayscale_alpha_8(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -118,7 +118,7 @@ fn reductions_rgba_to_grayscale_16(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -128,7 +128,7 @@ fn reductions_rgba_to_grayscale_8(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -138,7 +138,7 @@ fn reductions_rgb_to_grayscale_16(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -146,7 +146,7 @@ fn reductions_rgb_to_grayscale_8(b: &mut Bencher) {
|
|||
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_grayscale_8.png"));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -154,7 +154,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, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -162,7 +162,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, false).unwrap();
|
||||
|
||||
b.iter(|| reduce_color_type(&png.raw, true));
|
||||
b.iter(|| reduce_color_type(&png.raw, true, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -172,7 +172,7 @@ fn reductions_palette_duplicate_reduction(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduced_palette(&png.raw));
|
||||
b.iter(|| reduced_palette(&png.raw, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -182,7 +182,7 @@ fn reductions_palette_unused_reduction(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduced_palette(&png.raw));
|
||||
b.iter(|| reduced_palette(&png.raw, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
@ -192,7 +192,7 @@ fn reductions_palette_full_reduction(b: &mut Bencher) {
|
|||
));
|
||||
let png = PngData::new(&input, false).unwrap();
|
||||
|
||||
b.iter(|| reduced_palette(&png.raw));
|
||||
b.iter(|| reduced_palette(&png.raw, false));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
|
|
|||
|
|
@ -703,7 +703,7 @@ fn perform_reductions(
|
|||
}
|
||||
|
||||
if opts.palette_reduction {
|
||||
if let Some(reduced) = reduced_palette(&png) {
|
||||
if let Some(reduced) = reduced_palette(&png, opts.optimize_alpha) {
|
||||
png = Arc::new(reduced);
|
||||
eval.try_image(png.clone());
|
||||
report_reduction(&png);
|
||||
|
|
@ -737,7 +737,9 @@ fn perform_reductions(
|
|||
}
|
||||
|
||||
if opts.color_type_reduction {
|
||||
if let Some(reduced) = reduce_color_type(&png, opts.grayscale_reduction) {
|
||||
if let Some(reduced) =
|
||||
reduce_color_type(&png, opts.grayscale_reduction, opts.optimize_alpha)
|
||||
{
|
||||
png = Arc::new(reduced);
|
||||
eval.try_image(png.clone());
|
||||
report_reduction(&png);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub(crate) use crate::bit_depth::reduce_bit_depth;
|
|||
|
||||
/// Attempt to reduce the number of colors in the palette
|
||||
/// Returns `None` if palette hasn't changed
|
||||
pub fn reduced_palette(png: &PngImage) -> Option<PngImage> {
|
||||
pub fn reduced_palette(png: &PngImage, optimize_alpha: bool) -> Option<PngImage> {
|
||||
if png.ihdr.color_type != ColorType::Indexed {
|
||||
// Can't reduce if there is no palette
|
||||
return None;
|
||||
|
|
@ -90,10 +90,16 @@ pub fn reduced_palette(png: &PngImage) -> Option<PngImage> {
|
|||
continue;
|
||||
}
|
||||
// There are invalid files that use pixel indices beyond palette size
|
||||
let color = palette
|
||||
let mut color = palette
|
||||
.get(i)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| RGBA8::new(0, 0, 0, 255));
|
||||
// If there are multiple fully transparent entries, reduce them into one
|
||||
if optimize_alpha && color.a == 0 {
|
||||
color.r = 0;
|
||||
color.g = 0;
|
||||
color.b = 0;
|
||||
}
|
||||
match seen.entry(color) {
|
||||
Vacant(new) => {
|
||||
palette_map[i] = Some(next_index as u8);
|
||||
|
|
@ -191,7 +197,11 @@ fn reordered_palette(palette: &[RGBA8], palette_map: &[Option<u8>; 256]) -> Vec<
|
|||
|
||||
/// Attempt to reduce the color type of the image
|
||||
/// Returns true if the color type was reduced, false otherwise
|
||||
pub fn reduce_color_type(png: &PngImage, grayscale_reduction: bool) -> Option<PngImage> {
|
||||
pub fn reduce_color_type(
|
||||
png: &PngImage,
|
||||
grayscale_reduction: bool,
|
||||
optimize_alpha: bool,
|
||||
) -> Option<PngImage> {
|
||||
let mut should_reduce_bit_depth = false;
|
||||
let mut reduced = Cow::Borrowed(png);
|
||||
|
||||
|
|
@ -234,7 +244,7 @@ pub fn reduce_color_type(png: &PngImage, grayscale_reduction: bool) -> Option<Pn
|
|||
|
||||
//Make sure that palette gets sorted. Ideally, this should be done within reduced_color_to_palette.
|
||||
if should_reduce_bit_depth && reduced.ihdr.color_type == ColorType::Indexed {
|
||||
if let Some(r) = reduced_palette(&reduced) {
|
||||
if let Some(r) = reduced_palette(&reduced, optimize_alpha) {
|
||||
reduced = Cow::Owned(r);
|
||||
should_reduce_bit_depth = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue