001    /* ReplicateScaleFilter.java -- Java class for filtering images
002       Copyright (C) 1999 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package java.awt.image;
040    
041    import java.util.Hashtable;
042    
043    /**
044     * This filter should be used for fast scaling of images where the result
045     * does not need to ensure straight lines are still straight, etc.  The
046     * exact method is not defined by Sun but some sort of fast Box filter should
047     * probably be correct.
048     * <br>
049     * Currently this filter does nothing and needs to be implemented.
050     *
051     * @author C. Brian Jones (cbj@gnu.org) 
052     */
053    public class ReplicateScaleFilter extends ImageFilter
054    {
055        public ReplicateScaleFilter(int width, int height) {
056            destHeight = height;
057            destWidth = width;
058        }
059    
060        /**
061         * The height of the destination image.
062         */
063        protected int destHeight;
064    
065        /**
066         * The width of the destination image.
067         */
068        protected int destWidth;
069    
070        /**
071         * The height of the source image.
072         */
073        protected int srcHeight;
074    
075        /**
076         * The width of the source image.
077         */
078        protected int srcWidth;
079    
080        /**
081         *
082         */
083        protected int srcrows[];
084    
085        /**
086         *
087         */
088        protected int srccols[];
089    
090        /**
091         *
092         */
093        protected Object outpixbuf;
094    
095        /**
096         * An <code>ImageProducer</code> indicates the size of the image
097         * being produced using this method.  A filter can override this 
098         * method to intercept these calls from the producer in order to
099         * 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    }
258