Palette sorting (#193)
* Implement alpha and luminosity palette sorting * Also sort when reducing to palette * Bump Rust version * Color comparison
This commit is contained in:
parent
68b763bcdd
commit
e473958377
3 changed files with 28 additions and 5 deletions
|
|
@ -11,7 +11,7 @@ matrix:
|
||||||
env: TARGET=x86_64-apple-darwin
|
env: TARGET=x86_64-apple-darwin
|
||||||
cache: cargo
|
cache: cargo
|
||||||
- os: linux
|
- os: linux
|
||||||
rust: 1.34.0
|
rust: 1.36.0
|
||||||
env: TARGET=x86_64-unknown-linux-gnu
|
env: TARGET=x86_64-unknown-linux-gnu
|
||||||
cache: cargo
|
cache: cargo
|
||||||
- os: linux
|
- os: linux
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ cargo build --release
|
||||||
cp target/release/oxipng /usr/local/bin
|
cp target/release/oxipng /usr/local/bin
|
||||||
```
|
```
|
||||||
|
|
||||||
The current minimum supported Rust version is **1.34.0**. Oxipng may compile on earlier versions of Rust,
|
The current minimum supported Rust version is **1.36.0**. Oxipng may compile on earlier versions of Rust,
|
||||||
but there is no guarantee.
|
but there is no guarantee.
|
||||||
|
|
||||||
Oxipng follows Semantic Versioning.
|
Oxipng follows Semantic Versioning.
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,24 @@ pub fn reduced_palette(png: &PngImage) -> Option<PngImage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut used_enumerated : Vec<(usize, &bool)>= used.iter().enumerate().collect();
|
||||||
|
used_enumerated.sort_by(|a, b| {
|
||||||
|
//Sort by ascending alpha and descending luma.
|
||||||
|
let color_val = |i| {
|
||||||
|
let color = palette.get(i).copied()
|
||||||
|
.unwrap_or_else(|| RGBA8::new(0, 0, 0, 255));
|
||||||
|
((color.a as i32) << 18)
|
||||||
|
// These are coefficients for standard sRGB to luma conversion
|
||||||
|
- (color.r as i32) * 299
|
||||||
|
- (color.g as i32) * 587
|
||||||
|
- (color.b as i32) * 114
|
||||||
|
};
|
||||||
|
color_val(a.0).cmp(&color_val(b.0))
|
||||||
|
});
|
||||||
|
|
||||||
let mut next_index = 0u16;
|
let mut next_index = 0u16;
|
||||||
let mut seen = HashMap::with_capacity(palette.len());
|
let mut seen = HashMap::with_capacity(palette.len());
|
||||||
for (i, (used, palette_map)) in used.iter().cloned().zip(palette_map.iter_mut()).enumerate()
|
for (i, used) in used_enumerated.iter().cloned()
|
||||||
{
|
{
|
||||||
if !used {
|
if !used {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -75,12 +90,12 @@ pub fn reduced_palette(png: &PngImage) -> Option<PngImage> {
|
||||||
.unwrap_or_else(|| RGBA8::new(0, 0, 0, 255));
|
.unwrap_or_else(|| RGBA8::new(0, 0, 0, 255));
|
||||||
match seen.entry(color) {
|
match seen.entry(color) {
|
||||||
Vacant(new) => {
|
Vacant(new) => {
|
||||||
*palette_map = Some(next_index as u8);
|
palette_map[i] = Some(next_index as u8);
|
||||||
new.insert(next_index as u8);
|
new.insert(next_index as u8);
|
||||||
next_index += 1;
|
next_index += 1;
|
||||||
}
|
}
|
||||||
Occupied(remap_to) => {
|
Occupied(remap_to) => {
|
||||||
*palette_map = Some(*remap_to.get());
|
palette_map[i] = Some(*remap_to.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -211,6 +226,14 @@ pub fn reduce_color_type(png: &PngImage) -> Option<PngImage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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) {
|
||||||
|
reduced = Cow::Owned(r);
|
||||||
|
should_reduce_bit_depth = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if should_reduce_bit_depth {
|
if should_reduce_bit_depth {
|
||||||
// Some conversions will allow us to perform bit depth reduction that
|
// Some conversions will allow us to perform bit depth reduction that
|
||||||
// wasn't possible before
|
// wasn't possible before
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue