Attaching the patch this time.

On Wed, 2006-09-13 at 16:59 -0400, Francis Kung wrote:
> Hi,
> 
> This patch, committed, optimizes filtering in
> java.awt.image.BandCombineOp.
> 
> With this patch, running on cacao, our filtering is faster (!) than
> Sun's for small images (under ~ 150x150 pixels), but doesn't scale as
> well to larger images.
> 
> One catch is that the Op now does int arithmetic, instead of using
> floats (floats will be rounded and cast).  Using floats as image sample
> datatypes is pretty rare though (I think), and I've added a note in our
> API documentation about this (Sun's API states, "... built-in image
> processing operators may not operate on all possible sample types, but
> generally will work for unsigned integral samples of 16 bits or less.").
> I think the speed tradeoff is worth it.
> 
> Regards,
> Francis
> 
> 
> 2006-09-13  Francis Kung  <[EMAIL PROTECTED]>
> 
>       * java/awt/image/BandCombineOp.java: Updated documentation.
>       (filter(Raster, WritableRaster)): Use int arrays, and added simple
> cache.
> 
Index: java/awt/image/BandCombineOp.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/image/BandCombineOp.java,v
retrieving revision 1.5
diff -u -r1.5 BandCombineOp.java
--- java/awt/image/BandCombineOp.java	14 Aug 2006 16:12:38 -0000	1.5
+++ java/awt/image/BandCombineOp.java	13 Sep 2006 21:01:12 -0000
@@ -40,6 +40,7 @@
 import java.awt.RenderingHints;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
 
 /**
  * Filter Raster pixels by applying a matrix.
@@ -53,6 +54,9 @@
  * for the destination.  Therefore the destination Raster must contain the
  * same number of bands as the number of rows in the filter matrix.
  * 
+ * This Op assumes that samples are integers; floating point sample types will
+ * be rounded to their nearest integer value during filtering.
+ * 
  * @author Jerry Quinn ([EMAIL PROTECTED])
  */
 public class BandCombineOp implements RasterOp
@@ -109,19 +113,27 @@
       throw new IllegalArgumentException("Destination raster is incompatible with source raster");
 
     // Filter the pixels
-    float[] spix = new float[matrix[0].length - 1];
-    float[] dpix = new float[matrix.length];
+    int[] spix = new int[matrix[0].length - 1];
+    int[] spix2 = new int[matrix[0].length - 1];
+    int[] dpix = new int[matrix.length];
     for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
       for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
         {
           // In case matrix rows have implicit translation
-          spix[spix.length - 1] = 1.0f;
+          spix[spix.length - 1] = 1;
           src.getPixel(x, y, spix);
-          for (int i = 0; i < matrix.length; i++)
+          
+          // Do not re-calculate if pixel is identical to the last one
+          // (ie, blocks of the same colour)
+          if (!Arrays.equals(spix, spix2))
             {
-              dpix[i] = 0;
-              for (int j = 0; j < matrix[0].length - 1; j++)
-                dpix[i] += spix[j] * matrix[i][j];
+              System.arraycopy(spix, 0, spix2, 0, spix.length);
+              for (int i = 0; i < matrix.length; i++)
+                {
+                  dpix[i] = 0;
+                  for (int j = 0; j < matrix[0].length - 1; j++)
+                    dpix[i] += spix[j] * (int)matrix[i][j];
+                }
             }
           dest.setPixel(x, y, dpix);
         }
Index: ChangeLog
===================================================================
RCS file: /cvsroot/classpath/classpath/ChangeLog,v
retrieving revision 1.8536
diff -u -r1.8536 ChangeLog
--- ChangeLog	13 Sep 2006 17:18:01 -0000	1.8536
+++ ChangeLog	13 Sep 2006 21:01:12 -0000
@@ -1,5 +1,10 @@
 2006-09-13  Francis Kung  <[EMAIL PROTECTED]>
 
+	* java/awt/image/BandCombineOp.java: Updated documentation.
+	(filter(Raster, WritableRaster)): Use int arrays, and added simple cache.
+
+2006-09-13  Francis Kung  <[EMAIL PROTECTED]>
+
 	* java/awt/image/ConvolveOp.java (filter(Raster, WritableRaster)):
 	Removed hard-coded max sample value.
 	* java/awt/image/RescaleOp.java (filter(Raster, WritableRaster)): 

Reply via email to