This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 4a44a2b511a0beca0c9e28d383a4acba719e179e Author: Martin Desruisseaux <[email protected]> AuthorDate: Thu Sep 3 15:13:51 2020 +0200 Fix a 0.5 pixel offset when Interpolation.NEAREST is used. --- .../src/main/java/org/apache/sis/image/Interpolation.java | 1 + .../src/main/java/org/apache/sis/image/ResampledImage.java | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java b/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java index 3eee8df..60916ab 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java +++ b/core/sis-feature/src/main/java/org/apache/sis/image/Interpolation.java @@ -117,6 +117,7 @@ public interface Interpolation { @Override public void interpolate(final DoubleBuffer source, final int numBands, final double xfrac, final double yfrac, final double[] writeTo, int writeToOffset) { + // TODO: use `get(position(), …)` with JDK13 for avoiding mark/reset. source.mark(); source.get(writeTo, writeToOffset, numBands); source.reset(); diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java index de94d0d..f053baa 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java @@ -327,6 +327,7 @@ public class ResampledImage extends ComputedImage { * @see #toSourceSupport */ static double interpolationSupportOffset(final int span) { + if (span <= 1) return 0.5; // Nearest-neighbor (special case). return -Math.max(0, (span - 1) / 2); // Round toward 0. } @@ -634,7 +635,7 @@ public class ResampledImage extends ComputedImage { ymax = domain.getMaxY() - 1; xlim = xmax + support.width - 0.5; // Limit of coordinates where we can interpolate. ylim = ymax + support.height - 0.5; - xoff = interpolationSupportOffset(support.width) - 0.5; // Always negative. + xoff = interpolationSupportOffset(support.width) - 0.5; // Always negative (or 0 for nearest-neighbor). yoff = interpolationSupportOffset(support.height) - 0.5; } /* @@ -643,7 +644,7 @@ public class ResampledImage extends ComputedImage { * for minimal and maximal values. Shortcut may apply to both integer values and floating point values. */ final boolean useFillValues = (getDestination() == null); - final boolean shortcut = useFillValues && (interpolation == Interpolation.NEAREST) && + final boolean shortcut = useFillValues && Interpolation.NEAREST.equals(interpolation) && ImageUtilities.isLosslessConversion(sampleModel, tile.getSampleModel()); /* * Prepare a buffer where to store a line of interpolated values. We use this buffer for transferring @@ -719,9 +720,9 @@ public class ResampledImage extends ComputedImage { int ci = 0; // Index in `coordinates` array. int vi = 0; // Index in `values` or `intValues` array. for (int tx=tileMinX; tx<tileMaxX; tx++, ci+=tgtDim, vi+=numBands) { - final long x = Math.round(coordinates[ci]); + final long x = (long) Math.floor(coordinates[ci]); if (x >= it.lowerX && x < it.upperX) { - final long y = Math.round(coordinates[ci+1]); + final long y = (long) Math.floor(coordinates[ci+1]); if (y >= it.lowerY && y < it.upperY) { if (sx != (sx = (int) x) | // Really |, not ||. sy != (sy = (int) y))
