Merge pull request #46 from shssoichiro/bug/45-Indexed-Crash
Remove conversion from palette to grayscale
This commit is contained in:
commit
742b89f756
5 changed files with 2 additions and 84 deletions
|
|
@ -1,6 +1,7 @@
|
|||
**Version 0.10.0 (unreleased)**
|
||||
- [SEMVER_MINOR] Make clap and regex dependencies optional
|
||||
- Enabled by default, needed for executable build; can be disabled for use in crates
|
||||
- Remove reduction from palette to grayscale, which was not working and provided minimal benefit
|
||||
|
||||
**Version 0.9.0**
|
||||
- [SEMVER_MAJOR] Significant refactoring of modules
|
||||
|
|
|
|||
11
src/png.rs
11
src/png.rs
|
|
@ -707,16 +707,7 @@ impl PngData {
|
|||
}
|
||||
}
|
||||
|
||||
if self.ihdr_data.color_type == ColorType::Indexed && self.transparency_palette.is_none() &&
|
||||
self.palette.as_ref().map(|x| x.len()).unwrap() > 16 {
|
||||
if let Some(data) = reduce_palette_to_grayscale(self) {
|
||||
self.raw_data = data;
|
||||
self.palette = None;
|
||||
self.ihdr_data.color_type = ColorType::Grayscale;
|
||||
changed = true;
|
||||
should_reduce_bit_depth = false;
|
||||
}
|
||||
} else if self.ihdr_data.color_type == ColorType::Grayscale {
|
||||
if self.ihdr_data.color_type == ColorType::Grayscale {
|
||||
if let Some((data, palette)) = reduce_grayscale_to_palette(self) {
|
||||
self.raw_data = data;
|
||||
self.palette = Some(palette);
|
||||
|
|
|
|||
|
|
@ -234,50 +234,6 @@ pub fn reduce_grayscale_to_palette(png: &PngData) -> Option<(Vec<u8>, Vec<u8>)>
|
|||
Some((reduced.to_bytes(), color_palette))
|
||||
}
|
||||
|
||||
pub fn reduce_palette_to_grayscale(png: &PngData) -> Option<Vec<u8>> {
|
||||
let mut reduced = BitVec::with_capacity(png.raw_data.len() * 8);
|
||||
let mut cur_pixel = Vec::with_capacity(3);
|
||||
let palette = png.palette.clone().unwrap();
|
||||
// Iterate through palette and determine if all colors are grayscale
|
||||
for byte in &palette {
|
||||
cur_pixel.push(*byte);
|
||||
if cur_pixel.len() == 3 {
|
||||
if cur_pixel.iter().unique().count() > 1 {
|
||||
return None;
|
||||
}
|
||||
cur_pixel.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through scanlines and assign grayscale value to each pixel
|
||||
let bit_depth: usize = png.ihdr_data.bit_depth.as_u8() as usize;
|
||||
let bit_depth_inverse = 8 - bit_depth;
|
||||
for line in png.scan_lines() {
|
||||
reduced.extend(BitVec::from_bytes(&[line.filter]));
|
||||
let bit_vec = BitVec::from_bytes(&line.data);
|
||||
let mut cur_pixel = BitVec::with_capacity(bit_depth);
|
||||
for bit in bit_vec {
|
||||
// Handle bit depths less than 8-bits
|
||||
// At the end of each pixel, push its grayscale value onto the reduced image
|
||||
cur_pixel.push(bit);
|
||||
if cur_pixel.len() == bit_depth {
|
||||
// `to_bytes` gives us e.g. 10000000 for a 1-bit pixel, when we would want 00000001
|
||||
let padded_pixel = cur_pixel.to_bytes()[0] >> bit_depth_inverse;
|
||||
let palette_idx: usize = padded_pixel as usize * 3;
|
||||
reduced.extend(BitVec::from_bytes(&[palette[palette_idx]]));
|
||||
// BitVec's clear function doesn't set len to 0
|
||||
cur_pixel = BitVec::with_capacity(bit_depth);
|
||||
}
|
||||
}
|
||||
// Pad end of line to get 8 bits per byte
|
||||
while reduced.len() % 8 != 0 {
|
||||
reduced.push(false);
|
||||
}
|
||||
}
|
||||
|
||||
Some(reduced.to_bytes())
|
||||
}
|
||||
|
||||
pub fn reduce_rgb_to_grayscale(png: &PngData) -> Option<Vec<u8>> {
|
||||
let mut reduced = Vec::with_capacity(png.raw_data.len());
|
||||
let byte_depth: u8 = png.ihdr_data.bit_depth.as_u8() >> 3;
|
||||
|
|
|
|||
|
|
@ -753,21 +753,6 @@ fn interlaced_rgb_8_should_be_palette_1_grayscale() {
|
|||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_palette_8_should_be_grayscale_8() {
|
||||
let input = PathBuf::from("tests/files/interlaced_palette_8_should_be_grayscale_8.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Eight,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn interlaced_palette_8_should_be_palette_8() {
|
||||
let input = PathBuf::from("tests/files/interlaced_palette_8_should_be_palette_8.png");
|
||||
|
|
|
|||
|
|
@ -753,21 +753,6 @@ fn rgb_8_should_be_palette_1_grayscale() {
|
|||
BitDepth::One);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn palette_8_should_be_grayscale_8() {
|
||||
let input = PathBuf::from("tests/files/palette_8_should_be_grayscale_8.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::Indexed,
|
||||
BitDepth::Eight,
|
||||
ColorType::Grayscale,
|
||||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn palette_8_should_be_palette_8() {
|
||||
let input = PathBuf::from("tests/files/palette_8_should_be_palette_8.png");
|
||||
|
|
|
|||
Loading…
Reference in a new issue