diff --git a/Cargo.toml b/Cargo.toml index baf432f..a71fd27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,14 @@ exclude = ["tests/images/*", "tests/fuzz_images/*"] weezl = "0.1.0" jpeg = { package = "jpeg-decoder", version = "0.3.0", default-features = false } flate2 = "1.0.20" +zstd = { version = "0.13", optional = true } [dev-dependencies] criterion = "0.3.1" +[features] +zstd = ["dep:zstd"] + [[bench]] name = "lzw" harness = false diff --git a/README.md b/README.md index 9f00ca2..2ab4d86 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ This table lists photometric interpretations and sample formats which are suppor | Deflate | ✓ | ✓ | | PackBits | ✓ | ✓ | | JPEG | ✓ | not yet | +| ZSTD | ✓ | not yet | ## Not yet supported diff --git a/src/decoder/image.rs b/src/decoder/image.rs index 1a61640..532a8fb 100644 --- a/src/decoder/image.rs +++ b/src/decoder/image.rs @@ -378,7 +378,11 @@ impl Image { CompressionMethod::None => Box::new(reader), CompressionMethod::LZW => { Box::new(LZWReader::new(reader, usize::try_from(compressed_length)?)) - } + }, + #[cfg(feature = "zstd")] + CompressionMethod::ZSTD => { + Box::new(zstd::Decoder::new(reader)?) + }, CompressionMethod::PackBits => Box::new(PackBitsReader::new(reader, compressed_length)), CompressionMethod::Deflate | CompressionMethod::OldDeflate => { Box::new(DeflateReader::new(reader)) diff --git a/src/tags.rs b/src/tags.rs index 6c18fa5..81169ca 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -184,6 +184,9 @@ pub enum CompressionMethod(u16) unknown("A custom compression method") { Deflate = 8, OldDeflate = 0x80B2, PackBits = 0x8005, + + // Self-assigned by libtiff + ZSTD = 0xC350, } } diff --git a/tests/decode_images.rs b/tests/decode_images.rs index 1c769d0..5a62279 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -515,3 +515,10 @@ fn test_predictor_3_rgb_f32() { fn test_predictor_3_gray_f32() { test_image_sum_f32("predictor-3-gray-f32.tif", ColorType::Gray(32), 20008.275); } + +#[test] +#[cfg(feature = "zstd")] +fn test_zstd_compression() { + // gdal_translate -co COMPRESS=ZSTD -co ZSTD_LEVEL=20 int16.tif int16_zstd.tif + test_image_sum_i16("int16_zstd.tif", ColorType::Gray(16), 354396); +} diff --git a/tests/images/int16_zstd.tif b/tests/images/int16_zstd.tif new file mode 100644 index 0000000..c1093e4 Binary files /dev/null and b/tests/images/int16_zstd.tif differ