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
  69:    * IndexColorModel and canFilterIndexColorModel is true, we subsitute the
  70:    * ColorModel for a filtered one here and in setPixels whenever the original
  71:    * one appears. Otherwise overrides the default ColorModel of ImageProducer
  72:    * and specifies the default RGBColorModel
  73:    *
  74:    * @param model the color model to be used most often by setPixels
  75:    *
  76:    * @see ColorModel
  77:    */
  78:   public void setColorModel(ColorModel model) 
  79:   {
  80:     if ((model instanceof IndexColorModel) && canFilterIndexColorModel)
  81:       {
  82:         ColorModel newCM = filterIndexColorModel((IndexColorModel) model);
  83:         substituteColorModel(model, newCM);
  84:         consumer.setColorModel(newmodel);
  85:       }
  86:     else
  87:       {
  88:         consumer.setColorModel(ColorModel.getRGBdefault());
  89:       }
  90:   }
  91: 
  92:   /**
  93:    * Registers a new ColorModel to subsitute for the old ColorModel when 
  94:    * setPixels encounters the a pixel with the old ColorModel. The pixel 
  95:    * remains unchanged except for a new ColorModel.
  96:    * 
  97:    * @param oldcm the old ColorModel
  98:    * @param newcm the new ColorModel
  99:    */
 100:   public void substituteColorModel(ColorModel oldcm, 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();
 115:     byte[] reds = new byte[len];
 116:     byte[] greens = new byte[len];
 117:     byte[] blues = new byte[len];
 118:     byte[] alphas = new byte[len];
 119: 
 120:     icm.getAlphas( alphas );
 121:     icm.getReds( reds );
 122:     icm.getGreens( greens );
 123:     icm.getBlues( blues );
 124: 
 125:     int transparent = icm.getTransparentPixel();
 126:     boolean needAlpha = false;
 127:     for( int i = 0; i < len; i++ )
 128:       {
 129:         int rgb = filterRGB(-1, -1, icm.getRGB(i));
 130:         alphas[i] = (byte) (rgb >> 24);
 131:         if (alphas[i] != ((byte) 0xff) && i != transparent)
 132:           needAlpha = true;
 133:         reds[i] = (byte) (rgb >> 16);
 134:         greens[i] = (byte) (rgb >> 8);
 135:         blues[i] = (byte) (rgb);
 136:       }
 137:     IndexColorModel newIcm;
 138:     if (needAlpha)
 139:       newIcm = new IndexColorModel(icm.getPixelSize(), len, reds, greens,
 140:                                    blues, alphas);
 141:     else
 142:       newIcm = new IndexColorModel(icm.getPixelSize(), len, reds, greens,
 143:                                    blues, transparent);
 144:     return newIcm;
 145:   }
 146: 
 147:   /**
 148:    * This functions filters a set of RGB pixels through filterRGB.
 149:    *
 150:    * @param x the x coordinate of the rectangle
 151:    * @param y the y coordinate of the rectangle
 152:    * @param w the width of the rectangle
 153:    * @param h the height of the rectangle
 154:    * @param pixels the array of pixel values
 155:    * @param offset the index of the first pixels in the
 156:    *        <code>pixels</code> array
 157:    * @param scansize the width to use in extracting pixels from the
 158:    *        <code>pixels</code> array
 159:    */
 160:   public void filterRGBPixels(int x, int y, int w, int h, int[] pixels,
 161:                               int offset, int scansize)
 162:   {
 163:     int index = offset;
 164:     for (int yp = 0; yp < h; yp++)
 165:       {
 166:         for (int xp = 0; xp < w; xp++)
 167:           {
 168:             pixels[index] = filterRGB(xp + x, yp + y, pixels[index]);
 169:             index++;
 170:           }
 171:         index += scansize - w;
 172:       }
 173:     consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset,
 174:                        scansize);
 175:   }
 176: 
 177:   /**
 178:    * If the ColorModel is the same ColorModel which as already converted 
 179:    * then it converts it the converted ColorModel. Otherwise it passes the 
 180:    * array of pixels through filterRGBpixels.
 181:    *
 182:    * @param x the x coordinate of the rectangle
 183:    * @param y the y coordinate of the rectangle
 184:    * @param w the width of the rectangle
 185:    * @param h the height of the rectangle
 186:    * @param model the <code>ColorModel</code> used to translate the pixels
 187:    * @param pixels the array of pixel values
 188:    * @param offset the index of the first pixels in the <code>pixels</code>
 189:    *        array
 190:    * @param scansize the width to use in extracting pixels from the
 191:    *        <code>pixels</code> array
 192:    */
 193:   public void setPixels(int x, int y, int w, int h, ColorModel model,
 194:                         byte[] pixels, int offset, int scansize)
 195:   {
 196:     if (model == origmodel)
 197:       {
 198:         consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
 199:       }
 200:     else
 201:       {
 202:         int[] filtered = new int[w];
 203:         int index = offset;
 204:         for (int yp = 0; yp < h; yp++)
 205:           {
 206:             for (int xp = 0; xp < w; xp++)
 207:               {
 208:                 filtered[xp] = model.getRGB((pixels[index] & 0xff));
 209:                 index++;
 210:               }
 211:             index += scansize - w;
 212:             filterRGBPixels(x, y + yp, w, 1, filtered, 0, w);
 213:           }
 214:       }
 215:   }
 216: 
 217:   /**
 218:    * This function delivers a rectangle of pixels where any
 219:    * pixel(m,n) is stored in the array as an <code>int</code> at
 220:    * index (n * scansize + m + offset).  
 221:    *
 222:    * @param x the x coordinate of the rectangle
 223:    * @param y the y coordinate of the rectangle
 224:    * @param w the width of the rectangle
 225:    * @param h the height of the rectangle
 226:    * @param model the <code>ColorModel</code> used to translate the pixels
 227:    * @param pixels the array of pixel values
 228:    * @param offset the index of the first pixels in the <code>pixels</code>
 229:    *        array
 230:    * @param scansize the width to use in extracting pixels from the
 231:    *        <code>pixels</code> array
 232:    */
 233:   public void setPixels(int x, int y, int w, int h, ColorModel model,
 234:                         int[] pixels, int offset, int scansize)
 235:   {
 236:     if (model == origmodel)
 237:       {
 238:         consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
 239:       }
 240:     else
 241:       {
 242:         int[] filtered = new int[w];
 243:         int index = offset;
 244:         for (int yp = 0; yp < h; yp++)
 245:           {
 246:             for (int xp = 0; xp < w; xp++)
 247:               {
 248:                 filtered[xp] = model.getRGB((pixels[index] & 0xff));
 249:                 index++;
 250:               }
 251:             index += scansize - w;
 252:             filterRGBPixels(x, y + yp, w, 1, filtered, 0, w);
 253:           }
 254:       }
 255:   }
 256: 
 257:   /**
 258:    * Filters a single pixel from the default ColorModel.
 259:    *
 260:    * @param x x-coordinate
 261:    * @param y y-coordinate
 262:    * @param rgb color
 263:    */
 264:   public abstract int filterRGB(int x, int y, int rgb);
 265: }