From 0362e6e31d4551c4e4f25a6fe5fd3338281c1097 Mon Sep 17 00:00:00 2001 From: "Sergey \"Shnatsel\" Davidoff" Date: Thu, 5 Mar 2026 17:59:18 +0000 Subject: [PATCH] Implement DEFLATE compression level control properly, with a semver break --- benches/encode.rs | 4 ++-- src/encoder/compression/deflate.rs | 25 ++++++++----------------- src/encoder/compression/mod.rs | 2 +- src/encoder/mod.rs | 4 +--- tests/encode_images_with_compression.rs | 7 +++---- 5 files changed, 15 insertions(+), 27 deletions(-) diff --git a/benches/encode.rs b/benches/encode.rs index 23b2cf9..d655a5a 100644 --- a/benches/encode.rs +++ b/benches/encode.rs @@ -4,7 +4,7 @@ extern crate tiff; use criterion::{black_box, Criterion, Throughput}; use std::io::Cursor; use tiff::encoder::colortype::RGB32Float; -use tiff::encoder::{Compression, DeflateLevel, Predictor, TiffEncoder}; +use tiff::encoder::{Compression, Predictor, TiffEncoder}; const WIDTH: u32 = 500; const HEIGHT: u32 = 500; @@ -14,7 +14,7 @@ fn encode_image_f32_float_predictor_deflate(data: &[f32]) { TiffEncoder::new(&mut buf) .unwrap() .with_predictor(Predictor::FloatingPoint) - .with_compression(Compression::Deflate(DeflateLevel::Fast)) + .with_compression(Compression::Deflate(1)) .write_image::(WIDTH, HEIGHT, black_box(data)) .unwrap(); } diff --git a/src/encoder/compression/deflate.rs b/src/encoder/compression/deflate.rs index 3e5d528..cb5a882 100644 --- a/src/encoder/compression/deflate.rs +++ b/src/encoder/compression/deflate.rs @@ -7,24 +7,15 @@ pub struct Deflate { level: FlateCompression, } -/// The level of compression used by the Deflate algorithm. -/// It allows trading compression ratio for compression speed. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[non_exhaustive] -#[derive(Default)] -pub enum DeflateLevel { - /// The fastest possible compression mode. - Fast = 1, - /// The conserative choice between speed and ratio. - #[default] - Balanced = 6, - /// The best compression available with Deflate. - Best = 9, -} - impl Deflate { /// Create a new deflate compressor with a specific level of compression. - pub fn with_level(level: DeflateLevel) -> Self { + /// + /// The valid levels are 1 through 9 inclusive. The default level is 6. + /// + /// - `1` stands for light but fast compression + /// - `6` is the recommended balanced default + /// - `9` is maximum compression ratio at the cost of slow encoding + pub fn with_level(level: u8) -> Self { Self { level: FlateCompression::new(level as u32), } @@ -33,7 +24,7 @@ impl Deflate { impl Default for Deflate { fn default() -> Self { - Self::with_level(DeflateLevel::default()) + Self::with_level(6) } } diff --git a/src/encoder/compression/mod.rs b/src/encoder/compression/mod.rs index 4653973..73a80f1 100644 --- a/src/encoder/compression/mod.rs +++ b/src/encoder/compression/mod.rs @@ -9,7 +9,7 @@ mod packbits; mod uncompressed; #[cfg(feature = "deflate")] -pub use self::deflate::{Deflate, DeflateLevel}; +pub use self::deflate::Deflate; #[cfg(feature = "lzw")] pub use self::lzw::Lzw; diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index 23bf645..38b2739 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -38,8 +38,6 @@ use self::writer::*; /// [Predictor::Horizontal] is for integer sample types. /// [Predictor::FloatingPoint] is for floating-point sample types (f32, f64). pub type Predictor = crate::tags::Predictor; -#[cfg(feature = "deflate")] -pub type DeflateLevel = compression::DeflateLevel; #[derive(Clone, Copy, PartialEq, Default)] pub enum Compression { @@ -48,7 +46,7 @@ pub enum Compression { #[cfg(feature = "lzw")] Lzw, #[cfg(feature = "deflate")] - Deflate(DeflateLevel), + Deflate(u8), Packbits, } diff --git a/tests/encode_images_with_compression.rs b/tests/encode_images_with_compression.rs index a355fb1..fcae4d9 100644 --- a/tests/encode_images_with_compression.rs +++ b/tests/encode_images_with_compression.rs @@ -5,7 +5,6 @@ use tiff::{ decoder::{Decoder, DecodingResult}, encoder::{ colortype::{self, ColorType}, - compression::*, Compression, TiffEncoder, TiffValue, }, }; @@ -147,9 +146,9 @@ fn encode_decode_with_lzw() { #[test] #[cfg(feature = "deflate")] fn encode_decode_with_deflate() { - encode_decode_with_compression(Compression::Deflate(DeflateLevel::Fast)); - encode_decode_with_compression(Compression::Deflate(DeflateLevel::Balanced)); - encode_decode_with_compression(Compression::Deflate(DeflateLevel::Best)); + encode_decode_with_compression(Compression::Deflate(1)); + encode_decode_with_compression(Compression::Deflate(6)); + encode_decode_with_compression(Compression::Deflate(9)); } #[test]