diff --git a/src/main/java/net/imglib2/img/cell/Cell.java b/src/main/java/net/imglib2/img/cell/Cell.java index 68e69e922..4f788a550 100644 --- a/src/main/java/net/imglib2/img/cell/Cell.java +++ b/src/main/java/net/imglib2/img/cell/Cell.java @@ -81,7 +81,7 @@ public Cell( final int[] dimensions, final long[] min, final A data ) } /** - * Get the basic type array that stores this cells pixels. + * Get the basic type array that stores this cell's pixels. * * @return underlying basic type array. */ diff --git a/src/main/java/net/imglib2/img/cell/CellGrid.java b/src/main/java/net/imglib2/img/cell/CellGrid.java index 8b2cecdbe..40e75811f 100644 --- a/src/main/java/net/imglib2/img/cell/CellGrid.java +++ b/src/main/java/net/imglib2/img/cell/CellGrid.java @@ -34,13 +34,13 @@ package net.imglib2.img.cell; import java.util.Arrays; -import java.util.Iterator; import net.imglib2.Cursor; import net.imglib2.FinalInterval; import net.imglib2.FlatIterationOrder; import net.imglib2.Interval; import net.imglib2.IterableInterval; +import net.imglib2.Localizable; import net.imglib2.Point; import net.imglib2.Positionable; import net.imglib2.RandomAccess; @@ -337,6 +337,36 @@ public void getCellPosition( final long[] position, final Positionable cellPos ) cellPos.setPosition( position[ d ] / cellDimensions[ d ], d ); } + /** + * Compute all cell-related coordinates/sizes required by CellRandomAccess. + * + * @param position + * current image position + * @param cellSteps + * allocation steps for cell are written here. + * @param cellMin + * offset of the cell in image coordinates are written here. + * @param cellMax is set to the + * max of the cell in image coordinates are written here. + * @return index within the cell. + */ + int getCellCoordinates( final long[] position, final int[] cellSteps, final long[] cellMin, final long[] cellMax ) + { + int steps = 1; + int i = 0; + for ( int d = 0; d < n; ++d ) + { + final long gridPos = position[ d ] / cellDimensions[ d ]; + final int cellDim = ( gridPos + 1 == numCells[ d ] ) ? borderSize[ d ] : cellDimensions[ d ]; + cellMin[ d ] = gridPos * cellDimensions[ d ]; + cellMax[ d ] = cellMin[ d ] + cellDim - 1; + cellSteps[ d ] = steps; + i += steps * ( position[ d ] - cellMin[ d ] ); + steps *= cellDim; + } + return i; + } + @Override public int hashCode() { diff --git a/src/main/java/net/imglib2/img/cell/CellRandomAccess.java b/src/main/java/net/imglib2/img/cell/CellRandomAccess.java index e5f34c880..edc1d81a3 100644 --- a/src/main/java/net/imglib2/img/cell/CellRandomAccess.java +++ b/src/main/java/net/imglib2/img/cell/CellRandomAccess.java @@ -34,6 +34,7 @@ package net.imglib2.img.cell; +import java.util.Arrays; import net.imglib2.AbstractLocalizable; import net.imglib2.Localizable; import net.imglib2.RandomAccess; @@ -64,23 +65,15 @@ public class CellRandomAccess< T extends NativeType< T >, C extends Cell< ? > > protected final long[] dimensions; - protected int[] currentCellSteps; + protected final int[] currentCellSteps; - protected long[] currentCellMin; + protected final long[] currentCellMin; - protected long[] currentCellMax; + protected final long[] currentCellMax; protected boolean isOutOfBounds; - protected final long[] oobCellMin; - - protected final long[] oobCellMax; - - /** - * The current index of the type. It is faster to duplicate this here than - * to access it through type.getIndex(). - */ - protected int index; + private boolean typeNeedsUpdate; protected CellRandomAccess( final CellRandomAccess< T, C > randomAccess ) { @@ -95,18 +88,14 @@ protected CellRandomAccess( final CellRandomAccess< T, C > randomAccess ) cellDims = randomAccess.cellDims; dimensions = randomAccess.dimensions; - currentCellSteps = randomAccess.currentCellSteps; - currentCellMin = randomAccess.currentCellMin; - currentCellMax = randomAccess.currentCellMax; + currentCellSteps = randomAccess.currentCellSteps.clone(); + currentCellMin = randomAccess.currentCellMin.clone(); + currentCellMax = randomAccess.currentCellMax.clone(); isOutOfBounds = randomAccess.isOutOfBounds; - oobCellMin = randomAccess.oobCellMin; - oobCellMax = randomAccess.oobCellMax; - index = randomAccess.index; - if ( !isOutOfBounds ) - type.updateContainer( this ); - typeIndex.set( index ); + typeIndex.set( randomAccess.typeIndex.get() ); + typeNeedsUpdate = true; } public CellRandomAccess( final AbstractCellImg< T, ?, C, ? > img ) @@ -123,14 +112,11 @@ public CellRandomAccess( final AbstractCellImg< T, ?, C, ? > img ) img.getCellGrid().cellDimensions( cellDims ); img.getCellGrid().imgDimensions( dimensions ); + currentCellSteps = new int[ n ]; + currentCellMin = new long[ n ]; + currentCellMax = new long[ n ]; + isOutOfBounds = false; - oobCellMin = new long[ n ]; - oobCellMax = new long[ n ]; - for ( int d = 0; d < n; ++d ) - { - oobCellMin[ d ] = Long.MAX_VALUE; - oobCellMax[ d ] = Long.MIN_VALUE; - } img.getCellGrid().getCellPosition( position, randomAccessOnCells ); updatePosition( false ); @@ -145,6 +131,11 @@ public C getCell() @Override public T get() { + if ( typeNeedsUpdate ) + { + typeNeedsUpdate = false; + type.updateContainer( this ); + } return type; } @@ -157,51 +148,47 @@ public CellRandomAccess< T, C > copy() @Override public void fwd( final int d ) { - index += currentCellSteps[ d ]; + typeIndex.inc( currentCellSteps[ d ] ); if ( ++position[ d ] > currentCellMax[ d ] ) { randomAccessOnCells.fwd( d ); updatePosition( position[ d ] >= dimensions[ d ] ); } - typeIndex.set( index ); } @Override public void bck( final int d ) { - index -= currentCellSteps[ d ]; + typeIndex.dec( currentCellSteps[ d ] ); if ( --position[ d ] < currentCellMin[ d ] ) { randomAccessOnCells.bck( d ); updatePosition( position[ d ] < 0 ); } - typeIndex.set( index ); } @Override public void move( final int distance, final int d ) { - index += distance * currentCellSteps[ d ]; + typeIndex.inc( distance * currentCellSteps[ d ] ); position[ d ] += distance; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { randomAccessOnCells.setPosition( position[ d ] / cellDims[ d ], d ); updatePosition( position[ d ] < 0 || position[ d ] >= dimensions[ d ] ); } - typeIndex.set( index ); } @Override public void move( final long distance, final int d ) { - index += ( int ) distance * currentCellSteps[ d ]; + typeIndex.inc( ( int ) distance * currentCellSteps[ d ] ); position[ d ] += distance; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { randomAccessOnCells.setPosition( position[ d ] / cellDims[ d ], d ); updatePosition( position[ d ] < 0 || position[ d ] >= dimensions[ d ] ); } - typeIndex.set( index ); } @Override @@ -212,7 +199,7 @@ public void move( final Localizable localizable ) final long pos = localizable.getLongPosition( d ); if ( pos != 0 ) { - index += ( int ) pos * currentCellSteps[ d ]; + typeIndex.inc( ( int ) pos * currentCellSteps[ d ] ); position[ d ] += pos; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { @@ -237,7 +224,6 @@ public void move( final Localizable localizable ) } } } - typeIndex.set( index ); } @Override @@ -247,7 +233,7 @@ public void move( final int[] distance ) { if ( distance[ d ] != 0 ) { - index += distance[ d ] * currentCellSteps[ d ]; + typeIndex.inc( distance[ d ] * currentCellSteps[ d ] ); position[ d ] += distance[ d ]; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { @@ -271,7 +257,6 @@ public void move( final int[] distance ) } } } - typeIndex.set( index ); } @Override @@ -281,7 +266,7 @@ public void move( final long[] distance ) { if ( distance[ d ] != 0 ) { - index += ( int ) distance[ d ] * currentCellSteps[ d ]; + typeIndex.inc( ( int ) distance[ d ] * currentCellSteps[ d ] ); position[ d ] += distance[ d ]; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { @@ -305,33 +290,30 @@ public void move( final long[] distance ) } } } - typeIndex.set( index ); } @Override public void setPosition( final int pos, final int d ) { - index += ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ]; + typeIndex.inc( ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ] ); position[ d ] = pos; if ( pos < currentCellMin[ d ] || pos > currentCellMax[ d ] ) { randomAccessOnCells.setPosition( pos / cellDims[ d ], d ); updatePosition( position[ d ] < 0 || position[ d ] >= dimensions[ d ] ); } - typeIndex.set( index ); } @Override public void setPosition( final long pos, final int d ) { - index += ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ]; + typeIndex.inc( ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ] ); position[ d ] = pos; - if ( pos < currentCellMin[ d ] || pos > currentCellMax[ d ] ) + if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { randomAccessOnCells.setPosition( pos / cellDims[ d ], d ); updatePosition( position[ d ] < 0 || position[ d ] >= dimensions[ d ] ); } - typeIndex.set( index ); } @Override @@ -342,7 +324,7 @@ public void setPosition( final Localizable localizable ) final long pos = localizable.getLongPosition( d ); if ( pos != position[ d ] ) { - index += ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ]; + typeIndex.inc( ( int ) ( pos - position[ d ] ) * currentCellSteps[ d ] ); position[ d ] = pos; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { @@ -367,7 +349,6 @@ public void setPosition( final Localizable localizable ) } } } - typeIndex.set( index ); } @Override @@ -377,7 +358,7 @@ public void setPosition( final int[] pos ) { if ( pos[ d ] != position[ d ] ) { - index += ( int ) ( pos[ d ] - position[ d ] ) * currentCellSteps[ d ]; + typeIndex.inc( ( int ) ( pos[ d ] - position[ d ] ) * currentCellSteps[ d ] ); if ( pos[ d ] < currentCellMin[ d ] || pos[ d ] > currentCellMax[ d ] ) { setPos2( pos, d ); @@ -386,7 +367,6 @@ public void setPosition( final int[] pos ) position[ d ] = pos[ d ]; } } - typeIndex.set( index ); } private void setPos2( final int[] pos, final int d0 ) @@ -414,7 +394,7 @@ public void setPosition( final long[] pos ) { if ( pos[ d ] != position[ d ] ) { - index += ( int ) ( pos[ d ] - position[ d ] ) * currentCellSteps[ d ]; + typeIndex.inc( ( int ) ( pos[ d ] - position[ d ] ) * currentCellSteps[ d ] ); position[ d ] = pos[ d ]; if ( position[ d ] < currentCellMin[ d ] || position[ d ] > currentCellMax[ d ] ) { @@ -438,7 +418,6 @@ public void setPosition( final long[] pos ) } } } - typeIndex.set( index ); } /** @@ -452,8 +431,8 @@ private void updatePosition( final boolean movedOutOfBounds ) if ( movedOutOfBounds ) { isOutOfBounds = true; - currentCellMin = oobCellMin; - currentCellMax = oobCellMax; + Arrays.fill( currentCellMin, Long.MAX_VALUE ); + Arrays.fill( currentCellMax, Long.MIN_VALUE ); } else { @@ -470,15 +449,8 @@ private void updatePosition( final boolean movedOutOfBounds ) isOutOfBounds = false; grid.getCellPosition( position, randomAccessOnCells ); } - - final C cell = getCell(); - - currentCellSteps = cell.steps; - currentCellMin = cell.min; - currentCellMax = cell.max; - - index = cell.globalPositionToIndex( position ); - type.updateContainer( this ); + typeIndex.set( grid.getCellCoordinates( position, currentCellSteps, currentCellMin, currentCellMax ) ); + typeNeedsUpdate = true; } } } diff --git a/src/main/java/net/imglib2/img/cell/LazyCellImg.java b/src/main/java/net/imglib2/img/cell/LazyCellImg.java index 5d44fccbc..e20f30c09 100644 --- a/src/main/java/net/imglib2/img/cell/LazyCellImg.java +++ b/src/main/java/net/imglib2/img/cell/LazyCellImg.java @@ -45,7 +45,7 @@ /** * A {@link AbstractCellImg} that obtains its Cells lazily when they are * accessed. Cells are obtained by a {@link Get} method that is provided by the - * user. Typically this is some kind of cache. + * user. Typically, this is some kind of cache. * * @param * the pixel type