diff --git a/pom.xml b/pom.xml
index 8288285..74e51d7 100755
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
sc.fiji
pom-indago
- 2.2.4
+ 2.2.10
@@ -81,6 +81,18 @@
junit
test
+
+ org.openjdk.jmh
+ jmh-core
+ 1.19
+ test
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ 1.19
+ test
+
diff --git a/src/main/java/com/indago/io/DataMover.java b/src/main/java/com/indago/io/DataMover.java
index a6c5cf7..d6c79e1 100644
--- a/src/main/java/com/indago/io/DataMover.java
+++ b/src/main/java/com/indago/io/DataMover.java
@@ -3,6 +3,7 @@
*/
package com.indago.io;
+import java.util.Arrays;
import java.util.List;
import io.scif.img.ImgIOException;
@@ -15,12 +16,13 @@
import net.imglib2.exception.IncompatibleTypeException;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgFactory;
+import net.imglib2.loops.ClassCopyProvider;
import net.imglib2.type.NativeType;
import net.imglib2.type.Type;
import net.imglib2.type.numeric.ARGBType;
+import net.imglib2.type.numeric.IntegerType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.IntType;
-import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.type.numeric.real.DoubleType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
@@ -31,6 +33,9 @@
*/
public class DataMover {
+ private static final ClassCopyProvider copyLoopFactory =
+ new ClassCopyProvider<>(CopyLoopClass.class, CopyLoopInterface.class);
+
/**
* FROM: imglib Example 2c :)
* Copy from a source that is just
@@ -48,44 +53,23 @@ public class DataMover {
* - an IterableInterval as target
*/
public static < T extends Type< T >> void copy( final RandomAccessible< T > source, final IterableInterval< T > target ) {
- // create a cursor that automatically localizes itself on every move
- final Cursor< T > targetCursor = target.localizingCursor();
- final RandomAccess< T > sourceRandomAccess = source.randomAccess();
-
- // iterate over the input cursor
- while ( targetCursor.hasNext() ) {
- // move input cursor forward
- targetCursor.fwd();
-
- // set the output cursor to the position of the input cursor
- sourceRandomAccess.setPosition( targetCursor );
-
- // set the value of this pixel of the output image, every Type
- // supports T.set( T type )
- targetCursor.get().set( sourceRandomAccess.get() );
- }
+ copy(source, target, (in, out) -> out.set(in));
}
- public static < T1 extends Type< T1 >, T2 extends Type< T2 >> void copy( final RandomAccessible< T1 > source, final IterableInterval< T2 > target, final Converter< T1, T2 > converter ) {
- // create a cursor that automatically localizes itself on every move
- final Cursor< T2 > targetCursor = target.localizingCursor();
- final RandomAccess< T1 > sourceRandomAccess = source.randomAccess();
-
- // iterate over the input cursor
- while ( targetCursor.hasNext() ) {
- // move input cursor forward
- targetCursor.fwd();
-
- // set the output cursor to the position of the input cursor
- sourceRandomAccess.setPosition( targetCursor );
+ public static < T extends Type< T >> void copy( final RandomAccessible< T > source, final RandomAccessibleInterval< T > target ) {
+ copy( source, Views.iterable( target ) );
+ }
- // set converted value
- converter.convert( sourceRandomAccess.get(), targetCursor.get() );
- }
+ public static < T extends Type< T >> void copy( final RandomAccessible< T > source, final Img< T > target ) {
+ copy( source, (IterableInterval) target );
}
- public static < T extends Type< T >> void copy( final RandomAccessible< T > source, final RandomAccessibleInterval< T > target ) {
- copy( source, Views.iterable( target ) );
+ public static < S, T > void copy( final RandomAccessible< ? extends S > source, final IterableInterval< ? extends T > target, final Converter< S, T > converter ) {
+ RandomAccess< ? extends S > sourceRandomAccess = source.randomAccess();
+ Cursor< ? extends T > targetCursor = target.localizingCursor();
+ Object key = Arrays.asList(sourceRandomAccess.getClass(), sourceRandomAccess
+ .get().getClass(), targetCursor.getClass(), targetCursor.get().getClass(), converter.getClass());
+ copyLoopFactory.newInstanceForKey(key).copy(sourceRandomAccess, targetCursor, converter);
}
public static < T extends NativeType< T >> Img< T > createEmptyArrayImgLike( final RandomAccessibleInterval< ? > blueprint, final T type ) {
@@ -112,22 +96,7 @@ public static < T extends NativeType< T >> Img< T > createEmptyArrayImgLike( fin
public static < T extends RealType< T > > void add(
final RandomAccessible< T > source,
final IterableInterval< T > target ) {
- // create a cursor that automatically localizes itself on every move
- final Cursor< T > targetCursor = target.localizingCursor();
- final RandomAccess< T > sourceRandomAccess = source.randomAccess();
-
- // iterate over the input cursor
- while ( targetCursor.hasNext() ) {
- // move input cursor forward
- targetCursor.fwd();
-
- // set the output cursor to the position of the input cursor
- sourceRandomAccess.setPosition( targetCursor );
-
- // add the value of this pixel of the output image, every Type
- // supports T.set( T type )
- targetCursor.get().add( sourceRandomAccess.get() );
- }
+ copy(source, target, (in, out) -> out.add(in));
}
public static < T extends RealType< T > > void add(
@@ -136,6 +105,12 @@ public static < T extends RealType< T > > void add(
add( source, Views.iterable( target ) );
}
+ public static < T extends RealType< T > > void add(
+ final RandomAccessible< T > source,
+ final Img< T > target ) {
+ add( source, (IterableInterval< T >) target );
+ }
+
/**
* Util function that copies one image into another.
* I cases where the native pixel types match, convertAndCopy
@@ -163,255 +138,58 @@ public static < T extends RealType< T > > void add(
*
* @param source
* @param target
- * @throws Exception
*/
-// public static , TT extends NativeType> void convertAndCopy(final Img source, final Img target) throws Exception {
-// convertAndCopy( source, Views.iterable(target) );
-// }
-//
-// public static , TT extends NativeType> void convertAndCopy(final RandomAccessible source, final RandomAccessibleInterval target) throws Exception {
-// convertAndCopy( source, Views.iterable(target) );
-// }
@SuppressWarnings( "unchecked" )
public static < ST extends RealType< ST >, TT extends NativeType< TT > > void convertAndCopy(
final RandomAccessible< ST > source,
- final IterableInterval< TT > target ) throws Exception {
+ final IterableInterval< TT > target ) {
final ST sourceType = source.randomAccess().get();
final TT targetType = target.firstElement();
- // if source and target are of same type -> use copy since convert is not needed...
- if ( sourceType.getClass().isInstance( targetType ) ) {
- DataMover.copy( source, ( IterableInterval< ST > ) target );
- return;
- }
+ Converter, NativeType>> converter = getConverter(sourceType, targetType);
- // implemented conversion cases follow here...
+ DataMover.copy( source, target, converter );
+ }
- boolean throwException = false;
- if ( sourceType instanceof FloatType ) {
+ private static < ST extends RealType< ST >, TT extends NativeType< TT > > Converter,NativeType>> getConverter(ST sourceType, TT targetType) {
- if ( targetType instanceof DoubleType ) { // FloatType --> DoubleType
- final Cursor< TT > targetCursor = target.localizingCursor();
- final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
- final int v;
- while ( targetCursor.hasNext() ) {
- targetCursor.fwd();
- sourceRandomAccess.setPosition( targetCursor );
+ if ( sourceType.getClass().isInstance( targetType ) )
+ return (in, out) -> ((Type) out).set(in);
- ( ( DoubleType ) targetCursor.get() ).set( ( ( FloatType ) sourceRandomAccess.get() ).getRealDouble() );
- }
- } else // FloatType --> IntType
- if ( targetType instanceof IntType ) {
- final Cursor< TT > targetCursor = target.localizingCursor();
- final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
- final int v;
- while ( targetCursor.hasNext() ) {
- targetCursor.fwd();
- sourceRandomAccess.setPosition( targetCursor );
-
- ( ( IntType ) targetCursor.get() ).set( Math.round( ( ( FloatType ) sourceRandomAccess.get() ).getRealFloat() ) );
- }
- } else // FloatType --> ARGBType
- if ( targetType instanceof ARGBType ) {
- final Cursor< TT > targetCursor = target.localizingCursor();
- final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
- int v;
- while ( targetCursor.hasNext() ) {
- targetCursor.fwd();
- sourceRandomAccess.setPosition( targetCursor );
- try {
- v = Math.round( ( ( FloatType ) sourceRandomAccess.get() ).get() * 255 );
- } catch ( final ArrayIndexOutOfBoundsException e ) {
- v = 255; // If image-sizes do not match we pad with white pixels...
- }
- if ( v > 255 ) { throw new Exception( "TODO: in this case (source in not within [0,1]) I did not finish the code!!! Now would likely be a good time... ;)" ); }
- ( ( ARGBType ) targetCursor.get() ).set( ARGBType.rgba( v, v, v, 255 ) );
- }
- } else {
- throwException = true;
- }
+ if ( targetType instanceof DoubleType )
+ return (in, out) -> ((DoubleType) out).set( in.getRealDouble() );
- } else if ( sourceType instanceof UnsignedShortType ) {
+ if ( targetType instanceof FloatType )
+ return (in, out) -> ((FloatType) out).set(in.getRealFloat());
- // UnsignedShortType --> FloatType
- if ( targetType instanceof FloatType ) {
- final Cursor< TT > targetCursor = target.localizingCursor();
- final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
- final int v;
- while ( targetCursor.hasNext() ) {
- targetCursor.fwd();
- sourceRandomAccess.setPosition( targetCursor );
+ if ( targetType instanceof IntType ) {
+ if ( sourceType instanceof IntegerType )
+ return (in, out) -> ((IntType) out).set( ((IntegerType) in).getInteger());
+ else
+ return (in, out) -> ((IntType) out).set( Math.round(in.getRealFloat()));
+ }
- ( ( FloatType ) targetCursor.get() ).set( ( ( UnsignedShortType ) sourceRandomAccess.get() ).getRealFloat() );
+ if ( sourceType instanceof FloatType && targetType instanceof ARGBType ) {
+ return (in, out) -> {
+ int v;
+ try {
+ v = Math.round(((FloatType) in).get() * 255);
}
- } else
- if ( targetType instanceof DoubleType ) {
- final Cursor< TT > targetCursor = target.localizingCursor();
- final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
- final int v;
- while ( targetCursor.hasNext() ) {
- targetCursor.fwd();
- sourceRandomAccess.setPosition( targetCursor );
-
- ( ( DoubleType ) targetCursor.get() ).set( ( ( UnsignedShortType ) sourceRandomAccess.get() ).getRealDouble() );
+ catch (final ArrayIndexOutOfBoundsException e) {
+ v = 255; // If image-sizes do not match we pad with white pixels...
}
- } else // UnsignedShortType --> IntType
- if ( targetType instanceof IntType ) {
- final Cursor< TT > targetCursor = target.localizingCursor();
- final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
- final int v;
- while ( targetCursor.hasNext() ) {
- targetCursor.fwd();
- sourceRandomAccess.setPosition( targetCursor );
-
- ( ( IntType ) targetCursor.get() ).set( ( ( UnsignedShortType ) sourceRandomAccess.get() ).get() );
+ if (v > 255) {
+ v = 255;
+ } else if (v < 0) {
+ v = 0;
}
-// } else
-// if ( targetType instanceof ARGBType ) {
-// final Cursor< TT > targetCursor = target.localizingCursor();
-// final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
-// int v;
-// while ( targetCursor.hasNext() ) {
-// targetCursor.fwd();
-// sourceRandomAccess.setPosition( targetCursor );
-// try {
-// v =
-// Math.round( ( ( UnsignedShortType ) sourceRandomAccess.get() ).getRealFloat() * 255 );
-// } catch ( final ArrayIndexOutOfBoundsException e ) {
-// v = 255; // If image-sizes do not match we pad with white pixels...
-// }
-// if ( v > 255 ) { throw new Exception( "TODO: in this case (source in not within [0,1]) I did not finish the code!!! Now would likely be a good time... ;)" ); }
-// ( ( ARGBType ) targetCursor.get() ).set( ARGBType.rgba( v, v, v, 255 ) );
-// }
-// } else {
-// throwException = true;
- }
-// } else if ( sourceType instanceof ARGBType ) {
-//
-// // ARGBType --> FloatType
-// if ( targetType instanceof ARGBType ) {
-// final Cursor< TT > targetCursor = target.localizingCursor();
-// final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
-// double v;
-// int intRGB;
-// while ( targetCursor.hasNext() ) {
-// targetCursor.fwd();
-// sourceRandomAccess.setPosition( targetCursor );
-// intRGB = ( ( ARGBType ) sourceRandomAccess.get() ).get();
-// v =
-// 0.2989 * ARGBType.red( intRGB ) + 0.5870 * ARGBType.green( intRGB ) + 0.1140 * ARGBType.blue( intRGB );
-// v /= 255;
-// ( ( ARGBType ) targetCursor.get() ).set( ARGBType.rgba( v, v, v, 255 ) );
-// }
-// } else {
-// throwException = true;
-// }
- } else {
- throwException = true;
+ ((ARGBType) out).set(ARGBType.rgba(v, v, v, 255));
+ };
}
- if ( throwException )
- throw new Exception( "Convertion from " + sourceType.getClass().toString() + " to " + targetType.getClass() + " not implemented!" );
+ throw new RuntimeException( "Convertion from " + sourceType.getClass().toString() + " to " + targetType.getClass() + " not implemented!" );
}
-// @SuppressWarnings( "unchecked" )
-// public static < ST extends NativeType< ST >, TT extends NativeType< TT > > void convertAndCopy(
-// final RandomAccessible< ST > source,
-// final IterableInterval< TT > target ) throws Exception {
-// final ST sourceType = source.randomAccess().get();
-// final TT targetType = target.firstElement();
-//
-// // if source and target are of same type -> use copy since convert is not needed...
-// if ( sourceType.getClass().isInstance( targetType ) ) {
-// DataMover.copy( source, ( IterableInterval< ST > ) target );
-// }
-//
-// // implemented conversion cases follow here...
-//
-// boolean throwException = false;
-// if ( sourceType instanceof FloatType ) {
-//
-// // FloatType --> ARGBType
-// if ( targetType instanceof ARGBType ) {
-// final Cursor< TT > targetCursor = target.localizingCursor();
-// final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
-// int v;
-// while ( targetCursor.hasNext() ) {
-// targetCursor.fwd();
-// sourceRandomAccess.setPosition( targetCursor );
-// try {
-// v = Math.round( ( ( FloatType ) sourceRandomAccess.get() ).get() * 255 );
-// } catch ( final ArrayIndexOutOfBoundsException e ) {
-// v = 255; // If image-sizes do not match we pad with white pixels...
-// }
-// if ( v > 255 ) { throw new Exception( "TODO: in this case (source in not within [0,1]) I did not finish the code!!! Now would likely be a good time... ;)" ); }
-// ( ( ARGBType ) targetCursor.get() ).set( ARGBType.rgba( v, v, v, 255 ) );
-// }
-// } else {
-// throwException = true;
-// }
-//
-// } else if ( sourceType instanceof UnsignedShortType ) {
-//
-// // RealType --> FloatType
-// if ( targetType instanceof FloatType ) {
-// final Cursor< TT > targetCursor = target.localizingCursor();
-// final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
-// final int v;
-// while ( targetCursor.hasNext() ) {
-// targetCursor.fwd();
-// sourceRandomAccess.setPosition( targetCursor );
-//
-// ( ( FloatType ) targetCursor.get() ).set( ( ( UnsignedShortType ) sourceRandomAccess.get() ).getRealFloat() );
-// }
-// } else
-// // RealType --> ARGBType
-// if ( targetType instanceof ARGBType ) {
-// final Cursor< TT > targetCursor = target.localizingCursor();
-// final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
-// int v;
-// while ( targetCursor.hasNext() ) {
-// targetCursor.fwd();
-// sourceRandomAccess.setPosition( targetCursor );
-// try {
-// v =
-// Math.round( ( ( UnsignedShortType ) sourceRandomAccess.get() ).getRealFloat() * 255 );
-// } catch ( final ArrayIndexOutOfBoundsException e ) {
-// v = 255; // If image-sizes do not match we pad with white pixels...
-// }
-// if ( v > 255 ) { throw new Exception( "TODO: in this case (source in not within [0,1]) I did not finish the code!!! Now would likely be a good time... ;)" ); }
-// ( ( ARGBType ) targetCursor.get() ).set( ARGBType.rgba( v, v, v, 255 ) );
-// }
-// } else {
-// throwException = true;
-// }
-// } else if ( sourceType instanceof ARGBType ) {
-//
-// // ARGBType --> FloatType
-// if ( targetType instanceof ARGBType ) {
-// final Cursor< TT > targetCursor = target.localizingCursor();
-// final RandomAccess< ST > sourceRandomAccess = source.randomAccess();
-// double v;
-// int intRGB;
-// while ( targetCursor.hasNext() ) {
-// targetCursor.fwd();
-// sourceRandomAccess.setPosition( targetCursor );
-// intRGB = ( ( ARGBType ) sourceRandomAccess.get() ).get();
-// v =
-// 0.2989 * ARGBType.red( intRGB ) + 0.5870 * ARGBType.green( intRGB ) + 0.1140 * ARGBType.blue( intRGB );
-// v /= 255;
-// ( ( ARGBType ) targetCursor.get() ).set( ARGBType.rgba( v, v, v, 255 ) );
-// }
-// } else {
-// throwException = true;
-// }
-// } else {
-// throwException = true;
-// }
-//
-// if ( throwException )
-// throw new Exception( "Convertion between the given NativeTypes not implemented!" );
-// }
public static < T extends RealType< T > & NativeType< T > > Img< T > stackThemAsFrames( final List< Img< T > > imageList )
throws ImgIOException, IncompatibleTypeException, Exception {
@@ -446,4 +224,30 @@ public static < T extends RealType< T > & NativeType< T > > Img< T > stackThemAs
return stack;
}
+
+ // -- Helper classes --
+
+ public static class CopyLoopClass implements CopyLoopInterface {
+ // NB: This class needs to be public for ClassCopyProvider to work
+
+ @Override
+ public < S, T > void copy(
+ RandomAccess< ? extends S > source, Cursor< ? extends T > target,
+ Converter< S, T > converter)
+ {
+ while ( target.hasNext() ) {
+ target.fwd();
+ source.setPosition(target);
+ converter.convert( source.get(), target.get() );
+ }
+ }
+ }
+
+ public interface CopyLoopInterface {
+ // NB: This class needs to be public for ClassCopyProvider to work
+
+ < S, T > void copy(
+ RandomAccess< ? extends S > source, Cursor< ? extends T > target,
+ Converter< S, T > converter);
+ }
}
diff --git a/src/test/java/com/indago/io/DataMoverBenchmark.java b/src/test/java/com/indago/io/DataMoverBenchmark.java
new file mode 100644
index 0000000..f821b34
--- /dev/null
+++ b/src/test/java/com/indago/io/DataMoverBenchmark.java
@@ -0,0 +1,57 @@
+package com.indago.io;
+
+import net.imglib2.img.Img;
+import net.imglib2.img.array.ArrayImgs;
+import net.imglib2.type.numeric.integer.IntType;
+import net.imglib2.type.numeric.integer.UnsignedShortType;
+import net.imglib2.type.numeric.real.DoubleType;
+import net.imglib2.type.numeric.real.FloatType;
+import org.junit.Test;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+import org.openjdk.jmh.runner.options.TimeValue;
+
+@State(Scope.Benchmark)
+public class DataMoverBenchmark {
+
+ private final long[] dimensions = {1000, 1000};
+
+ Img floats = ArrayImgs.floats(dimensions);
+ Img floats2 = ArrayImgs.floats(dimensions);
+ Img doubles = ArrayImgs.doubles(dimensions);
+ Img doubles2 = ArrayImgs.doubles(dimensions);
+ Img shorts = ArrayImgs.unsignedShorts(dimensions);
+ Img shorts2 = ArrayImgs.unsignedShorts(dimensions);
+ Img ints = ArrayImgs.ints(dimensions);
+
+ @Benchmark
+ public void benchmarkConvertAndCopy() throws Exception {
+ DataMover.convertAndCopy(floats, doubles);
+ DataMover.convertAndCopy(shorts, ints);
+ DataMover.convertAndCopy(shorts, floats);
+ }
+
+ @Benchmark
+ public void benchmarkCopy() {
+ DataMover.copy(floats, floats2);
+ DataMover.copy(doubles, doubles2);
+ DataMover.copy(shorts, shorts2);
+ }
+ public static void main( final String... args ) throws RunnerException
+ {
+ final Options opt = new OptionsBuilder()
+ .include( DataMover.class.getSimpleName() )
+ .forks( 0 )
+ .warmupIterations( 20 )
+ .measurementIterations( 20 )
+ .warmupTime( TimeValue.milliseconds( 100 ) )
+ .measurementTime( TimeValue.milliseconds( 100 ) )
+ .build();
+ new Runner( opt ).run();
+ }
+}
diff --git a/src/test/java/com/indago/io/DataMoverTest.java b/src/test/java/com/indago/io/DataMoverTest.java
new file mode 100644
index 0000000..ce51b9e
--- /dev/null
+++ b/src/test/java/com/indago/io/DataMoverTest.java
@@ -0,0 +1,111 @@
+package com.indago.io;
+
+import net.imglib2.IterableInterval;
+import net.imglib2.RandomAccessibleInterval;
+import net.imglib2.img.Img;
+import net.imglib2.img.array.ArrayImgFactory;
+import net.imglib2.img.array.ArrayImgs;
+import net.imglib2.img.list.ListImg;
+import net.imglib2.type.NativeType;
+import net.imglib2.type.numeric.ARGBType;
+import net.imglib2.type.numeric.RealType;
+import net.imglib2.type.numeric.integer.ByteType;
+import net.imglib2.type.numeric.integer.IntType;
+import net.imglib2.type.numeric.integer.UnsignedShortType;
+import net.imglib2.type.numeric.real.DoubleType;
+import net.imglib2.type.numeric.real.FloatType;
+import org.junit.Test;
+
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class DataMoverTest {
+
+ @Test
+ public void testCopy() {
+ Img in = ArrayImgs.ints(new int[]{42}, 1);
+ Img out = ArrayImgs.ints(1);
+ DataMover.copy(in, (RandomAccessibleInterval) out);
+ assertEquals(42, out.firstElement().get());
+ }
+
+ @Test
+ public void testCopyWithConverter() {
+ Img in = ArrayImgs.ints(new int[]{42}, 1);
+ Img out = ArrayImgs.floats(1);
+ DataMover.copy(in, (IterableInterval) out, (i,o) -> o.set(i.get()));
+ assertEquals(42, out.firstElement().get(), 0.0f);
+ }
+
+ @Test
+ public void testAdd() {
+ Img in = ArrayImgs.ints(new int[]{42}, 1);
+ Img out = ArrayImgs.ints(new int[]{4}, 1);
+ DataMover.add(in, (RandomAccessibleInterval) out);
+ assertEquals(46, out.firstElement().get());
+ }
+
+ @Test
+ public void testConvertAndCopyIntTypeToIntType() {
+ testConvertAndCopy(new IntType(42), new IntType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyFloatTypeToDoubleType() {
+ testConvertAndCopy(new FloatType(42), new DoubleType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyIntegerTypeToIntType() {
+ testConvertAndCopy(new ByteType((byte) 42), new IntType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyFloatTypeToIntType() {
+ testConvertAndCopy(new FloatType(42), new IntType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyRealTypeToFloatType() {
+ testConvertAndCopy(new IntType(42), new FloatType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyRealTypeToDoubleType() {
+ testConvertAndCopy(new IntType(42), new DoubleType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyFloatTypeToARGBType() {
+ testConvertAndCopy(new FloatType(0.5f), new ARGBType(ARGBType.rgba(128, 128, 128, 255)));
+ }
+
+ @Test
+ public void testConvertAndCopyUnsignedShortTypeToFloatType() {
+ testConvertAndCopy(new UnsignedShortType(42), new FloatType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyUnsignedShortTypeToIntType() {
+ testConvertAndCopy(new UnsignedShortType(42), new IntType(42));
+ }
+
+ @Test
+ public void testConvertAndCopyUnsignedShortTypeToDoubleType() {
+ testConvertAndCopy(new UnsignedShortType(42), new DoubleType(42));
+ }
+
+ private , T extends NativeType> void testConvertAndCopy(S input, T expected) {
+ Img in = new ListImg<>(Collections.singleton(input), 1);
+ Img out = new ArrayImgFactory<>(expected.createVariable()).create(1);
+ try {
+ DataMover.convertAndCopy(in, out);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ assertTrue(expected.valueEquals(out.randomAccess().get()));
+ }
+}