Source for java.awt.image.ReplicateScaleFilter

   1: /* ReplicateScaleFilter.java -- Java class for filtering images
   2:    Copyright (C) 1999 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: import java.util.Hashtable;
  42: 
  43: /**
  44:  * This filter should be used for fast scaling of images where the result
  45:  * does not need to ensure straight lines are still straight, etc.  The
  46:  * exact method is not defined by Sun but some sort of fast Box filter should
  47:  * probably be correct.
  48:  * <br>
  49:  * Currently this filter does nothing and needs to be implemented.
  50:  *
  51:  * @author C. Brian Jones (cbj@gnu.org) 
  52:  */
  53: public class ReplicateScaleFilter extends ImageFilter
  54: {
  55:     public ReplicateScaleFilter(int width, int height) {
  56:     destHeight = height;
  57:     destWidth = width;
  58:     }
  59: 
  60:     /**
  61:      * The height of the destination image.
  62:      */
  63:     protected int destHeight;
  64: 
  65:     /**
  66:      * The width of the destination image.
  67:      */
  68:     protected int destWidth;
  69: 
  70:     /**
  71:      * The height of the source image.
  72:      */
  73:     protected int srcHeight;
  74: 
  75:     /**
  76:      * The width of the source image.
  77:      */
  78:     protected int srcWidth;
  79: 
  80:     /**
  81:      *
  82:      */
  83:     protected int srcrows[];
  84: 
  85:     /**
  86:      *
  87:      */
  88:     protected int srccols[];
  89: 
  90:     /**
  91:      *
  92:      */
  93:     protected Object outpixbuf;
  94: 
  95:     /**
  96:      * An <code>ImageProducer</code> indicates the size of the image
  97:      * being produced using this method.  A filter can override this 
  98:      * method to intercept these calls from the producer in order to
  99:      * change either the width or the height before in turn calling
 100:      * the consumer's <code>setDimensions</code> method.
 101:      * 
 102:      * @param width the width of the image
 103:      * @param height the height of the image 
 104:      */
 105:     public void setDimensions(int width, int height)
 106:     {
 107:     srcWidth = width;
 108:     srcHeight = height;
 109: 
 110:     /* If either destHeight or destWidth is < 0, the image should
 111:        maintain its original aspect ratio.  When both are < 0,
 112:        just maintain the original width and height. */
 113:     if (destWidth < 0 && destHeight < 0)
 114:         {
 115:         destWidth = width;
 116:         destHeight = height;
 117:     }
 118:     else if (destWidth < 0)
 119:     {
 120:         destWidth = width * destHeight / srcHeight;
 121:     }
 122:     else if (destHeight < 0)
 123:     {
 124:         destHeight = height * destWidth / srcWidth;
 125:     }
 126: 
 127:     if (consumer != null)
 128:       consumer.setDimensions(destWidth, destHeight);
 129:     }
 130: 
 131:     /**
 132:      * An <code>ImageProducer</code> can set a list of properties
 133:      * associated with this image by using this method.
 134:      *
 135:      * @param props the list of properties associated with this image 
 136:      */
 137:     public void setProperties(Hashtable<?, ?> props)
 138:     {
 139:       Hashtable<Object, Object> prop2 = (Hashtable<Object, Object>) props;
 140:       prop2.put("filters", "ReplicateScaleFilter");
 141:       if (consumer != null)
 142:         consumer.setProperties(prop2);
 143:     }
 144: 
 145:     /**
 146:      * This function delivers a rectangle of pixels where any
 147:      * pixel(m,n) is stored in the array as a <code>byte</code> at
 148:      * index (n * scansize + m + offset).  
 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 model the <code>ColorModel</code> used to translate the pixels
 155:      * @param pixels the array of pixel values
 156:      * @param offset the index of the first pixels in the <code>pixels</code> array
 157:      * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
 158:      */
 159:     public void setPixels(int x, int y, int w, int h, 
 160:        ColorModel model, byte[] pixels, int offset, int scansize)
 161:     {
 162:       if (srcrows == null || srccols == null)
 163:         setupSources();
 164:       int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * destWidth);
 165:       int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * destHeight);
 166:       byte[] pix;
 167:       if (outpixbuf != null && outpixbuf instanceof byte[])
 168:         {
 169:           pix = (byte[]) outpixbuf;
 170:         }
 171:       else
 172:         {
 173:           pix = new byte[destWidth];
 174:           outpixbuf = pix;
 175:         }
 176:       int sy, sx;
 177:       for (int yy = dy1; (sy = srcrows[yy]) < y + h; yy++)
 178:         {
 179:           int offs = offset + scansize * (sy - y);
 180:           int xx;
 181:           for (xx = dx1; (sx = srccols[xx]) < x + w; xx++)
 182:             {
 183:               pix[xx] = pixels[offs + sx - x];
 184:             }
 185:           if (xx > dx1)
 186:             {
 187:               consumer.setPixels(dx1, yy, xx - dx1, 1, model, pix, dx1,
 188:                                  destWidth);
 189:             }
 190:         }
 191:     }
 192: 
 193:     /**
 194:      * This function delivers a rectangle of pixels where any
 195:      * pixel(m,n) is stored in the array as an <code>int</code> at
 196:      * index (n * scansize + m + offset).  
 197:      *
 198:      * @param x the x coordinate of the rectangle
 199:      * @param y the y coordinate of the rectangle
 200:      * @param w the width of the rectangle
 201:      * @param h the height of the rectangle
 202:      * @param model the <code>ColorModel</code> used to translate the pixels
 203:      * @param pixels the array of pixel values
 204:      * @param offset the index of the first pixels in the <code>pixels</code> array
 205:      * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
 206:      */
 207:     public void setPixels(int x, int y, int w, int h, 
 208:            ColorModel model, int[] pixels, int offset, int scansize)
 209:     {
 210:       if (srcrows == null || srccols == null)
 211:         setupSources();
 212:       int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * destWidth);
 213:       int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * destHeight);
 214:       int[] pix;
 215:       if (outpixbuf != null && outpixbuf instanceof int[])
 216:         {
 217:           pix = (int[]) outpixbuf;
 218:         }
 219:       else
 220:         {
 221:           pix = new int[destWidth];
 222:           outpixbuf = pix;
 223:         }
 224:       int sy, sx;
 225:       for (int yy = dy1; (sy = srcrows[yy]) < y + h; yy++)
 226:         {
 227:           int offs = offset + scansize * (sy - y);
 228:           int xx;
 229:           for (xx = dx1; (sx = srccols[xx]) < x + w; xx++)
 230:             {
 231:               pix[xx] = pixels[offs + sx - x];
 232:             }
 233:           if (xx > dx1)
 234:             {
 235:               consumer.setPixels(dx1, yy, xx - dx1, 1, model, pix, dx1,
 236:                                  destWidth);
 237:             }
 238:         }
 239:     }
 240: 
 241:   /**
 242:    * Sets up the srcrows and srccols arrays.
 243:    */
 244:   private void setupSources()
 245:   {
 246:     srcrows = new int[destHeight + 1];
 247:     for (int y = 0; y <= destHeight; y++)
 248:       {
 249:         srcrows[y] = (2 * y * srcHeight + srcHeight) / (2 * destHeight);
 250:       }
 251:     srccols = new int[destWidth + 1];
 252:     for (int x = 0; x <= destWidth; x++)
 253:       {
 254:         srccols[x] = (2 * x * srcWidth + srcWidth) / (2 * destWidth);
 255:       }
 256:   }
 257: }