diff --git a/src/deflate/deflate.rs b/src/deflate/deflate.rs index 14ddf550..312b3a33 100644 --- a/src/deflate/deflate.rs +++ b/src/deflate/deflate.rs @@ -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, String> { @@ -25,10 +26,12 @@ pub fn deflate(data: &[u8], zc: u8, zm: u8, zs: u8, zw: u8) -> Result, 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)), } diff --git a/tests/files/small_files.png b/tests/files/small_files.png new file mode 100644 index 00000000..576b88c9 Binary files /dev/null and b/tests/files/small_files.png differ diff --git a/tests/interlaced.rs b/tests/interlaced.rs index 5c24cad6..57df44e6 100644 --- a/tests/interlaced.rs +++ b/tests/interlaced.rs @@ -1272,5 +1272,5 @@ fn interlaced_small_files() { png::ColorType::Indexed, png::BitDepth::Eight, png::ColorType::Indexed, - png::BitDepth::Two); + png::BitDepth::One); } diff --git a/tests/reduction.rs b/tests/reduction.rs index d7a35033..68704325 100644 --- a/tests/reduction.rs +++ b/tests/reduction.rs @@ -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); +}