Source for java.awt.image.RGBImageFilter

   1: /* RGBImageFilter.java -- Java class for filtering Pixels by RGB values
   2:    Copyright (C) 1999, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt.image;
  40: 
  41: /**
  42:  * A filter designed to filter images in the default RGBColorModel regardless of 
  43:  * the ImageProducer's ColorModel.
  44:  *
  45:  * @author Mark Benvenuto (mcb54@columbia.edu)
  46:  */
  47: public abstract class RGBImageFilter extends ImageFilter
  48: {
  49:     protected ColorModel origmodel;
  50: 
  51:     protected ColorModel newmodel;
  52:     
  53:     /**
  54:        Specifies whether to apply the filter to the index entries of the 
  55:        IndexColorModel. Subclasses should set this to true if the filter 
  56:        does not depend on the pixel's coordinate.
  57:      */
  58:     protected boolean canFilterIndexColorModel = false;
  59: 
  60:     /**
  61:        Construct new RGBImageFilter.
  62:      */
  63:     public RGBImageFilter() 
  64:     {
  65:     }
  66: 
  67:     /**
  68:      * Sets the ColorModel used to filter with. If the specified ColorModel is IndexColorModel 
  69:      * and canFilterIndexColorModel is true, we subsitute the ColorModel for a filtered one
  70:      * here and in setPixels whenever the original one appears. Otherwise overrides the default
  71:      * ColorModel of ImageProducer and specifies the default RGBColorModel
  72:      *
  73:      * @param model the color model to be used most often by setPixels
  74:      * @see ColorModel */
  75:     public void setColorModel(ColorModel model) 
  76:     {
  77:     origmodel = model;
  78:     newmodel = model;
  79: 
  80:     if( ( model instanceof IndexColorModel) && canFilterIndexColorModel  ) {
  81:         newmodel = filterIndexColorModel( (IndexColorModel) model );
  82:         if (consumer != null)
  83:           consumer.setColorModel(newmodel);
  84:         }
  85:     else {
  86:       if (consumer != null)
  87:         consumer.setColorModel(ColorModel.getRGBdefault());
  88:     }
  89:     }
  90:     
  91:     /**
  92:        Registers a new ColorModel to subsitute for the old ColorModel when 
  93:        setPixels encounters the a pixel with the old ColorModel. The pixel 
  94:        remains unchanged except for a new ColorModel.
  95:        
  96:        @param oldcm the old ColorModel
  97:        @param newcm the new ColorModel
  98:      */
  99:     public void substituteColorModel(ColorModel oldcm,
 100:                      ColorModel newcm)
 101:     {
 102:     origmodel = oldcm;
 103:     newmodel = newcm;
 104:     }
 105: 
 106:     /**
 107:        Filters an IndexColorModel through the filterRGB function. Uses
 108:        coordinates of -1 to indicate its filtering an index and not a pixel.
 109: 
 110:        @param icm an IndexColorModel to filter
 111:      */
 112:     public IndexColorModel filterIndexColorModel(IndexColorModel icm) 
 113:     {
 114:     int len = icm.getMapSize(), rgb;
 115:     byte reds[] = new byte[len], greens[] = new byte[len], blues[] = new byte[len], alphas[]  = new byte[len];
 116:     
 117:     icm.getAlphas( alphas );
 118:     icm.getReds( reds );
 119:     icm.getGreens( greens );
 120:     icm.getBlues( blues );
 121: 
 122:     for( int i = 0; i < len; i++ )
 123:         {
 124:         rgb = filterRGB( -1, -1, makeColor ( alphas[i], reds[i], greens[i], blues[i] ) );
 125:         alphas[i] = (byte)(( 0xff000000 & rgb ) >> 24);
 126:         reds[i] = (byte)(( 0xff0000 & rgb ) >> 16);
 127:         greens[i] = (byte)(( 0xff00 & rgb ) >> 8);
 128:         blues[i] = (byte)(0xff & rgb);
 129:         }
 130:     return new IndexColorModel( icm.getPixelSize(), len, reds, greens, blues, alphas );
 131:     }
 132: 
 133:     private int makeColor( byte a, byte r, byte g, byte b )
 134:     {
 135:     return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b ); 
 136:     }
 137: 
 138:     /**
 139:        This functions filters a set of RGB pixels through filterRGB.
 140: 
 141:        @param x the x coordinate of the rectangle
 142:        @param y the y coordinate of the rectangle
 143:        @param w the width of the rectangle
 144:        @param h the height of the rectangle
 145:        @param pixels the array of pixel values
 146:        @param offset the index of the first pixels in the <code>pixels</code> array
 147:        @param scansize the width to use in extracting pixels from the <code>pixels</code> array
 148:     */
 149:     public void filterRGBPixels(int x, int y, int w, int h, int[] pixels,
 150:                 int offset, int scansize)
 151:     {
 152:       for (int yp = 0; yp < h; yp++)
 153:     {
 154:       for (int xp = 0; xp < w; xp++)
 155:         {
 156:           pixels[offset + xp] = filterRGB(xp + x, yp + y, pixels[offset + xp]);
 157:         }
 158:       offset += scansize;
 159:     }
 160:     }
 161: 
 162: 
 163:     /**
 164:      * If the ColorModel is the same ColorModel which as already converted 
 165:      * then it converts it the converted ColorModel. Otherwise it passes the 
 166:      * array of pixels through filterRGBpixels.
 167:      *
 168:      * @param x the x coordinate of the rectangle
 169:      * @param y the y coordinate of the rectangle
 170:      * @param w the width of the rectangle
 171:      * @param h the height of the rectangle
 172:      * @param model the <code>ColorModel</code> used to translate the pixels
 173:      * @param pixels the array of pixel values
 174:      * @param offset the index of the first pixels in the <code>pixels</code> array
 175:      * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
 176:      */
 177:     public void setPixels(int x, int y, int w, int h, 
 178:                           ColorModel model, byte[] pixels,
 179:                           int offset, int scansize)
 180:     {
 181:     if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
 182:     {
 183:       if (consumer != null)
 184:         consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
 185:     }
 186:     else
 187:     {
 188:         int intPixels[] =
 189:         convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
 190:         filterRGBPixels( x, y, w, h, intPixels, offset, scansize );
 191:         if (consumer != null)
 192:           consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), intPixels, offset, scansize);
 193:     }
 194:     }
 195: 
 196:     /**
 197:      * This function delivers a rectangle of pixels where any
 198:      * pixel(m,n) is stored in the array as an <code>int</code> at
 199:      * index (n * scansize + m + offset).  
 200:      *
 201:      * @param x the x coordinate of the rectangle
 202:      * @param y the y coordinate of the rectangle
 203:      * @param w the width of the rectangle
 204:      * @param h the height of the rectangle
 205:      * @param model the <code>ColorModel</code> used to translate the pixels
 206:      * @param pixels the array of pixel values
 207:      * @param offset the index of the first pixels in the <code>pixels</code> array
 208:      * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
 209:      */
 210:     public void setPixels(int x, int y, int w, int h, 
 211:                           ColorModel model, int[] pixels,
 212:                           int offset, int scansize)
 213:     {
 214:     if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
 215:     {
 216:       if (consumer != null)
 217:         consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
 218:     }
 219:     else
 220:     {
 221:         //FIXME: Store the filtered pixels in a separate temporary buffer?
 222:       convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
 223:       filterRGBPixels( x, y, w, h, pixels, offset, scansize );
 224:       if (consumer != null)
 225:         consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, scansize);
 226:     }
 227:     }
 228: 
 229:     private int[] convertColorModelToDefault(int x, int y, int w, int h, 
 230:                                             ColorModel model, byte pixels[],
 231:                                             int offset, int scansize)
 232:     {
 233:     int intPixels[] = new int[pixels.length];
 234:     for (int i = 0; i < pixels.length; i++)
 235:         intPixels[i] = makeColorbyDefaultCM(model, pixels[i]);
 236:     return intPixels;
 237:     }
 238: 
 239:     private void convertColorModelToDefault(int x, int y, int w, int h, 
 240:                                             ColorModel model, int pixels[],
 241:                                             int offset, int scansize)
 242:     {
 243:     for (int i = 0; i < pixels.length; i++)
 244:         pixels[i] = makeColorbyDefaultCM(model, pixels[i]);
 245:     }
 246: 
 247:     private int makeColorbyDefaultCM(ColorModel model, byte rgb) 
 248:     {
 249:     return makeColor( model.getAlpha( rgb ) * 4, model.getRed( rgb ) * 4, model.getGreen( rgb ) * 4, model.getBlue( rgb ) * 4 );
 250:     }
 251: 
 252:     private int makeColorbyDefaultCM(ColorModel model, int rgb) 
 253:     {
 254:     return makeColor( model.getAlpha( rgb ), model.getRed( rgb ), model.getGreen( rgb ), model.getBlue( rgb ) );
 255:     }
 256: 
 257:     private int makeColor( int a, int r, int g, int b )
 258:     {
 259:     return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b ); 
 260:     }
 261: 
 262: 
 263:     /**
 264:        Filters a single pixel from the default ColorModel.
 265: 
 266:        @param x x-coordinate
 267:        @param y y-coordinate
 268:        @param rgb color
 269:      */
 270:     public abstract int filterRGB(int x,
 271:                   int y,
 272:                   int rgb);
 273: }