summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt/image/RGBImageFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/awt/image/RGBImageFilter.java')
-rw-r--r--libjava/classpath/java/awt/image/RGBImageFilter.java267
1 files changed, 267 insertions, 0 deletions
diff --git a/libjava/classpath/java/awt/image/RGBImageFilter.java b/libjava/classpath/java/awt/image/RGBImageFilter.java
new file mode 100644
index 00000000000..f7b39b97b28
--- /dev/null
+++ b/libjava/classpath/java/awt/image/RGBImageFilter.java
@@ -0,0 +1,267 @@
+/* RGBImageFilter.java -- Java class for filtering Pixels by RGB values
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+/**
+ * A filter designed to filter images in the default RGBColorModel regardless of
+ * the ImageProducer's ColorModel.
+ *
+ * @author Mark Benvenuto (mcb54@columbia.edu)
+ */
+public abstract class RGBImageFilter extends ImageFilter
+{
+ protected ColorModel origmodel;
+
+ protected ColorModel newmodel;
+
+ /**
+ Specifies whether to apply the filter to the index entries of the
+ IndexColorModel. Subclasses should set this to true if the filter
+ does not depend on the pixel's coordinate.
+ */
+ protected boolean canFilterIndexColorModel = false;
+
+ /**
+ Construct new RGBImageFilter.
+ */
+ public RGBImageFilter()
+ {
+ }
+
+ /**
+ * Sets the ColorModel used to filter with. If the specified ColorModel is IndexColorModel
+ * and canFilterIndexColorModel is true, we subsitute the ColorModel for a filtered one
+ * here and in setPixels whenever the original one appears. Otherwise overrides the default
+ * ColorModel of ImageProducer and specifies the default RGBColorModel
+ *
+ * @param model the color model to be used most often by setPixels
+ * @see ColorModel */
+ public void setColorModel(ColorModel model)
+ {
+ origmodel = model;
+ newmodel = model;
+
+ if( ( model instanceof IndexColorModel) && canFilterIndexColorModel ) {
+ newmodel = filterIndexColorModel( (IndexColorModel) model );
+ consumer.setColorModel(newmodel);
+ }
+ else {
+ consumer.setColorModel(ColorModel.getRGBdefault());
+ }
+ }
+
+ /**
+ Registers a new ColorModel to subsitute for the old ColorModel when
+ setPixels encounters the a pixel with the old ColorModel. The pixel
+ remains unchanged except for a new ColorModel.
+
+ @param oldcm the old ColorModel
+ @param newcm the new ColorModel
+ */
+ public void substituteColorModel(ColorModel oldcm,
+ ColorModel newcm)
+ {
+ origmodel = oldcm;
+ newmodel = newcm;
+ }
+
+ /**
+ Filters an IndexColorModel through the filterRGB function. Uses
+ coordinates of -1 to indicate its filtering an index and not a pixel.
+
+ @param icm an IndexColorModel to filter
+ */
+ public IndexColorModel filterIndexColorModel(IndexColorModel icm)
+ {
+ int len = icm.getMapSize(), rgb;
+ byte reds[] = new byte[len], greens[] = new byte[len], blues[] = new byte[len], alphas[] = new byte[len];
+
+ icm.getAlphas( alphas );
+ icm.getReds( reds );
+ icm.getGreens( greens );
+ icm.getBlues( blues );
+
+ for( int i = 0; i < len; i++ )
+ {
+ rgb = filterRGB( -1, -1, makeColor ( alphas[i], reds[i], greens[i], blues[i] ) );
+ alphas[i] = (byte)(( 0xff000000 & rgb ) >> 24);
+ reds[i] = (byte)(( 0xff0000 & rgb ) >> 16);
+ greens[i] = (byte)(( 0xff00 & rgb ) >> 8);
+ blues[i] = (byte)(0xff & rgb);
+ }
+ return new IndexColorModel( icm.getPixelSize(), len, reds, greens, blues, alphas );
+ }
+
+ private int makeColor( byte a, byte r, byte g, byte b )
+ {
+ return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b );
+ }
+
+ /**
+ This functions filters a set of RGB pixels through filterRGB.
+
+ @param x the x coordinate of the rectangle
+ @param y the y coordinate of the rectangle
+ @param w the width of the rectangle
+ @param h the height of the rectangle
+ @param pixels the array of pixel values
+ @param offset the index of the first pixels in the <code>pixels</code> array
+ @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void filterRGBPixels(int x, int y, int w, int h, int[] pixels,
+ int offset, int scansize)
+ {
+ for (int yp = 0; yp < h; yp++)
+ {
+ for (int xp = 0; xp < w; xp++)
+ {
+ pixels[offset + xp] = filterRGB(xp + x, yp + y, pixels[offset + xp]);
+ }
+ offset += scansize;
+ }
+ }
+
+
+ /**
+ * If the ColorModel is the same ColorModel which as already converted
+ * then it converts it the converted ColorModel. Otherwise it passes the
+ * array of pixels through filterRGBpixels.
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels,
+ int offset, int scansize)
+ {
+ if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
+ {
+ consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
+ }
+ else
+ {
+ int intPixels[] =
+ convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
+ filterRGBPixels( x, y, w, h, intPixels, offset, scansize );
+ consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), intPixels, offset, scansize);
+ }
+ }
+
+ /**
+ * This function delivers a rectangle of pixels where any
+ * pixel(m,n) is stored in the array as an <code>int</code> at
+ * index (n * scansize + m + offset).
+ *
+ * @param x the x coordinate of the rectangle
+ * @param y the y coordinate of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param model the <code>ColorModel</code> used to translate the pixels
+ * @param pixels the array of pixel values
+ * @param offset the index of the first pixels in the <code>pixels</code> array
+ * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
+ */
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels,
+ int offset, int scansize)
+ {
+ if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
+ {
+ consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
+ }
+ else
+ {
+ //FIXME: Store the filtered pixels in a separate temporary buffer?
+ convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
+ filterRGBPixels( x, y, w, h, pixels, offset, scansize );
+ consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, scansize);
+ }
+ }
+
+ private int[] convertColorModelToDefault(int x, int y, int w, int h,
+ ColorModel model, byte pixels[],
+ int offset, int scansize)
+ {
+ int intPixels[] = new int[pixels.length];
+ for (int i = 0; i < pixels.length; i++)
+ intPixels[i] = makeColorbyDefaultCM(model, pixels[i]);
+ return intPixels;
+ }
+
+ private void convertColorModelToDefault(int x, int y, int w, int h,
+ ColorModel model, int pixels[],
+ int offset, int scansize)
+ {
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = makeColorbyDefaultCM(model, pixels[i]);
+ }
+
+ private int makeColorbyDefaultCM(ColorModel model, byte rgb)
+ {
+ return makeColor( model.getAlpha( rgb ) * 4, model.getRed( rgb ) * 4, model.getGreen( rgb ) * 4, model.getBlue( rgb ) * 4 );
+ }
+
+ private int makeColorbyDefaultCM(ColorModel model, int rgb)
+ {
+ return makeColor( model.getAlpha( rgb ), model.getRed( rgb ), model.getGreen( rgb ), model.getBlue( rgb ) );
+ }
+
+ private int makeColor( int a, int r, int g, int b )
+ {
+ return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b );
+ }
+
+
+ /**
+ Filters a single pixel from the default ColorModel.
+
+ @param x x-coordinate
+ @param y y-coordinate
+ @param rgb color
+ */
+ public abstract int filterRGB(int x,
+ int y,
+ int rgb);
+}