sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 04/04: Fix a 0.5 pixel offset when Interpolation.NEAREST is used.
Date Thu, 03 Sep 2020 13:51:13 GMT
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 <martin.desruisseaux@geomatys.com>
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))


Mime
View raw message