1/*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.awt.image;
27
28
29/**
30 * The {@code Kernel} class defines a matrix that describes how a
31 * specified pixel and its surrounding pixels affect the value
32 * computed for the pixel's position in the output image of a filtering
33 * operation.  The X origin and Y origin indicate the kernel matrix element
34 * that corresponds to the pixel position for which an output value is
35 * being computed.
36 *
37 * @see ConvolveOp
38 */
39public class Kernel implements Cloneable {
40    private int  width;
41    private int  height;
42    private int  xOrigin;
43    private int  yOrigin;
44    private float data[];
45
46    private static native void initIDs();
47    static {
48        ColorModel.loadLibraries();
49        initIDs();
50    }
51
52    /**
53     * Constructs a {@code Kernel} object from an array of floats.
54     * The first {@code width}*{@code height} elements of
55     * the {@code data} array are copied.
56     * If the length of the {@code data} array is less
57     * than width*height, an {@code IllegalArgumentException} is thrown.
58     * The X origin is (width-1)/2 and the Y origin is (height-1)/2.
59     * @param width         width of the kernel
60     * @param height        height of the kernel
61     * @param data          kernel data in row major order
62     * @throws IllegalArgumentException if the length of {@code data}
63     *         is less than the product of {@code width} and
64     *         {@code height}
65     */
66    public Kernel(int width, int height, float data[]) {
67        this.width  = width;
68        this.height = height;
69        this.xOrigin  = (width-1)>>1;
70        this.yOrigin  = (height-1)>>1;
71        int len = width*height;
72        if (data.length < len) {
73            throw new IllegalArgumentException("Data array too small "+
74                                               "(is "+data.length+
75                                               " and should be "+len);
76        }
77        this.data = new float[len];
78        System.arraycopy(data, 0, this.data, 0, len);
79
80    }
81
82    /**
83     * Returns the X origin of this {@code Kernel}.
84     * @return the X origin.
85     */
86    public final int getXOrigin(){
87        return xOrigin;
88    }
89
90    /**
91     * Returns the Y origin of this {@code Kernel}.
92     * @return the Y origin.
93     */
94    public final int getYOrigin() {
95        return yOrigin;
96    }
97
98    /**
99     * Returns the width of this {@code Kernel}.
100     * @return the width of this {@code Kernel}.
101     */
102    public final int getWidth() {
103        return width;
104    }
105
106    /**
107     * Returns the height of this {@code Kernel}.
108     * @return the height of this {@code Kernel}.
109     */
110    public final int getHeight() {
111        return height;
112    }
113
114    /**
115     * Returns the kernel data in row major order.
116     * The {@code data} array is returned.  If {@code data}
117     * is {@code null}, a new array is allocated.
118     * @param data  if non-null, contains the returned kernel data
119     * @return the {@code data} array containing the kernel data
120     *         in row major order or, if {@code data} is
121     *         {@code null}, a newly allocated array containing
122     *         the kernel data in row major order
123     * @throws IllegalArgumentException if {@code data} is less
124     *         than the size of this {@code Kernel}
125     */
126    public final float[] getKernelData(float[] data) {
127        if (data == null) {
128            data = new float[this.data.length];
129        }
130        else if (data.length < this.data.length) {
131            throw new IllegalArgumentException("Data array too small "+
132                                               "(should be "+this.data.length+
133                                               " but is "+
134                                               data.length+" )");
135        }
136        System.arraycopy(this.data, 0, data, 0, this.data.length);
137
138        return data;
139    }
140
141    /**
142     * Clones this object.
143     * @return a clone of this object.
144     */
145    public Object clone() {
146        try {
147            return super.clone();
148        } catch (CloneNotSupportedException e) {
149            // this shouldn't happen, since we are Cloneable
150            throw new InternalError(e);
151        }
152    }
153}
154