diff --git a/src/main/java/net/imglib2/blocks/BlockInterval.java b/src/main/java/net/imglib2/blocks/BlockInterval.java new file mode 100644 index 000000000..d3d510405 --- /dev/null +++ b/src/main/java/net/imglib2/blocks/BlockInterval.java @@ -0,0 +1,119 @@ +package net.imglib2.blocks; + +import net.imglib2.Interval; +import net.imglib2.util.Util; + +import java.util.Arrays; + +import static net.imglib2.util.Util.safeInt; + +/** + * An {@code Interval} where dimensions are {@code int[]}. + *

+ * Used internally by {@code PrimitiveBlocks} and {@code BlockProcessor}. + */ +public final class BlockInterval implements Interval +{ + public BlockInterval( final int numDimensions ) + { + this( new long[ numDimensions ], new int[ numDimensions ] ); + } + + public static BlockInterval wrap( final long[] min, final int[] size ) + { + return new BlockInterval( min, size ); + } + + /** + * Return {@code interval} if it is a {@code BlockInterval}. + * Otherwise, copy into a new {@link BlockInterval}. + */ + public static BlockInterval asBlockInterval( final Interval interval ) + { + return interval instanceof BlockInterval + ? ( BlockInterval ) interval + : new BlockInterval( interval ); + } + + private final long[] min; + + private final int[] size; + + private BlockInterval( final long[] min, final int[] size ) + { + this.min = min; + this.size = size; + } + + private BlockInterval( final Interval interval ) + { + this( interval.numDimensions() ); + interval.min( min ); + Arrays.setAll( size, d -> safeInt( interval.dimension( d ) ) ); + } + + public void setFrom( Interval interval ) + { + final int n = numDimensions(); + if ( n != interval.numDimensions() ) + { + throw new IllegalArgumentException( "Interval dimensions mismatch" ); + } + if ( interval instanceof BlockInterval ) + { + System.arraycopy( ( ( BlockInterval ) interval ).min, 0, min, 0, n ); + System.arraycopy( ( ( BlockInterval ) interval ).size, 0, size, 0, n ); + } + for ( int d = 0; d < n; ++d ) + { + min[ d ] = interval.min( d ); + size[ d ] = Util.safeInt( interval.dimension( d ) ); + } + } + + /** + * This returns the internal {@code long[] min}. + * Modifications are reflected in this interval! + * + * @return the internal {@code long[]} storing the min of this interval. + */ + public long[] min() + { + return min; + } + + /** + * This returns the internal {@code int[] dimensions}. + * Modifications are reflected in this interval! + * + * @return the internal {@code int[]} storing the dimensions of this interval. + */ + public int[] size() + { + return size; + } + + @Override + public int numDimensions() + { + return size.length; + } + + @Override + public long min( final int d ) + { + return min[ d ]; + } + + @Override + public long max( final int d ) + { + return min[ d ] + size[ d ] - 1; + } + + @Override + public long dimension( final int d ) + { + return size[ d ]; + } +} diff --git a/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java index c1f75e841..543ef2fab 100644 --- a/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java +++ b/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java @@ -33,7 +33,7 @@ */ package net.imglib2.blocks; -import net.imglib2.FinalInterval; +import net.imglib2.Interval; import net.imglib2.RandomAccessible; import net.imglib2.img.array.ArrayImg; import net.imglib2.img.basictypeaccess.array.ArrayDataAccess; @@ -41,7 +41,6 @@ import net.imglib2.type.NativeType; import net.imglib2.type.NativeTypeFactory; import net.imglib2.util.Cast; -import net.imglib2.util.Util; import net.imglib2.view.Views; class FallbackPrimitiveBlocks< T extends NativeType< T >, A extends ArrayDataAccess< A > > implements PrimitiveBlocks< T > @@ -84,11 +83,10 @@ public int numDimensions() } @Override - public void copy( final long[] srcPos, final Object dest, final int[] size ) + public void copy( final Interval interval, final Object dest ) { - final ArrayImg< T, A > img = new ArrayImg<>( primitiveTypeProperties.wrap( dest ), Util.int2long( size ), type.getEntitiesPerPixel() ); + final ArrayImg< T, A > img = new ArrayImg<>( primitiveTypeProperties.wrap( dest ), interval.dimensionsAsLongArray(), type.getEntitiesPerPixel() ); img.setLinkedType( nativeTypeFactory.createLinkedType( img ) ); - final FinalInterval interval = FinalInterval.createMinSize( srcPos, Util.int2long( size ) ); LoopBuilder.setImages( Views.interval( source, interval ), img ).forEachPixel( ( a, b ) -> b.set( a ) ); } diff --git a/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java index 927287d79..b2fb0ba1c 100644 --- a/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java +++ b/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java @@ -37,6 +37,7 @@ import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.WARN; import net.imglib2.EuclideanSpace; +import net.imglib2.Interval; import net.imglib2.RandomAccessible; import net.imglib2.Typed; import net.imglib2.type.NativeType; @@ -105,6 +106,19 @@ */ public interface PrimitiveBlocks< T extends NativeType< T > > extends Typed< T >, EuclideanSpace { + /** + * Copy a block from the ({@code T}-typed) source into primitive arrays (of + * the appropriate type). + * + * @param interval + * position and size of the block to copy + * @param dest + * primitive array to copy into. Must correspond to {@code T}, for + * example, if {@code T} is {@code UnsignedByteType} then {@code dest} must + * be {@code byte[]}. + */ + void copy( Interval interval, Object dest ); + /** * Copy a block from the ({@code T}-typed) source into primitive arrays (of * the appropriate type). @@ -118,7 +132,10 @@ public interface PrimitiveBlocks< T extends NativeType< T > > extends Typed< T > * @param size * the size of the block to copy */ - void copy( long[] srcPos, Object dest, int[] size ); + default void copy( long[] srcPos, Object dest, int[] size ) + { + copy( BlockInterval.wrap( srcPos, size ), dest ); + } /** * Copy a block from the ({@code T}-typed) source into primitive arrays (of diff --git a/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java index 1a42af41f..9b3d44c2d 100644 --- a/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java +++ b/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java @@ -37,6 +37,7 @@ import java.util.function.Supplier; +import net.imglib2.Interval; import net.imglib2.img.basictypeaccess.nio.BufferAccess; import net.imglib2.transform.integer.MixedTransform; import net.imglib2.type.NativeType; @@ -94,16 +95,22 @@ public int numDimensions() } /** - * @param srcPos - * min coordinates of block to copy from src Img. + * Copy a block from the ({@code T}-typed) source into primitive arrays (of + * the appropriate type). + * + * @param interval + * position and size of the block to copy * @param dest - * destination array. Type is {@code byte[]}, {@code float[]}, - * etc, corresponding to the src Img's native type. - * @param size - * dimensions of block to copy from src Img. + * primitive array to copy into. Must correspond to {@code T}, for + * example, if {@code T} is {@code UnsignedByteType} then {@code dest} must + * be {@code byte[]}. */ - public void copy( final long[] srcPos, final Object dest, final int[] size ) + public void copy( final Interval interval, final Object dest ) { + final BlockInterval blockInterval = BlockInterval.asBlockInterval( interval ); + final long[] srcPos = blockInterval.min(); + final int[] size = blockInterval.size(); + final long[] destPos; final int[] destSize; if ( props.hasTransform() ) @@ -185,9 +192,9 @@ public int numDimensions() } @Override - public void copy( final long[] srcPos, final Object dest, final int[] size ) + public void copy( final Interval interval, final Object dest ) { - threadSafeSupplier.get().copy( srcPos, dest, size ); + threadSafeSupplier.get().copy( interval, dest ); } @Override