This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gui] Add bilinear interpolation to AffineTransformOp


2004-11-06 Jerry Quinn <jlquinn@optonline.net>

	* java/awt/image/AffineTransformOp.java (filter):  Implement
	bilinear interpolation for Rasters.

Index: AffineTransformOp.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/AffineTransformOp.java,v
retrieving revision 1.1.2.9
retrieving revision 1.1.2.10
diff -u -r1.1.2.9 -r1.1.2.10
--- AffineTransformOp.java	3 Nov 2004 06:10:40 -0000	1.1.2.9
+++ AffineTransformOp.java	6 Nov 2004 06:39:03 -0000	1.1.2.10
@@ -45,6 +45,7 @@
 import java.awt.geom.NoninvertibleTransformException;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.util.Arrays;

 /**
  * This class performs affine transformation between two images or
@@ -207,34 +208,84 @@
         throw new IllegalArgumentException("src and dst must have same number"
 					   + " of bands");

+ double[] dpts = new double[dst.getWidth() * 2];
+ double[] pts = new double[dst.getWidth() * 2];
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ dpts[2 * x] = x + dst.getMinX();
+ dpts[2 * x + 1] = x;
+ }
Rectangle srcbounds = src.getBounds();
- for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
+ if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
{
- double[] pts = new double[dst.getWidth() * 2];
- for (int x = 0; x < dst.getWidth(); x++)
- {
- pts[2 * x] = x + dst.getMinX();
- pts[2 * x + 1] = y;
- }
- try {
- transform.inverseTransform(pts, 0, pts, 0, dst.getWidth() * 2);
- } catch (NoninvertibleTransformException e) {
- // Can't happen since the constructor traps this
- e.printStackTrace();
- }
+ for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
+ {
+ try {
+ transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
+ } catch (NoninvertibleTransformException e) {
+ // Can't happen since the constructor traps this
+ e.printStackTrace();
+ }


-        // FIXME: nearest neighbor is hardwired here.  In fact, these should
-        // be rounded properly.
-        for (int x = 0; x < dst.getWidth(); x++)
+	    for (int x = 0; x < dst.getWidth(); x++)
+	      {
+		if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
+		  continue;
+		dst.setDataElements(x + dst.getMinX(), y,
+				    src.getDataElements((int)pts[2 * x],
+							(int)pts[2 * x + 1],
+							null));
+	      }
+	  }
+      }
+      else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+      {
+        double[] tmp = new double[4 * src.getNumBands()];
+        for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
         {
-          if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
-            continue;
-          dst.setDataElements(x + dst.getMinX(), y,
-			      src.getDataElements((int)pts[2 * x],
-						  (int)pts[2 * x + 1],
-						  null));
+          try {
+            transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
+          } catch (NoninvertibleTransformException e) {
+            // Can't happen since the constructor traps this
+            e.printStackTrace();
+          }
+	
+          for (int x = 0; x < dst.getWidth(); x++)
+          {
+            if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
+              continue;
+            int xx = (int)pts[2 * x];
+            int yy = (int)pts[2 * x + 1];
+            double dx = (pts[2 * x] - xx);
+            double dy = (pts[2 * x + 1] - yy);
+		
+            // TODO write this more intelligently
+            if (xx == src.getMinX() + src.getWidth() - 1 ||
+                yy == src.getMinY() + src.getHeight() - 1)
+            {
+              // bottom or right edge
+              Arrays.fill(tmp, 0);
+              src.getPixel(xx, yy, tmp);
+            }
+            else
+	    {
+              // Normal case
+              src.getPixels(xx, yy, 2, 2, tmp);
+	      for (int b = 0; b < src.getNumBands(); b++)
+		tmp[b] = dx * dy * tmp[b]
+		  + (1 - dx) * dy * tmp[b + src.getNumBands()]
+		  + dx * (1 - dy) * tmp[b + 2 * src.getNumBands()]
+		  + (1 - dx) * (1 - dy) * tmp[b + 3 * src.getNumBands()];
+	    }
+            dst.setPixel(x, y, tmp);
+          }
         }
       }
+      else
+      {
+        // Bicubic
+        throw new UnsupportedOperationException("not implemented yet");
+      }

       return dst;
     }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]