Fix issue with very small images [ci skip]

This commit is contained in:
Joshua Holmer 2016-04-04 11:06:00 -04:00
parent 7280ca80ce
commit 2974bbbee3
4 changed files with 21 additions and 3 deletions

View file

@ -1,5 +1,6 @@
use libz_sys;
use libc::c_int;
use std::cmp::max;
/// Decompress a data stream using the DEFLATE algorithm
pub fn inflate(data: &[u8]) -> Result<Vec<u8>, String> {
@ -25,10 +26,12 @@ pub fn deflate(data: &[u8], zc: u8, zm: u8, zs: u8, zw: u8) -> Result<Vec<u8>, S
zw as c_int,
zm as c_int,
zs as c_int);
let mut output = Vec::with_capacity(data.len() / 20);
// Compressed input should be smaller than decompressed, so allocate less than data.len()
// However, it needs a minimum capacity in order to handle very small images
let mut output = Vec::with_capacity(max(1024, data.len() / 20));
loop {
match stream.compress_vec(input.as_mut(), output.as_mut()) {
libz_sys::Z_OK => output.reserve(data.len() / 20),
libz_sys::Z_OK => output.reserve(max(1024, data.len() / 20)),
libz_sys::Z_STREAM_END => break,
c => return Err(format!("Error code on compress: {}", c)),
}

BIN
tests/files/small_files.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -1272,5 +1272,5 @@ fn interlaced_small_files() {
png::ColorType::Indexed,
png::BitDepth::Eight,
png::ColorType::Indexed,
png::BitDepth::Two);
png::BitDepth::One);
}

View file

@ -1259,3 +1259,18 @@ fn grayscale_8_should_be_palette_1() {
png::ColorType::Indexed,
png::BitDepth::One);
}
#[test]
fn small_files() {
let input = PathBuf::from("tests/files/small_files.png");
let opts = get_opts(&input);
let output = opts.out_file.clone();
test_it_converts(&input,
&output,
&opts,
png::ColorType::Indexed,
png::BitDepth::Eight,
png::ColorType::Indexed,
png::BitDepth::One);
}