From a967f9744ec284742e9e4840b376b2782794593c Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 5 Sep 2024 11:27:10 +0200 Subject: [PATCH 01/10] Avoid creating additional arrays in Intervals methods --- src/main/java/net/imglib2/util/Intervals.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/imglib2/util/Intervals.java b/src/main/java/net/imglib2/util/Intervals.java index 99af561ee..a3ac9626e 100644 --- a/src/main/java/net/imglib2/util/Intervals.java +++ b/src/main/java/net/imglib2/util/Intervals.java @@ -154,7 +154,7 @@ public static FinalInterval expand( final Interval interval, final long border ) min[ d ] -= border; max[ d ] += border; } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -198,7 +198,7 @@ public static FinalInterval expand( final Interval interval, final Dimensions bo min[ d ] -= border.dimension( d ); max[ d ] += border.dimension( d ); } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -224,7 +224,7 @@ public static FinalInterval expand( final Interval interval, final long border, interval.max( max ); min[ d ] -= border; max[ d ] += border; - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -250,7 +250,7 @@ public static FinalInterval translate( final Interval interval, final long t, fi interval.max( max ); min[ d ] += t; max[ d ] += t; - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -277,7 +277,7 @@ public static FinalInterval translate( final Interval interval, final long... tr min[ d ] += translation[ d ]; max[ d ] += translation[ d ]; } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -304,7 +304,7 @@ public static FinalInterval translateInverse( final Interval interval, final lon min[ d ] -= translation[ d ]; max[ d ] -= translation[ d ]; } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -333,7 +333,7 @@ public static FinalInterval addDimension( final Interval interval, final long mi } min[ m ] = minOfNewDim; max[ m ] = maxOfNewDim; - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -354,7 +354,7 @@ public static FinalInterval invertAxis( final Interval interval, final int d ) final long tmp = min[ d ]; min[ d ] = -max[ d ]; max[ d ] = -tmp; - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -380,7 +380,7 @@ else if ( e > d ) max[ e - 1 ] = interval.max( e ); } } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -404,7 +404,7 @@ public static FinalInterval moveAxis( final Interval interval, final int fromAxi min[ newAxisIndices[ d ] ] = interval.min( d ); max[ newAxisIndices[ d ] ] = interval.max( d ); } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -427,7 +427,7 @@ public static FinalInterval permuteAxes( final Interval interval, final int from max[ toAxis ] = max[ fromAxis ]; min[ fromAxis ] = fromMinNew; max[ fromAxis ] = fromMaxNew; - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -458,7 +458,7 @@ public static FinalInterval rotate( final Interval interval, final int fromAxis, min[ fromAxis ] = fromMinNew; max[ fromAxis ] = fromMaxNew; } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -510,7 +510,7 @@ public static FinalInterval intersect( final Interval intervalA, final Interval min[ d ] = Math.max( intervalA.min( d ), intervalB.min( d ) ); max[ d ] = Math.min( intervalA.max( d ), intervalB.max( d ) ); } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -566,7 +566,7 @@ public static FinalInterval unionUnsafe( final Interval intervalA, final Interva min[ d ] = Math.min( intervalA.min( d ), intervalB.min( d ) ); max[ d ] = Math.max( intervalA.max( d ), intervalB.max( d ) ); } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -663,7 +663,7 @@ public static Interval smallestContainingInterval( final RealInterval ri ) min[ d ] = ( long ) Math.floor( ri.realMin( d ) ); max[ d ] = ( long ) Math.ceil( ri.realMax( d ) ); } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** @@ -685,7 +685,7 @@ public static Interval largestContainedInterval( final RealInterval ri ) min[ d ] = ( long ) Math.ceil( ri.realMin( d ) ); max[ d ] = ( long ) Math.floor( ri.realMax( d ) ); } - return new FinalInterval( min, max ); + return FinalInterval.wrap( min, max ); } /** From 85d263f609c822ddb695b05431b13ecbe70987da Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 9 Aug 2024 17:00:07 +0200 Subject: [PATCH 02/10] Make generics match reality better --- src/main/java/net/imglib2/img/array/ArrayImgFactory.java | 5 +++-- .../imglib2/img/basictypeaccess/ArrayDataAccessFactory.java | 4 ++-- src/main/java/net/imglib2/img/cell/CellImgFactory.java | 2 +- src/main/java/net/imglib2/img/planar/PlanarImgFactory.java | 5 +++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/imglib2/img/array/ArrayImgFactory.java b/src/main/java/net/imglib2/img/array/ArrayImgFactory.java index 51ad7eb84..d930bb93d 100644 --- a/src/main/java/net/imglib2/img/array/ArrayImgFactory.java +++ b/src/main/java/net/imglib2/img/array/ArrayImgFactory.java @@ -85,12 +85,13 @@ public ArrayImgFactory( final T type ) private < A extends ArrayDataAccess< A > > ArrayImg< T, A > create( final long[] dimensions, final T type, - final NativeTypeFactory< T, A > typeFactory ) + final NativeTypeFactory< T, ? super A > typeFactory ) { Dimensions.verify( dimensions ); final Fraction entitiesPerPixel = type.getEntitiesPerPixel(); final int numEntities = numEntitiesRangeCheck( dimensions, entitiesPerPixel ); - final A data = ArrayDataAccessFactory.get( typeFactory ).createArray( numEntities ); + final A access = ArrayDataAccessFactory.get( typeFactory ); + final A data = access.createArray( numEntities ); final ArrayImg< T, A > img = new ArrayImg<>( data, dimensions, entitiesPerPixel ); img.setLinkedType( typeFactory.createLinkedType( img ) ); return img; diff --git a/src/main/java/net/imglib2/img/basictypeaccess/ArrayDataAccessFactory.java b/src/main/java/net/imglib2/img/basictypeaccess/ArrayDataAccessFactory.java index e5ea07c71..ef759a3e3 100644 --- a/src/main/java/net/imglib2/img/basictypeaccess/ArrayDataAccessFactory.java +++ b/src/main/java/net/imglib2/img/basictypeaccess/ArrayDataAccessFactory.java @@ -98,13 +98,13 @@ public static < T extends NativeType< T >, A extends ArrayDataAccess< A > > A ge } public static < A extends ArrayDataAccess< A > > A get( - final NativeTypeFactory< ?, ? super A > typeFactory ) + final NativeTypeFactory< ?, ? > typeFactory ) { return get( typeFactory.getPrimitiveType(), AccessFlags.setOf() ); } public static < A extends ArrayDataAccess< A > > A get( - final NativeTypeFactory< ?, ? super A > typeFactory, + final NativeTypeFactory< ?, ? > typeFactory, final Set< AccessFlags > flags ) { return get( typeFactory.getPrimitiveType(), flags ); diff --git a/src/main/java/net/imglib2/img/cell/CellImgFactory.java b/src/main/java/net/imglib2/img/cell/CellImgFactory.java index 91ec35ea3..7cf06035d 100644 --- a/src/main/java/net/imglib2/img/cell/CellImgFactory.java +++ b/src/main/java/net/imglib2/img/cell/CellImgFactory.java @@ -115,7 +115,7 @@ public static int[] getCellDimensions( final int[] defaultCellDimensions, final private < A extends ArrayDataAccess< A > > CellImg< T, A > create( final long[] dimensions, final T type, - final NativeTypeFactory< T, A > typeFactory ) + final NativeTypeFactory< T, ? super A > typeFactory ) { Dimensions.verify( dimensions ); diff --git a/src/main/java/net/imglib2/img/planar/PlanarImgFactory.java b/src/main/java/net/imglib2/img/planar/PlanarImgFactory.java index 7c86b76ba..b44464c3d 100644 --- a/src/main/java/net/imglib2/img/planar/PlanarImgFactory.java +++ b/src/main/java/net/imglib2/img/planar/PlanarImgFactory.java @@ -86,11 +86,12 @@ public PlanarImgFactory( final T type ) private < A extends ArrayDataAccess< A > > PlanarImg< T, ? > create( final long[] dimensions, final T type, - final NativeTypeFactory< T, A > typeFactory ) + final NativeTypeFactory< T, ? super A > typeFactory ) { Dimensions.verify( dimensions ); final Fraction entitiesPerPixel = type.getEntitiesPerPixel(); - final PlanarImg< T, A > img = new PlanarImg<>( ArrayDataAccessFactory.get( typeFactory ), dimensions, entitiesPerPixel ); + final A access = ArrayDataAccessFactory.get( typeFactory ); + final PlanarImg< T, A > img = new PlanarImg<>( access, dimensions, entitiesPerPixel ); img.setLinkedType( typeFactory.createLinkedType( img ) ); return img; } From 85ecb6f647bc75b8a323c0874073f9badfae4a6c Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 27 Jun 2024 10:49:54 +0200 Subject: [PATCH 03/10] Add IntervalIndexer.createAllocationSteps variants that allocate the steps array --- src/main/java/net/imglib2/util/IntervalIndexer.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/net/imglib2/util/IntervalIndexer.java b/src/main/java/net/imglib2/util/IntervalIndexer.java index e2966c5cb..84778fc81 100644 --- a/src/main/java/net/imglib2/util/IntervalIndexer.java +++ b/src/main/java/net/imglib2/util/IntervalIndexer.java @@ -401,4 +401,17 @@ public static void createAllocationSteps( final int[] dimensions, final int[] st steps[ d ] = steps[ d - 1 ] * dimensions[ d - 1 ]; } + public static long[] createAllocationSteps( final long[] dimensions ) + { + final long[] steps = new long[ dimensions.length ]; + createAllocationSteps( dimensions, steps ); + return steps; + } + + public static int[] createAllocationSteps( final int[] dimensions ) + { + final int[] steps = new int[ dimensions.length ]; + createAllocationSteps( dimensions, steps ); + return steps; + } } From 2982afd56a27f2cc24537a4e795a845d8d91e8bd Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Tue, 23 Jul 2024 21:40:32 +0200 Subject: [PATCH 04/10] Add double[] and boolean[] versions of Util.expandArray --- src/main/java/net/imglib2/util/Util.java | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/main/java/net/imglib2/util/Util.java b/src/main/java/net/imglib2/util/Util.java index 336952175..d647a1940 100644 --- a/src/main/java/net/imglib2/util/Util.java +++ b/src/main/java/net/imglib2/util/Util.java @@ -129,6 +129,32 @@ public static long[] getArrayFromValue( final long value, final int numDimension return values; } + /** + * Expand or truncate the provided array of {@code values} to length {@code + * newLength}. + *

+ * If {@code values.length < newLength} then the last value is repeated. + * That is, the remaining elements are filled with {@code + * values[values.length - 1]}. + *

+ * If {@code values.length == newLength} then {@code values} is returned, + * otherwise a new array is created. + * + * @param values + * values to copy + * @param newLength + * length of expanded array + * + * @return an array where {@code array.length == newLength} and {@code array[i] == values[Math.max(i, values.length)]} + */ + public static double[] expandArray( final double[] values, final int newLength ) + { + final double[] expandedValues = ( values.length == newLength ) ? values : Arrays.copyOf( values, newLength ); + if ( values.length < newLength ) + Arrays.fill( expandedValues, values.length, newLength, values[ values.length - 1 ] ); + return expandedValues; + } + /** * Expand or truncate the provided array of {@code values} to length {@code * newLength}. @@ -181,6 +207,32 @@ public static int[] expandArray( final int[] values, final int newLength ) return expandedValues; } + /** + * Expand or truncate the provided array of {@code values} to length {@code + * newLength}. + *

+ * If {@code values.length < newLength} then the last value is repeated. + * That is, the remaining elements are filled with {@code + * values[values.length - 1]}. + *

+ * If {@code values.length == newLength} then {@code values} is returned, + * otherwise a new array is created. + * + * @param values + * values to copy + * @param newLength + * length of expanded array + * + * @return an array where {@code array.length == newLength} and {@code array[i] == values[Math.max(i, values.length)]} + */ + public static boolean[] expandArray( final boolean[] values, final int newLength ) + { + final boolean[] expandedValues = ( values.length == newLength ) ? values : Arrays.copyOf( values, newLength ); + if ( values.length < newLength ) + Arrays.fill( expandedValues, values.length, newLength, values[ values.length - 1 ] ); + return expandedValues; + } + public static double distance( final RealLocalizable position1, final RealLocalizable position2 ) { double dist = 0; From 02912654bb582a79b8ccf1a1144467c3ab8f66fb Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 11 Jan 2024 18:22:42 +0100 Subject: [PATCH 05/10] MemCopy: Buffer support, generate from template, add "subarray-copy" * Add generic parameter S to MemCopy S is source, e.g., float[] or FloatBuffer T is target, e.g., float[] or FloatBuffer * Generate MemCopy.java from velocity template (run bin/generate.groovy to generate) * new method copyNDRangeRecursive() copies sub-region between flattened arrays (of different sizes) --- bin/generate.groovy | 238 ++ .../imglib2/blocks/ArrayImgRangeCopier.java | 24 +- .../imglib2/blocks/CellImgRangeCopier.java | 22 +- src/main/java/net/imglib2/blocks/MemCopy.java | 2127 ++++++++++++++++- .../imglib2/blocks/PlanarImgRangeCopier.java | 26 +- .../java/net/imglib2/blocks/RangeCopier.java | 12 +- .../main/java/net/imglib2/blocks/MemCopy.list | 2 + .../main/java/net/imglib2/blocks/MemCopy.vm | 533 +++++ 8 files changed, 2871 insertions(+), 113 deletions(-) create mode 100755 bin/generate.groovy create mode 100644 templates/main/java/net/imglib2/blocks/MemCopy.list create mode 100644 templates/main/java/net/imglib2/blocks/MemCopy.vm diff --git a/bin/generate.groovy b/bin/generate.groovy new file mode 100755 index 000000000..3e26050d9 --- /dev/null +++ b/bin/generate.groovy @@ -0,0 +1,238 @@ +#!/usr/bin/env groovy + +/* + * #%L + * SciJava Operations: a framework for reusable algorithms. + * %% + * Copyright (C) 2018 SciJava developers. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +debug = System.getenv('DEBUG') +def debug(msg) { + if (debug) System.err.println("[DEBUG] $msg") +} + +@Grab('org.apache.velocity:velocity:1.7') +import org.apache.velocity.app.VelocityEngine + +// TODO: Get path to Groovy script and make these dirs relative to that. +templateDirectory = 'templates' +outputDirectory = 'src' + +knownFiles = new java.util.HashSet(); + +/* Gets the last modified timestamp for the given file. */ +def timestamp(dir, file) { + if (file == null) return Long.MAX_VALUE; + file = new java.io.File(dir, file); + knownFiles.add(file); + return file.lastModified(); +} + +/* Processes a template using Apache Velocity. */ +def processTemplate(engine, context, templateFile, outFilename) { + debug("processTemplate('$engine', '$context', '$templateFile', '$outFilename')") + + if (outFilename == null) return; // nothing to do + + // create output directory if it does not already exist + outFile = new java.io.File(outputDirectory, outFilename); + knownFiles.add(outFile); + if (outFile.getParentFile() != null) outFile.getParentFile().mkdirs(); + + // apply the template and write out the result + t = engine.getTemplate(templateFile); + writer = new StringWriter(); + t.merge(context, writer); + out = new PrintWriter(outFile, "UTF-8"); + out.print(writer.toString()); + out.close(); +} + +/* Evaluates a string using Groovy. */ +def parseValue(sh, translationsFile, key, expression) { + try { + result = sh.evaluate(expression) + sh.setVariable(key, result) + return result + } + catch (groovy.lang.GroovyRuntimeException e) { + print("[WARNING] $translationsFile: " + + "key '$key' has unparseable value: " + e.getMessage()); + } +} + +/* Reads a translations File */ +def readTranslation(engine, globalContext, reader, templateSubdirectory, templateFile, translationsFile, isInclude){ + sh = new groovy.lang.GroovyShell(); + for (;;) { + // read the line + line = reader.readLine(); + + if (line == null) break; + // check if the line starts a new section + if (line.startsWith("[") && line.endsWith("]")) { + // if we are parsing a .include file, return when we hit any sections + if(isInclude){ + println("[WARNING] $translationsFile: Section definition in .include file. Ending processing of $translationsFile"); + return context; + } + // write out the previous file + processTemplate(engine, context, templateFile, outputFilename); + + // start a new file + outputFilename = line.substring(1, line.length() - 1); + if (!templateDirectory.equals(templateSubdirectory)) { + subPath = templateSubdirectory.substring(templateDirectory.length() + 1); + outputFilename = "$subPath/$outputFilename"; + } + context = new org.apache.velocity.VelocityContext(globalContext); + continue; + } + + // ignore blank lines + trimmedLine = line.trim(); + if (trimmedLine.isEmpty()) continue; + + // ignore comments + if (trimmedLine.startsWith("#")) continue; + + // include any global files + if (trimmedLine.startsWith(".include")){ + includeFile = line.substring(9); + if(includeFile.startsWith("templates")){ + includeSubdirectory = includeFile.substring(0, includeFile.lastIndexOf("/")) + includeFile = includeFile.substring(includeFile.lastIndexOf("/")) + } + else{ + includeSubdirectory = templateSubdirectory + } + globalReader = new java.io.BufferedReader(new java.io.FileReader("$includeSubdirectory/$includeFile")); + encapsulatedContext = new org.apache.velocity.VelocityContext(context) + context = readTranslation(engine, encapsulatedContext, globalReader, templateSubdirectory, templateFile, includeFile, true) + continue; + } + + if (!line.contains('=')) { + print("[WARNING] $translationsFile: Ignoring spurious line: $line"); + continue; + } + + int idx = line.indexOf('='); + key = line.substring(0, idx).trim(); + value = line.substring(idx + 1); + + if (value.trim().equals('```')) { + // multi-line value + builder = new StringBuilder(); + for (;;) { + line = reader.readLine(); + if (line == null) { + throw new RuntimeException("Unfinished value: " + builder.toString()); + } + if (line.equals('```')) { + break; + } + if (builder.length() > 0) { + builder.append("\n"); + } + builder.append(line); + } + value = builder.toString(); + } + + context.put(key, parseValue(sh, translationsFile, key, value)); + } + + return context; +} + +/* + * Translates a template into many files in the outputDirectory, + * given a translations file in INI style; e.g.: + * + * [filename1] + * variable1 = value1 + * variable2 = value2 + * ... + * [filename2] + * variable1 = value3 + * variable2 = value4 + * ... + */ +def translate(templateSubdirectory, templateFile, translationsFile) { + debug("translate('$templateSubdirectory', '$templateFile', '$translationsFile')") + + // initialize the Velocity engine + engine = new org.apache.velocity.app.VelocityEngine(); + p = new java.util.Properties(); + // fail if template uses an invalid expression; e.g., an undefined variable + p.setProperty("runtime.references.strict", "true"); + // tell Velocity where the templates are located + p.setProperty("file.resource.loader.path", "$templateSubdirectory"); + // tell Velocity to log to stderr rather than to a velocity.log file + p.setProperty(org.apache.velocity.runtime.RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, + "org.apache.velocity.runtime.log.SystemLogChute"); + engine.init(p); + + // read translation lines + outputFilename = null; + context = globalContext = new org.apache.velocity.VelocityContext(); + reader = new java.io.BufferedReader(new java.io.FileReader("$templateSubdirectory/$translationsFile")); + + readTranslation(engine, context, reader, templateSubdirectory, templateFile, translationsFile, false); + + reader.close(); + + // process the template + processTemplate(engine, context, templateFile, outputFilename); +} + +/* Recursively translates all templates in the given directory. */ +def translateDirectory(templateSubdirectory) { + debug("translateDirectory('$templateSubdirectory')") + + for (file in new java.io.File(templateSubdirectory).listFiles()) { + if (file.isDirectory()) { + // process subdirectories recursively + translateDirectory(file.getPath()); + } + else { + // process Velocity template files only + name = file.getName(); + if (!name.endsWith('.vm')) continue; + prefix = name.substring(0, name.lastIndexOf('.')); + translate(templateSubdirectory, name, prefix + '.list'); + } + } +} + +try { + translateDirectory(templateDirectory); +} +catch (Throwable t) { + t.printStackTrace(System.err); + throw t; +} diff --git a/src/main/java/net/imglib2/blocks/ArrayImgRangeCopier.java b/src/main/java/net/imglib2/blocks/ArrayImgRangeCopier.java index 671a4d8fa..84e4a407a 100644 --- a/src/main/java/net/imglib2/blocks/ArrayImgRangeCopier.java +++ b/src/main/java/net/imglib2/blocks/ArrayImgRangeCopier.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -44,13 +44,13 @@ * * @param a primitive array type, e.g., {@code byte[]}. */ -class ArrayImgRangeCopier< T > implements RangeCopier< T > +class ArrayImgRangeCopier< S, T > implements RangeCopier< T > { private final int n; private final int[] srcDims; private final Ranges findRanges; - private final MemCopy< T > memCopy; - private final T oob; + private final MemCopy< S, T > memCopy; + private final S oob; private final List< Ranges.Range >[] rangesPerDimension; private final Ranges.Range[] ranges; @@ -60,13 +60,13 @@ class ArrayImgRangeCopier< T > implements RangeCopier< T > private final int[] csteps; private final int[] lengths; - private final T src; + private final S src; public ArrayImgRangeCopier( final ArrayImg< ?, ? > arrayImg, final Ranges findRanges, - final MemCopy< T > memCopy, - final T oob ) + final MemCopy< S, T > memCopy, + final S oob ) { n = arrayImg.numDimensions(); @@ -86,11 +86,11 @@ public ArrayImgRangeCopier( csteps = new int[ n ]; lengths = new int[ n ]; - src = ( T ) ( ( ( ArrayDataAccess< ? > ) arrayImg.update( null ) ).getCurrentStorageArray() ); + src = ( S ) ( ( ArrayDataAccess< ? > ) arrayImg.update( null ) ).getCurrentStorageArray(); } // creates an independent copy of {@code other} - private ArrayImgRangeCopier( ArrayImgRangeCopier< T > copier ) + private ArrayImgRangeCopier( ArrayImgRangeCopier< S, T > copier ) { n = copier.n; srcDims = copier.srcDims.clone(); @@ -108,7 +108,7 @@ private ArrayImgRangeCopier( ArrayImgRangeCopier< T > copier ) } @Override - public ArrayImgRangeCopier< T > newInstance() + public ArrayImgRangeCopier< S, T > newInstance() { return new ArrayImgRangeCopier<>( this ); } @@ -220,7 +220,7 @@ private void copyRanges( final T dest ) } } - private void copyRangesRecursively( final T src, final int srcPos, final T dest, final int destPos, final int d ) + private void copyRangesRecursively( final S src, final int srcPos, final T dest, final int destPos, final int d ) { final int length = lengths[ d ]; final int cstep = csteps[ d ]; diff --git a/src/main/java/net/imglib2/blocks/CellImgRangeCopier.java b/src/main/java/net/imglib2/blocks/CellImgRangeCopier.java index 8956ad62b..12da510a8 100644 --- a/src/main/java/net/imglib2/blocks/CellImgRangeCopier.java +++ b/src/main/java/net/imglib2/blocks/CellImgRangeCopier.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -48,15 +48,15 @@ * * @param a primitive array type, e.g., {@code byte[]}. */ -class CellImgRangeCopier< T > implements RangeCopier< T > +class CellImgRangeCopier< S, T > implements RangeCopier< T > { private final int n; private final CellGrid cellGrid; private final RandomAccess< ? extends Cell< ? > > cellAccess; private final long[] srcDims; private final Ranges findRanges; - private final MemCopy< T > memCopy; - private final T oob; + private final MemCopy< S, T > memCopy; + private final S oob; private final List< Ranges.Range >[] rangesPerDimension; private final Ranges.Range[] ranges; @@ -70,8 +70,8 @@ class CellImgRangeCopier< T > implements RangeCopier< T > public CellImgRangeCopier( final AbstractCellImg< ?, ?, ?, ? > cellImg, final Ranges findRanges, - final MemCopy< T > memCopy, - final T oob ) + final MemCopy< S, T > memCopy, + final S oob ) { n = cellImg.numDimensions(); cellGrid = cellImg.getCellGrid(); @@ -93,7 +93,7 @@ public CellImgRangeCopier( } // creates an independent copy of {@code other} - private CellImgRangeCopier( CellImgRangeCopier< T > copier ) + private CellImgRangeCopier( CellImgRangeCopier< S, T > copier ) { n = copier.n; cellGrid = copier.cellGrid; @@ -113,7 +113,7 @@ private CellImgRangeCopier( CellImgRangeCopier< T > copier ) } @Override - public CellImgRangeCopier< T > newInstance() + public CellImgRangeCopier< S, T > newInstance() { return new CellImgRangeCopier<>( this ); } @@ -218,7 +218,7 @@ private void copyRanges( final T dest ) final int dOffset = doffsets[ 0 ]; - final T src = ( T ) ( ( ( ArrayDataAccess< ? > ) cellAccess.get().getData() ).getCurrentStorageArray() ); + final S src = ( S ) ( ( ArrayDataAccess< ? > ) cellAccess.get().getData() ).getCurrentStorageArray(); if ( n > 1 ) copyRangesRecursively( src, sOffset, dest, dOffset, n - 1 ); else @@ -229,7 +229,7 @@ private void copyRanges( final T dest ) } } - private void copyRangesRecursively( final T src, final int srcPos, final T dest, final int destPos, final int d ) + private void copyRangesRecursively( final S src, final int srcPos, final T dest, final int destPos, final int d ) { final int length = lengths[ d ]; final int cstep = csteps[ d ]; diff --git a/src/main/java/net/imglib2/blocks/MemCopy.java b/src/main/java/net/imglib2/blocks/MemCopy.java index 4b8a5a217..563bf383d 100644 --- a/src/main/java/net/imglib2/blocks/MemCopy.java +++ b/src/main/java/net/imglib2/blocks/MemCopy.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -33,14 +33,43 @@ */ package net.imglib2.blocks; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; import java.util.Arrays; + import net.imglib2.type.PrimitiveType; +/* + * This is autogenerated source code -- DO NOT EDIT. Instead, edit the + * corresponding template in templates/ and rerun bin/generate.groovy. + */ + // TODO javadoc // low-level copying methods // implementations for all primitive types // T is a primitive array type -interface MemCopy< T > + +/** + * Low-level range copying methods between source {@code S} and target {@code T} + * which can be either primitive array types (e.g., {@code double[]}) or the + * corresponding {@code Buffer} (e.g., {@code DoubleBuffer}). + *

+ * All combinations are implemented (e.g., {@code byte[]}-to-{@code byte[]}, + * {@code byte[]}-to-{@code ByteBuffer}, {@code ByteBuffer}-to-{@code byte[]}, + * and {@code ByteBuffer}-to-{@code ByteBuffer}). + * + * @param + * the source type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer}) + * @param + * the target type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer}) + */ +interface MemCopy< S, T > { /** * Copy {@code length} components from the {@code src} array to the {@code @@ -49,7 +78,7 @@ interface MemCopy< T > * destPos} through {@code destPos+length-1}, respectively, of the * destination array. */ - void copyForward( T src, int srcPos, T dest, int destPos, int length ); + void copyForward( S src, int srcPos, T dest, int destPos, int length ); /** * Copy {@code length} components from the {@code src} array to the {@code @@ -58,19 +87,24 @@ interface MemCopy< T > * positions {@code destPos} through {@code destPos+length-1}, respectively, * of the destination array. */ - void copyReverse( T src, int srcPos, T dest, int destPos, int length ); + void copyReverse( S src, int srcPos, T dest, int destPos, int length ); /** * Copy component at position {@code srcPos} in the {@code src} array * ({@code length} times) into positions {@code destPos} through {@code * destPos+length-1} of the destination array. */ - void copyValue( T src, int srcPos, T dest, int destPos, int length ); + void copyValue( S src, int srcPos, T dest, int destPos, int length ); /** - * TODO javadoc + * Copy {@code length} components from the {@code src} array to the {@code + * dest} array. The components at positions {@code srcPos} through {@code + * srcPos+length-1} in the source array are copied into positions {@code + * destPos}, {@code destPos+destStride}, {@code destPos + 2*destStride}, + * etc., through {@code destPos+(length-1)*destStride} of the destination + * array. */ - void copyStrided( T src, int srcPos, T dest, int destPos, int destStride, int length ); + void copyStrided( S src, int srcPos, T dest, int destPos, int destStride, int length ); /** * Copy {@code numLines} stretches of {@code lineLength} elements. @@ -93,7 +127,7 @@ default void copyLines( final int lineDir, final int lineLength, final int numLines, - final T src, + final S src, final int srcPos, final int srcStep, final T dest, @@ -111,6 +145,63 @@ else if ( lineDir == -1 ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + /** + * Recursively copy a {@code (d+1)} dimensional region from {@code src} to + * {@code dest}, where {@code src} and {@code dest} are flattened nD array + * with strides {@code srcStrides} and {@code destStrides}, respectively. + *

+ * 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 + */ + // Note that this default implementation is overridden in each + // implementation (with identical code) to soften the performance hit from + // polymorphism. The default implementation is left here, to make additional + // implementations easier. + default void copyNDRangeRecursive( + final int d, + final S src, + final int[] srcStrides, + final int srcPos, + final T dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } MemCopyBoolean BOOLEAN = new MemCopyBoolean(); MemCopyByte BYTE = new MemCopyByte(); @@ -121,33 +212,124 @@ else if ( lineDir == -1 ) MemCopyFloat FLOAT = new MemCopyFloat(); MemCopyDouble DOUBLE = new MemCopyDouble(); - static MemCopy< ? > forPrimitiveType( final PrimitiveType primitiveType ) + MemCopyByteBufferToArray BUFFER_TO_ARRAY_BYTE = new MemCopyByteBufferToArray(); + MemCopyCharBufferToArray BUFFER_TO_ARRAY_CHAR = new MemCopyCharBufferToArray(); + MemCopyShortBufferToArray BUFFER_TO_ARRAY_SHORT = new MemCopyShortBufferToArray(); + MemCopyIntBufferToArray BUFFER_TO_ARRAY_INT = new MemCopyIntBufferToArray(); + MemCopyLongBufferToArray BUFFER_TO_ARRAY_LONG = new MemCopyLongBufferToArray(); + MemCopyFloatBufferToArray BUFFER_TO_ARRAY_FLOAT = new MemCopyFloatBufferToArray(); + MemCopyDoubleBufferToArray BUFFER_TO_ARRAY_DOUBLE = new MemCopyDoubleBufferToArray(); + + MemCopyByteArrayToBuffer ARRAY_TO_BUFFER_BYTE = new MemCopyByteArrayToBuffer(); + MemCopyCharArrayToBuffer ARRAY_TO_BUFFER_CHAR = new MemCopyCharArrayToBuffer(); + MemCopyShortArrayToBuffer ARRAY_TO_BUFFER_SHORT = new MemCopyShortArrayToBuffer(); + MemCopyIntArrayToBuffer ARRAY_TO_BUFFER_INT = new MemCopyIntArrayToBuffer(); + MemCopyLongArrayToBuffer ARRAY_TO_BUFFER_LONG = new MemCopyLongArrayToBuffer(); + MemCopyFloatArrayToBuffer ARRAY_TO_BUFFER_FLOAT = new MemCopyFloatArrayToBuffer(); + MemCopyDoubleArrayToBuffer ARRAY_TO_BUFFER_DOUBLE = new MemCopyDoubleArrayToBuffer(); + + MemCopyByteBufferToBuffer BUFFER_TO_BUFFER_BYTE = new MemCopyByteBufferToBuffer(); + MemCopyCharBufferToBuffer BUFFER_TO_BUFFER_CHAR = new MemCopyCharBufferToBuffer(); + MemCopyShortBufferToBuffer BUFFER_TO_BUFFER_SHORT = new MemCopyShortBufferToBuffer(); + MemCopyIntBufferToBuffer BUFFER_TO_BUFFER_INT = new MemCopyIntBufferToBuffer(); + MemCopyLongBufferToBuffer BUFFER_TO_BUFFER_LONG = new MemCopyLongBufferToBuffer(); + MemCopyFloatBufferToBuffer BUFFER_TO_BUFFER_FLOAT = new MemCopyFloatBufferToBuffer(); + MemCopyDoubleBufferToBuffer BUFFER_TO_BUFFER_DOUBLE = new MemCopyDoubleBufferToBuffer(); + + static MemCopy< ?, ? > forPrimitiveType( final PrimitiveType primitiveType ) + { + return forPrimitiveType( primitiveType, false, false ); + } + + static MemCopy< ?, ? > forPrimitiveType( final PrimitiveType primitiveType, final boolean fromBuffer, final boolean toBuffer ) { switch ( primitiveType ) { case BOOLEAN: - return BOOLEAN; + if ( fromBuffer || toBuffer ) + throw new IllegalArgumentException( "No BufferAccess implementation for PrimitiveType.BOOLEAN" ); + else + return BOOLEAN; case BYTE: - return BYTE; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_BYTE : BUFFER_TO_ARRAY_BYTE ) + : ( toBuffer ? ARRAY_TO_BUFFER_BYTE : BYTE ); case CHAR: - return CHAR; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_CHAR : BUFFER_TO_ARRAY_CHAR ) + : ( toBuffer ? ARRAY_TO_BUFFER_CHAR : CHAR ); case SHORT: - return SHORT; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_SHORT : BUFFER_TO_ARRAY_SHORT ) + : ( toBuffer ? ARRAY_TO_BUFFER_SHORT : SHORT ); case INT: - return INT; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_INT : BUFFER_TO_ARRAY_INT ) + : ( toBuffer ? ARRAY_TO_BUFFER_INT : INT ); case LONG: - return LONG; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_LONG : BUFFER_TO_ARRAY_LONG ) + : ( toBuffer ? ARRAY_TO_BUFFER_LONG : LONG ); case FLOAT: - return FLOAT; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_FLOAT : BUFFER_TO_ARRAY_FLOAT ) + : ( toBuffer ? ARRAY_TO_BUFFER_FLOAT : FLOAT ); case DOUBLE: - return DOUBLE; + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_DOUBLE : BUFFER_TO_ARRAY_DOUBLE ) + : ( toBuffer ? ARRAY_TO_BUFFER_DOUBLE : DOUBLE ); default: case UNDEFINED: throw new IllegalArgumentException(); } } - class MemCopyBoolean implements MemCopy< boolean[] > + + // TODO: Remove? + static PrimitiveType primitiveTypeForClass( final Class< ? > clz ) + { + if ( clz.equals( boolean[].class ) ) + return PrimitiveType.BOOLEAN; + else if ( clz.equals( byte[].class ) || clz.equals( ByteBuffer.class ) ) + return PrimitiveType.BYTE; + else if ( clz.equals( char[].class ) || clz.equals( CharBuffer.class ) ) + return PrimitiveType.CHAR; + else if ( clz.equals( short[].class ) || clz.equals( ShortBuffer.class ) ) + return PrimitiveType.SHORT; + else if ( clz.equals( int[].class ) || clz.equals( IntBuffer.class ) ) + return PrimitiveType.INT; + else if ( clz.equals( long[].class ) || clz.equals( LongBuffer.class ) ) + return PrimitiveType.LONG; + else if ( clz.equals( float[].class ) || clz.equals( FloatBuffer.class ) ) + return PrimitiveType.FLOAT; + else if ( clz.equals( double[].class ) || clz.equals( DoubleBuffer.class ) ) + return PrimitiveType.DOUBLE; + else + throw new IllegalArgumentException(); + } + + // TODO: Remove? + static MemCopy< ?, ? > forClasses( final Class< ? > srcClass, final Class< ? > destClass ) + { + final PrimitiveType primitiveType = primitiveTypeForClass( srcClass ); + if ( !primitiveTypeForClass( destClass ).equals( primitiveType ) ) + throw new IllegalArgumentException( "primitive types for src and dest do not match" ); + final boolean fromBuffer = Buffer.class.isAssignableFrom( srcClass ); + final boolean toBuffer = Buffer.class.isAssignableFrom( destClass ); + return forPrimitiveType( primitiveType, fromBuffer, toBuffer ); + } + + /* + * ----------------------------------------------------------------------- + * + * Implementations for all combinations of primitive array and Buffer + * + * ----------------------------------------------------------------------- + */ + + + + class MemCopyBoolean implements MemCopy< boolean[], boolean[] > { @Override public void copyForward( final boolean[] src, final int srcPos, final boolean[] dest, final int destPos, final int length ) @@ -177,7 +359,6 @@ public void copyStrided( final boolean[] src, final int srcPos, final boolean[] for ( int i = 0; i < length; ++i ) dest[ destPos + i * destStride ] = src[ srcPos + i ]; } - @Override public void copyLines( final int lineDir, final int lineLength, final int numLines, final boolean[] src, final int srcPos, final int srcStep, final boolean[] dest, final int destPos, final int destStep ) { @@ -191,9 +372,38 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final boolean[] src, + final int[] srcStrides, + final int srcPos, + final boolean[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyByte implements MemCopy< byte[] > + + + + class MemCopyByte implements MemCopy< byte[], byte[] > { @Override public void copyForward( final byte[] src, final int srcPos, final byte[] dest, final int destPos, final int length ) @@ -223,7 +433,6 @@ public void copyStrided( final byte[] src, final int srcPos, final byte[] dest, for ( int i = 0; i < length; ++i ) dest[ destPos + i * destStride ] = src[ srcPos + i ]; } - @Override public void copyLines( final int lineDir, final int lineLength, final int numLines, final byte[] src, final int srcPos, final int srcStep, final byte[] dest, final int destPos, final int destStep ) { @@ -237,42 +446,221 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final byte[] src, + final int[] srcStrides, + final int srcPos, + final byte[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyShort implements MemCopy< short[] > + class MemCopyByteBufferToArray implements MemCopy< ByteBuffer, byte[] > { @Override - public void copyForward( final short[] src, final int srcPos, final short[] dest, final int destPos, final int length ) + public void copyForward( final ByteBuffer src, final int srcPos, final byte[] dest, final int destPos, final int length ) { - System.arraycopy( src, srcPos, dest, destPos, length ); + src.position( srcPos ); + src.get( dest, destPos, length ); } @Override - public void copyReverse( final short[] src, final int srcPos, final short[] dest, final int destPos, final int length ) + public void copyReverse( final ByteBuffer src, final int srcPos, final byte[] dest, final int destPos, final int length ) { for ( int i = 0; i < length; ++i ) - dest[ destPos + i ] = src[ srcPos - i ]; + dest[ destPos + i ] = src.get( srcPos - i ); } @Override - public void copyValue( final short[] src, final int srcPos, final short[] dest, final int destPos, final int length ) + public void copyValue( final ByteBuffer src, final int srcPos, final byte[] dest, final int destPos, final int length ) { - Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + final byte val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); } + @Override + public void copyStrided( final ByteBuffer src, final int srcPos, final byte[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } @Override - public void copyStrided( final short[] src, final int srcPos, final short[] dest, final int destPos, final int destStride, final int length ) + public void copyLines( final int lineDir, final int lineLength, final int numLines, final ByteBuffer src, final int srcPos, final int srcStep, final byte[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final ByteBuffer src, + final int[] srcStrides, + final int srcPos, + final byte[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyByteArrayToBuffer implements MemCopy< byte[], ByteBuffer > + { + @Override + public void copyForward( final byte[] src, final int srcPos, final ByteBuffer dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final byte[] src, final int srcPos, final ByteBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final byte[] src, final int srcPos, final ByteBuffer dest, final int destPos, final int length ) + { + final byte val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final byte[] src, final int srcPos, final ByteBuffer dest, final int destPos, final int destStride, final int length ) { if ( destStride == 1 ) copyForward( src, srcPos, dest, destPos, length ); else for ( int i = 0; i < length; ++i ) - dest[ destPos + i * destStride ] = src[ srcPos + i ]; + dest.put( destPos + i * destStride, src[ srcPos + i ] ); } @Override - public void copyLines( final int lineDir, final int lineLength, final int numLines, final short[] src, final int srcPos, final int srcStep, final short[] dest, final int destPos, final int destStep ) + public void copyLines( final int lineDir, final int lineLength, final int numLines, final byte[] src, final int srcPos, final int srcStep, final ByteBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final byte[] src, + final int[] srcStrides, + final int srcPos, + final ByteBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyByteBufferToBuffer implements MemCopy< ByteBuffer, ByteBuffer > + { + @Override + public void copyForward( final ByteBuffer src, final int srcPos, final ByteBuffer dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final ByteBuffer src, final int srcPos, final ByteBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final ByteBuffer src, final int srcPos, final ByteBuffer dest, final int destPos, final int length ) + { + final byte val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final ByteBuffer src, final int srcPos, final ByteBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final ByteBuffer src, final int srcPos, final int srcStep, final ByteBuffer dest, final int destPos, final int destStep ) { if ( lineDir == 1 ) for ( int i = 0; i < numLines; ++i ) @@ -284,9 +672,38 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final ByteBuffer src, + final int[] srcStrides, + final int srcPos, + final ByteBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyChar implements MemCopy< char[] > + + + + class MemCopyChar implements MemCopy< char[], char[] > { @Override public void copyForward( final char[] src, final int srcPos, final char[] dest, final int destPos, final int length ) @@ -316,7 +733,6 @@ public void copyStrided( final char[] src, final int srcPos, final char[] dest, for ( int i = 0; i < length; ++i ) dest[ destPos + i * destStride ] = src[ srcPos + i ]; } - @Override public void copyLines( final int lineDir, final int lineLength, final int numLines, final char[] src, final int srcPos, final int srcStep, final char[] dest, final int destPos, final int destStep ) { @@ -330,41 +746,69 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final char[] src, + final int[] srcStrides, + final int srcPos, + final char[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyInt implements MemCopy< int[] > + class MemCopyCharBufferToArray implements MemCopy< CharBuffer, char[] > { @Override - public void copyForward( final int[] src, final int srcPos, final int[] dest, final int destPos, final int length ) + public void copyForward( final CharBuffer src, final int srcPos, final char[] dest, final int destPos, final int length ) { - System.arraycopy( src, srcPos, dest, destPos, length ); + src.position( srcPos ); + src.get( dest, destPos, length ); } @Override - public void copyReverse( final int[] src, final int srcPos, final int[] dest, final int destPos, final int length ) + public void copyReverse( final CharBuffer src, final int srcPos, final char[] dest, final int destPos, final int length ) { for ( int i = 0; i < length; ++i ) - dest[ destPos + i ] = src[ srcPos - i ]; + dest[ destPos + i ] = src.get( srcPos - i ); } @Override - public void copyValue( final int[] src, final int srcPos, final int[] dest, final int destPos, final int length ) + public void copyValue( final CharBuffer src, final int srcPos, final char[] dest, final int destPos, final int length ) { - Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + final char val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); } @Override - public void copyStrided( final int[] src, final int srcPos, final int[] dest, final int destPos, final int destStride, final int length ) + public void copyStrided( final CharBuffer src, final int srcPos, final char[] dest, final int destPos, final int destStride, final int length ) { if ( destStride == 1 ) copyForward( src, srcPos, dest, destPos, length ); else for ( int i = 0; i < length; ++i ) - dest[ destPos + i * destStride ] = src[ srcPos + i ]; + dest[ destPos + i * destStride ] = src.get( srcPos + i ); } @Override - public void copyLines( final int lineDir, final int lineLength, final int numLines, final int[] src, final int srcPos, final int srcStep, final int[] dest, final int destPos, final int destStep ) + public void copyLines( final int lineDir, final int lineLength, final int numLines, final CharBuffer src, final int srcPos, final int srcStep, final char[] dest, final int destPos, final int destStep ) { if ( lineDir == 1 ) for ( int i = 0; i < numLines; ++i ) @@ -376,41 +820,70 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final CharBuffer src, + final int[] srcStrides, + final int srcPos, + final char[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyLong implements MemCopy< long[] > + class MemCopyCharArrayToBuffer implements MemCopy< char[], CharBuffer > { @Override - public void copyForward( final long[] src, final int srcPos, final long[] dest, final int destPos, final int length ) + public void copyForward( final char[] src, final int srcPos, final CharBuffer dest, final int destPos, final int length ) { - System.arraycopy( src, srcPos, dest, destPos, length ); + dest.position( destPos ); + dest.put( src, srcPos, length ); } @Override - public void copyReverse( final long[] src, final int srcPos, final long[] dest, final int destPos, final int length ) + public void copyReverse( final char[] src, final int srcPos, final CharBuffer dest, final int destPos, final int length ) { for ( int i = 0; i < length; ++i ) - dest[ destPos + i ] = src[ srcPos - i ]; + dest.put( destPos + i, src[ srcPos - i ] ); } @Override - public void copyValue( final long[] src, final int srcPos, final long[] dest, final int destPos, final int length ) + public void copyValue( final char[] src, final int srcPos, final CharBuffer dest, final int destPos, final int length ) { - Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + final char val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); } @Override - public void copyStrided( final long[] src, final int srcPos, final long[] dest, final int destPos, final int destStride, final int length ) + public void copyStrided( final char[] src, final int srcPos, final CharBuffer dest, final int destPos, final int destStride, final int length ) { if ( destStride == 1 ) copyForward( src, srcPos, dest, destPos, length ); else for ( int i = 0; i < length; ++i ) - dest[ destPos + i * destStride ] = src[ srcPos + i ]; + dest.put( destPos + i * destStride, src[ srcPos + i ] ); } @Override - public void copyLines( final int lineDir, final int lineLength, final int numLines, final long[] src, final int srcPos, final int srcStep, final long[] dest, final int destPos, final int destStep ) + public void copyLines( final int lineDir, final int lineLength, final int numLines, final char[] src, final int srcPos, final int srcStep, final CharBuffer dest, final int destPos, final int destStep ) { if ( lineDir == 1 ) for ( int i = 0; i < numLines; ++i ) @@ -422,41 +895,72 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final char[] src, + final int[] srcStrides, + final int srcPos, + final CharBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyFloat implements MemCopy< float[] > + class MemCopyCharBufferToBuffer implements MemCopy< CharBuffer, CharBuffer > { @Override - public void copyForward( final float[] src, final int srcPos, final float[] dest, final int destPos, final int length ) + public void copyForward( final CharBuffer src, final int srcPos, final CharBuffer dest, final int destPos, final int length ) { - System.arraycopy( src, srcPos, dest, destPos, length ); + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); } @Override - public void copyReverse( final float[] src, final int srcPos, final float[] dest, final int destPos, final int length ) + public void copyReverse( final CharBuffer src, final int srcPos, final CharBuffer dest, final int destPos, final int length ) { for ( int i = 0; i < length; ++i ) - dest[ destPos + i ] = src[ srcPos - i ]; + dest.put( destPos + i, src.get( srcPos - i ) ); } @Override - public void copyValue( final float[] src, final int srcPos, final float[] dest, final int destPos, final int length ) + public void copyValue( final CharBuffer src, final int srcPos, final CharBuffer dest, final int destPos, final int length ) { - Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + final char val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); } @Override - public void copyStrided( final float[] src, final int srcPos, final float[] dest, final int destPos, final int destStride, final int length ) + public void copyStrided( final CharBuffer src, final int srcPos, final CharBuffer dest, final int destPos, final int destStride, final int length ) { if ( destStride == 1 ) copyForward( src, srcPos, dest, destPos, length ); else for ( int i = 0; i < length; ++i ) - dest[ destPos + i * destStride ] = src[ srcPos + i ]; + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); } @Override - public void copyLines( final int lineDir, final int lineLength, final int numLines, final float[] src, final int srcPos, final int srcStep, final float[] dest, final int destPos, final int destStep ) + public void copyLines( final int lineDir, final int lineLength, final int numLines, final CharBuffer src, final int srcPos, final int srcStep, final CharBuffer dest, final int destPos, final int destStep ) { if ( lineDir == 1 ) for ( int i = 0; i < numLines; ++i ) @@ -468,31 +972,60 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final CharBuffer src, + final int[] srcStrides, + final int srcPos, + final CharBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } - class MemCopyDouble implements MemCopy< double[] > + + + + class MemCopyShort implements MemCopy< short[], short[] > { @Override - public void copyForward( final double[] src, final int srcPos, final double[] dest, final int destPos, final int length ) + public void copyForward( final short[] src, final int srcPos, final short[] dest, final int destPos, final int length ) { System.arraycopy( src, srcPos, dest, destPos, length ); } @Override - public void copyReverse( final double[] src, final int srcPos, final double[] dest, final int destPos, final int length ) + public void copyReverse( final short[] src, final int srcPos, final short[] dest, final int destPos, final int length ) { for ( int i = 0; i < length; ++i ) dest[ destPos + i ] = src[ srcPos - i ]; } @Override - public void copyValue( final double[] src, final int srcPos, final double[] dest, final int destPos, final int length ) + public void copyValue( final short[] src, final int srcPos, final short[] dest, final int destPos, final int length ) { Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); } @Override - public void copyStrided( final double[] src, final int srcPos, final double[] dest, final int destPos, final int destStride, final int length ) + public void copyStrided( final short[] src, final int srcPos, final short[] dest, final int destPos, final int destStride, final int length ) { if ( destStride == 1 ) copyForward( src, srcPos, dest, destPos, length ); @@ -500,9 +1033,8 @@ public void copyStrided( final double[] src, final int srcPos, final double[] de for ( int i = 0; i < length; ++i ) dest[ destPos + i * destStride ] = src[ srcPos + i ]; } - @Override - public void copyLines( final int lineDir, final int lineLength, final int numLines, final double[] src, final int srcPos, final int srcStep, final double[] dest, final int destPos, final int destStep ) + public void copyLines( final int lineDir, final int lineLength, final int numLines, final short[] src, final int srcPos, final int srcStep, final short[] dest, final int destPos, final int destStep ) { if ( lineDir == 1 ) for ( int i = 0; i < numLines; ++i ) @@ -514,5 +1046,1458 @@ else if ( lineDir == -1 ) for ( int i = 0; i < numLines; ++i ) copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); } + + @Override + public void copyNDRangeRecursive( + final int d, + final short[] src, + final int[] srcStrides, + final int srcPos, + final short[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } } + + class MemCopyShortBufferToArray implements MemCopy< ShortBuffer, short[] > + { + @Override + public void copyForward( final ShortBuffer src, final int srcPos, final short[] dest, final int destPos, final int length ) + { + src.position( srcPos ); + src.get( dest, destPos, length ); + } + + @Override + public void copyReverse( final ShortBuffer src, final int srcPos, final short[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src.get( srcPos - i ); + } + + @Override + public void copyValue( final ShortBuffer src, final int srcPos, final short[] dest, final int destPos, final int length ) + { + final short val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); + } + + @Override + public void copyStrided( final ShortBuffer src, final int srcPos, final short[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final ShortBuffer src, final int srcPos, final int srcStep, final short[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final ShortBuffer src, + final int[] srcStrides, + final int srcPos, + final short[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyShortArrayToBuffer implements MemCopy< short[], ShortBuffer > + { + @Override + public void copyForward( final short[] src, final int srcPos, final ShortBuffer dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final short[] src, final int srcPos, final ShortBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final short[] src, final int srcPos, final ShortBuffer dest, final int destPos, final int length ) + { + final short val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final short[] src, final int srcPos, final ShortBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src[ srcPos + i ] ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final short[] src, final int srcPos, final int srcStep, final ShortBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final short[] src, + final int[] srcStrides, + final int srcPos, + final ShortBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyShortBufferToBuffer implements MemCopy< ShortBuffer, ShortBuffer > + { + @Override + public void copyForward( final ShortBuffer src, final int srcPos, final ShortBuffer dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final ShortBuffer src, final int srcPos, final ShortBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final ShortBuffer src, final int srcPos, final ShortBuffer dest, final int destPos, final int length ) + { + final short val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final ShortBuffer src, final int srcPos, final ShortBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final ShortBuffer src, final int srcPos, final int srcStep, final ShortBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final ShortBuffer src, + final int[] srcStrides, + final int srcPos, + final ShortBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + + + + class MemCopyInt implements MemCopy< int[], int[] > + { + @Override + public void copyForward( final int[] src, final int srcPos, final int[] dest, final int destPos, final int length ) + { + System.arraycopy( src, srcPos, dest, destPos, length ); + } + + @Override + public void copyReverse( final int[] src, final int srcPos, final int[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src[ srcPos - i ]; + } + + @Override + public void copyValue( final int[] src, final int srcPos, final int[] dest, final int destPos, final int length ) + { + Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + } + + @Override + public void copyStrided( final int[] src, final int srcPos, final int[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src[ srcPos + i ]; + } + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final int[] src, final int srcPos, final int srcStep, final int[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final int[] src, + final int[] srcStrides, + final int srcPos, + final int[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyIntBufferToArray implements MemCopy< IntBuffer, int[] > + { + @Override + public void copyForward( final IntBuffer src, final int srcPos, final int[] dest, final int destPos, final int length ) + { + src.position( srcPos ); + src.get( dest, destPos, length ); + } + + @Override + public void copyReverse( final IntBuffer src, final int srcPos, final int[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src.get( srcPos - i ); + } + + @Override + public void copyValue( final IntBuffer src, final int srcPos, final int[] dest, final int destPos, final int length ) + { + final int val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); + } + + @Override + public void copyStrided( final IntBuffer src, final int srcPos, final int[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final IntBuffer src, final int srcPos, final int srcStep, final int[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final IntBuffer src, + final int[] srcStrides, + final int srcPos, + final int[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyIntArrayToBuffer implements MemCopy< int[], IntBuffer > + { + @Override + public void copyForward( final int[] src, final int srcPos, final IntBuffer dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final int[] src, final int srcPos, final IntBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final int[] src, final int srcPos, final IntBuffer dest, final int destPos, final int length ) + { + final int val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final int[] src, final int srcPos, final IntBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src[ srcPos + i ] ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final int[] src, final int srcPos, final int srcStep, final IntBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final int[] src, + final int[] srcStrides, + final int srcPos, + final IntBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyIntBufferToBuffer implements MemCopy< IntBuffer, IntBuffer > + { + @Override + public void copyForward( final IntBuffer src, final int srcPos, final IntBuffer dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final IntBuffer src, final int srcPos, final IntBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final IntBuffer src, final int srcPos, final IntBuffer dest, final int destPos, final int length ) + { + final int val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final IntBuffer src, final int srcPos, final IntBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final IntBuffer src, final int srcPos, final int srcStep, final IntBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final IntBuffer src, + final int[] srcStrides, + final int srcPos, + final IntBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + + + + class MemCopyLong implements MemCopy< long[], long[] > + { + @Override + public void copyForward( final long[] src, final int srcPos, final long[] dest, final int destPos, final int length ) + { + System.arraycopy( src, srcPos, dest, destPos, length ); + } + + @Override + public void copyReverse( final long[] src, final int srcPos, final long[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src[ srcPos - i ]; + } + + @Override + public void copyValue( final long[] src, final int srcPos, final long[] dest, final int destPos, final int length ) + { + Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + } + + @Override + public void copyStrided( final long[] src, final int srcPos, final long[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src[ srcPos + i ]; + } + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final long[] src, final int srcPos, final int srcStep, final long[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final long[] src, + final int[] srcStrides, + final int srcPos, + final long[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyLongBufferToArray implements MemCopy< LongBuffer, long[] > + { + @Override + public void copyForward( final LongBuffer src, final int srcPos, final long[] dest, final int destPos, final int length ) + { + src.position( srcPos ); + src.get( dest, destPos, length ); + } + + @Override + public void copyReverse( final LongBuffer src, final int srcPos, final long[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src.get( srcPos - i ); + } + + @Override + public void copyValue( final LongBuffer src, final int srcPos, final long[] dest, final int destPos, final int length ) + { + final long val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); + } + + @Override + public void copyStrided( final LongBuffer src, final int srcPos, final long[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final LongBuffer src, final int srcPos, final int srcStep, final long[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final LongBuffer src, + final int[] srcStrides, + final int srcPos, + final long[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyLongArrayToBuffer implements MemCopy< long[], LongBuffer > + { + @Override + public void copyForward( final long[] src, final int srcPos, final LongBuffer dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final long[] src, final int srcPos, final LongBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final long[] src, final int srcPos, final LongBuffer dest, final int destPos, final int length ) + { + final long val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final long[] src, final int srcPos, final LongBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src[ srcPos + i ] ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final long[] src, final int srcPos, final int srcStep, final LongBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final long[] src, + final int[] srcStrides, + final int srcPos, + final LongBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyLongBufferToBuffer implements MemCopy< LongBuffer, LongBuffer > + { + @Override + public void copyForward( final LongBuffer src, final int srcPos, final LongBuffer dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final LongBuffer src, final int srcPos, final LongBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final LongBuffer src, final int srcPos, final LongBuffer dest, final int destPos, final int length ) + { + final long val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final LongBuffer src, final int srcPos, final LongBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final LongBuffer src, final int srcPos, final int srcStep, final LongBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final LongBuffer src, + final int[] srcStrides, + final int srcPos, + final LongBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + + + + class MemCopyFloat implements MemCopy< float[], float[] > + { + @Override + public void copyForward( final float[] src, final int srcPos, final float[] dest, final int destPos, final int length ) + { + System.arraycopy( src, srcPos, dest, destPos, length ); + } + + @Override + public void copyReverse( final float[] src, final int srcPos, final float[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src[ srcPos - i ]; + } + + @Override + public void copyValue( final float[] src, final int srcPos, final float[] dest, final int destPos, final int length ) + { + Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + } + + @Override + public void copyStrided( final float[] src, final int srcPos, final float[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src[ srcPos + i ]; + } + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final float[] src, final int srcPos, final int srcStep, final float[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final float[] src, + final int[] srcStrides, + final int srcPos, + final float[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyFloatBufferToArray implements MemCopy< FloatBuffer, float[] > + { + @Override + public void copyForward( final FloatBuffer src, final int srcPos, final float[] dest, final int destPos, final int length ) + { + src.position( srcPos ); + src.get( dest, destPos, length ); + } + + @Override + public void copyReverse( final FloatBuffer src, final int srcPos, final float[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src.get( srcPos - i ); + } + + @Override + public void copyValue( final FloatBuffer src, final int srcPos, final float[] dest, final int destPos, final int length ) + { + final float val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); + } + + @Override + public void copyStrided( final FloatBuffer src, final int srcPos, final float[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final FloatBuffer src, final int srcPos, final int srcStep, final float[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final FloatBuffer src, + final int[] srcStrides, + final int srcPos, + final float[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyFloatArrayToBuffer implements MemCopy< float[], FloatBuffer > + { + @Override + public void copyForward( final float[] src, final int srcPos, final FloatBuffer dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final float[] src, final int srcPos, final FloatBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final float[] src, final int srcPos, final FloatBuffer dest, final int destPos, final int length ) + { + final float val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final float[] src, final int srcPos, final FloatBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src[ srcPos + i ] ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final float[] src, final int srcPos, final int srcStep, final FloatBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final float[] src, + final int[] srcStrides, + final int srcPos, + final FloatBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyFloatBufferToBuffer implements MemCopy< FloatBuffer, FloatBuffer > + { + @Override + public void copyForward( final FloatBuffer src, final int srcPos, final FloatBuffer dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final FloatBuffer src, final int srcPos, final FloatBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final FloatBuffer src, final int srcPos, final FloatBuffer dest, final int destPos, final int length ) + { + final float val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final FloatBuffer src, final int srcPos, final FloatBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final FloatBuffer src, final int srcPos, final int srcStep, final FloatBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final FloatBuffer src, + final int[] srcStrides, + final int srcPos, + final FloatBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + + + + class MemCopyDouble implements MemCopy< double[], double[] > + { + @Override + public void copyForward( final double[] src, final int srcPos, final double[] dest, final int destPos, final int length ) + { + System.arraycopy( src, srcPos, dest, destPos, length ); + } + + @Override + public void copyReverse( final double[] src, final int srcPos, final double[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src[ srcPos - i ]; + } + + @Override + public void copyValue( final double[] src, final int srcPos, final double[] dest, final int destPos, final int length ) + { + Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + } + + @Override + public void copyStrided( final double[] src, final int srcPos, final double[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src[ srcPos + i ]; + } + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final double[] src, final int srcPos, final int srcStep, final double[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final double[] src, + final int[] srcStrides, + final int srcPos, + final double[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyDoubleBufferToArray implements MemCopy< DoubleBuffer, double[] > + { + @Override + public void copyForward( final DoubleBuffer src, final int srcPos, final double[] dest, final int destPos, final int length ) + { + src.position( srcPos ); + src.get( dest, destPos, length ); + } + + @Override + public void copyReverse( final DoubleBuffer src, final int srcPos, final double[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src.get( srcPos - i ); + } + + @Override + public void copyValue( final DoubleBuffer src, final int srcPos, final double[] dest, final int destPos, final int length ) + { + final double val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); + } + + @Override + public void copyStrided( final DoubleBuffer src, final int srcPos, final double[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final DoubleBuffer src, final int srcPos, final int srcStep, final double[] dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final DoubleBuffer src, + final int[] srcStrides, + final int srcPos, + final double[] dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyDoubleArrayToBuffer implements MemCopy< double[], DoubleBuffer > + { + @Override + public void copyForward( final double[] src, final int srcPos, final DoubleBuffer dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final double[] src, final int srcPos, final DoubleBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final double[] src, final int srcPos, final DoubleBuffer dest, final int destPos, final int length ) + { + final double val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final double[] src, final int srcPos, final DoubleBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src[ srcPos + i ] ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final double[] src, final int srcPos, final int srcStep, final DoubleBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final double[] src, + final int[] srcStrides, + final int srcPos, + final DoubleBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + + class MemCopyDoubleBufferToBuffer implements MemCopy< DoubleBuffer, DoubleBuffer > + { + @Override + public void copyForward( final DoubleBuffer src, final int srcPos, final DoubleBuffer dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final DoubleBuffer src, final int srcPos, final DoubleBuffer dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final DoubleBuffer src, final int srcPos, final DoubleBuffer dest, final int destPos, final int length ) + { + final double val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final DoubleBuffer src, final int srcPos, final DoubleBuffer dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final DoubleBuffer src, final int srcPos, final int srcStep, final DoubleBuffer dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final DoubleBuffer src, + final int[] srcStrides, + final int srcPos, + final DoubleBuffer dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + } + } diff --git a/src/main/java/net/imglib2/blocks/PlanarImgRangeCopier.java b/src/main/java/net/imglib2/blocks/PlanarImgRangeCopier.java index 96a325815..5f2da7ab6 100644 --- a/src/main/java/net/imglib2/blocks/PlanarImgRangeCopier.java +++ b/src/main/java/net/imglib2/blocks/PlanarImgRangeCopier.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -44,14 +44,14 @@ * * @param a primitive array type, e.g., {@code byte[]}. */ -class PlanarImgRangeCopier< T > implements RangeCopier< T > +class PlanarImgRangeCopier< S, T > implements RangeCopier< T > { private final int n; - private final SliceAccess< T > sliceAccess; + private final SliceAccess< S > sliceAccess; private final int[] srcDims; private final Ranges findRanges; - private final MemCopy< T > memCopy; - private final T oob; + private final MemCopy< S, T > memCopy; + private final S oob; private final List< Ranges.Range >[] rangesPerDimension; private final Ranges.Range[] ranges; @@ -66,8 +66,8 @@ class PlanarImgRangeCopier< T > implements RangeCopier< T > public PlanarImgRangeCopier( final PlanarImg< ?, ? > planarImg, final Ranges findRanges, - final MemCopy< T > memCopy, - final T oob ) + final MemCopy< S, T > memCopy, + final S oob ) { n = planarImg.numDimensions(); sliceAccess = new SliceAccess<>( planarImg ); @@ -94,7 +94,7 @@ public PlanarImgRangeCopier( } // creates an independent copy of {@code other} - private PlanarImgRangeCopier( PlanarImgRangeCopier< T > copier ) + private PlanarImgRangeCopier( PlanarImgRangeCopier< S, T > copier ) { n = copier.n; sliceAccess = copier.sliceAccess.copy(); @@ -113,7 +113,7 @@ private PlanarImgRangeCopier( PlanarImgRangeCopier< T > copier ) } @Override - public PlanarImgRangeCopier< T > newInstance() + public PlanarImgRangeCopier< S, T > newInstance() { return new PlanarImgRangeCopier<>( this ); } @@ -217,7 +217,7 @@ private void copyRanges( final T dest ) final int dOffset = doffsets[ 0 ]; - final T src = sliceAccess.getCurrentStorageArray(); + final S src = sliceAccess.getCurrentStorageArray(); if ( n > 1 ) copyRangesRecursively( src, sOffset, dest, dOffset, n - 1 ); else @@ -228,7 +228,7 @@ private void copyRanges( final T dest ) } } - private void copyRangesRecursively( final T src, final int srcPos, final T dest, final int destPos, final int d ) + private void copyRangesRecursively( final S src, final int srcPos, final T dest, final int destPos, final int d ) { final int length = lengths[ d ]; final int cstep = csteps[ d ]; @@ -307,7 +307,7 @@ public void setPosition( final int position, final int d ) public T getCurrentStorageArray() { - return ( T ) ( ( ( ArrayDataAccess< ? > ) planarImg.update( this ) ).getCurrentStorageArray() ); + return ( T ) planarImg.update( this ).getCurrentStorageArray(); } @Override diff --git a/src/main/java/net/imglib2/blocks/RangeCopier.java b/src/main/java/net/imglib2/blocks/RangeCopier.java index 6a06e0091..1a64814f1 100644 --- a/src/main/java/net/imglib2/blocks/RangeCopier.java +++ b/src/main/java/net/imglib2/blocks/RangeCopier.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -73,18 +73,18 @@ interface RangeCopier< T > */ RangeCopier< T > newInstance(); - static < T > RangeCopier< T > create( + static < S, T > RangeCopier< T > create( final NativeImg< ?, ? > img, final Ranges findRanges, - final MemCopy< T > memCopy, - final T oob ) + final MemCopy< S, T > memCopy, + final S oob ) { if ( img instanceof AbstractCellImg ) return new CellImgRangeCopier<>( ( AbstractCellImg< ?, ?, ? extends Cell< ? >, ? > ) img, findRanges, memCopy, oob ); else if ( img instanceof PlanarImg ) return new PlanarImgRangeCopier<>( ( PlanarImg< ?, ? > ) img, findRanges, memCopy, oob ); else if ( img instanceof ArrayImg ) - return new ArrayImgRangeCopier<>( ( ArrayImg ) img, findRanges, memCopy, oob ); + return new ArrayImgRangeCopier<>( ( ArrayImg< ?, ? > ) img, findRanges, memCopy, oob ); else throw new IllegalArgumentException(); } diff --git a/templates/main/java/net/imglib2/blocks/MemCopy.list b/templates/main/java/net/imglib2/blocks/MemCopy.list new file mode 100644 index 000000000..3e03c4a70 --- /dev/null +++ b/templates/main/java/net/imglib2/blocks/MemCopy.list @@ -0,0 +1,2 @@ +[MemCopy.java] + diff --git a/templates/main/java/net/imglib2/blocks/MemCopy.vm b/templates/main/java/net/imglib2/blocks/MemCopy.vm new file mode 100644 index 000000000..42e702669 --- /dev/null +++ b/templates/main/java/net/imglib2/blocks/MemCopy.vm @@ -0,0 +1,533 @@ +/*- + * #%L + * ImgLib2: a general-purpose, multidimensional image processing library. + * %% + * Copyright (C) 2009 - 2024 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld, + * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke, + * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner, + * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert, + * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin, + * Jean-Yves Tinevez and Michael Zinsmaier. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package net.imglib2.blocks; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import java.util.Arrays; + +import net.imglib2.type.PrimitiveType; + +/* + * This is autogenerated source code -- DO NOT EDIT. Instead, edit the + * corresponding template in templates/ and rerun bin/generate.groovy. + */ + +// TODO javadoc +// low-level copying methods +// implementations for all primitive types +// T is a primitive array type + +/** + * Low-level range copying methods between source {@code S} and target {@code T} + * which can be either primitive array types (e.g., {@code double[]}) or the + * corresponding {@code Buffer} (e.g., {@code DoubleBuffer}). + *

+ * All combinations are implemented (e.g., {@code byte[]}-to-{@code byte[]}, + * {@code byte[]}-to-{@code ByteBuffer}, {@code ByteBuffer}-to-{@code byte[]}, + * and {@code ByteBuffer}-to-{@code ByteBuffer}). + * + * @param + * the source type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer}) + * @param + * the target type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer}) + */ +interface MemCopy< S, T > +{ + /** + * Copy {@code length} components from the {@code src} array to the {@code + * dest} array. The components at positions {@code srcPos} through {@code + * srcPos+length-1} in the source array are copied into positions {@code + * destPos} through {@code destPos+length-1}, respectively, of the + * destination array. + */ + void copyForward( S src, int srcPos, T dest, int destPos, int length ); + + /** + * Copy {@code length} components from the {@code src} array to the {@code + * dest} array, in reverse order. The components at positions {@code srcPos} + * through {@code srcPos-length-1} in the source array are copied into + * positions {@code destPos} through {@code destPos+length-1}, respectively, + * of the destination array. + */ + void copyReverse( S src, int srcPos, T dest, int destPos, int length ); + + /** + * Copy component at position {@code srcPos} in the {@code src} array + * ({@code length} times) into positions {@code destPos} through {@code + * destPos+length-1} of the destination array. + */ + void copyValue( S src, int srcPos, T dest, int destPos, int length ); + + /** + * Copy {@code length} components from the {@code src} array to the {@code + * dest} array. The components at positions {@code srcPos} through {@code + * srcPos+length-1} in the source array are copied into positions {@code + * destPos}, {@code destPos+destStride}, {@code destPos + 2*destStride}, + * etc., through {@code destPos+(length-1)*destStride} of the destination + * array. + */ + void copyStrided( S src, int srcPos, T dest, int destPos, int destStride, int length ); + + /** + * Copy {@code numLines} stretches of {@code lineLength} elements. + * + * @param lineDir {@code 1}, {@code -1}, or {@code 0}. This corresponds (for every line being copied) to the source position moving forward, backward, or not at all, as the dest position is moving forward. + * @param lineLength how many elements to copy per line + * @param numLines how many lines to copy + * @param src source array + * @param srcPos starting position in source array + * @param srcStep offset to next line in src + * @param dest dest array + * @param destPos starting position in dest array + * @param destStep offset to next line in dest + */ + // Note that this default implementation is overridden in each + // implementation (with identical code) to soften the performance hit from + // polymorphism. The default implementation is left here, to make additional + // implementations easier. + default void copyLines( + final int lineDir, + final int lineLength, + final int numLines, + final S src, + final int srcPos, + final int srcStep, + final T dest, + final int destPos, + final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + /** + * Recursively copy a {@code (d+1)} dimensional region from {@code src} to + * {@code dest}, where {@code src} and {@code dest} are flattened nD array + * with strides {@code srcStrides} and {@code destStrides}, respectively. + *

+ * 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 + */ + // Note that this default implementation is overridden in each + // implementation (with identical code) to soften the performance hit from + // polymorphism. The default implementation is left here, to make additional + // implementations easier. + default void copyNDRangeRecursive( + final int d, + final S src, + final int[] srcStrides, + final int srcPos, + final T dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } + + MemCopyBoolean BOOLEAN = new MemCopyBoolean(); + MemCopyByte BYTE = new MemCopyByte(); + MemCopyChar CHAR = new MemCopyChar(); + MemCopyShort SHORT = new MemCopyShort(); + MemCopyInt INT = new MemCopyInt(); + MemCopyLong LONG = new MemCopyLong(); + MemCopyFloat FLOAT = new MemCopyFloat(); + MemCopyDouble DOUBLE = new MemCopyDouble(); + + MemCopyByteBufferToArray BUFFER_TO_ARRAY_BYTE = new MemCopyByteBufferToArray(); + MemCopyCharBufferToArray BUFFER_TO_ARRAY_CHAR = new MemCopyCharBufferToArray(); + MemCopyShortBufferToArray BUFFER_TO_ARRAY_SHORT = new MemCopyShortBufferToArray(); + MemCopyIntBufferToArray BUFFER_TO_ARRAY_INT = new MemCopyIntBufferToArray(); + MemCopyLongBufferToArray BUFFER_TO_ARRAY_LONG = new MemCopyLongBufferToArray(); + MemCopyFloatBufferToArray BUFFER_TO_ARRAY_FLOAT = new MemCopyFloatBufferToArray(); + MemCopyDoubleBufferToArray BUFFER_TO_ARRAY_DOUBLE = new MemCopyDoubleBufferToArray(); + + MemCopyByteArrayToBuffer ARRAY_TO_BUFFER_BYTE = new MemCopyByteArrayToBuffer(); + MemCopyCharArrayToBuffer ARRAY_TO_BUFFER_CHAR = new MemCopyCharArrayToBuffer(); + MemCopyShortArrayToBuffer ARRAY_TO_BUFFER_SHORT = new MemCopyShortArrayToBuffer(); + MemCopyIntArrayToBuffer ARRAY_TO_BUFFER_INT = new MemCopyIntArrayToBuffer(); + MemCopyLongArrayToBuffer ARRAY_TO_BUFFER_LONG = new MemCopyLongArrayToBuffer(); + MemCopyFloatArrayToBuffer ARRAY_TO_BUFFER_FLOAT = new MemCopyFloatArrayToBuffer(); + MemCopyDoubleArrayToBuffer ARRAY_TO_BUFFER_DOUBLE = new MemCopyDoubleArrayToBuffer(); + + MemCopyByteBufferToBuffer BUFFER_TO_BUFFER_BYTE = new MemCopyByteBufferToBuffer(); + MemCopyCharBufferToBuffer BUFFER_TO_BUFFER_CHAR = new MemCopyCharBufferToBuffer(); + MemCopyShortBufferToBuffer BUFFER_TO_BUFFER_SHORT = new MemCopyShortBufferToBuffer(); + MemCopyIntBufferToBuffer BUFFER_TO_BUFFER_INT = new MemCopyIntBufferToBuffer(); + MemCopyLongBufferToBuffer BUFFER_TO_BUFFER_LONG = new MemCopyLongBufferToBuffer(); + MemCopyFloatBufferToBuffer BUFFER_TO_BUFFER_FLOAT = new MemCopyFloatBufferToBuffer(); + MemCopyDoubleBufferToBuffer BUFFER_TO_BUFFER_DOUBLE = new MemCopyDoubleBufferToBuffer(); + + static MemCopy< ?, ? > forPrimitiveType( final PrimitiveType primitiveType ) + { + return forPrimitiveType( primitiveType, false, false ); + } + + static MemCopy< ?, ? > forPrimitiveType( final PrimitiveType primitiveType, final boolean fromBuffer, final boolean toBuffer ) + { + switch ( primitiveType ) + { + case BOOLEAN: + if ( fromBuffer || toBuffer ) + throw new IllegalArgumentException( "No BufferAccess implementation for PrimitiveType.BOOLEAN" ); + else + return BOOLEAN; + case BYTE: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_BYTE : BUFFER_TO_ARRAY_BYTE ) + : ( toBuffer ? ARRAY_TO_BUFFER_BYTE : BYTE ); + case CHAR: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_CHAR : BUFFER_TO_ARRAY_CHAR ) + : ( toBuffer ? ARRAY_TO_BUFFER_CHAR : CHAR ); + case SHORT: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_SHORT : BUFFER_TO_ARRAY_SHORT ) + : ( toBuffer ? ARRAY_TO_BUFFER_SHORT : SHORT ); + case INT: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_INT : BUFFER_TO_ARRAY_INT ) + : ( toBuffer ? ARRAY_TO_BUFFER_INT : INT ); + case LONG: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_LONG : BUFFER_TO_ARRAY_LONG ) + : ( toBuffer ? ARRAY_TO_BUFFER_LONG : LONG ); + case FLOAT: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_FLOAT : BUFFER_TO_ARRAY_FLOAT ) + : ( toBuffer ? ARRAY_TO_BUFFER_FLOAT : FLOAT ); + case DOUBLE: + return fromBuffer + ? ( toBuffer ? BUFFER_TO_BUFFER_DOUBLE : BUFFER_TO_ARRAY_DOUBLE ) + : ( toBuffer ? ARRAY_TO_BUFFER_DOUBLE : DOUBLE ); + default: + case UNDEFINED: + throw new IllegalArgumentException(); + } + } + + + // TODO: Remove? + static PrimitiveType primitiveTypeForClass( final Class< ? > clz ) + { + if ( clz.equals( boolean[].class ) ) + return PrimitiveType.BOOLEAN; + else if ( clz.equals( byte[].class ) || clz.equals( ByteBuffer.class ) ) + return PrimitiveType.BYTE; + else if ( clz.equals( char[].class ) || clz.equals( CharBuffer.class ) ) + return PrimitiveType.CHAR; + else if ( clz.equals( short[].class ) || clz.equals( ShortBuffer.class ) ) + return PrimitiveType.SHORT; + else if ( clz.equals( int[].class ) || clz.equals( IntBuffer.class ) ) + return PrimitiveType.INT; + else if ( clz.equals( long[].class ) || clz.equals( LongBuffer.class ) ) + return PrimitiveType.LONG; + else if ( clz.equals( float[].class ) || clz.equals( FloatBuffer.class ) ) + return PrimitiveType.FLOAT; + else if ( clz.equals( double[].class ) || clz.equals( DoubleBuffer.class ) ) + return PrimitiveType.DOUBLE; + else + throw new IllegalArgumentException(); + } + + // TODO: Remove? + static MemCopy< ?, ? > forClasses( final Class< ? > srcClass, final Class< ? > destClass ) + { + final PrimitiveType primitiveType = primitiveTypeForClass( srcClass ); + if ( !primitiveTypeForClass( destClass ).equals( primitiveType ) ) + throw new IllegalArgumentException( "primitive types for src and dest do not match" ); + final boolean fromBuffer = Buffer.class.isAssignableFrom( srcClass ); + final boolean toBuffer = Buffer.class.isAssignableFrom( destClass ); + return forPrimitiveType( primitiveType, fromBuffer, toBuffer ); + } + + /* + * ----------------------------------------------------------------------- + * + * Implementations for all combinations of primitive array and Buffer + * + * ----------------------------------------------------------------------- + */ +#macro(override_default_methods) + @Override + public void copyLines( final int lineDir, final int lineLength, final int numLines, final ${src_t} src, final int srcPos, final int srcStep, final ${dest_t} dest, final int destPos, final int destStep ) + { + if ( lineDir == 1 ) + for ( int i = 0; i < numLines; ++i ) + copyForward( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else if ( lineDir == -1 ) + for ( int i = 0; i < numLines; ++i ) + copyReverse( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + else // cstep0 == 0 + for ( int i = 0; i < numLines; ++i ) + copyValue( src, srcPos + i * srcStep, dest, destPos + i * destStep, lineLength ); + } + + @Override + public void copyNDRangeRecursive( + final int d, + final ${src_t} src, + final int[] srcStrides, + final int srcPos, + final ${dest_t} dest, + final int[] destStrides, + final int destPos, + final int[] size ) + { + final int len = size[ d ]; + if ( d > 0 ) + { + final int stride_src = srcStrides[ d ]; + final int stride_dst = destStrides[ d ]; + for ( int i = 0; i < len; ++i ) + copyNDRangeRecursive( d - 1, + src, srcStrides, srcPos + i * stride_src, + dest, destStrides, destPos + i * stride_dst, + size ); + } + else + copyForward( src, srcPos, dest, destPos, len ); + } +#end +#set( $primitive_types = ["boolean", "byte", "char", "short", "int", "long", "float", "double"] ) +#foreach( $t in $primitive_types ) +#set( $tuc = $t.substring(0,1).toUpperCase() + $t.substring(1)) +#set( $b = $tuc + "Buffer" ) + + + + class MemCopy${tuc} implements MemCopy< ${t}[], ${t}[] > + { + @Override + public void copyForward( final ${t}[] src, final int srcPos, final ${t}[] dest, final int destPos, final int length ) + { + System.arraycopy( src, srcPos, dest, destPos, length ); + } + + @Override + public void copyReverse( final ${t}[] src, final int srcPos, final ${t}[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src[ srcPos - i ]; + } + + @Override + public void copyValue( final ${t}[] src, final int srcPos, final ${t}[] dest, final int destPos, final int length ) + { + Arrays.fill( dest, destPos, destPos + length, src[ srcPos ] ); + } + + @Override + public void copyStrided( final ${t}[] src, final int srcPos, final ${t}[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src[ srcPos + i ]; + } +#set( $src_t = $t + "[]" ) +#set( $dest_t = $t + "[]" ) +#override_default_methods() + } + +#if( !$t.equals("boolean") ) + class MemCopy${tuc}BufferToArray implements MemCopy< ${b}, ${t}[] > + { + @Override + public void copyForward( final ${b} src, final int srcPos, final ${t}[] dest, final int destPos, final int length ) + { + src.position( srcPos ); + src.get( dest, destPos, length ); + } + + @Override + public void copyReverse( final ${b} src, final int srcPos, final ${t}[] dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest[ destPos + i ] = src.get( srcPos - i ); + } + + @Override + public void copyValue( final ${b} src, final int srcPos, final ${t}[] dest, final int destPos, final int length ) + { + final ${t} val = src.get( srcPos ); + Arrays.fill( dest, destPos, destPos + length, val ); + } + + @Override + public void copyStrided( final ${b} src, final int srcPos, final ${t}[] dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest[ destPos + i * destStride ] = src.get( srcPos + i ); + } + +#set( $src_t = $b ) +#set( $dest_t = $t + "[]" ) +#override_default_methods() + } + + class MemCopy${tuc}ArrayToBuffer implements MemCopy< ${t}[], ${b} > + { + @Override + public void copyForward( final ${t}[] src, final int srcPos, final ${b} dest, final int destPos, final int length ) + { + dest.position( destPos ); + dest.put( src, srcPos, length ); + } + + @Override + public void copyReverse( final ${t}[] src, final int srcPos, final ${b} dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src[ srcPos - i ] ); + } + + @Override + public void copyValue( final ${t}[] src, final int srcPos, final ${b} dest, final int destPos, final int length ) + { + final ${t} val = src[ srcPos ]; + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final ${t}[] src, final int srcPos, final ${b} dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src[ srcPos + i ] ); + } + +#set( $src_t = $t + "[]" ) +#set( $dest_t = $b ) +#override_default_methods() + } + + class MemCopy${tuc}BufferToBuffer implements MemCopy< ${b}, ${b} > + { + @Override + public void copyForward( final ${b} src, final int srcPos, final ${b} dest, final int destPos, final int length ) + { + src.limit( srcPos + length ); + src.position( srcPos ); + dest.position( destPos ); + dest.put( src ); + } + + @Override + public void copyReverse( final ${b} src, final int srcPos, final ${b} dest, final int destPos, final int length ) + { + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, src.get( srcPos - i ) ); + } + + @Override + public void copyValue( final ${b} src, final int srcPos, final ${b} dest, final int destPos, final int length ) + { + final ${t} val = src.get( srcPos ); + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i, val ); + } + + @Override + public void copyStrided( final ${b} src, final int srcPos, final ${b} dest, final int destPos, final int destStride, final int length ) + { + if ( destStride == 1 ) + copyForward( src, srcPos, dest, destPos, length ); + else + for ( int i = 0; i < length; ++i ) + dest.put( destPos + i * destStride, src.get( srcPos + i ) ); + } + +#set( $src_t = $b ) +#set( $dest_t = $b ) +#override_default_methods() + } + +#end +#end +} From a1be3a237ee3ee57f2b07e2ef54c5dfb98160a7a Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 11 Jan 2024 18:23:22 +0100 Subject: [PATCH 06/10] Add ViewProperties.getRootAccessType() --- .../java/net/imglib2/blocks/ViewProperties.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/net/imglib2/blocks/ViewProperties.java b/src/main/java/net/imglib2/blocks/ViewProperties.java index bb5dd89dd..2eb54f1d7 100644 --- a/src/main/java/net/imglib2/blocks/ViewProperties.java +++ b/src/main/java/net/imglib2/blocks/ViewProperties.java @@ -37,6 +37,7 @@ import net.imglib2.RandomAccessible; import net.imglib2.converter.Converter; import net.imglib2.img.NativeImg; +import net.imglib2.img.basictypeaccess.array.ArrayDataAccess; import net.imglib2.transform.integer.MixedTransform; import net.imglib2.type.NativeType; import net.imglib2.view.TransformBuilder; @@ -134,6 +135,22 @@ public R getRootType() return rootType; } + public ArrayDataAccess< ? > getRootAccessType() + { + return ( ArrayDataAccess< ? > ) getDataAccess( root ); + } + + /* + * TODO: There should be a better way to get straight to a DataAccess instance. + * This is similar to the getType() problem. + * For now, this will work. + * Make an issue about getDataAccess() ... + */ + private static < A > A getDataAccess( NativeImg< ?, A > img ) + { + return img.update( img.cursor() ); + } + public Extension getExtension() { return extension; From 6c0c5e34b8ef361ea0d2915c859314ddc3c0d92d Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 8 Mar 2024 10:43:42 +0100 Subject: [PATCH 07/10] relax generics --- src/main/java/net/imglib2/blocks/PrimitiveTypeProperties.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/net/imglib2/blocks/PrimitiveTypeProperties.java b/src/main/java/net/imglib2/blocks/PrimitiveTypeProperties.java index e06eb8722..f08630972 100644 --- a/src/main/java/net/imglib2/blocks/PrimitiveTypeProperties.java +++ b/src/main/java/net/imglib2/blocks/PrimitiveTypeProperties.java @@ -37,7 +37,6 @@ import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.ToIntFunction; -import net.imglib2.img.basictypeaccess.array.ArrayDataAccess; import net.imglib2.img.basictypeaccess.array.BooleanArray; import net.imglib2.img.basictypeaccess.array.ByteArray; import net.imglib2.img.basictypeaccess.array.CharArray; @@ -61,7 +60,7 @@ * @param

a primitive array type, e.g., {@code byte[]}. * @param the corresponding {@code ArrayDataAccess} type. */ -class PrimitiveTypeProperties< P, A extends ArrayDataAccess< A > > +class PrimitiveTypeProperties< P, A > { final Class< P > primitiveArrayClass; From 9fe57fad12e30042923a674fdb4daa66458f0989 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 9 Aug 2024 21:35:47 +0200 Subject: [PATCH 08/10] Make PrimitiveBlocks.of(nio_backed_img) work --- src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java index ea581eaa4..699fed751 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.img.basictypeaccess.nio.BufferAccess; import net.imglib2.transform.integer.MixedTransform; import net.imglib2.type.NativeType; import net.imglib2.type.PrimitiveType; @@ -67,7 +68,7 @@ public ViewPrimitiveBlocks( final ViewProperties< T, R > props ) { this.props = props; final PrimitiveType primitiveType = props.getRootType().getNativeTypeFactory().getPrimitiveType(); - final MemCopy memCopy = MemCopy.forPrimitiveType( primitiveType ); + final MemCopy memCopy = MemCopy.forPrimitiveType( primitiveType, props.getRootAccessType() instanceof BufferAccess, false ); final Extension extension = props.getExtension() != null ? props.getExtension() : Extension.border(); final Object oob = extractOobValue( props.getRootType(), extension ); final Ranges findRanges = Ranges.forExtension( extension ); From dba752c97e2d69bae85952384256cfb801cbf740 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Mon, 1 Jul 2024 03:32:11 +0200 Subject: [PATCH 09/10] Add PrimitiveBlocks.numDimensions() --- .../net/imglib2/blocks/FallbackPrimitiveBlocks.java | 6 ++++++ .../java/net/imglib2/blocks/PrimitiveBlocks.java | 6 +++--- src/main/java/net/imglib2/blocks/ViewAnalyzer.java | 3 ++- .../java/net/imglib2/blocks/ViewPrimitiveBlocks.java | 12 ++++++++++++ src/main/java/net/imglib2/blocks/ViewProperties.java | 11 +++++++++++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java index 7354dee96..c1f75e841 100644 --- a/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java +++ b/src/main/java/net/imglib2/blocks/FallbackPrimitiveBlocks.java @@ -77,6 +77,12 @@ public T getType() return type; } + @Override + public int numDimensions() + { + return source.numDimensions(); + } + @Override public void copy( final long[] srcPos, final Object dest, final int[] size ) { diff --git a/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java index 9c1b96c48..927287d79 100644 --- a/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java +++ b/src/main/java/net/imglib2/blocks/PrimitiveBlocks.java @@ -36,7 +36,9 @@ import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.FAIL; import static net.imglib2.blocks.PrimitiveBlocks.OnFallback.WARN; +import net.imglib2.EuclideanSpace; import net.imglib2.RandomAccessible; +import net.imglib2.Typed; import net.imglib2.type.NativeType; import net.imglib2.util.Util; @@ -101,10 +103,8 @@ * @param * pixel type */ -public interface PrimitiveBlocks< T extends NativeType< T > > +public interface PrimitiveBlocks< T extends NativeType< T > > extends Typed< T >, EuclideanSpace { - T getType(); - /** * Copy a block from the ({@code T}-typed) source into primitive arrays (of * the appropriate type). diff --git a/src/main/java/net/imglib2/blocks/ViewAnalyzer.java b/src/main/java/net/imglib2/blocks/ViewAnalyzer.java index 9a992b89f..2d490fc7c 100644 --- a/src/main/java/net/imglib2/blocks/ViewAnalyzer.java +++ b/src/main/java/net/imglib2/blocks/ViewAnalyzer.java @@ -596,9 +596,10 @@ private boolean splitTransform() private < T extends NativeType< T >, R extends NativeType< R > > ViewProperties< T, R > getViewProperties() { final T viewType = Cast.unchecked( ra.getType() ); + final int viewNumDimensions = ra.numDimensions(); final NativeImg< R, ? > root = Cast.unchecked( nodes.get( nodes.size() - 1 ).view() ); final R rootType = root.createLinkedType(); - return new ViewProperties<>( viewType, root, rootType, oobExtension, transform, permuteInvertTransform, converterSupplier ); + return new ViewProperties<>( viewType, viewNumDimensions, root, rootType, oobExtension, transform, permuteInvertTransform, converterSupplier ); } private < T extends NativeType< T > > FallbackProperties< T > getFallbackProperties() diff --git a/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java b/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java index 699fed751..b41e41196 100644 --- a/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java +++ b/src/main/java/net/imglib2/blocks/ViewPrimitiveBlocks.java @@ -87,6 +87,12 @@ public T getType() return props.getViewType(); } + @Override + public int numDimensions() + { + return props.getViewNumDimensions(); + } + /** * @param srcPos * min coordinates of block to copy from src Img. @@ -172,6 +178,12 @@ public T getType() return props.getViewType(); } + @Override + public int numDimensions() + { + return props.getViewNumDimensions(); + } + @Override public void copy( final long[] srcPos, final Object dest, final int[] size ) { diff --git a/src/main/java/net/imglib2/blocks/ViewProperties.java b/src/main/java/net/imglib2/blocks/ViewProperties.java index 2eb54f1d7..b44941b11 100644 --- a/src/main/java/net/imglib2/blocks/ViewProperties.java +++ b/src/main/java/net/imglib2/blocks/ViewProperties.java @@ -58,6 +58,8 @@ class ViewProperties< T extends NativeType< T >, R extends NativeType< R > > { private final T viewType; + private final int viewNumDimensions; + private final NativeImg< R, ? > root; private final R rootType; @@ -78,6 +80,7 @@ class ViewProperties< T extends NativeType< T >, R extends NativeType< R > > * Create {@code ViewProperties}. * * @param viewType pixel type of the View to copy from + * @param viewNumDimensions number of dimensions of the View to copy from * @param root the {@code NativeImg} at the root of the View chain * @param rootType pixel type of the root {@code NativeImg} * @param extension out-of-bounds extension to apply to the root @@ -87,6 +90,7 @@ class ViewProperties< T extends NativeType< T >, R extends NativeType< R > > */ ViewProperties( final T viewType, + final int viewNumDimensions, final NativeImg< R, ? > root, final R rootType, final Extension extension, @@ -95,6 +99,7 @@ class ViewProperties< T extends NativeType< T >, R extends NativeType< R > > final Supplier< ? extends Converter< ?, ? > > converterSupplier ) { this.viewType = viewType; + this.viewNumDimensions = viewNumDimensions; this.root = root; this.rootType = rootType; this.extension = extension; @@ -110,6 +115,7 @@ public String toString() { return "ViewProperties{" + "viewType=" + viewType.getClass().getSimpleName() + + ", viewNumDimensions=" + viewNumDimensions + ", root=" + root + ", rootType=" + rootType.getClass().getSimpleName() + ", extension=" + extension + @@ -125,6 +131,11 @@ public T getViewType() return viewType; } + public int getViewNumDimensions() + { + return viewNumDimensions; + } + public NativeImg< R, ? > getRoot() { return root; From 72fd9ec438b2b6ef7fa6f3dafdf4872c35eb53f1 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 10 Mar 2024 10:55:28 +0100 Subject: [PATCH 10/10] Add SubArrayCopy for copying sub-regions between flattened arrays (of different sizes) Add javadoc --- .../java/net/imglib2/blocks/SubArrayCopy.java | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 src/main/java/net/imglib2/blocks/SubArrayCopy.java 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 + * the source type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer}) + * @param + * the target type. Must be a primitive array or buffer type (e.g., {@code double[]} or {@code IntBuffer}) + */ + interface Typed< S, T > + { + /** + * 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 + */ + default void copy( + final S src, final int[] srcSize, final int[] srcPos, + final T dest, final int[] destSize, final int[] destPos, + final int[] size ) + { + 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 ); + + copyNDRangeRecursive( n - 1, + src, srcStrides, oSrc, + dest, destStrides, oDest, + size ); + } + + /** + * Recursively copy a {@code (d+1)} dimensional region from {@code src} to + * {@code dest}, where {@code src} and {@code dest} are flattened nD array + * with strides {@code srcStrides} and {@code destStrides}, respectively. + *

+ * 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 ); + } +}