Skip to content

Commit 8b0881b

Browse files
authored
Allow setting a specific PNG DEFLATE compression level (#2583)
1 parent 965a602 commit 8b0881b

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,8 @@ harness = false
116116
path = "benches/blur.rs"
117117
name = "blur"
118118
harness = false
119+
120+
# because of https://github.com/image-rs/image/pull/2583
121+
# TODO: remove when shipping the next major release after 0.25
122+
[package.metadata.cargo-semver-checks.lints]
123+
enum_discriminants_undefined_non_unit_variant = { level = "warn" }

src/codecs/png.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use std::borrow::Cow;
99
use std::io::{BufRead, Seek, Write};
1010

11-
use png::{BlendOp, DisposeOp};
11+
use png::{BlendOp, DeflateCompression, DisposeOp};
1212

1313
use crate::animation::{Delay, Frame, Frames, Ratio};
1414
use crate::color::{Blend, ColorType, ExtendedColorType};
@@ -523,7 +523,7 @@ pub struct PngEncoder<W: Write> {
523523
exif_metadata: Vec<u8>,
524524
}
525525

526-
/// Compression level of a PNG encoder. The default setting is `Fast`.
526+
/// DEFLATE compression level of a PNG encoder. The default setting is `Fast`.
527527
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
528528
#[non_exhaustive]
529529
#[derive(Default)]
@@ -535,6 +535,10 @@ pub enum CompressionType {
535535
Fast,
536536
/// High compression level
537537
Best,
538+
/// No compression whatsoever
539+
Uncompressed,
540+
/// Detailed compression level between 1 and 9
541+
Level(u8),
538542
}
539543

540544
/// Filter algorithms used to process image data to improve compression.
@@ -628,7 +632,17 @@ impl<W: Write> PngEncoder<W> {
628632
let comp = match self.compression {
629633
CompressionType::Default => png::Compression::Balanced,
630634
CompressionType::Best => png::Compression::High,
631-
_ => png::Compression::Fast,
635+
CompressionType::Fast => png::Compression::Fast,
636+
CompressionType::Uncompressed => png::Compression::NoCompression,
637+
CompressionType::Level(0) => png::Compression::NoCompression,
638+
CompressionType::Level(_) => png::Compression::Fast, // whatever, will be overridden
639+
};
640+
641+
let advanced_comp = match self.compression {
642+
// Do not set level 0 as a Zlib level to avoid Zlib backend variance.
643+
// For example, in miniz_oxide level 0 is very slow.
644+
CompressionType::Level(n @ 1..) => Some(DeflateCompression::Level(n)),
645+
_ => None,
632646
};
633647

634648
let filter = match self.filter {
@@ -655,6 +669,9 @@ impl<W: Write> PngEncoder<W> {
655669
encoder.set_color(ct);
656670
encoder.set_depth(bits);
657671
encoder.set_compression(comp);
672+
if let Some(compression) = advanced_comp {
673+
encoder.set_deflate_compression(compression);
674+
}
658675
encoder.set_filter(filter);
659676
let mut writer = encoder
660677
.write_header()

0 commit comments

Comments
 (0)