From a4a5ac9c46983f500cb81c8f815b2457e6c301f7 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Sun, 3 Dec 2023 09:13:14 -0500 Subject: [PATCH] Add ZstdCompression based on Apache Commons Compress Note tests will fail since the optional dependency zstd-jni is not a dependency. --- .../saalfeldlab/n5/ZstdCompression.java | 90 +++++++++++++++++++ .../saalfeldlab/n5/AbstractN5Test.java | 3 +- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/janelia/saalfeldlab/n5/ZstdCompression.java diff --git a/src/main/java/org/janelia/saalfeldlab/n5/ZstdCompression.java b/src/main/java/org/janelia/saalfeldlab/n5/ZstdCompression.java new file mode 100644 index 00000000..a4649442 --- /dev/null +++ b/src/main/java/org/janelia/saalfeldlab/n5/ZstdCompression.java @@ -0,0 +1,90 @@ +package org.janelia.saalfeldlab.n5; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorInputStream; +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorOutputStream; +import org.janelia.saalfeldlab.n5.Compression.CompressionType; + +/** + * Zstandard compression for N5 + * + * Implementation wrapper around Apache Commons Compress + * + * Note that zstd-jni is an optional dependency of Apache Commons Compress. + * However, it is required for this class, ZstdCompression, to work + * https://github.com/luben/zstd-jni + * + * Add the following dependency entry under to the Maven pom.xml + * + * + * com.github.luben + * zstd-jni + * 1.5.5-10 + * + * + * See the Zstandard manual for details on parameters. + * https://facebook.github.io/zstd/zstd_manual.html + * + * @author mkitti + * + */ +@CompressionType("zstd") +public class ZstdCompression implements DefaultBlockReader, DefaultBlockWriter, Compression { + + /** + * + */ + private static final long serialVersionUID = 8592416400988371189L; + + /* + * Compression level + * + * Standard compression level is between 1 and 22 + * Negative compression levels offer speed + * + * Note that zarr-developers/numcodecs defaults to 1 + * + * Default: 3 (see ZSTD_CLEVEL_DEFAULT) + */ + @CompressionParameter + private int level = 3; + + /* + * Default compression level from zstd.h + */ + public static final int ZSTD_CLEVEL_DEFAULT = 3; + + public ZstdCompression() { + this.level = ZSTD_CLEVEL_DEFAULT; + } + + public ZstdCompression(int level) { + this.level = level; + } + + @Override + public BlockReader getReader() { + return this; + } + + @Override + public BlockWriter getWriter() { + return this; + } + + @Override + public OutputStream getOutputStream(OutputStream out) throws IOException { + ZstdCompressorOutputStream zstdOut = new ZstdCompressorOutputStream(out, level); + return zstdOut; + } + + @Override + public InputStream getInputStream(InputStream in) throws IOException { + ZstdCompressorInputStream zstdIn = new ZstdCompressorInputStream(in); + return zstdIn; + } + +} diff --git a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java index db3b9a07..f424cb4f 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java @@ -115,7 +115,8 @@ protected Compression[] getCompressions() { new GzipCompression(), new GzipCompression(5, true), new Lz4Compression(), - new XzCompression() + new XzCompression(), + new ZstdCompression() }; }