/*- * #%L * Fiji distribution of ImageJ for the life sciences. * %% * Copyright (C) 2007 - 2017 Fiji developers. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package spim.process.cuda; import java.util.ArrayList; import mpicbg.spim.io.IOFunctions; import net.imglib2.iterator.LocalizingZeroMinIntervalIterator; import net.imglib2.util.Util; public class BlockGeneratorFixedSizePrecise implements BlockGenerator< Block > { final long[] blockSize; public BlockGeneratorFixedSizePrecise( final long[] blockSize ) { this.blockSize = blockSize; } /** * Divides an image into blocks * * @param imgSize - the size of the image * @param kernelSize - the size of the kernel (has to be odd!) * @return */ public Block[] divideIntoBlocks( final long[] imgSize, final long[] kernelSize ) { final int numDimensions = imgSize.length; // compute the effective size & local offset of each block // this is the same for all blocks final long[] effectiveSizeGeneral = new long[ numDimensions ]; final long[] effectiveLocalOffset = new long[ numDimensions ]; for ( int d = 0; d < numDimensions; ++d ) { effectiveSizeGeneral[ d ] = blockSize[ d ] - kernelSize[ d ] + 1; if ( effectiveSizeGeneral[ d ] <= 0 ) { IOFunctions.println( "Blocksize in dimension " + d + " (" + blockSize[ d ] + ") is smaller than the kernel (" + kernelSize[ d ] + ") which results in an negative effective size: " + effectiveSizeGeneral[ d ] + ". Quitting." ); return null; } effectiveLocalOffset[ d ] = kernelSize[ d ] / 2; } // compute the amount of blocks needed final long[] numBlocks = new long[ numDimensions ]; for ( int d = 0; d < numDimensions; ++d ) { numBlocks[ d ] = imgSize[ d ] / effectiveSizeGeneral[ d ]; // if the modulo is not 0 we need one more that is only partially useful if ( imgSize[ d ] % effectiveSizeGeneral[ d ] != 0 ) ++numBlocks[ d ]; } System.out.println( "imgSize " + Util.printCoordinates( imgSize ) ); System.out.println( "kernelSize " + Util.printCoordinates( kernelSize ) ); System.out.println( "blockSize " + Util.printCoordinates( blockSize ) ); System.out.println( "numBlocks " + Util.printCoordinates( numBlocks ) ); IOFunctions.println( "effectiveSize of blocks" + Util.printCoordinates( effectiveSizeGeneral ) ); System.out.println( "effectiveLocalOffset " + Util.printCoordinates( effectiveLocalOffset ) ); // now we instantiate the individual blocks iterating over all dimensions // we use the well-known ArrayLocalizableCursor for that final LocalizingZeroMinIntervalIterator cursor = new LocalizingZeroMinIntervalIterator( numBlocks ); final ArrayList< Block > blockList = new ArrayList< Block >(); final int[] currentBlock = new int[ numDimensions ]; while ( cursor.hasNext() ) { cursor.fwd(); cursor.localize( currentBlock ); // compute the current offset final long[] offset = new long[ numDimensions ]; final long[] effectiveOffset = new long[ numDimensions ]; final long[] effectiveSize = effectiveSizeGeneral.clone(); for ( int d = 0; d < numDimensions; ++d ) { effectiveOffset[ d ] = currentBlock[ d ] * effectiveSize[ d ]; offset[ d ] = effectiveOffset[ d ] - kernelSize[ d ]/2; if ( effectiveOffset[ d ] + effectiveSize[ d ] > imgSize[ d ] ) effectiveSize[ d ] = imgSize[ d ] - effectiveOffset[ d ]; } blockList.add( new Block( blockSize, offset, effectiveSize, effectiveOffset, effectiveLocalOffset, true ) ); //System.out.println( "block " + Util.printCoordinates( currentBlock ) + " effectiveOffset: " + Util.printCoordinates( effectiveOffset ) + " effectiveSize: " + Util.printCoordinates( effectiveSize ) + " offset: " + Util.printCoordinates( offset ) + " inside: " + inside ); } final Block[] blocks = new Block[ blockList.size() ]; for ( int i = 0; i < blockList.size(); ++i ) blocks[ i ] = blockList.get( i ); return blocks; } }