Author: desruisseaux Date: Wed Aug 2 17:17:06 2017 New Revision: 1803883 URL: http://svn.apache.org/viewvc?rev=1803883&view=rev Log: Optimization for the common case where the requested region if fully contained inside the current tile.
Modified: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java Modified: sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java?rev=1803883&r1=1803882&r2=1803883&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-raster/src/main/java/org/apache/sis/image/DefaultIterator.java [UTF-8] Wed Aug 2 17:17:06 2017 @@ -308,46 +308,57 @@ final class DefaultIterator extends Pixe transfer = new double[window.length /*- numBands * Math.min(windowWidth, windowHeight)*/]; // 'transfer' will always have at least one row or one column less than 'window'. } - int subX = x; // Upper-left corner of a sub-window inside the window. - int subY = y; + Raster raster = currentRaster; + int subEndX = (raster.getMinX() - x) + raster.getWidth(); + int subEndY = (raster.getMinY() - y) + raster.getHeight(); + int subWidth = Math.min(windowWidth, subEndX); + int subHeight = Math.min(windowHeight, subEndY); + boolean fullWidth = (subWidth == windowWidth); + if (fullWidth && subHeight == windowHeight) { + /* + * Optimization for the case where the full window is inside current raster. + * This is the vast majority of cases, so we perform this check soon before + * to compute more internal variables. + */ + return raster.getPixels(x, y, subWidth, subHeight, window); + } + /* + * At this point, we determined that the window is overlapping two or more tiles. + * We will need more variables for iterating over the tiles around 'currentRaster'. + */ + int destOffset = 0; // Index in 'window' array where to copy the sample values. + int subX = 0; // Upper-left corner of a sub-window inside the window. + int subY = 0; int tileSubX = tileX; // The tile where is located the (subX, subY) coordinate. int tileSubY = tileY; - final int endX = subX + windowWidth; // Upper limit of the full window. May be located in another tile. - final int endY = subY + windowHeight; final int stride = windowWidth * numBands; // Number of samples between two rows in the 'windows' array. - Raster raster = currentRaster; - int subEndX = raster.getMinX() + raster.getWidth(); - int subEndY = raster.getMinY() + raster.getHeight(); final int rewind = subEndX; - int destOffset = 0; // Index in 'window' array where to copy the sample values. for (;;) { - final int subWidth = Math.min(endX, subEndX) - subX; - final int subHeight = Math.min(endY, subEndY) - subY; if (subWidth > 0 && subHeight > 0) { - final boolean fullWidth = (subWidth == windowWidth); - if (fullWidth && subHeight == windowHeight) { -// return raster.getPixels(subX, subY, subWidth, subHeight, window); - } - transfer = raster.getPixels(subX, subY, subWidth, subHeight, transfer); - final int rowLength = numBands * subWidth; - final int fullLength = rowLength * subHeight; - for (int srcOffset=0; srcOffset < fullLength; srcOffset += rowLength) { - System.arraycopy(transfer, srcOffset, window, destOffset, rowLength); - destOffset += stride; + final double[] data = raster.getPixels(x + subX, y + subY, subWidth, subHeight, transfer); + if (fullWidth) { + final int fullLength = stride * subHeight; + System.arraycopy(data, 0, window, destOffset, fullLength); + destOffset += fullLength; + } else { + final int rowLength = numBands * subWidth; + final int fullLength = rowLength * subHeight; + for (int srcOffset=0; srcOffset < fullLength; srcOffset += rowLength) { + System.arraycopy(data, srcOffset, window, destOffset, rowLength); + destOffset += stride; + } } } /* * At this point, we copied all sample values that we could obtain from the current tile. - * In most cases we will be done, since the window size should be much smaller than the tile size. - * However in a few cases the window overlaps more than one tile, in which case we need to move to - * next tile. + * Move to the next tile on current row, or if we reached the end of row move to the next row. */ - if (subEndX < endX) { + if (subEndX < windowWidth) { subX = subEndX; subEndX += tileWidth; // Next tile on the same row. tileSubX++; } else { - if (subEndY >= endY) { + if (subEndY >= windowHeight) { return window; // Completed last row of tiles. } subY = subEndY; @@ -355,10 +366,13 @@ final class DefaultIterator extends Pixe tileSubY++; tileSubX = tileX; subEndX = rewind; - subX = x; // Move x position back to the window left border. + subX = 0; // Move x position back to the window left border. } - raster = image.getTile(tileSubX, tileSubY); - destOffset = ((subY - y) * windowWidth + (subX - x)) * numBands; + raster = image.getTile(tileSubX, tileSubY); + destOffset = (subY * windowWidth + subX) * numBands; + subWidth = Math.min(windowWidth, subEndX) - subX; + subHeight = Math.min(windowHeight, subEndY) - subY; + fullWidth = (subWidth == windowWidth); } } }