diff --git a/src/main/java/net/imglib2/blocks/SubArrayCopy.java b/src/main/java/net/imglib2/blocks/SubArrayCopy.java new file mode 100644 index 000000000..57a548dd2 --- /dev/null +++ b/src/main/java/net/imglib2/blocks/SubArrayCopy.java @@ -0,0 +1,166 @@ +package net.imglib2.blocks; + +import net.imglib2.type.PrimitiveType; +import net.imglib2.util.Cast; +import net.imglib2.util.IntervalIndexer; + +/** + * Copy sub-region between flattened arrays (of different sizes). + *
+ * The {@link #copy(Object, int[], int[], Object, int[], int[], int[]) SubArrayCopy.copy} + * method requires the nD size of the flattened source and target arrays, the nD + * starting position and nD size of the source region to copy, and the nD + * starting position in the target to copy to. + *
+ * The {@link #copy(Object, int[], int[], Object, int[], int[], int[]) + * SubArrayCopy.copy} method determines the appropriate implementation by + * looking at the types of the {@code src} and {@code dest} arguments. + *
+ * If for repeated calls the types are known beforehand, this implementation
+ * lookup can be done once, up-front. {@link #forPrimitiveType(PrimitiveType,
+ * boolean, boolean) SubArrayCopy.forPrimitiveType} returns a {@link
+ * SubArrayCopy.Typed} instance with explicit {@code src} and {@code dest}
+ * types.
+ */
+public interface SubArrayCopy
+{
+ /**
+ * Copy a nD region from {@code src} to {@code dest}, where {@code src} and
+ * {@code dest} are flattened nD array of dimensions {@code srcSize} and
+ * {@code destSize}, respectively.
+ *
+ * @param src
+ * flattened nD source array
+ * @param srcSize
+ * dimensions of src
+ * @param srcPos
+ * starting position, in src, of the range to copy
+ * @param dest
+ * flattened nD destination array
+ * @param destSize
+ * dimensions of dest
+ * @param destPos
+ * starting position, in dest, of the range to copy
+ * @param size
+ * size of the range to copy
+ */
+ @SuppressWarnings( { "unchecked", "rawtypes" } )
+ static void copy( Object src, int[] srcSize, int[] srcPos, Object dest, int[] destSize, int[] destPos, int[] size )
+ {
+ final MemCopy memcopy = MemCopy.forClasses( src.getClass(), dest.getClass() );
+
+ final int n = srcSize.length;
+ assert srcPos.length == n;
+ assert destSize.length == n;
+ assert destPos.length == n;
+ assert size.length == n;
+
+ final int[] srcStrides = IntervalIndexer.createAllocationSteps( srcSize );
+ final int[] destStrides = IntervalIndexer.createAllocationSteps( destSize );
+ final int oSrc = IntervalIndexer.positionToIndex( srcPos, srcSize );
+ final int oDest = IntervalIndexer.positionToIndex( destPos, destSize );
+
+ memcopy.copyNDRangeRecursive( n - 1,
+ src, srcStrides, oSrc,
+ dest, destStrides, oDest,
+ size );
+ }
+
+ static < T > Typed< T, T > forPrimitiveType( final PrimitiveType primitiveType )
+ {
+ MemCopy< T, T > memcopy = Cast.unchecked( MemCopy.forPrimitiveType( primitiveType, false, false ) );
+ return memcopy::copyNDRangeRecursive;
+ }
+
+ static < S, T > Typed< S, T > forPrimitiveType( final PrimitiveType primitiveType, final boolean fromBuffer, final boolean toBuffer )
+ {
+ MemCopy< S, T > memcopy = Cast.unchecked( MemCopy.forPrimitiveType( primitiveType, fromBuffer, toBuffer ) );
+ return memcopy::copyNDRangeRecursive;
+ }
+
+ /**
+ * @param
+ * For {@code d=0}, a 1D line of length {@code size[0]} is copied
+ * (equivalent to {@code System.arraycopy}). For {@code d=1}, a 2D plane of
+ * size {@code size[0] * size[1]} is copied, by recursively copying 1D
+ * lines, starting {@code srcStrides[1]} (respectively {@code
+ * destStrides[1]}) apart. For {@code d=2}, a 3D box is copied by
+ * recursively copying 2D planes, etc.
+ *
+ * @param d
+ * current dimension
+ * @param src
+ * flattened nD source array
+ * @param srcStrides
+ * nD strides of src
+ * @param srcPos
+ * flattened index (in src) to start copying from
+ * @param dest
+ * flattened nD destination array
+ * @param destStrides
+ * nD strides of dest
+ * @param destPos
+ * flattened index (in dest) to start copying to
+ * @param size
+ * nD size of the range to copy
+ */
+ void copyNDRangeRecursive(
+ int d,
+ S src, int[] srcStrides, int srcPos,
+ T dest, int[] destStrides, int destPos,
+ int[] size );
+ }
+}
+ * the source type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer})
+ * @param