Commit 7a664439 authored by pietzsch's avatar pietzsch Committed by pietzsch
Browse files

Clean up and simplify VirtualStackImageLoader

parent 0fea6b51
package bdv.img.virtualstack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.function.Function;
import bdv.AbstractViewerSetupImgLoader;
import bdv.ViewerImgLoader;
import bdv.img.cache.CacheArrayLoader;
import bdv.img.cache.VolatileGlobalCellCache;
import ij.ImagePlus;
import mpicbg.spim.data.generic.sequence.BasicSetupImgLoader;
import mpicbg.spim.data.generic.sequence.ImgLoaderHint;
import mpicbg.spim.data.generic.sequence.TypedBasicImgLoader;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.Volatile;
import net.imglib2.cache.img.CachedCellImg;
import net.imglib2.cache.volatiles.CacheHints;
import net.imglib2.cache.volatiles.LoadingStrategy;
import net.imglib2.img.NativeImg;
import net.imglib2.img.basictypeaccess.volatiles.VolatileAccess;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileByteArray;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileFloatArray;
......@@ -26,6 +17,7 @@ import net.imglib2.img.cell.AbstractCellImg;
import net.imglib2.img.cell.CellGrid;
import net.imglib2.realtransform.AffineTransform3D;
import net.imglib2.type.NativeType;
import net.imglib2.type.PrimitiveType;
import net.imglib2.type.numeric.ARGBType;
import net.imglib2.type.numeric.integer.UnsignedByteType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
......@@ -35,6 +27,15 @@ import net.imglib2.type.volatiles.VolatileFloatType;
import net.imglib2.type.volatiles.VolatileUnsignedByteType;
import net.imglib2.type.volatiles.VolatileUnsignedShortType;
import bdv.AbstractViewerSetupImgLoader;
import bdv.ViewerImgLoader;
import bdv.img.cache.CacheArrayLoader;
import bdv.img.cache.VolatileGlobalCellCache;
import ij.ImagePlus;
import mpicbg.spim.data.generic.sequence.BasicSetupImgLoader;
import mpicbg.spim.data.generic.sequence.ImgLoaderHint;
import mpicbg.spim.data.generic.sequence.TypedBasicImgLoader;
/**
* ImageLoader backed by a ImagePlus. The ImagePlus may be virtual and in
* contrast to the imglib2 wrappers, we do not try to load all slices into
......@@ -59,7 +60,7 @@ import net.imglib2.type.volatiles.VolatileUnsignedShortType;
*
* @author Tobias Pietzsch <tobias.pietzsch@gmail.com>
*/
public abstract class VirtualStackImageLoader< T extends NativeType< T >, V extends Volatile< T > & NativeType< V >, A extends VolatileAccess >
public class VirtualStackImageLoader< T extends NativeType< T >, V extends Volatile< T > & NativeType< V >, A extends VolatileAccess >
implements ViewerImgLoader, TypedBasicImgLoader< T >
{
public static VirtualStackImageLoader< FloatType, VolatileFloatType, VolatileFloatArray > createFloatInstance( final ImagePlus imp )
......@@ -69,21 +70,7 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
public static VirtualStackImageLoader< FloatType, VolatileFloatType, VolatileFloatArray > createFloatInstance( final ImagePlus imp, final int offset )
{
return new VirtualStackImageLoader< FloatType, VolatileFloatType, VolatileFloatArray >(
imp, new VirtualStackVolatileFloatArrayLoader( imp ), new FloatType(), new VolatileFloatType(), offset )
{
@Override
protected void linkType( final CachedCellImg< FloatType, VolatileFloatArray > img )
{
img.setLinkedType( new FloatType( img ) );
}
@Override
protected void linkVolatileType( final CachedCellImg< VolatileFloatType, VolatileFloatArray > img )
{
img.setLinkedType( new VolatileFloatType( img ) );
}
};
return new VirtualStackImageLoader<>( imp,array -> new VolatileFloatArray( ( float[] ) array, true ), new FloatType(), new VolatileFloatType(), offset );
}
public static VirtualStackImageLoader< UnsignedShortType, VolatileUnsignedShortType, VolatileShortArray > createUnsignedShortInstance( final ImagePlus imp )
......@@ -93,21 +80,7 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
public static VirtualStackImageLoader< UnsignedShortType, VolatileUnsignedShortType, VolatileShortArray > createUnsignedShortInstance( final ImagePlus imp, final int offset )
{
return new VirtualStackImageLoader< UnsignedShortType, VolatileUnsignedShortType, VolatileShortArray >(
imp, new VirtualStackVolatileShortArrayLoader( imp ), new UnsignedShortType(), new VolatileUnsignedShortType(), offset )
{
@Override
protected void linkType( final CachedCellImg< UnsignedShortType, VolatileShortArray > img )
{
img.setLinkedType( new UnsignedShortType( img ) );
}
@Override
protected void linkVolatileType( final CachedCellImg< VolatileUnsignedShortType, VolatileShortArray > img )
{
img.setLinkedType( new VolatileUnsignedShortType( img ) );
}
};
return new VirtualStackImageLoader<>( imp, array -> new VolatileShortArray( ( short[] ) array, true ), new UnsignedShortType(), new VolatileUnsignedShortType(), offset );
}
public static VirtualStackImageLoader< UnsignedByteType, VolatileUnsignedByteType, VolatileByteArray > createUnsignedByteInstance( final ImagePlus imp )
......@@ -117,21 +90,7 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
public static VirtualStackImageLoader< UnsignedByteType, VolatileUnsignedByteType, VolatileByteArray > createUnsignedByteInstance( final ImagePlus imp, final int offset )
{
return new VirtualStackImageLoader< UnsignedByteType, VolatileUnsignedByteType, VolatileByteArray >(
imp, new VirtualStackVolatileByteArrayLoader( imp ), new UnsignedByteType(), new VolatileUnsignedByteType(), offset )
{
@Override
protected void linkType( final CachedCellImg< UnsignedByteType, VolatileByteArray > img )
{
img.setLinkedType( new UnsignedByteType( img ) );
}
@Override
protected void linkVolatileType( final CachedCellImg< VolatileUnsignedByteType, VolatileByteArray > img )
{
img.setLinkedType( new VolatileUnsignedByteType( img ) );
}
};
return new VirtualStackImageLoader<>( imp, array -> new VolatileByteArray( ( byte[] ) array, true ), new UnsignedByteType(), new VolatileUnsignedByteType(), offset );
}
public static VirtualStackImageLoader< ARGBType, VolatileARGBType, VolatileIntArray > createARGBInstance( final ImagePlus imp )
......@@ -141,21 +100,7 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
public static VirtualStackImageLoader< ARGBType, VolatileARGBType, VolatileIntArray > createARGBInstance( final ImagePlus imp, final int offset )
{
return new VirtualStackImageLoader< ARGBType, VolatileARGBType, VolatileIntArray >(
imp, new VirtualStackVolatileARGBArrayLoader( imp ), new ARGBType(), new VolatileARGBType(), offset )
{
@Override
protected void linkType( final CachedCellImg< ARGBType, VolatileIntArray > img )
{
img.setLinkedType( new ARGBType( img ) );
}
@Override
protected void linkVolatileType( final CachedCellImg< VolatileARGBType, VolatileIntArray > img )
{
img.setLinkedType( new VolatileARGBType( img ) );
}
};
return new VirtualStackImageLoader<>( imp, array -> new VolatileIntArray( ( int[] ) array, true ), new ARGBType(), new VolatileARGBType(), offset );
}
private static double[][] mipmapResolutions = new double[][] { { 1, 1, 1 } };
......@@ -172,9 +117,25 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
private final HashMap< Integer, SetupImgLoader > setupImgLoaders;
protected VirtualStackImageLoader( final ImagePlus imp, final CacheArrayLoader< A > loader, final T type, final V volatileType, int setupOffset )
private static int getByteCount( final PrimitiveType primitiveType )
{
this.loader = loader;
// TODO: PrimitiveType.getByteCount() should be public, then we wouldn't have to do this...
switch ( primitiveType )
{
case BYTE:
return 1;
case SHORT:
return 2;
case INT:
case FLOAT:
default:
return 4;
}
}
protected VirtualStackImageLoader( final ImagePlus imp, final Function< Object, A > wrapPixels, final T type, final V volatileType, final int setupOffset )
{
this.loader = new VirtualStackArrayLoader<>( imp, wrapPixels, getByteCount( type.getNativeTypeFactory().getPrimitiveType() ) );
dimensions = new long[] { imp.getWidth(), imp.getHeight(), imp.getNSlices() };
cellDimensions = new int[] { imp.getWidth(), imp.getHeight(), 1 };
final int numSetups = imp.getNChannels();
......@@ -184,15 +145,11 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
setupImgLoaders.put( setupOffset + setupId, new SetupImgLoader( setupId, type, volatileType ) );
}
protected VirtualStackImageLoader( final ImagePlus imp, final CacheArrayLoader< A > loader, final T type, final V volatileType )
protected VirtualStackImageLoader( final ImagePlus imp, final Function< Object, A > wrapPixels, final T type, final V volatileType )
{
this( imp, loader, type, volatileType, 0 );
this( imp, wrapPixels, type, volatileType, 0 );
}
protected abstract void linkType( CachedCellImg< T, A > img );
protected abstract void linkVolatileType( CachedCellImg< V, A > img );
@Override
public VolatileGlobalCellCache getCacheControl()
{
......@@ -205,6 +162,37 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
return setupImgLoaders.get( setupId );
}
static class VirtualStackArrayLoader< A > implements CacheArrayLoader< A >
{
private final ImagePlus imp;
private final Function< Object, A > wrapPixels;
private final int bytesPerElement;
public VirtualStackArrayLoader( final ImagePlus imp, final Function< Object, A > wrapPixels, final int bytesPerElement )
{
this.imp = imp;
this.wrapPixels = wrapPixels;
this.bytesPerElement = bytesPerElement;
}
@Override
public A loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException
{
final int channel = setup + 1;
final int slice = ( int ) min[ 2 ] + 1;
final int frame = timepoint + 1;
return wrapPixels.apply( imp.getStack().getProcessor( imp.getStackIndex( channel, slice, frame ) ).getPixels() );
}
@Override
public int getBytesPerElement()
{
return bytesPerElement;
}
}
public class SetupImgLoader extends AbstractViewerSetupImgLoader< T, V >
{
private final int setupId;
......@@ -228,10 +216,7 @@ public abstract class VirtualStackImageLoader< T extends NativeType< T >, V exte
}
/**
* (Almost) create a {@link CachedCellImg} backed by the cache. The created
* image needs a {@link NativeImg#setLinkedType(net.imglib2.type.Type)
* linked type} before it can be used. The type should be either
* {@link ARGBType} and {@link VolatileARGBType}.
* Create a {@link CachedCellImg} backed by the cache.
*/
protected < T extends NativeType< T > > AbstractCellImg< T, A, ?, ? > prepareCachedImage( final int timepointId, final int level, final LoadingStrategy loadingStrategy, final T type )
{
......
package bdv.img.virtualstack;
import bdv.img.cache.CacheArrayLoader;
import ij.ImagePlus;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray;
public class VirtualStackVolatileARGBArrayLoader implements CacheArrayLoader< VolatileIntArray >
{
private final ImagePlus imp;
public VirtualStackVolatileARGBArrayLoader( final ImagePlus imp )
{
this.imp = imp;
}
@Override
public VolatileIntArray loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException
{
final int channel = setup + 1;
final int slice = ( int ) min[ 2 ] + 1;
final int frame = timepoint + 1;
final int[] data = ( int[] ) imp.getStack().getProcessor( imp.getStackIndex( channel, slice, frame ) ).getPixels();
return new VolatileIntArray( data, true );
}
@Override
public int getBytesPerElement()
{
return 4;
}
}
package bdv.img.virtualstack;
import bdv.img.cache.CacheArrayLoader;
import ij.ImagePlus;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileByteArray;
public class VirtualStackVolatileByteArrayLoader implements CacheArrayLoader< VolatileByteArray >
{
private final ImagePlus imp;
public VirtualStackVolatileByteArrayLoader( final ImagePlus imp )
{
this.imp = imp;
}
@Override
public VolatileByteArray loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException
{
final int channel = setup + 1;
final int slice = ( int ) min[ 2 ] + 1;
final int frame = timepoint + 1;
final byte[] data = ( byte[] ) imp.getStack().getProcessor( imp.getStackIndex( channel, slice, frame ) ).getPixels();
return new VolatileByteArray( data, true );
}
@Override
public int getBytesPerElement()
{
return 1;
}
}
package bdv.img.virtualstack;
import bdv.img.cache.CacheArrayLoader;
import ij.ImagePlus;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileFloatArray;
public class VirtualStackVolatileFloatArrayLoader implements CacheArrayLoader< VolatileFloatArray >
{
private final ImagePlus imp;
public VirtualStackVolatileFloatArrayLoader( final ImagePlus imp )
{
this.imp = imp;
}
@Override
public VolatileFloatArray loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException
{
final int channel = setup + 1;
final int slice = ( int ) min[ 2 ] + 1;
final int frame = timepoint + 1;
final float[] data = ( float[] ) imp.getStack().getProcessor( imp.getStackIndex( channel, slice, frame ) ).getPixels();
return new VolatileFloatArray( data, true );
}
@Override
public int getBytesPerElement()
{
return 4;
}
}
package bdv.img.virtualstack;
import bdv.img.cache.CacheArrayLoader;
import ij.ImagePlus;
import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
public class VirtualStackVolatileShortArrayLoader implements CacheArrayLoader< VolatileShortArray >
{
private final ImagePlus imp;
public VirtualStackVolatileShortArrayLoader( final ImagePlus imp )
{
this.imp = imp;
}
@Override
public VolatileShortArray loadArray( final int timepoint, final int setup, final int level, final int[] dimensions, final long[] min ) throws InterruptedException
{
final int channel = setup + 1;
final int slice = ( int ) min[ 2 ] + 1;
final int frame = timepoint + 1;
final short[] data = ( short[] ) imp.getStack().getProcessor( imp.getStackIndex( channel, slice, frame ) ).getPixels();
return new VolatileShortArray( data, true );
}
@Override
public int getBytesPerElement()
{
return 2;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment