001/* CropImageFilter.java -- Java class for cropping image filter
002   Copyright (C) 1999, 2004  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.awt.image;
040
041import java.awt.Rectangle;
042import java.util.Hashtable;
043
044/**
045 * Currently this filter does almost nothing and needs to be implemented.
046 *
047 * @author C. Brian Jones (cbj@gnu.org) 
048 */
049public class CropImageFilter extends ImageFilter
050{
051    int x;
052    int y;
053    int width;
054    int height;
055
056    /**
057     * Construct a new <code>CropImageFilter</code> instance.
058     *
059     * @param x the x-coordinate location of the top-left of the cropped rectangle
060     * @param y the y-coordinate location of the top-left of the cropped rectangle
061     * @param width the width of the cropped rectangle
062     * @param height the height of the cropped rectangle
063     */
064    public CropImageFilter(int x, int y, int width, int height) {
065        this.x = x;
066        this.y = y;
067        this.width = width;
068        this.height = height;
069    }
070
071    /**
072     * An <code>ImageProducer</code> indicates the size of the image
073     * being produced using this method.  This filter overrides this
074     * method in order to set the dimentions to the size of the
075     * cropped rectangle instead of the size of the image.
076     * 
077     * @param width the width of the image
078     * @param height the height of the image 
079     */
080    public void setDimensions(int width, int height)
081    {
082      if (consumer != null)
083        consumer.setDimensions(this.width, this.height);
084    }
085
086    /**
087     * An <code>ImageProducer</code> can set a list of properties
088     * associated with this image by using this method.
089     * <br>
090     * FIXME - What property is set for this class?
091     *
092     * @param props the list of properties associated with this image 
093     */
094    public void setProperties(Hashtable<?, ?> props)
095    {
096      Hashtable<Object, Object> prop2 = (Hashtable<Object, Object>) props;
097      prop2.put("filters", "CropImageFilter");
098      if (consumer != null)
099        consumer.setProperties(prop2);
100    }
101
102    /**
103     * This function delivers a rectangle of pixels where any
104     * pixel(m,n) is stored in the array as a <code>byte</code> at
105     * index (n * scansize + m + offset).  
106     *
107     * @param x the x coordinate of the rectangle
108     * @param y the y coordinate of the rectangle
109     * @param w the width of the rectangle
110     * @param h the height of the rectangle
111     * @param model the <code>ColorModel</code> used to translate the pixels
112     * @param pixels the array of pixel values
113     * @param offset the index of the first pixels in the <code>pixels</code> array
114     * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
115     */
116    public void setPixels(int x, int y, int w, int h, 
117           ColorModel model, byte[] pixels, int offset, int scansize)
118    {
119        Rectangle filterBounds = new Rectangle(this.x, this.y,
120                                               this.width, this.height);
121        Rectangle pixelBounds = new Rectangle(x, y, w, h);
122
123        if (filterBounds.intersects(pixelBounds))
124        {
125            Rectangle bounds = filterBounds.intersection(pixelBounds);
126
127            byte[] cropped = new byte[bounds.width * bounds.height];
128            for (int i = 0; i < bounds.height; i++)
129            {
130                int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
131
132                for (int j = 0; j < bounds.width; j++)
133                    cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
134            }
135            
136            if (consumer != null)
137              consumer.setPixels(0, 0,
138                                 bounds.width, bounds.height,
139                                 model, cropped, 0, bounds.width);
140        }
141    }
142
143    /**
144     * This function delivers a rectangle of pixels where any
145     * pixel(m,n) is stored in the array as an <code>int</code> at
146     * index (n * scansize + m + offset).  
147     *
148     * @param x the x coordinate of the rectangle
149     * @param y the y coordinate of the rectangle
150     * @param w the width of the rectangle
151     * @param h the height of the rectangle
152     * @param model the <code>ColorModel</code> used to translate the pixels
153     * @param pixels the array of pixel values
154     * @param offset the index of the first pixels in the <code>pixels</code> array
155     * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
156     */
157    public void setPixels(int x, int y, int w, int h, 
158           ColorModel model, int[] pixels, int offset, int scansize)
159    {
160        Rectangle filterBounds = new Rectangle(this.x, this.y,
161                                               this.width, this.height);
162        Rectangle pixelBounds = new Rectangle(x, y, w, h);
163
164        if (filterBounds.intersects(pixelBounds))
165        {
166            Rectangle bounds = filterBounds.intersection(pixelBounds);
167
168            int[] cropped = new int[bounds.width * bounds.height];
169            for (int i = 0; i < bounds.height; i++)
170            {
171                int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
172
173                for (int j = 0; j < bounds.width; j++)
174                    cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
175            }
176            
177            if (consumer != null)
178              consumer.setPixels(0, 0,
179                                 bounds.width, bounds.height,
180                                 model, cropped, 0, bounds.width);
181        }
182    }
183
184}
185