diff --git a/src/main/java/bdv/img/n5/BdvN5Format.java b/src/main/java/bdv/img/n5/BdvN5Format.java index 88bc8cf3..a151a4fd 100644 --- a/src/main/java/bdv/img/n5/BdvN5Format.java +++ b/src/main/java/bdv/img/n5/BdvN5Format.java @@ -28,11 +28,58 @@ */ package bdv.img.n5; -public class BdvN5Format +import org.janelia.saalfeldlab.n5.DataType; +import org.janelia.saalfeldlab.n5.N5Reader; + +import bdv.img.cache.VolatileCachedCellImg; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.type.NativeType; + +public class BdvN5Format implements N5Properties { public static final String DOWNSAMPLING_FACTORS_KEY = "downsamplingFactors"; public static final String DATA_TYPE_KEY = "dataType"; + @Override + public String getPath( final int setupId ) + { + return getPathName( setupId ); + } + + @Override + public String getPath( final int setupId, final int timepointId) + { + return getPathName( setupId, timepointId ); + } + + @Override + public String getPath( final int setupId, final int timepointId, final int level) + { + return getPathName( setupId, timepointId, level ); + } + + @Override + public DataType getDataType( final N5Reader n5, final int setupId ) + { + return n5.getAttribute( getPath( setupId ), DATA_TYPE_KEY, DataType.class ); + } + + @Override + public double[][] getMipmapResolutions( final N5Reader n5, final int setupId ) + { + return n5.getAttribute( getPath( setupId ), DOWNSAMPLING_FACTORS_KEY, double[][].class ); + } + + @Override + public > RandomAccessibleInterval extractImg( + final VolatileCachedCellImg img, + final int setupId, + final int timepointId) + { + return img; + } + + // left the old code for compatibility public static String getPathName( final int setupId ) { return String.format( "setup%d", setupId ); diff --git a/src/main/java/bdv/img/n5/N5ImageLoader.java b/src/main/java/bdv/img/n5/N5ImageLoader.java index e4ce3873..ea367b04 100644 --- a/src/main/java/bdv/img/n5/N5ImageLoader.java +++ b/src/main/java/bdv/img/n5/N5ImageLoader.java @@ -28,10 +28,6 @@ */ package bdv.img.n5; -import static bdv.img.n5.BdvN5Format.DATA_TYPE_KEY; -import static bdv.img.n5.BdvN5Format.DOWNSAMPLING_FACTORS_KEY; -import static bdv.img.n5.BdvN5Format.getPathName; - import java.io.File; import java.io.IOException; import java.net.URI; @@ -54,6 +50,7 @@ import bdv.cache.CacheControl; import bdv.cache.SharedQueue; import bdv.img.cache.SimpleCacheArrayLoader; +import bdv.img.cache.VolatileCachedCellImg; import bdv.img.cache.VolatileGlobalCellCache; import bdv.util.ConstantRandomAccessible; import bdv.util.MipmapTransforms; @@ -83,6 +80,7 @@ public class N5ImageLoader implements ViewerImgLoader, MultiResolutionImgLoader { private final URI n5URI; + protected final N5Properties n5properties; // TODO: it would be good if this would not be needed // find available setups from the n5 @@ -97,6 +95,7 @@ public N5ImageLoader( final URI n5URI, final AbstractSequenceDescription< ?, ?, { this.n5URI = n5URI; this.seq = sequenceDescription; + this.n5properties = createN5PropertiesInstance(); } public N5ImageLoader( final File n5File, final AbstractSequenceDescription< ?, ?, ? > sequenceDescription ) @@ -120,6 +119,11 @@ public File getN5File() return new File( n5URI ); } + /** + * @return a class that creates the pathnames for the setupId, timePointId and multiresolution levels + */ + public N5Properties createN5PropertiesInstance() { return new BdvN5Format(); } + private volatile boolean isOpen = false; private SharedQueue createdSharedQueue; private VolatileGlobalCellCache cache; @@ -219,11 +223,10 @@ public void close() private < T extends NativeType< T >, V extends Volatile< T > & NativeType< V > > SetupImgLoader< T, V > createSetupImgLoader( final int setupId ) throws IOException { - final String pathName = getPathName( setupId ); final DataType dataType; try { - dataType = n5.getAttribute( pathName, DATA_TYPE_KEY, DataType.class ); + dataType = n5properties.getDataType( n5, setupId ); } catch ( final N5Exception e ) { @@ -258,10 +261,9 @@ public SetupImgLoader( final int setupId, final T type, final V volatileType ) t { super( type, volatileType ); this.setupId = setupId; - final String pathName = getPathName( setupId ); try { - mipmapResolutions = n5.getAttribute( pathName, DOWNSAMPLING_FACTORS_KEY, double[][].class ); + mipmapResolutions = n5properties.getMipmapResolutions( n5, setupId ); } catch ( final N5Exception e ) { @@ -289,7 +291,7 @@ public Dimensions getImageSize( final int timepointId, final int level ) { try { - final String pathName = getPathName( setupId, timepointId, level ); + final String pathName = n5properties.getPath( setupId, timepointId, level ); final DatasetAttributes attributes = n5.getDatasetAttributes( pathName ); return new FinalDimensions( attributes.getDimensions() ); } @@ -330,7 +332,7 @@ private < T extends NativeType< T > > RandomAccessibleInterval< T > prepareCache { try { - final String pathName = getPathName( setupId, timepointId, level ); + final String pathName = n5properties.getPath( setupId, timepointId, level ); final DatasetAttributes attributes = n5.getDatasetAttributes( pathName ); final long[] dimensions = attributes.getDimensions(); final int[] cellDimensions = attributes.getBlockSize(); @@ -340,7 +342,9 @@ private < T extends NativeType< T > > RandomAccessibleInterval< T > prepareCache final CacheHints cacheHints = new CacheHints( loadingStrategy, priority, false ); final SimpleCacheArrayLoader< ? > loader = createCacheArrayLoader( n5, pathName ); - return cache.createImg( grid, timepointId, setupId, level, cacheHints, loader, type ); + final VolatileCachedCellImg img = cache.createImg( grid, timepointId, setupId, level, cacheHints, loader, type ); + + return n5properties.extractImg( img, setupId, timepointId ); } catch ( final IOException | N5Exception e ) { diff --git a/src/main/java/bdv/img/n5/N5Properties.java b/src/main/java/bdv/img/n5/N5Properties.java new file mode 100644 index 00000000..5211e07a --- /dev/null +++ b/src/main/java/bdv/img/n5/N5Properties.java @@ -0,0 +1,20 @@ +package bdv.img.n5; + +import org.janelia.saalfeldlab.n5.DataType; +import org.janelia.saalfeldlab.n5.N5Reader; + +import bdv.img.cache.VolatileCachedCellImg; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.type.NativeType; + +public interface N5Properties +{ + // in case of OME-ZARR, it has an underlying 5D container + public < T extends NativeType > RandomAccessibleInterval extractImg( final VolatileCachedCellImg img, final int setupId, final int timepointId ); + + public DataType getDataType( final N5Reader n5, final int setupId ); + public double[][] getMipmapResolutions( final N5Reader n5, final int setupId ); + public String getPath( final int setupId ); + public String getPath( final int setupId, final int timepointId ); + public String getPath( final int setupId, final int timepointId, final int level ); +}