diff --git a/src/main/java/qupath/ext/imglib2/AccessibleScaler.java b/src/main/java/qupath/ext/imglib2/AccessibleScaler.java index d33280a..db56c40 100644 --- a/src/main/java/qupath/ext/imglib2/AccessibleScaler.java +++ b/src/main/java/qupath/ext/imglib2/AccessibleScaler.java @@ -9,7 +9,6 @@ import net.imglib2.realtransform.RealViews; import net.imglib2.realtransform.Scale2D; import net.imglib2.realtransform.Translation2D; -import net.imglib2.type.NativeType; import net.imglib2.type.numeric.NumericType; import net.imglib2.view.Views; @@ -40,7 +39,7 @@ private AccessibleScaler() { * @throws IllegalArgumentException if the input interval has at least one minimum different from 0, if the provided scale is less * than or equal to 0, or if the input interval has less than two dimensions */ - public static & NumericType> RandomAccessibleInterval scaleWithLinearInterpolation( + public static > RandomAccessibleInterval scaleWithLinearInterpolation( RandomAccessibleInterval input, double scale ) { @@ -59,7 +58,7 @@ public static & NumericType> RandomAccessibleInterva * @throws IllegalArgumentException if the input interval has at least one minimum different from 0, if the provided scale is less * than or equal to 0, or if the input interval has less than two dimensions */ - public static & NumericType> RandomAccessibleInterval scaleWithNearestNeighborInterpolation( + public static RandomAccessibleInterval scaleWithNearestNeighborInterpolation( RandomAccessibleInterval input, double scale ) { @@ -79,7 +78,7 @@ public static & NumericType> RandomAccessibleInterva * @throws IllegalArgumentException if the input interval has at least one minimum different from 0, if the provided scale is less * than or equal to 0, or if the input interval has less than two dimensions */ - public static & NumericType> RandomAccessibleInterval scale( + public static RandomAccessibleInterval scale( RandomAccessibleInterval input, double scale, InterpolatorFactory> interpolatorFactory @@ -104,7 +103,7 @@ public static & NumericType> RandomAccessibleInterva } } - private static & NumericType> RandomAccessibleInterval scaleWithoutChecks( + private static RandomAccessibleInterval scaleWithoutChecks( RandomAccessibleInterval input, double scale, Scale2D scale2D, diff --git a/src/main/java/qupath/ext/imglib2/ImgBuilder.java b/src/main/java/qupath/ext/imglib2/ImgBuilder.java index 17325cc..6b7871f 100644 --- a/src/main/java/qupath/ext/imglib2/ImgBuilder.java +++ b/src/main/java/qupath/ext/imglib2/ImgBuilder.java @@ -8,6 +8,7 @@ import net.imglib2.type.NativeType; import net.imglib2.type.numeric.ARGBType; import net.imglib2.type.numeric.NumericType; +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.ShortType; @@ -17,6 +18,7 @@ import net.imglib2.type.numeric.real.DoubleType; import net.imglib2.type.numeric.real.FloatType; import qupath.ext.imglib2.accesses.ArgbBufferedImageAccess; +import qupath.ext.imglib2.accesses.ByteBufferedImageAccess; import qupath.ext.imglib2.accesses.ByteRasterAccess; import qupath.ext.imglib2.accesses.DoubleRasterAccess; import qupath.ext.imglib2.accesses.FloatRasterAccess; @@ -33,20 +35,20 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.function.Function; import java.util.stream.IntStream; /** * A class to create {@link Img} or {@link RandomAccessibleInterval} from an {@link ImageServer}. *

- * Use a {@link #createBuilder(ImageServer)} or {@link #createBuilder(ImageServer, NativeType)} to create an instance of this class. + * Use {@link #createBuilder(ImageServer)}, {@link #createBuilder(ImageServer, NumericType)}, + * {@link #createRealBuilder(ImageServer)} or {@link #createRealBuilder(ImageServer, RealType)} to create an instance + * of this class. *

* This class is thread-safe. * * @param the type of the returned accessibles - * @param the type contained in the input image */ -public class ImgBuilder & NumericType, A extends SizableDataAccess> { +public class ImgBuilder> { /** * The index of the X axis of accessibles returned by functions of this class @@ -74,19 +76,20 @@ public class ImgBuilder & NumericType, A extends Siza public static final int NUMBER_OF_AXES = 5; private static final CellCache DEFAULT_CELL_CACHE = new CellCache((int) (Runtime.getRuntime().maxMemory() * 0.5 / (1024 * 1024))); private final ImageServer server; - private final Function cellCreator; private final int numberOfChannels; private final T type; private CellCache cellCache = DEFAULT_CELL_CACHE; - private ImgBuilder(ImageServer server, T type, Function cellCreator) { - if (server.nChannels() <= 0) { + private ImgBuilder(ImageServer server, T type, int numberOfChannels) { + Objects.requireNonNull(server, "Server must not be null"); + Objects.requireNonNull(type, "Type must not be null"); + if (numberOfChannels <= 0) { throw new IllegalArgumentException(String.format("The provided image has less than one channel (%d)", server.nChannels())); } + checkType(server, type, numberOfChannels); this.server = server; - this.numberOfChannels = server.isRGB() ? 1 : server.nChannels(); - this.cellCreator = cellCreator; + this.numberOfChannels = numberOfChannels; this.type = type; } @@ -94,67 +97,30 @@ private ImgBuilder(ImageServer server, T type, Function * The type of the output image is not checked, which might lead to problems later when accessing pixel values of the - * returned accessibles of this class. It is recommended to use {@link #createBuilder(ImageServer, NativeType)} instead. + * returned accessibles of this class. It is recommended to use {@link #createBuilder(ImageServer, NumericType)} instead. + *

+ * To query the pixel type that will be used, see {@link #getDefaultType(ImageServer)}. * * @param server the input image * @return a builder to create an instance of this class * @throws IllegalArgumentException if the provided image has less than one channel */ - public static ImgBuilder createBuilder(ImageServer server) { - if (server.isRGB()) { - return new ImgBuilder<>(server, new ARGBType(), ArgbBufferedImageAccess::new); - } else { - return switch (server.getPixelType()) { - case UINT8 -> new ImgBuilder<>( - server, - new UnsignedByteType(), - image -> new ByteRasterAccess(image.getRaster()) - ); - case INT8 -> new ImgBuilder<>( - server, - new ByteType(), - image -> new ByteRasterAccess(image.getRaster()) - ); - case UINT16 -> new ImgBuilder<>( - server, - new UnsignedShortType(), - image -> new ShortRasterAccess(image.getRaster()) - ); - case INT16 -> new ImgBuilder<>( - server, - new ShortType(), - image -> new ShortRasterAccess(image.getRaster()) - ); - case UINT32 -> new ImgBuilder<>( - server, - new UnsignedIntType(), - image -> new IntRasterAccess(image.getRaster()) - ); - case INT32 -> new ImgBuilder<>( - server, - new IntType(), - image -> new IntRasterAccess(image.getRaster()) - ); - case FLOAT32 -> new ImgBuilder<>( - server, - new FloatType(), - image -> new FloatRasterAccess(image.getRaster()) - ); - case FLOAT64 -> new ImgBuilder<>( - server, - new DoubleType(), - image -> new DoubleRasterAccess(image.getRaster()) - ); - }; - } + public static > ImgBuilder> createBuilder(ImageServer server) { + T type = getDefaultTypeUnsafe(server); + return createBuilder(server, type); } + /** * Create a builder from an {@link ImageServer}. This doesn't create any accessibles yet. *

* The provided type must be compatible with the input image: *