home *** CD-ROM | disk | FTP | other *** search
/ Chip: Shareware for Win 95 / Chip-Shareware-Win95.bin / ostatni / powerj / java.z / RGBImageFilter.java < prev    next >
Encoding:
Java Source  |  1996-05-03  |  8.4 KB  |  239 lines

  1. /*
  2.  * @(#)RGBImageFilter.java    1.10 95/12/14 Jim Graham
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.awt.image;
  21.  
  22. import java.awt.image.ImageConsumer;
  23. import java.awt.image.ColorModel;
  24.  
  25. /**
  26.  * This class provides an easy way to create an ImageFilter which modifies
  27.  * the pixels of an image in the default RGB ColorModel.  It is meant to
  28.  * be used in conjunction with a FilteredImageSource object to produce
  29.  * filtered versions of existing images.  It is an abstract class that
  30.  * provides the calls needed to channel all of the pixel data through a
  31.  * single method which converts pixels one at a time in the default RGB
  32.  * ColorModel regardless of the ColorModel being used by the ImageProducer.
  33.  * The only method which needs to be defined to create a useable image
  34.  * filter is the filterRGB method.  Here is an example of a definition
  35.  * of a filter which swaps the red and blue components of an image:
  36.  * <pre>
  37.  *
  38.  *    class RedBlueSwapFilter extends RGBImageFilter {
  39.  *        public RedBlueSwapFilter() {
  40.  *        // The filter's operation does not depend on the
  41.  *        // pixel's location, so IndexColorModels can be
  42.  *        // filtered directly.
  43.  *        canFilterIndexColorModel = true;
  44.  *        }
  45.  *
  46.  *        public int filterRGB(int x, int y, int rgb) {
  47.  *        return ((rgb & 0xff00ff00)
  48.  *            | ((rgb & 0xff0000) >> 16)
  49.  *            | ((rgb & 0xff) << 16));
  50.  *        }
  51.  *    }
  52.  *
  53.  * </pre>
  54.  *
  55.  * @see FilteredImageSource
  56.  * @see ImageFilter
  57.  * @see ColorModel#getRGBdefault
  58.  *
  59.  * @version    1.10 14 Dec 1995
  60.  * @author     Jim Graham
  61.  */
  62. public abstract class RGBImageFilter extends ImageFilter {
  63.     protected ColorModel origmodel;
  64.     protected ColorModel newmodel;
  65.  
  66.     /**
  67.      * This boolean indicates whether or not it is acceptable to apply
  68.      * the color filtering of the filterRGB method to the color table
  69.      * entries of an IndexColorModel object in lieu of pixel by pixel
  70.      * filtering.  Subclasses should set this variable to true in their
  71.      * constructor if their filterRGB method does not depend on the
  72.      * coordinate of the pixel being filtered.
  73.      * @see #substituteColorModel
  74.      * @see #filterRGB
  75.      * @see IndexColorModel
  76.      */
  77.     protected boolean canFilterIndexColorModel;
  78.  
  79.     /**
  80.      * If the ColorModel is an IndexColorModel, and the subclass has
  81.      * set the canFilterIndexColorModel flag to true, we substitute
  82.      * a filtered version of the color model here and wherever
  83.      * that original ColorModel object appears in the setPixels methods. Otherwise
  84.      * overrides the default ColorModel used by the ImageProducer and
  85.      * specifies the default RGB ColorModel instead.
  86.  
  87.      * @see ImageConsumer
  88.      * @see ColorModel#getRGBdefault
  89.      */
  90.     public void setColorModel(ColorModel model) {
  91.     if (canFilterIndexColorModel && (model instanceof IndexColorModel)) {
  92.         ColorModel newcm = filterIndexColorModel((IndexColorModel)model);
  93.         substituteColorModel(model, newcm);
  94.         consumer.setColorModel(newcm);
  95.     } else {
  96.         consumer.setColorModel(ColorModel.getRGBdefault());
  97.     }
  98.     }
  99.  
  100.     /**
  101.      * Registers two ColorModel objects for substitution.  If the oldcm
  102.      * is encountered during any of the setPixels methods, the newcm
  103.      * is substituted and the pixels passed through
  104.      * untouched (but with the new ColorModel object).
  105.      * @param oldcm the ColorModel object to be replaced on the fly
  106.      * @param newcm the ColorModel object to replace oldcm on the fly
  107.      */
  108.     public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
  109.     origmodel = oldcm;
  110.     newmodel = newcm;
  111.     }
  112.  
  113.     /**
  114.      * Filters an IndexColorModel object by running each entry in its
  115.      * color tables through the filterRGB function that RGBImageFilter
  116.      * subclasses must provide.  Uses coordinates of -1 to indicate that
  117.      * a color table entry is being filtered rather than an actual
  118.      * pixel value.
  119.      * @param icm the IndexColorModel object to be filtered
  120.      * @return a new IndexColorModel representing the filtered colors
  121.      */
  122.     public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
  123.     int mapsize = icm.getMapSize();
  124.     byte r[] = new byte[mapsize];
  125.     byte g[] = new byte[mapsize];
  126.     byte b[] = new byte[mapsize];
  127.     byte a[] = new byte[mapsize];
  128.     icm.getReds(r);
  129.     icm.getGreens(g);
  130.     icm.getBlues(b);
  131.     icm.getAlphas(a);
  132.     int trans = icm.getTransparentPixel();
  133.     boolean needalpha = false;
  134.     for (int i = 0; i < mapsize; i++) {
  135.         int rgb = filterRGB(-1, -1, icm.getRGB(i));
  136.         a[i] = (byte) (rgb >> 24);
  137.         if (a[i] != ((byte)0xff) && i != trans) {
  138.         needalpha = true;
  139.         }
  140.         r[i] = (byte) (rgb >> 16);
  141.         g[i] = (byte) (rgb >> 8);
  142.         b[i] = (byte) (rgb >> 0);
  143.     }
  144.     if (needalpha) {
  145.         return new IndexColorModel(icm.getPixelSize(), mapsize,
  146.                        r, g, b, a);
  147.     } else {
  148.         return new IndexColorModel(icm.getPixelSize(), mapsize,
  149.                        r, g, b, trans);
  150.     }
  151.     }
  152.  
  153.     /**
  154.      * Filters a buffer of pixels in the default RGB ColorModel by passing
  155.      * them one by one through the filterRGB method.
  156.      * @see ColorModel#getRGBdefault
  157.      * @see #filterRGB
  158.      */
  159.     public void filterRGBPixels(int x, int y, int w, int h,
  160.                 int pixels[], int off, int scansize) {
  161.     int index = off;
  162.     for (int cy = 0; cy < h; cy++) {
  163.         for (int cx = 0; cx < w; cx++) {
  164.         pixels[index] = filterRGB(x + cx, y + cy, pixels[index]);
  165.         index++;
  166.         }
  167.         index += scansize - w;
  168.     }
  169.     consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(),
  170.                pixels, off, scansize);
  171.     }
  172.  
  173.     /**
  174.      * If the ColorModel object is the same one that has already
  175.      * been converted, then simply passes the pixels through with the
  176.      * converted ColorModel. Otherwise converts the buffer of byte
  177.      * pixels to the default RGB ColorModel and passes the converted
  178.      * buffer to the filterRGBPixels method to be converted one by one.
  179.      * @see ColorModel#getRGBdefault
  180.      * @see #filterRGBPixels
  181.      */
  182.     public void setPixels(int x, int y, int w, int h,
  183.               ColorModel model, byte pixels[], int off,
  184.               int scansize) {
  185.     if (model == origmodel) {
  186.         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
  187.     } else {
  188.         int filteredpixels[] = new int[w];
  189.         int index = off;
  190.         for (int cy = 0; cy < h; cy++) {
  191.         for (int cx = 0; cx < w; cx++) {
  192.             filteredpixels[cx] = model.getRGB((pixels[index] & 0xff));
  193.             index++;
  194.         }
  195.         index += scansize - w;
  196.         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
  197.         }
  198.     }
  199.     }
  200.  
  201.     /**
  202.      * If the ColorModel object is the same one that has already
  203.      * been converted, then simply passes the pixels through with the
  204.      * converted ColorModel, otherwise converts the buffer of integer
  205.      * pixels to the default RGB ColorModel and passes the converted
  206.      * buffer to the filterRGBPixels method to be converted one by one.
  207.      * Converts a buffer of integer pixels to the default RGB ColorModel
  208.      * and passes the converted buffer to the filterRGBPixels method.
  209.      * @see ColorModel#getRGBdefault
  210.      * @see #filterRGBPixels
  211.      */
  212.     public void setPixels(int x, int y, int w, int h,
  213.               ColorModel model, int pixels[], int off,
  214.               int scansize) {
  215.     if (model == origmodel) {
  216.         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
  217.     } else {
  218.         int filteredpixels[] = new int[w];
  219.         int index = off;
  220.         for (int cy = 0; cy < h; cy++) {
  221.         for (int cx = 0; cx < w; cx++) {
  222.             filteredpixels[cx] = model.getRGB(pixels[index]);
  223.             index++;
  224.         }
  225.         index += scansize - w;
  226.         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
  227.         }
  228.     }
  229.     }
  230.  
  231.     /**
  232.      * Subclasses must specify a method to convert a single input pixel
  233.      * in the default RGB ColorModel to a single output pixel.
  234.      * @see ColorModel#getRGBdefault
  235.      * @see #filterRGBPixels
  236.      */
  237.     public abstract int filterRGB(int x, int y, int rgb);
  238. }
  239.