Use libdeflater to inflate

This commit is contained in:
Andrew 2022-10-24 09:44:42 +13:00
parent 62ebd64aae
commit ae010773d1
4 changed files with 21 additions and 4 deletions

View file

@ -1,6 +1,6 @@
use crate::atomicmin::AtomicMin; use crate::atomicmin::AtomicMin;
use crate::{PngError, PngResult}; use crate::{PngError, PngResult};
use libdeflater::{CompressionError, CompressionLvl, Compressor}; use libdeflater::*;
pub fn deflate(data: &[u8], level: u8, max_size: &AtomicMin) -> PngResult<Vec<u8>> { pub fn deflate(data: &[u8], level: u8, max_size: &AtomicMin) -> PngResult<Vec<u8>> {
let mut compressor = Compressor::new(CompressionLvl::new(level.into()).unwrap()); let mut compressor = Compressor::new(CompressionLvl::new(level.into()).unwrap());
@ -23,3 +23,16 @@ pub fn deflate(data: &[u8], level: u8, max_size: &AtomicMin) -> PngResult<Vec<u8
dest.truncate(len); dest.truncate(len);
Ok(dest) Ok(dest)
} }
pub fn inflate(data: &[u8], out_size: usize) -> PngResult<Vec<u8>> {
let mut decompressor = Decompressor::new();
let mut dest = vec![0; out_size];
let len = decompressor
.zlib_decompress(data, &mut dest)
.map_err(|err| match err {
DecompressionError::BadData => PngError::InvalidData,
DecompressionError::InsufficientSpace => PngError::new("inflated data too long"),
})?;
dest.truncate(len);
Ok(dest)
}

View file

@ -14,6 +14,8 @@ pub mod miniz_stream;
mod deflater; mod deflater;
#[cfg(feature = "libdeflater")] #[cfg(feature = "libdeflater")]
pub use deflater::deflate as libdeflater_deflate; pub use deflater::deflate as libdeflater_deflate;
#[cfg(feature = "libdeflater")]
pub use deflater::inflate as libdeflater_inflate;
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
pub mod cfzlib; pub mod cfzlib;

View file

@ -26,7 +26,7 @@ mod rayon;
use crate::atomicmin::AtomicMin; use crate::atomicmin::AtomicMin;
use crate::colors::BitDepth; use crate::colors::BitDepth;
use crate::deflate::inflate; use crate::deflate::libdeflater_inflate;
use crate::evaluate::Evaluator; use crate::evaluate::Evaluator;
use crate::png::PngData; use crate::png::PngData;
use crate::png::PngImage; use crate::png::PngImage;
@ -948,7 +948,9 @@ fn srgb_rendering_intent(mut iccp: &[u8]) -> Option<u8> {
if compression_method != 0 { if compression_method != 0 {
return None; // The profile is supposed to be compressed (method 0) return None; // The profile is supposed to be compressed (method 0)
} }
let icc_data = inflate(compressed_data).ok()?; // The decompressed size is unknown so we have to guess the required buffer size
let max_size = (compressed_data.len() * 2).max(1000);
let icc_data = libdeflater_inflate(compressed_data, max_size).ok()?;
let rendering_intent = *icc_data.get(67)?; let rendering_intent = *icc_data.get(67)?;

View file

@ -112,7 +112,7 @@ impl PngData {
None => return Err(PngError::ChunkMissing("IHDR")), None => return Err(PngError::ChunkMissing("IHDR")),
}; };
let ihdr_header = parse_ihdr_header(&ihdr)?; let ihdr_header = parse_ihdr_header(&ihdr)?;
let raw_data = deflate::inflate(idat_headers.as_ref())?; let raw_data = deflate::libdeflater_inflate(idat_headers.as_ref(), ihdr_header.raw_data_size())?;
// Reject files with incorrect width/height or truncated data // Reject files with incorrect width/height or truncated data
if raw_data.len() != ihdr_header.raw_data_size() { if raw_data.len() != ihdr_header.raw_data_size() {