/* * $Id$ * * Copyright 2011 Glencoe Software, Inc. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package omero.util; /** * @author Josh Moore, josh at glencoesoftware.com * @since 4.3.0 */ public abstract class TileLoop { /** * Subclasses must provide a fresh instance of {@link TileData}. * The instance will be closed after the run of * {@link #forEachTile(int, int, int, int, int, int, int, TileLoopIteration)}. * @return the new instance */ public abstract TileData createData(); /** * Iterates over every tile in a given pixel based on the * over arching dimensions and a requested maximum tile width and height. * @param sizeX the size of the plane's X dimension * @param sizeY the size of the plane's Y dimension * @param sizeZ the size of the plane's Z dimension * @param sizeC the size of the plane's C dimension * @param sizeT the size of the plane's T dimension * @param iteration Invoker to call for each tile. * @param tileWidth <b>Maximum</b> width of the tile requested. The tile * request itself will be smaller than the original tile width requested if * <code>x + tileWidth > sizeX</code>. * @param tileHeight <b>Maximum</b> height of the tile requested. The tile * request itself will be smaller if <code>y + tileHeight > sizeY</code>. * @return The total number of tiles iterated over. */ public int forEachTile(int sizeX, int sizeY, int sizeZ, int sizeC, int sizeT, int tileWidth, int tileHeight, TileLoopIteration iteration) { final TileData data = createData(); try { int x, y, w, h; int tileCount = 0; for (int t = 0; t < sizeT; t++) { for (int c = 0; c < sizeC; c++) { for (int z = 0; z < sizeZ; z++) { for (int tileOffsetY = 0; tileOffsetY < (sizeY + tileHeight - 1) / tileHeight; tileOffsetY++) { for (int tileOffsetX = 0; tileOffsetX < (sizeX + tileWidth - 1) / tileWidth; tileOffsetX++) { x = tileOffsetX * tileWidth; y = tileOffsetY * tileHeight; w = tileWidth; if (w + x > sizeX) { w = sizeX - x; } h = tileHeight; if (h + y > sizeY) { h = sizeY - y; } iteration.run(data, z, c, t, x, y, w, h, tileCount); tileCount++; } } } } } return tileCount; } finally { data.close(); } } }