Skip to content

Commit 7d939b0

Browse files
committed
Add SubArrayCopy for copying sub-regions between flattened arrays (of different sizes)
Add javadoc
1 parent 865e0c1 commit 7d939b0

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package net.imglib2.blocks;
2+
3+
import net.imglib2.type.PrimitiveType;
4+
import net.imglib2.util.Cast;
5+
import net.imglib2.util.IntervalIndexer;
6+
7+
/**
8+
* Copy sub-region between flattened arrays (of different sizes).
9+
* <p>
10+
* The {@link #copy(Object, int[], int[], Object, int[], int[], int[]) SubArrayCopy.copy}
11+
* method requires the nD size of the flattened source and target arrays, the nD
12+
* starting position and nD size of the source region to copy, and the nD
13+
* starting position in the target to copy to.
14+
* <p>
15+
* The {@link #copy(Object, int[], int[], Object, int[], int[], int[])
16+
* SubArrayCopy.copy} method determines the appropriate implementation by
17+
* looking at the types of the {@code src} and {@code dest} arguments.
18+
* <p>
19+
* If for repeated calls the types are known beforehand, this implementation
20+
* lookup can be done once, up-front. {@link #forPrimitiveType(PrimitiveType,
21+
* boolean, boolean) SubArrayCopy.forPrimitiveType} returns a {@link
22+
* SubArrayCopy.Typed} instance with explicit {@code src} and {@code dest}
23+
* types.
24+
*/
25+
public interface SubArrayCopy
26+
{
27+
/**
28+
* Copy a nD region from {@code src} to {@code dest}, where {@code src} and
29+
* {@code dest} are flattened nD array of dimensions {@code srcSize} and
30+
* {@code destSize}, respectively.
31+
*
32+
* @param src
33+
* flattened nD source array
34+
* @param srcSize
35+
* dimensions of src
36+
* @param srcPos
37+
* starting position, in src, of the range to copy
38+
* @param dest
39+
* flattened nD destination array
40+
* @param destSize
41+
* dimensions of dest
42+
* @param destPos
43+
* starting position, in dest, of the range to copy
44+
* @param size
45+
* size of the range to copy
46+
*/
47+
@SuppressWarnings( { "unchecked", "rawtypes" } )
48+
static void copy( Object src, int[] srcSize, int[] srcPos, Object dest, int[] destSize, int[] destPos, int[] size )
49+
{
50+
final MemCopy memcopy = MemCopy.forClasses( src.getClass(), dest.getClass() );
51+
52+
final int n = srcSize.length;
53+
assert srcPos.length == n;
54+
assert destSize.length == n;
55+
assert destPos.length == n;
56+
assert size.length == n;
57+
58+
final int[] srcStrides = IntervalIndexer.createAllocationSteps( srcSize );
59+
final int[] destStrides = IntervalIndexer.createAllocationSteps( destSize );
60+
final int oSrc = IntervalIndexer.positionToIndex( srcPos, srcSize );
61+
final int oDest = IntervalIndexer.positionToIndex( destPos, destSize );
62+
63+
memcopy.copyNDRangeRecursive( n - 1,
64+
src, srcStrides, oSrc,
65+
dest, destStrides, oDest,
66+
size );
67+
}
68+
69+
static < T > Typed< T, T > forPrimitiveType( final PrimitiveType primitiveType )
70+
{
71+
MemCopy< T, T > memcopy = Cast.unchecked( MemCopy.forPrimitiveType( primitiveType, false, false ) );
72+
return memcopy::copyNDRangeRecursive;
73+
}
74+
75+
static < S, T > Typed< S, T > forPrimitiveType( final PrimitiveType primitiveType, final boolean fromBuffer, final boolean toBuffer )
76+
{
77+
MemCopy< S, T > memcopy = Cast.unchecked( MemCopy.forPrimitiveType( primitiveType, fromBuffer, toBuffer ) );
78+
return memcopy::copyNDRangeRecursive;
79+
}
80+
81+
/**
82+
* @param <S>
83+
* the source type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer})
84+
* @param <T>
85+
* the target type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer})
86+
*/
87+
interface Typed< S, T >
88+
{
89+
/**
90+
* Copy a nD region from {@code src} to {@code dest}, where {@code src} and
91+
* {@code dest} are flattened nD array of dimensions {@code srcSize} and
92+
* {@code destSize}, respectively.
93+
*
94+
* @param src
95+
* flattened nD source array
96+
* @param srcSize
97+
* dimensions of src
98+
* @param srcPos
99+
* starting position, in src, of the range to copy
100+
* @param dest
101+
* flattened nD destination array
102+
* @param destSize
103+
* dimensions of dest
104+
* @param destPos
105+
* starting position, in dest, of the range to copy
106+
* @param size
107+
* size of the range to copy
108+
*/
109+
default void copy(
110+
final S src, final int[] srcSize, final int[] srcPos,
111+
final T dest, final int[] destSize, final int[] destPos,
112+
final int[] size )
113+
{
114+
final int n = srcSize.length;
115+
assert srcPos.length == n;
116+
assert destSize.length == n;
117+
assert destPos.length == n;
118+
assert size.length == n;
119+
120+
final int[] srcStrides = IntervalIndexer.createAllocationSteps( srcSize );
121+
final int[] destStrides = IntervalIndexer.createAllocationSteps( destSize );
122+
final int oSrc = IntervalIndexer.positionToIndex( srcPos, srcSize );
123+
final int oDest = IntervalIndexer.positionToIndex( destPos, destSize );
124+
125+
copyNDRangeRecursive( n - 1,
126+
src, srcStrides, oSrc,
127+
dest, destStrides, oDest,
128+
size );
129+
}
130+
131+
/**
132+
* Recursively copy a {@code (d+1)} dimensional region from {@code src} to
133+
* {@code dest}, where {@code src} and {@code dest} are flattened nD array
134+
* with strides {@code srcStrides} and {@code destStrides}, respectively.
135+
* <p>
136+
* For {@code d=0}, a 1D line of length {@code size[0]} is copied
137+
* (equivalent to {@code System.arraycopy}). For {@code d=1}, a 2D plane of
138+
* size {@code size[0] * size[1]} is copied, by recursively copying 1D
139+
* lines, starting {@code srcStrides[1]} (respectively {@code
140+
* destStrides[1]}) apart. For {@code d=2}, a 3D box is copied by
141+
* recursively copying 2D planes, etc.
142+
*
143+
* @param d
144+
* current dimension
145+
* @param src
146+
* flattened nD source array
147+
* @param srcStrides
148+
* nD strides of src
149+
* @param srcPos
150+
* flattened index (in src) to start copying from
151+
* @param dest
152+
* flattened nD destination array
153+
* @param destStrides
154+
* nD strides of dest
155+
* @param destPos
156+
* flattened index (in dest) to start copying to
157+
* @param size
158+
* nD size of the range to copy
159+
*/
160+
void copyNDRangeRecursive(
161+
int d,
162+
S src, int[] srcStrides, int srcPos,
163+
T dest, int[] destStrides, int destPos,
164+
int[] size );
165+
}
166+
}

0 commit comments

Comments
 (0)