001    /* Kernel.java -- Java class for an image processing kernel
002       Copyright (C) 2004, 2005, 2006,  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    /**
042     * Kernel represents an image processing kernel.  It gets used to hold
043     * convolution filters among other purposes.  It stores an array of float
044     * values representing a 2-dimensional array in row-major order.
045     *
046     * @author Jerry Quinn (jlquinn@optonline.net)
047     */
048    public class Kernel implements Cloneable
049    {
050      /** The kernel width. */
051      private final int width;
052    
053      /** The kernel height. */
054      private final int height;
055    
056      /** Internal storage for the kernel's values. */
057      private final float[] data;
058    
059      /**
060       * Creates a new <code>Kernel</code> instance with the specified dimensions
061       * and values.  The first <code>width * height</code> values in the specified
062       * <code>data</code> array are copied to internal storage.
063       *
064       * @param width  the kernel width.
065       * @param height  the kernel height.
066       * @param data  the source data array (<code>null</code> not permitted).
067       *
068       * @throws IllegalArgumentException if <code>data.length</code> is less than
069       *     <code>width * height</code>.
070       * @throws IllegalArgumentException if <code>width</code> or
071       *      <code>height</code> is less than zero.
072       * @throws NullPointerException if <code>data</code> is <code>null</code>.
073       */
074      public Kernel(int width, int height, float[] data)
075        throws IllegalArgumentException
076      {
077        this.width = width;
078        this.height = height;
079        if (data.length < width * height || width < 0 || height < 0)
080          throw new IllegalArgumentException();
081        this.data = new float[width * height];
082        System.arraycopy(data, 0, this.data, 0, width * height);
083      }
084    
085      /**
086       * Returns the x-origin for the kernel, which is calculated as
087       * <code>(width - 1) / 2</code>.
088       *
089       * @return The x-origin for the kernel.
090       */
091      public final int getXOrigin()
092      {
093        return (width - 1) / 2;
094      }
095    
096      /**
097       * Returns the y-origin for the kernel, which is calculated as
098       * <code>(height - 1) / 2</code>.
099       *
100       * @return The y-origin for the kernel.
101       */
102      public final int getYOrigin()
103      {
104        return (height - 1) / 2;
105      }
106    
107      /**
108       * Returns the kernel width (as supplied to the constructor).
109       *
110       * @return The kernel width.
111       */
112      public final int getWidth()
113      {
114        return width;
115      }
116    
117      /**
118       * Returns the kernel height (as supplied to the constructor).
119       *
120       * @return The kernel height.
121       */
122      public final int getHeight()
123      {
124        return height;
125      }
126    
127      /**
128       * Returns an array containing a copy of the kernel data.  If the
129       * <code>data</code> argument is non-<code>null</code>, the kernel values
130       * are copied into it and then <code>data</code> is returned as the result.
131       * If the <code>data</code> argument is <code>null</code>, this method
132       * allocates a new array then populates and returns it.
133       *
134       * @param data  an array to copy the return values into (if
135       *     <code>null</code>, a new array is allocated).
136       *
137       * @return The array with copied values.
138       *
139       * @throws IllegalArgumentException if <code>data.length</code> is less than
140       *     the kernel's <code>width * height</code>.
141       */
142      public final float[] getKernelData(float[] data)
143        throws IllegalArgumentException
144      {
145        if (data == null)
146          return (float[]) this.data.clone();
147    
148        if (data.length < this.data.length)
149          throw new IllegalArgumentException();
150    
151        System.arraycopy(this.data, 0, data, 0, this.data.length);
152        return data;
153      }
154    
155      /**
156       * Returns a clone of this kernel.
157       *
158       * @return a clone of this Kernel.
159       */
160      public Object clone()
161      {
162        try
163          {
164            return super.clone();
165          }
166        catch (CloneNotSupportedException e)
167          {
168            throw (Error) new InternalError().initCause(e); // Impossible
169          }
170      }
171    }