diff --git a/src/png/mod.rs b/src/png/mod.rs index 424d7fae..d9ebd764 100644 --- a/src/png/mod.rs +++ b/src/png/mod.rs @@ -190,12 +190,13 @@ impl PngData { // Palette if let Some(ref palette) = self.raw.palette { let mut palette_data = Vec::with_capacity(palette.len() * 3); - for px in palette { + let max_palette_size = 1 << (self.raw.ihdr.bit_depth.as_u8() as usize); + for px in palette.iter().take(max_palette_size) { palette_data.extend_from_slice(px.rgb().as_slice()); } write_png_block(b"PLTE", &palette_data, &mut output); let num_transparent = - palette.iter().enumerate().fold( + palette.iter().take(max_palette_size).enumerate().fold( 0, |prev, (index, px)| { if px.a != 255 { diff --git a/src/reduction/bit_depth.rs b/src/reduction/bit_depth.rs index 01046311..491a2183 100644 --- a/src/reduction/bit_depth.rs +++ b/src/reduction/bit_depth.rs @@ -68,7 +68,7 @@ pub fn reduce_bit_depth(png: &PngImage, minimum_bits: usize) -> Option bit_depth: BitDepth::Eight, ..png.ihdr }, - palette: png.palette.clone(), + palette: None, transparency_pixel: png.transparency_pixel.clone(), aux_headers: png.aux_headers.clone(), }) diff --git a/tests/files/issue-159.png b/tests/files/issue-159.png new file mode 100644 index 00000000..cd5585ab Binary files /dev/null and b/tests/files/issue-159.png differ diff --git a/tests/filters.rs b/tests/filters.rs index a3f9c063..82d2b6d7 100644 --- a/tests/filters.rs +++ b/tests/filters.rs @@ -55,6 +55,11 @@ fn test_it_converts( assert_eq!(png.raw.ihdr.color_type, color_type_out); assert_eq!(png.raw.ihdr.bit_depth, bit_depth_out); + if let Some(palette) = png.raw.palette.as_ref() { + assert!(palette.len() <= 1 << (png.raw.ihdr.bit_depth.as_u8() as usize)); + } else { + assert!(png.raw.ihdr.color_type != ColorType::Indexed); + } remove_file(output).ok(); } diff --git a/tests/regression.rs b/tests/regression.rs index 3ee18f4f..e53ba734 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -33,8 +33,8 @@ fn test_it_converts( let (output, opts) = custom.unwrap_or_else(|| get_opts(&input)); let png = PngData::new(&input, opts.fix_errors).unwrap(); - assert_eq!(png.raw.ihdr.color_type, color_type_in); - assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in); + assert_eq!(png.raw.ihdr.color_type, color_type_in, "test file is broken"); + assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in, "test file is broken"); match oxipng::optimize(&InFile::Path(input), &output, &opts) { Ok(_) => (), @@ -51,8 +51,13 @@ fn test_it_converts( } }; - assert_eq!(png.raw.ihdr.color_type, color_type_out); - assert_eq!(png.raw.ihdr.bit_depth, bit_depth_out); + assert_eq!(png.raw.ihdr.color_type, color_type_out, "optimized to wrong color type"); + assert_eq!(png.raw.ihdr.bit_depth, bit_depth_out, "optimized to wrong bit depth"); + if let Some(palette) = png.raw.palette.as_ref() { + assert!(palette.len() <= 1 << (png.raw.ihdr.bit_depth.as_u8() as usize)); + } else { + assert!(png.raw.ihdr.color_type != ColorType::Indexed); + } remove_file(output).ok(); } @@ -572,3 +577,15 @@ fn issue_153() { BitDepth::Eight, ); } + +#[test] +fn issue_159() { + test_it_converts( + "tests/files/issue-159.png", + None, + ColorType::Indexed, + BitDepth::One, + ColorType::Indexed, + BitDepth::One, + ); +}