This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gui] Add bilinear interpolation to AffineTransformOp
- From: Jerry Quinn <jlquinn at optonline dot net>
- To: java-patches at gcc dot gnu dot org
- Date: Sat, 06 Nov 2004 01:43:53 -0500
- Subject: [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;
}