diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/DType.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/DType.java
index 0af7c689..718ac09e 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/DType.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/DType.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2022 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import java.nio.ByteBuffer;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/Filter.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/Filter.java
index 377a3b7e..53bdfd24 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/Filter.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/Filter.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import com.google.gson.JsonDeserializationContext;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrReader.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrReader.java
index f77cfc49..b76071c4 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrReader.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrReader.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrWriter.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrWriter.java
index c0e9c034..9db12152 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrWriter.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrWriter.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZArrayAttributes.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZArrayAttributes.java
index f685a420..9d889675 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZArrayAttributes.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZArrayAttributes.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import java.lang.reflect.Type;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java
index f4ab1eb3..5ee74f04 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrCompressor.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import java.io.IOException;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrDatasetAttributes.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrDatasetAttributes.java
index 7df3fa9a..cc533098 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrDatasetAttributes.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrDatasetAttributes.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2022 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import com.google.gson.Gson;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java
index 40d38d68..500709d0 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueReader.java
@@ -1,28 +1,3 @@
-/**
- * Copyright (c) 2017--2021, Stephan Saalfeld
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
package org.janelia.saalfeldlab.n5.zarr;
import java.io.IOException;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java
index 06d3ed3b..ef14b6b8 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/ZarrKeyValueWriter.java
@@ -1,28 +1,3 @@
-/**
- * Copyright (c) 2017--2021, Stephan Saalfeld
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
package org.janelia.saalfeldlab.n5.zarr;
import java.io.IOException;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/cache/ZarrJsonCache.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/cache/ZarrJsonCache.java
index 2bc15e67..060262ed 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/cache/ZarrJsonCache.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/cache/ZarrJsonCache.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr.cache;
import org.janelia.saalfeldlab.n5.cache.N5JsonCache;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/package-info.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/package-info.java
index e510284b..a5d2e3cf 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/package-info.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/package-info.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
/**
* Zarr backends for N5
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Compressor.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Compressor.java
index 3d66cc73..bc1d3cb5 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Compressor.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Compressor.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2022 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr.v3;
import java.lang.reflect.Field;
@@ -217,9 +189,6 @@ public Blosc(final BloscCompression compression)
case BloscCompression.BITSHUFFLE:
shuffle = "bitshuffle";
break;
- case BloscCompression.AUTOSHUFFLE:
- shuffle = typesize == 1 ? "bitshuffle" : "shuffle";
- break;
default:
throw new N5Exception("Invalid shuffle: " + _shuffle);
}
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributes.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributes.java
index ba30c0aa..547672d4 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributes.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributes.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2022 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr.v3;
import java.lang.reflect.Type;
@@ -607,6 +579,11 @@ public static Builder builder(final long[] dimensions, final DataType dataType)
return new Builder(dimensions, dataType);
}
+ public static Builder builder(DatasetAttributes attributes) {
+
+ return new Builder(attributes);
+ }
+
/**
* Builder for constructing {@link ZarrV3DatasetAttributes} instances.
*
@@ -623,7 +600,7 @@ public static Builder builder(final long[] dimensions, final DataType dataType)
* .build();
* }
*/
- public static class Builder {
+ public static class Builder extends DatasetAttributes.Builder {
// Required parameters
private final long[] dimensions;
@@ -641,7 +618,7 @@ public static class Builder {
private DataCodecInfo[] shardIndexDataCodecInfos = new DataCodecInfo[0];
// For sharding
- private int[] shardSize;
+ private int[] chunkSize;
/**
* Creates a new builder with the required parameters.
@@ -651,9 +628,11 @@ public static class Builder {
*/
public Builder(final long[] dimensions, final DataType dataType) {
+
+ super(dimensions, dataType);
this.dimensions = dimensions.clone();
this.dataType = ZarrV3DataType.fromDataType(dataType);
- this.blockSize = Arrays.stream(dimensions).mapToInt(x -> (int)x).toArray();
+ this.blockSize = defaultChunkShape(dimensions);
}
/**
@@ -664,9 +643,24 @@ public Builder(final long[] dimensions, final DataType dataType) {
*/
public Builder(final long[] dimensions, final ZarrV3DataType dataType) {
+ super(dimensions, dataType.getDataType());
this.dimensions = dimensions.clone();
this.dataType = dataType;
- this.blockSize = Arrays.stream(dimensions).mapToInt(x -> (int)x).toArray();
+ this.blockSize = defaultChunkShape(dimensions);
+ }
+
+ public Builder(final DatasetAttributes attributes) {
+
+ super( attributes.getDimensions(), attributes.getDataType());
+ this.dimensions = attributes.getDimensions();
+ this.dataType = ZarrV3DataType.fromDataType(attributes.getDataType());
+ dataCodecInfos(attributes.getDataCodecInfos());
+ if (attributes.isSharded()) {
+ chunkSize(attributes.getChunkSize());
+ blockSize(attributes.getBlockSize());
+ } else {
+ blockSize(attributes.getBlockSize());
+ }
}
/**
@@ -682,17 +676,38 @@ public Builder blockSize(final int[] blockSize) {
}
/**
- * Sets the shard shape for sharded arrays.
+ * Sets the chunk shape for sharded arrays.
* When set, chunks will be grouped into shards of this size.
*
- * @param shardShape the shard dimensions
+ * @param chunkSize the shard dimensions
* @return this builder
*/
- public Builder shardSize(final int[] shardSize) {
+ public Builder chunkSize(final int[] chunkSize) {
- this.shardSize = shardSize.clone();
+ validateLength("chunk size", chunkSize.length);
+ validateBlockChunkSize(blockSize, chunkSize);
+
+ this.chunkSize = chunkSize.clone();
return this;
}
+
+ private void validateBlockChunkSize( int[] blockSize, int[] chunkSize ) {
+
+ if (blockSize != null && chunkSize != null) {
+ for (int i = 0; i < chunkSize.length; i++) {
+ if (chunkSize[i] > blockSize[i])
+ throw new IllegalArgumentException(
+ String.format("index %d: chunk size (%d) is greater than block size (%d)",
+ i, chunkSize[i], blockSize[i]));
+ }
+ }
+ }
+
+ private void validateLength(final String name, final int length) {
+ if (length != dimensions.length)
+ throw new IllegalArgumentException(name + " must be same length as dimensions (" +
+ +dimensions.length + ") but is (" + length + ")");
+ }
/**
* Sets the fill value for uninitialized chunks.
@@ -751,7 +766,7 @@ public Builder chunkKeyEncoding(final DefaultChunkKeyEncoding chunkKeyEncoding)
public Builder compression(final Compression compression) {
if (compression != null && !(compression instanceof RawCompression)) {
- this.dataCodecInfos = new DataCodecInfo[]{ZarrV3Compressor.fromCompression(compression)};
+ this.dataCodecInfos = new DataCodecInfo[]{compression};
}
return this;
}
@@ -821,21 +836,23 @@ public ZarrV3DatasetAttributes build() {
? chunkKeyEncoding
: new DefaultChunkKeyEncoding(dimensionSeparator);
- final int[] resolvedBlockSize = blockSize != null
- ? blockSize
- : defaultChunkShape(dimensions);
// Determine if sharding is enabled
- if (shardSize != null) {
+ if (blockSize != null && chunkSize != null) {
+ // if both blockSize and chunkSize are specified, the dataset is sharded
+ final int[] resolvedChunkSize = chunkSize != null
+ ? chunkSize
+ : defaultChunkShape(dimensions);
+
// Sharded configuration
final BlockCodecInfo resolvedBlockCodecInfo = blockCodecInfo != null
? blockCodecInfo
- : defaultShardCodecInfo(resolvedBlockSize, dataCodecInfos, shardIndexDataCodecInfos);
+ : defaultShardCodecInfo(resolvedChunkSize, dataCodecInfos, shardIndexDataCodecInfos);
// For sharding, the outer chunk is the shard size
return new ZarrV3DatasetAttributes(
dimensions,
- shardSize,
+ blockSize,
dataType,
fillValue,
resolvedDimensionNames,
@@ -843,6 +860,17 @@ public ZarrV3DatasetAttributes build() {
resolvedBlockCodecInfo,
datasetCodecInfos);
} else {
+ // one or both of blockSize or chunkSize is null.
+ // either one sets the block size
+ final int[] resolvedBlockSize;
+ if( chunkSize != null )
+ resolvedBlockSize = chunkSize;
+ else if( blockSize != null )
+
+ resolvedBlockSize = blockSize;
+ else
+ resolvedBlockSize = defaultChunkShape(dimensions);
+
// Non-sharded configuration
final BlockCodecInfo resolvedBlockCodecInfo = blockCodecInfo != null
? blockCodecInfo
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueReader.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueReader.java
index 6b9b538e..4b5d7b41 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueReader.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueReader.java
@@ -1,28 +1,3 @@
-/**
- * Copyright (c) 2017--2021, Stephan Saalfeld
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
package org.janelia.saalfeldlab.n5.zarr.v3;
import java.lang.reflect.Type;
diff --git a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueWriter.java b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueWriter.java
index 9d1b3a64..c424c3f4 100644
--- a/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueWriter.java
+++ b/src/main/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3KeyValueWriter.java
@@ -1,28 +1,3 @@
-/**
- * Copyright (c) 2017--2021, Stephan Saalfeld
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
package org.janelia.saalfeldlab.n5.zarr.v3;
import java.util.Collections;
diff --git a/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java b/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java
index a4b5a643..b7b5f671 100644
--- a/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java
+++ b/src/test/java/org/janelia/saalfeldlab/n5/zarr/N5ZarrTest.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import static org.junit.Assert.assertArrayEquals;
diff --git a/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java b/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java
index 911073a2..37714ad6 100644
--- a/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java
+++ b/src/test/java/org/janelia/saalfeldlab/n5/zarr/ZarrCachedFSTest.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2025 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr;
import static org.junit.Assert.assertEquals;
diff --git a/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributesTest.java b/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributesTest.java
new file mode 100644
index 00000000..370e0304
--- /dev/null
+++ b/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3DatasetAttributesTest.java
@@ -0,0 +1,103 @@
+package org.janelia.saalfeldlab.n5.zarr.v3;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.janelia.saalfeldlab.n5.DataType;
+import org.janelia.saalfeldlab.n5.GzipCompression;
+import org.janelia.saalfeldlab.n5.RawCompression;
+import org.janelia.saalfeldlab.n5.zarr.chunks.DefaultChunkKeyEncoding;
+import org.junit.Test;
+
+public class ZarrV3DatasetAttributesTest {
+
+ @Test
+ public void builderTests() {
+
+ final long[] dims = new long[]{100, 200, 300};
+ final int[] blk = new int[]{32, 32, 32};
+
+ // default blockSize uses defaultChunkShape, not full dimensions
+ final ZarrV3DatasetAttributes defaultBlk = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32).build();
+ assertArrayEquals(ZarrV3DatasetAttributes.defaultChunkShape(dims), defaultBlk.getBlockSize());
+
+ // blockSize is reflected in output
+ final ZarrV3DatasetAttributes withBlk = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).build();
+ assertArrayEquals(blk, withBlk.getBlockSize());
+ assertFalse(withBlk.isSharded());
+
+ // fillValue is reflected
+ final ZarrV3DatasetAttributes withFill = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).fillValue("1.5").build();
+ assertEquals("1.5", withFill.getFillValue());
+
+ // dimensionNames are reflected
+ final String[] names = new String[]{"x", "y", "z"};
+ final ZarrV3DatasetAttributes withNames = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).dimensionNames(names).build();
+ assertArrayEquals(names, withNames.getDimensionNames());
+
+ // dimensionSeparator is reflected in chunk key encoding
+ final ZarrV3DatasetAttributes withSlash = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).dimensionSeparator("/").build();
+ assertTrue(withSlash.relativeBlockPath(1, 2, 3).contains("/"));
+
+ final ZarrV3DatasetAttributes withDot = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).dimensionSeparator(".").build();
+ assertTrue(withDot.relativeBlockPath(1, 2, 3).contains("."));
+
+ // chunkKeyEncoding overrides dimensionSeparator
+ final DefaultChunkKeyEncoding encoding = new DefaultChunkKeyEncoding(".");
+ final ZarrV3DatasetAttributes withEncoding = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).chunkKeyEncoding(encoding).build();
+ assertTrue(withEncoding.relativeBlockPath(1, 2, 3).contains("."));
+
+ // compression sets a data codec; RawCompression is a no-op
+ final ZarrV3DatasetAttributes withGzip = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).compression(new GzipCompression()).build();
+ assertEquals(1, withGzip.getDataCodecInfos().length);
+
+ final ZarrV3DatasetAttributes withRaw = ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(blk).compression(new RawCompression()).build();
+ assertEquals(0, withRaw.getDataCodecInfos().length);
+
+ // sharding: both blockSize (shard) and chunkSize (inner) set
+ final int[] shardSize = new int[]{64, 64, 64};
+ final int[] chunkSize = new int[]{16, 16, 16};
+ final ZarrV3DatasetAttributes sharded = ZarrV3DatasetAttributes.builder(dims, DataType.UINT16)
+ .blockSize(shardSize).chunkSize(chunkSize).build();
+ assertTrue(sharded.isSharded());
+ assertArrayEquals(shardSize, sharded.getBlockSize());
+ assertArrayEquals(chunkSize, sharded.getChunkSize());
+ assertNotNull(sharded.getBlockCodecInfo());
+
+ // round-trip through Builder(DatasetAttributes)
+ final ZarrV3DatasetAttributes roundTrip = ZarrV3DatasetAttributes.builder(withGzip).build();
+ assertArrayEquals(withGzip.getDimensions(), roundTrip.getDimensions());
+ assertArrayEquals(withGzip.getBlockSize(), roundTrip.getBlockSize());
+ assertEquals(withGzip.getDataType(), roundTrip.getDataType());
+ assertEquals(withGzip.getDataCodecInfos().length, roundTrip.getDataCodecInfos().length);
+
+ // validateLength: blockSize wrong length throws
+ try {
+ ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32).blockSize(new int[]{32, 32}).build();
+ // blockSize setter does not validate length — only chunkSize() does, so no exception expected here
+ } catch (final IllegalArgumentException e) {
+ // acceptable if validation is added to blockSize()
+ }
+
+ // validateBlockChunkSize: chunkSize > blockSize throws
+ try {
+ ZarrV3DatasetAttributes.builder(dims, DataType.FLOAT32)
+ .blockSize(new int[]{16, 16, 16})
+ .chunkSize(new int[]{32, 32, 32})
+ .build();
+ throw new AssertionError("Expected IllegalArgumentException for chunkSize > blockSize");
+ } catch (final IllegalArgumentException expected) {}
+ }
+
+}
diff --git a/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Test.java b/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Test.java
index 3283fbaa..48beefa0 100644
--- a/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Test.java
+++ b/src/test/java/org/janelia/saalfeldlab/n5/zarr/v3/ZarrV3Test.java
@@ -1,31 +1,3 @@
-/*-
- * #%L
- * Not HDF5
- * %%
- * Copyright (C) 2019 - 2022 Stephan Saalfeld
- * %%
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * #L%
- */
package org.janelia.saalfeldlab.n5.zarr.v3;
import static org.junit.Assert.assertArrayEquals;