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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new bc36b68  Add Lanczos interpolation (experimental).
bc36b68 is described below

commit bc36b680ccf811df33986a1b0c4ce5db79cf975a
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Mar 26 01:15:04 2020 +0100

    Add Lanczos interpolation (experimental).
---
 .../java/org/apache/sis/image/Interpolation.java   |  13 +++
 .../org/apache/sis/image/LanczosInterpolation.java | 114 +++++++++++++++++++++
 2 files changed, 127 insertions(+)

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 f5d8bd3..cdb0498 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
@@ -27,6 +27,7 @@ import java.nio.DoubleBuffer;
  *
  * <p>This interface is designed for interpolations in a two-dimensional space 
only.</p>
  *
+ * @author  Rémi Marechal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @version 1.1
@@ -131,4 +132,16 @@ public interface Interpolation {
             return true;
         }
     };
+
+    /**
+     * Lanczos interpolation. The kernel is:
+     *
+     * <blockquote>
+     * <var>L</var>(<var>x</var>) = 
<var>a</var>⋅sin(π⋅<var>x</var>)⋅sin(π⋅<var>x</var>/<var>a</var>)/(π⋅<var>x</var>)²
+     * for |<var>x</var>| ≤ lanczos window size
+     * </blockquote>
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Lanczos_resampling";>Lanczos 
resampling on Wikipedia</a>
+     */
+    Interpolation LANCZOS = new LanczosInterpolation(2);
 }
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/image/LanczosInterpolation.java 
b/core/sis-feature/src/main/java/org/apache/sis/image/LanczosInterpolation.java
new file mode 100644
index 0000000..138df5f
--- /dev/null
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/image/LanczosInterpolation.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.image;
+
+import java.util.Arrays;
+import java.awt.Dimension;
+import java.nio.DoubleBuffer;
+
+
+/**
+ * Lanczos interpolation of arbitrary size.
+ * The kernel is:
+ *
+ * <blockquote>
+ * <var>L</var>(<var>x</var>) = 
<var>a</var>⋅sin(π⋅<var>x</var>)⋅sin(π⋅<var>x</var>/<var>a</var>)/(π⋅<var>x</var>)²
+ * for |<var>x</var>| ≤ lanczos window size
+ * </blockquote>
+ *
+ * @author  Rémi Marechal (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.1
+ *
+ * @see <a href="https://en.wikipedia.org/wiki/Lanczos_resampling";>Lanczos 
resampling on Wikipedia</a>
+ *
+ * @since 1.1
+ * @module
+ */
+final class LanczosInterpolation implements Interpolation {
+    /**
+     * The Lanczos window size. This is denoted <var>a</var> in this class 
javadoc.
+     */
+    private final double a;
+
+    /**
+     * Width of the interpolation support region.
+     */
+    private final int span;
+
+    /**
+     * Creates a new interpolation.
+     *
+     * @param  a  the Lanczos window size.
+     */
+    LanczosInterpolation(final int a) {
+        this.a = a;
+        span = 2*a;
+    }
+
+    /**
+     * Interpolation name for debugging purpose.
+     */
+    @Override
+    public String toString() {
+        return "LANCZOS";
+    }
+
+    /**
+     * Size of the area over which to provide values.
+     */
+    @Override
+    public Dimension getSupportSize() {
+        return new Dimension(span, span);
+    }
+
+    /**
+     * Applies Lanczos interpolation.
+     */
+    @Override
+    public boolean interpolate(final DoubleBuffer source, final int numBands,
+            final double xfrac, final double yfrac, final double[] writeTo, 
final int writeToOffset)
+    {
+        Arrays.fill(writeTo, writeToOffset, writeToOffset + numBands, 0);
+        final double[] kx = new double[span];
+        final double[] ky = new double[span];
+        for (int i=0; i<span; i++) {
+            final double offset = i - a;
+            kx[i] = kernel(offset + xfrac);
+            ky[i] = kernel(offset + yfrac);
+        }
+        source.mark();
+        for (int y=0; y<span; y++) {
+            for (int x=0; x<span; x++) {
+                final double k = kx[x] * ky[y];
+                for (int b=0; b<numBands; b++) {
+                    writeTo[writeToOffset + b] += k * source.get();
+                }
+            }
+        }
+        source.reset();
+        return true;
+    }
+
+    /**
+     * Computes a value of the Lanczos reconstruction kernel L(x).
+     */
+    private double kernel(double x) {
+        x *= Math.PI;
+        return (x != 0) ? Math.sin(x) * Math.sin(x/a)*a / (x*x) : 1;
+    }
+}

Reply via email to