From 6a0c3ebb5747c1f906a9268cd6665d01f70c5044 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Thu, 16 Apr 2026 17:45:45 -0500 Subject: [PATCH 1/3] Fix `BigEndian` in `OME/METADATA.ome.xml` Default zarr-java behavior is to write little-endian data, so `OME/METADATA.ome.xml` should match this behavior. --- .../java/com/glencoesoftware/bioformats2raw/Converter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java b/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java index 3bbc9204..c3407ceb 100644 --- a/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java +++ b/src/main/java/com/glencoesoftware/bioformats2raw/Converter.java @@ -1607,7 +1607,10 @@ public void convert() } for (int s=0; s Date: Fri, 17 Apr 2026 16:28:10 -0500 Subject: [PATCH 2/3] Add endianness checks to Zarr tests --- .../bioformats2raw/test/ZarrTest.java | 5 ++ .../bioformats2raw/test/ZarrV3Test.java | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java index 21d6c78e..22814a69 100644 --- a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java +++ b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java @@ -27,6 +27,7 @@ import dev.zarr.zarrjava.utils.Utils; import dev.zarr.zarrjava.v2.Array; import dev.zarr.zarrjava.v2.DataType; +import dev.zarr.zarrjava.v2.Endianness; import dev.zarr.zarrjava.v2.Group; import dev.zarr.zarrjava.v2.codec.Codec; import dev.zarr.zarrjava.v2.codec.core.BloscCodec; @@ -866,6 +867,7 @@ public void testPixelType(String type, DataType dataType) throws Exception { // Check series dimensions and special pixels Array series0 = Array.open(store.resolve("0", "0")); assertEquals(dataType, series0.metadata().dataType); + assertEquals(Endianness.LITTLE, series0.metadata().endianness); assertArrayEquals(new long[] {1, 1, 1, 512, 512}, series0.metadata().shape); assertArrayEquals( new int[] {1, 1, 1, 512, 512}, series0.metadata().chunkShape()); @@ -873,6 +875,9 @@ public void testPixelType(String type, DataType dataType) throws Exception { int pixelType = FormatTools.pixelTypeFromString(type); checkSpecialPixels(0, 1, 1, 1, shape, series0, pixelType); + + OME ome = getOMEMetadata(); + assertFalse(ome.getImage(0).getPixels().getBigEndian()); } /** diff --git a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrV3Test.java b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrV3Test.java index 4e5b3205..92199373 100644 --- a/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrV3Test.java +++ b/src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrV3Test.java @@ -7,6 +7,7 @@ */ package com.glencoesoftware.bioformats2raw.test; +import java.nio.ByteOrder; import java.nio.file.Files; import java.util.Arrays; import java.util.List; @@ -18,13 +19,16 @@ import dev.zarr.zarrjava.core.Attributes; import dev.zarr.zarrjava.v3.Array; import dev.zarr.zarrjava.v3.ArrayMetadata; +import dev.zarr.zarrjava.v3.DataType; import dev.zarr.zarrjava.v3.Group; import dev.zarr.zarrjava.v3.codec.Codec; import dev.zarr.zarrjava.v3.codec.core.BloscCodec; +import dev.zarr.zarrjava.v3.codec.core.BytesCodec; import dev.zarr.zarrjava.v3.codec.core.GzipCodec; import dev.zarr.zarrjava.v3.codec.core.ShardingIndexedCodec; import dev.zarr.zarrjava.v3.codec.core.ZstdCodec; +import loci.formats.FormatTools; import ome.xml.model.OME; import picocli.CommandLine.ExecutionException; @@ -443,4 +447,49 @@ public void testBadCompressionOptions(String codec) throws Exception { }); } + /** + * Test pixel type preservation. + * + * @param type string representation of Bio-Formats pixel type + * @param dataType expected corresponding Zarr data type + */ + @ParameterizedTest + @MethodSource("getPixelTypes") + public void testPixelType(String type, DataType dataType) throws Exception { + input = fake("pixelType", type); + assertTool("--ngff-version", getNGFFVersion()); + Group z = Group.open(store.resolve("")); + + // Check series dimensions and special pixels + Array series0 = Array.open(store.resolve("0", "0")); + assertEquals(dataType, series0.metadata().dataType); + for (Codec codec : series0.metadata().codecs) { + if (codec instanceof BytesCodec) { + assertEquals(((BytesCodec) codec).configuration.endian.getByteOrder(), + ByteOrder.LITTLE_ENDIAN); + } + } + assertArrayEquals(new long[] {1, 1, 1, 512, 512}, series0.metadata().shape); + int[] shape = new int[] {1, 1, 1, 512, 512}; + assertArrayEquals(shape, series0.metadata().chunkShape()); + + int pixelType = FormatTools.pixelTypeFromString(type); + checkSpecialPixels(0, 1, 1, 1, shape, series0, pixelType); + + OME ome = getOMEMetadata(); + assertFalse(ome.getImage(0).getPixels().getBigEndian()); + } + + /** + * @return pairs of pixel type strings and Zarr data types + */ + static Stream getPixelTypes() { + return Stream.of( + Arguments.of("float", DataType.FLOAT32), + Arguments.of("double", DataType.FLOAT64), + Arguments.of("uint32", DataType.UINT32), + Arguments.of("int32", DataType.INT32) + ); + } + } From 13531c7b4d051f9485eca56b715df7d0fb319378 Mon Sep 17 00:00:00 2001 From: Melissa Linkert Date: Fri, 17 Apr 2026 16:28:28 -0500 Subject: [PATCH 3/3] Update README to reference switch to zarr-java and little-endian output --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 209c7cc2..41423c57 100644 --- a/README.md +++ b/README.md @@ -358,6 +358,11 @@ by default. This includes calculating the minimum and maximum pixel values for t We recommend keeping this metadata for maximum compatibility with downstream applications, but it can be omitted by using the `--no-minmax` option. +Version 0.12.0 and later switches the underlying library that reads and writes Zarr from jzarr to +[zarr-java](https://github.com/zarr-developers/zarr-java). This allows Zarr v2 and Zarr v3 to be +supported with a single library. A consequence of this change is that all data is now written +as little-endian. + Performance ===========