diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f4e028c..8967a752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +**Version 0.14.3** + - Fix multiple bugs when reducing transparency palettes + **Version 0.14.2** - Fix a bug when reducing palette in images with bit depth less than 8 - Fix a bug when reducing palette in images with transparency diff --git a/Cargo.lock b/Cargo.lock index 0ce0b147..5e0a4b22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ [root] name = "oxipng" -version = "0.14.2" +version = "0.14.3" dependencies = [ "bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 846d4255..7b533cec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://github.com/shssoichiro/oxipng" license = "MIT" name = "oxipng" repository = "https://github.com/shssoichiro/oxipng" -version = "0.14.2" +version = "0.14.3" [lib] name = "oxipng" diff --git a/src/png.rs b/src/png.rs index 39dd57c6..3692ac88 100644 --- a/src/png.rs +++ b/src/png.rs @@ -471,7 +471,7 @@ impl PngData { .clone() .unwrap() .chunks(3) - .zip(trns.iter()) + .zip(trns.iter().chain([255].iter().cycle())) .flat_map(|(pixel, trns)| { let mut pixel = pixel.to_owned(); pixel.push(*trns); @@ -574,7 +574,6 @@ impl PngData { index_map: &mut HashMap, indexed_palette: &mut Vec<&[u8]>) { let mut new_data = Vec::with_capacity(self.raw_data.len()); - let mut alpha_palette = self.aux_headers.get("tRNS").cloned(); let original_len = indexed_palette.len(); for idx in indices.iter().sorted_by(|a, b| b.cmp(a)) { for i in (*idx as usize + 1)..original_len { @@ -584,14 +583,15 @@ impl PngData { } } indexed_palette.remove(*idx as usize); - if let Some(ref mut alpha) = alpha_palette { - alpha.remove(*idx as usize); + if let Some(ref mut alpha) = self.transparency_palette { + if (*idx as usize) < alpha.len() { + alpha.remove(*idx as usize); + } } } - if alpha_palette.is_some() { - let alpha_header = self.aux_headers.get_mut("tRNS"); - if let Some(alpha_hdr) = alpha_header { - *alpha_hdr = alpha_palette.unwrap(); + if let Some(ref mut alpha) = self.transparency_palette { + while let Some(255) = alpha.last().cloned() { + alpha.pop(); } } // Reassign data bytes to new indices @@ -615,7 +615,7 @@ impl PngData { new_byte |= if let Some(new_idx) = index_map.get(&upper) { *new_idx << 4 } else { - upper << 4 + upper }; new_byte |= if let Some(new_idx) = index_map.get(&lower) { *new_idx @@ -660,7 +660,13 @@ impl PngData { } index_map.clear(); self.raw_data = new_data; - let new_palette = indexed_palette.iter().cloned().flatten().cloned().collect::>(); + let new_palette = indexed_palette.iter() + .cloned() + .flatten() + .enumerate() + .filter(|&(i, _)| !(self.transparency_palette.is_some() && i % 4 == 3)) + .map(|(_, x)| *x) + .collect::>(); self.palette = Some(new_palette); } diff --git a/tests/files/issue-58.png b/tests/files/issue-58.png new file mode 100644 index 00000000..8a58f5d2 Binary files /dev/null and b/tests/files/issue-58.png differ diff --git a/tests/regression.rs b/tests/regression.rs index 998bd418..d8a7f267 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -222,3 +222,18 @@ fn issue_56() { ColorType::Indexed, BitDepth::Four); } + +#[test] +fn issue_58() { + let input = PathBuf::from("tests/files/issue-58.png"); + let opts = get_opts(&input); + let output = opts.out_file.clone(); + + test_it_converts(&input, + &output, + &opts, + ColorType::Indexed, + BitDepth::Four, + ColorType::Indexed, + BitDepth::Four); +}