home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / RGBImageFilter.java < prev    next >
Text File  |  1997-10-27  |  9KB  |  242 lines

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