diff --git a/pom.xml b/pom.xml
index a49ce776..ecc5ed77 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
sc.fiji
bigdataviewer-core
- 10.2.1-SNAPSHOT
+ 10.2.1-SNAPSHOT
BigDataViewer Core
BigDataViewer core classes with minimal dependencies.
diff --git a/src/main/java/bdv/export/DownsampleBlock.java b/src/main/java/bdv/export/DownsampleBlock.java
index 8f43abb2..b71de212 100644
--- a/src/main/java/bdv/export/DownsampleBlock.java
+++ b/src/main/java/bdv/export/DownsampleBlock.java
@@ -6,13 +6,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
@@ -29,8 +29,11 @@
package bdv.export;
import java.util.Arrays;
-import net.imglib2.Cursor;
-import net.imglib2.RandomAccess;
+
+import gnu.trove.iterator.TLongLongIterator;
+import gnu.trove.map.hash.TLongLongHashMap;
+import gnu.trove.set.TLongSet;
+import net.imglib2.*;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.loops.ClassCopyProvider;
import net.imglib2.type.numeric.RealType;
@@ -39,15 +42,23 @@
public interface DownsampleBlock< T extends RealType< T > >
{
+ enum DownsamplingMethod
+ {
+ Average,
+ Centre,
+ Mode
+ }
+
void downsampleBlock( final RandomAccess< T > in, final Cursor< T > out, final int[] dimensions );
static < T extends RealType< T > > DownsampleBlock< T > create(
final int[] blockDimensions,
final int[] downsamplingFactors,
- final Class< ? > pixelTypeClass,
+ final DownsamplingMethod downsamplingMethod,
+ final Class< ? > pixelTypeClass,
final Class< ? > inAccessClass )
{
- return DownsampleBlockInstances.create( blockDimensions, downsamplingFactors, pixelTypeClass, inAccessClass );
+ return DownsampleBlockInstances.create( blockDimensions, downsamplingFactors, downsamplingMethod, pixelTypeClass, inAccessClass );
}
}
@@ -60,7 +71,8 @@ class DownsampleBlockInstances
public static < T extends RealType< T > > DownsampleBlock< T > create(
final int[] blockDimensions,
final int[] downsamplingFactors,
- final Class< ? > pixelTypeClass,
+ DownsampleBlock.DownsamplingMethod downsamplingMethod,
+ final Class< ? > pixelTypeClass,
final Class< ? > inAccessClass )
{
if ( provider == null )
@@ -68,7 +80,20 @@ public static < T extends RealType< T > > DownsampleBlock< T > create(
synchronized ( DownsampleBlockInstances.class )
{
if ( provider == null )
- provider = new ClassCopyProvider<>( Imp.class, DownsampleBlock.class, int[].class, int[].class );
+ {
+ switch ( downsamplingMethod )
+ {
+ case Average:
+ provider = new ClassCopyProvider<>( AverageDownsampler.class, DownsampleBlock.class, int[].class, int[].class );
+ break;
+ case Centre:
+ provider = new ClassCopyProvider<>( CentreDownsampler.class, DownsampleBlock.class, int[].class, int[].class );
+ break;
+ case Mode:
+ provider = new ClassCopyProvider<>( ModeDownsampler.class, DownsampleBlock.class, int[].class, int[].class );
+ break;
+ }
+ }
}
}
@@ -78,7 +103,7 @@ public static < T extends RealType< T > > DownsampleBlock< T > create(
return provider.newInstanceForKey( key, blockDimensions, downsamplingFactors );
}
- public static class Imp< T extends RealType< T > > implements DownsampleBlock< T >
+ public static class AverageDownsampler< T extends RealType< T > > implements DownsampleBlock< T >
{
private final int n;
@@ -90,7 +115,7 @@ public static class Imp< T extends RealType< T > > implements DownsampleBlock< T
private final RandomAccess< DoubleType > acc;
- public Imp(
+ public AverageDownsampler(
final int[] blockDimensions,
final int[] downsamplingFactors )
{
@@ -120,13 +145,11 @@ public void downsampleBlock(
{
downsampleBlock3D( acc, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], in );
writeOutput3D( out, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], acc );
- }
- else if ( n == 2 )
+ } else if ( n == 2 )
{
downsampleBlock2D( acc, dimensions[ 0 ], dimensions[ 1 ], in );
writeOutput2D( out, dimensions[ 0 ], dimensions[ 1 ], acc );
- }
- else
+ } else
{
downsampleBlock1D( acc, dimensions[ 0 ], in );
writeOutput1D( out, dimensions[ 0 ], acc );
@@ -247,4 +270,465 @@ private void writeOutput1D(
acc.move( -asx, 0 );
}
}
+
+ public static class CentreDownsampler< T extends RealType< T > > implements DownsampleBlock< T >
+ {
+ private final int n;
+
+ private final int[] downsamplingFactors;
+
+ private final double[] accumulator;
+
+ private final RandomAccess< DoubleType > acc;
+
+ public CentreDownsampler(
+ final int[] blockDimensions,
+ final int[] downsamplingFactors )
+ {
+ n = blockDimensions.length;
+ if ( n < 1 || n > 3 )
+ throw new IllegalArgumentException();
+
+ this.downsamplingFactors = downsamplingFactors;
+
+ accumulator = new double[ ( int ) Intervals.numElements( blockDimensions ) ];
+
+ final long[] dims = new long[ n ];
+ Arrays.setAll( dims, d -> blockDimensions[ d ] );
+ acc = ArrayImgs.doubles( accumulator, dims ).randomAccess();
+ }
+
+ @Override
+ public void downsampleBlock(
+ final RandomAccess< T > in,
+ final Cursor< T > out, // must be flat iteration order
+ final int[] dimensions )
+ {
+ clearAccumulator();
+
+ if ( n == 3 )
+ {
+ downsampleBlock3D( acc, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], in );
+ writeOutput3D( out, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], acc );
+ } else if ( n == 2 )
+ {
+ downsampleBlock2D( acc, dimensions[ 0 ], dimensions[ 1 ], in );
+ writeOutput2D( out, dimensions[ 0 ], dimensions[ 1 ], acc );
+ } else
+ {
+ downsampleBlock1D( acc, dimensions[ 0 ], in );
+ writeOutput1D( out, dimensions[ 0 ], acc );
+ }
+ }
+
+ private void clearAccumulator()
+ {
+ Arrays.fill( accumulator, 0, accumulator.length, 0 );
+ }
+
+ private void downsampleBlock3D(
+ final RandomAccess< DoubleType > acc,
+ final int asx, // size of accumulator image
+ final int asy,
+ final int asz,
+ final RandomAccess< T > in )
+ {
+ final int d = 2;
+ final int bsz = downsamplingFactors[ d ];
+ in.move( bsz / 2, d );
+ for ( int az = 0; az < asz; ++az )
+ {
+ downsampleBlock2D( acc, asx, asy, in );
+ in.move( bsz, d );
+ acc.fwd( d );
+ }
+ in.move( -bsz * asz - bsz / 2, d );
+ acc.move( -asz, d );
+ }
+
+ private void downsampleBlock2D(
+ final RandomAccess< DoubleType > acc,
+ final int asx, // size of accumulator image
+ final int asy,
+ final RandomAccess< T > in )
+ {
+ final int d = 1;
+ final int bsy = downsamplingFactors[ d ];
+ in.move( bsy / 2, d );
+ for ( int ay = 0; ay < asy; ++ay )
+ {
+ downsampleBlock1D( acc, asx, in );
+ in.move( bsy, d );
+ acc.fwd( d );
+ }
+ in.move( -bsy * asy - bsy / 2, d );
+ acc.move( -asy, d );
+ }
+
+ private void downsampleBlock1D(
+ final RandomAccess< DoubleType > acc,
+ final int asx, // size of output image
+ final RandomAccess< T > in )
+ {
+ final int d = 0;
+ final int bsx = downsamplingFactors[ d ];
+ in.move( bsx / 2, d );
+ for ( int ax = 0; ax < asx; ++ax )
+ {
+ acc.get().set( in.get().getRealDouble() );
+ in.move( bsx, d );
+ acc.fwd( d );
+ }
+ in.move( -bsx * asx - bsx / 2, d );
+ acc.move( -asx, d );
+ }
+
+ private void writeOutput3D(
+ final Cursor< T > out, // must be flat iteration order
+ final int asx, // size of accumulator image
+ final int asy,
+ final int asz,
+ final RandomAccess< DoubleType > acc )
+ {
+ for ( int z = 0; z < asz; ++z )
+ {
+ writeOutput2D( out, asx, asy, acc );
+ acc.fwd( 2 );
+ }
+ acc.move( -asz, 2 );
+ }
+
+ private void writeOutput2D(
+ final Cursor< T > out, // must be flat iteration order
+ final int asx, // size of output image
+ final int asy,
+ final RandomAccess< DoubleType > acc )
+ {
+ for ( int y = 0; y < asy; ++y )
+ {
+ writeOutput1D( out, asx, acc );
+ acc.fwd( 1 );
+ }
+ acc.move( -asy, 1 );
+ }
+
+ private void writeOutput1D(
+ final Cursor< T > out, // must be flat iteration order
+ final int asx, // size of output (resp accumulator) image
+ final RandomAccess< DoubleType > acc )
+ {
+ for ( int x = 0; x < asx; ++x )
+ {
+ out.next().setReal( acc.get().get() );
+ acc.fwd( 0 );
+ }
+ acc.move( -asx, 0 );
+ }
+ }
+
+ public static class ModeDownsampler< T extends RealType< T > > implements DownsampleBlock< T >
+ {
+ private final int n;
+
+ private final int[] downsamplingFactors;
+
+ private final TLongLongHashMapRandomAccess acc;
+
+ public ModeDownsampler(
+ final int[] blockDimensions,
+ final int[] downsamplingFactors )
+ {
+ n = blockDimensions.length;
+ if ( n < 1 || n > 3 )
+ throw new IllegalArgumentException();
+
+ this.downsamplingFactors = downsamplingFactors;
+
+ final int[] dims = new int[ n ];
+ Arrays.setAll( dims, d -> blockDimensions[ d ] );
+
+ acc = new TLongLongHashMapRandomAccess( dims );
+ }
+
+ @Override
+ public void downsampleBlock(
+ final RandomAccess< T > in,
+ final Cursor< T > out, // must be flat iteration order
+ final int[] dimensions )
+ {
+ clearAccumulator();
+
+ if ( n == 3 )
+ {
+ downsampleBlock3D( acc, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], in );
+ writeOutput3D( out, dimensions[ 0 ], dimensions[ 1 ], dimensions[ 2 ], acc );
+ } else if ( n == 2 )
+ {
+ downsampleBlock2D( acc, dimensions[ 0 ], dimensions[ 1 ], in );
+ writeOutput2D( out, dimensions[ 0 ], dimensions[ 1 ], acc );
+ } else
+ {
+ downsampleBlock1D( acc, dimensions[ 0 ], in );
+ writeOutput1D( out, dimensions[ 0 ], acc );
+ }
+ }
+
+ private void clearAccumulator()
+ {
+ acc.init();
+ }
+
+ private void downsampleBlock3D(
+ final TLongLongHashMapRandomAccess acc,
+ final int asx, // size of output (resp accumulator) image
+ final int asy,
+ final int asz,
+ final RandomAccess< T > in )
+ {
+ final int bsz = downsamplingFactors[ 2 ];
+ final int sz = asz * bsz;
+ for ( int z = 0, bz = 0; z < sz; ++z )
+ {
+ downsampleBlock2D( acc, asx, asy, in );
+ in.fwd( 2 );
+ if ( ++bz == bsz )
+ {
+ bz = 0;
+ acc.fwd( 2 );
+ }
+ }
+ in.move( -sz, 2 );
+ acc.move( -asz, 2 );
+ }
+
+ private void downsampleBlock2D(
+ final TLongLongHashMapRandomAccess acc,
+ final int asx, // size of output (resp accumulator) image
+ final int asy,
+ final RandomAccess< T > in )
+ {
+ final int bsy = downsamplingFactors[ 1 ];
+ final int sy = asy * bsy;
+ for ( int y = 0, by = 0; y < sy; ++y )
+ {
+ downsampleBlock1D( acc, asx, in );
+ in.fwd( 1 );
+ if ( ++by == bsy )
+ {
+ by = 0;
+ acc.fwd( 1 );
+ }
+ }
+ in.move( -sy, 1 );
+ acc.move( -asy, 1 );
+ }
+
+ private void downsampleBlock1D(
+ final TLongLongHashMapRandomAccess acc,
+ final int asx, // size of output (resp accumulator) image
+ final RandomAccess< T > in )
+ {
+ final int bsx = downsamplingFactors[ 0 ];
+ final int sx = asx * bsx;
+ for ( int x = 0, bx = 0; x < sx; ++x )
+ {
+ final long value = (long) in.get().getRealDouble();
+ final TLongLongHashMap map = acc.get();
+ final long newCount = map.get( value ) + 1;
+ map.put( value, newCount );
+
+ in.fwd( 0 );
+ if ( ++bx == bsx )
+ {
+ bx = 0;
+ acc.fwd( 0 );
+ }
+ }
+ in.move( -sx, 0 );
+ acc.move( -asx, 0 );
+ }
+
+ private void writeOutput3D(
+ final Cursor< T > out, // must be flat iteration order
+ final int asx, // size of output (resp accumulator) image
+ final int asy,
+ final int asz,
+ final TLongLongHashMapRandomAccess acc )
+ {
+ for ( int z = 0; z < asz; ++z )
+ {
+ writeOutput2D( out, asx, asy, acc );
+ acc.fwd( 2 );
+ }
+ acc.move( -asz, 2 );
+ }
+
+ private void writeOutput2D(
+ final Cursor< T > out, // must be flat iteration order
+ final int asx, // size of output (resp accumulator) image
+ final int asy,
+ final TLongLongHashMapRandomAccess acc )
+ {
+ for ( int y = 0; y < asy; ++y )
+ {
+ writeOutput1D( out, asx, acc );
+ acc.fwd( 1 );
+ }
+ acc.move( -asy, 1 );
+ }
+
+ private void writeOutput1D(
+ final Cursor< T > out, // must be flat iteration order
+ final int asx, // size of output (resp accumulator) image
+ final TLongLongHashMapRandomAccess acc )
+ {
+ for ( int x = 0; x < asx; ++x )
+ {
+ long label = getLabel( acc );
+ out.next().setReal( label );
+ acc.fwd( 0 );
+ }
+ acc.move( -asx, 0 );
+ }
+
+ private long getLabel( TLongLongHashMapRandomAccess acc )
+ {
+ final TLongLongIterator iterator = acc.get().iterator();
+ long maxCount = 0;
+ long label = 0;
+ while ( iterator.hasNext() )
+ {
+ iterator.advance();
+ if ( iterator.value() > maxCount )
+ {
+ maxCount = iterator.value();
+ label = iterator.key();
+ }
+ }
+ return label;
+ }
+ }
+
+ public static class TLongLongHashMapRandomAccess extends AbstractLocalizableInt implements RandomAccess< TLongLongHashMap >
+ {
+ private TLongLongHashMap[][][] maps;
+ private final int[] dims;
+
+ public TLongLongHashMapRandomAccess( int[] dims )
+ {
+ super( dims.length );
+
+ this.dims = dims;
+ init();
+ }
+
+ public void init()
+ {
+ if( dims.length == 1 )
+ maps = new TLongLongHashMap[ dims[ 0 ] ][ 1 ][ 1 ];
+ else if ( dims.length == 2 )
+ maps = new TLongLongHashMap[ dims[ 0 ] ][ dims[ 1 ] ][ 1 ];
+ else if ( dims.length == 3 )
+ maps = new TLongLongHashMap[ dims[ 0 ] ][ dims[ 1 ] ][ dims[ 2 ] ];
+ else
+ throw new UnsupportedOperationException( "The number of dimensions must be <= 3" );
+
+ for ( int x = 0; x < dims[ 0 ]; x++ )
+ for ( int y = 0; y < dims[ 1 ]; y++ )
+ for ( int z = 0; z < dims[ 2 ]; z++ )
+ maps[ x ][ y ][ z ] = new TLongLongHashMap();
+ }
+
+ @Override
+ public RandomAccess< TLongLongHashMap > copyRandomAccess()
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void fwd( int d )
+ {
+ position[ d ]++;
+ }
+
+ @Override
+ public void bck( int d )
+ {
+ position[ d ]--;
+ }
+
+ @Override
+ public void move( int distance, int d )
+ {
+ position[ d ] += distance;
+ }
+
+ @Override
+ public void move( long distance, int d )
+ {
+ position[ d ] += distance;
+ }
+
+ @Override
+ public void move( Localizable distance )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void move( int[] distance )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void move( long[] distance )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void setPosition( Localizable position )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void setPosition( int[] position )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void setPosition( long[] position )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void setPosition( int position, int d )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public void setPosition( long position, int d )
+ {
+ throw new UnsupportedOperationException( );
+ }
+
+ @Override
+ public TLongLongHashMap get()
+ {
+ return maps[ position[ 0 ] ][ position[ 1 ] ][ position[ 2 ] ];
+ }
+
+ @Override
+ public Sampler< TLongLongHashMap > copy()
+ {
+ throw new UnsupportedOperationException( );
+ }
+ }
}
+
+
diff --git a/src/main/java/bdv/export/ExportScalePyramid.java b/src/main/java/bdv/export/ExportScalePyramid.java
index 7e3a601b..a7da2b97 100644
--- a/src/main/java/bdv/export/ExportScalePyramid.java
+++ b/src/main/java/bdv/export/ExportScalePyramid.java
@@ -227,6 +227,7 @@ public static < T extends RealType< T > & NativeType< T >, D > void writeScalePy
final RandomAccessibleInterval< T > img,
final T type,
final ExportMipmapInfo mipmapInfo,
+ final DownsampleBlock.DownsamplingMethod downsamplingMethod,
final DatasetIO< D, T > io,
final ExecutorService executorService,
final int numThreads,
@@ -362,7 +363,7 @@ public static < T extends RealType< T > & NativeType< T >, D > void writeScalePy
final Class< ? extends RealType > kl1 = type.getClass();
final Class< ? extends RandomAccess > kl2 = in.getClass();
final CopyBlock< T > copyBlock = fullResolution ? CopyBlock.create( n, kl1, kl2 ) : null;
- final DownsampleBlock< T > downsampleBlock = fullResolution ? null : DownsampleBlock.create( cellDimensions, factor, kl1, kl2 );
+ final DownsampleBlock< T > downsampleBlock = fullResolution ? null : DownsampleBlock.create( cellDimensions, factor, downsamplingMethod, kl1, kl2 );
for ( int i = nextCellInPlane.getAndIncrement(); i < numBlocksPerPlane; i = nextCellInPlane.getAndIncrement() )
{
diff --git a/src/main/java/bdv/export/WriteSequenceToHdf5.java b/src/main/java/bdv/export/WriteSequenceToHdf5.java
index 591f8a4c..bd350872 100644
--- a/src/main/java/bdv/export/WriteSequenceToHdf5.java
+++ b/src/main/java/bdv/export/WriteSequenceToHdf5.java
@@ -133,6 +133,7 @@ public class WriteSequenceToHdf5
public static void writeHdf5File(
final AbstractSequenceDescription< ?, ?, ? > seq,
final Map< Integer, ExportMipmapInfo > perSetupMipmapInfo,
+ final DownsampleBlock.DownsamplingMethod downsamplingMethod,
final boolean deflate,
final File hdf5File,
final LoopbackHeuristic loopbackHeuristic,
@@ -149,13 +150,13 @@ public static void writeHdf5File(
setupIdSequenceToPartition.put( setup.getId(), setup.getId() );
final Partition partition = new Partition( hdf5File.getPath(), timepointIdSequenceToPartition, setupIdSequenceToPartition );
- writeHdf5PartitionFile( seq, perSetupMipmapInfo, deflate, partition, loopbackHeuristic, afterEachPlane, numCellCreatorThreads, progressWriter );
+ writeHdf5PartitionFile( seq, perSetupMipmapInfo, downsamplingMethod, deflate, partition, loopbackHeuristic, afterEachPlane, numCellCreatorThreads, progressWriter );
}
/**
* Create a hdf5 file containing image data from all views and all
* timepoints in a chunked, mipmaped representation. This is the same as
- * {@link WriteSequenceToHdf5#writeHdf5File(AbstractSequenceDescription, Map, boolean, File, LoopbackHeuristic, AfterEachPlane, int, ProgressWriter)}
+ * {@link WriteSequenceToHdf5#writeHdf5File(AbstractSequenceDescription, Map, DownsampleBlock.DownsamplingMethod, boolean, File, LoopbackHeuristic, AfterEachPlane, int, ProgressWriter)}
* except that only one set of supsampling factors and and subdivision
* blocksizes is given, which is used for all {@link BasicViewSetup views}.
*
@@ -195,6 +196,7 @@ public static void writeHdf5File(
final AbstractSequenceDescription< ?, ?, ? > seq,
final int[][] resolutions,
final int[][] subdivisions,
+ final DownsampleBlock.DownsamplingMethod downsamplingMethod,
final boolean deflate,
final File hdf5File,
final LoopbackHeuristic loopbackHeuristic,
@@ -206,7 +208,7 @@ public static void writeHdf5File(
final ExportMipmapInfo mipmapInfo = new ExportMipmapInfo( resolutions, subdivisions );
for ( final BasicViewSetup setup : seq.getViewSetupsOrdered() )
perSetupMipmapInfo.put( setup.getId(), mipmapInfo );
- writeHdf5File( seq, perSetupMipmapInfo, deflate, hdf5File, loopbackHeuristic, afterEachPlane, numCellCreatorThreads, progressWriter );
+ writeHdf5File( seq, perSetupMipmapInfo, downsamplingMethod, deflate, hdf5File, loopbackHeuristic, afterEachPlane, numCellCreatorThreads, progressWriter );
}
/**
@@ -245,7 +247,7 @@ public static void writeHdf5PartitionLinkFile( final AbstractSequenceDescription
*
* Note that this method only writes the master file containing links. The
* individual partitions need to be written with
- * {@link #writeHdf5PartitionFile(AbstractSequenceDescription, Map, boolean, Partition, LoopbackHeuristic, AfterEachPlane, int, ProgressWriter)}.
+ * {@link #writeHdf5PartitionFile(AbstractSequenceDescription, Map, bdv.export.DownsampleBlock.DownsamplingMethod, boolean, Partition, LoopbackHeuristic, AfterEachPlane, int, ProgressWriter)}.
*
* @param seq
* description of the sequence to be stored as hdf5. (The
@@ -354,6 +356,7 @@ public static void writeHdf5PartitionLinkFile( final AbstractSequenceDescription
public static void writeHdf5PartitionFile(
final AbstractSequenceDescription< ?, ?, ? > seq,
final Map< Integer, ExportMipmapInfo > perSetupMipmapInfo,
+ final DownsampleBlock.DownsamplingMethod downsamplingMethod,
final boolean deflate,
final Partition partition,
final LoopbackHeuristic loopbackHeuristic,
@@ -449,7 +452,7 @@ public static void writeHdf5PartitionFile(
final ProgressWriter subProgressWriter = new SubTaskProgressWriter( progressWriter, startCompletionRatio, endCompletionRatio );
writeViewToHdf5PartitionFile(
- img, timepointIdPartition, setupIdPartition, mipmapInfo, false,
+ img, timepointIdPartition, setupIdPartition, mipmapInfo, false, downsamplingMethod,
deflate, writerQueue, executorService, numCellCreatorThreads, loopbackHeuristic, afterEachPlane, subProgressWriter );
}
}
@@ -515,6 +518,7 @@ public static void writeViewToHdf5PartitionFile(
final int setupIdPartition,
final ExportMipmapInfo mipmapInfo,
final boolean writeMipmapInfo,
+ final DownsampleBlock.DownsamplingMethod downsamplingMethod,
final boolean deflate,
final LoopbackHeuristic loopbackHeuristic,
final AfterEachPlane afterEachPlane,
@@ -532,7 +536,7 @@ public static void writeViewToHdf5PartitionFile(
try
{
// write the image
- writeViewToHdf5PartitionFile( img, timepointIdPartition, setupIdPartition, mipmapInfo, writeMipmapInfo, deflate, writerQueue, executorService, numCellCreatorThreads, loopbackHeuristic, afterEachPlane, progressWriter );
+ writeViewToHdf5PartitionFile( img, timepointIdPartition, setupIdPartition, mipmapInfo, writeMipmapInfo, downsamplingMethod, deflate, writerQueue, executorService, numCellCreatorThreads, loopbackHeuristic, afterEachPlane, progressWriter );
}
finally
{
@@ -661,6 +665,7 @@ public static void writeViewToHdf5PartitionFile(
final int setupIdPartition,
final ExportMipmapInfo mipmapInfo,
final boolean writeMipmapInfo,
+ final DownsampleBlock.DownsamplingMethod downsamplingMethod,
final boolean deflate,
final IHDF5Access writerQueue,
final ExecutorService executorService, // TODO
@@ -689,6 +694,7 @@ public static void writeViewToHdf5PartitionFile(
img,
new UnsignedShortType(),
mipmapInfo,
+ downsamplingMethod,
io,
executorService,
numThreads,
diff --git a/src/main/java/bdv/export/n5/WriteSequenceToN5.java b/src/main/java/bdv/export/n5/WriteSequenceToN5.java
index d5cd0dfc..4c5a8dc0 100644
--- a/src/main/java/bdv/export/n5/WriteSequenceToN5.java
+++ b/src/main/java/bdv/export/n5/WriteSequenceToN5.java
@@ -28,11 +28,7 @@
*/
package bdv.export.n5;
-import bdv.export.ExportMipmapInfo;
-import bdv.export.ExportScalePyramid;
-import bdv.export.ProgressWriter;
-import bdv.export.ProgressWriterNull;
-import bdv.export.SubTaskProgressWriter;
+import bdv.export.*;
import bdv.export.ExportScalePyramid.AfterEachPlane;
import bdv.export.ExportScalePyramid.LoopbackHeuristic;
import bdv.img.cache.SimpleCacheArrayLoader;
@@ -253,7 +249,7 @@ static < T extends RealType< T > & NativeType< T > > void writeScalePyramid(
final T type = setupImgLoader.getImageType();
final N5DatasetIO< T > io = new N5DatasetIO<>( n5, compression, setupId, timepointId, type );
ExportScalePyramid.writeScalePyramid(
- img, type, mipmapInfo, io,
+ img, type, mipmapInfo, DownsampleBlock.DownsamplingMethod.Average, io,
executorService, numThreads,
loopbackHeuristic, afterEachPlane, progressWriter );
}
diff --git a/src/main/java/bdv/tools/crop/CropDialog.java b/src/main/java/bdv/tools/crop/CropDialog.java
index cce6641e..b764f86b 100644
--- a/src/main/java/bdv/tools/crop/CropDialog.java
+++ b/src/main/java/bdv/tools/crop/CropDialog.java
@@ -28,6 +28,7 @@
*/
package bdv.tools.crop;
+import bdv.export.DownsampleBlock;
import bdv.viewer.SourceAndConverter;
import bdv.viewer.ViewerState;
import java.awt.BorderLayout;
@@ -389,7 +390,7 @@ public void cropGlobal( final int minTimepointIndex, final int maxTimepointIndex
}
final int numThreads = Math.max( 1, Runtime.getRuntime().availableProcessors() - 2 );
- WriteSequenceToHdf5.writeHdf5File( seq, perSetupMipmapInfo, true, hdf5File, null, null, numThreads, null );
+ WriteSequenceToHdf5.writeHdf5File( seq, perSetupMipmapInfo, DownsampleBlock.DownsamplingMethod.Average, true, hdf5File, null, null, numThreads, null );
// Build ViewRegistrations with adjusted transforms.
final ArrayList< ViewRegistration > registrations = new ArrayList<>();