blob: cb9792aae82bf2056a10eba1eb365418968f5275 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt.image;
27
28import java.awt.geom.AffineTransform;
29import java.awt.image.AffineTransformOp;
30import java.awt.image.BufferedImage;
31import java.awt.image.BufferedImageOp;
32import java.awt.image.ByteLookupTable;
33import java.awt.image.ConvolveOp;
34import java.awt.image.Kernel;
35import java.awt.image.LookupOp;
36import java.awt.image.LookupTable;
37import java.awt.image.RasterOp;
38import java.awt.image.Raster;
39import java.awt.image.WritableRaster;
40import java.security.AccessController;
41import java.security.PrivilegedAction;
42
43/**
44 * This class provides a hook to access platform-specific
45 * imaging code.
46 *
47 * If the implementing class cannot handle the op, tile format or
48 * image format, the method will return null;
49 * If there is an error when processing the
50 * data, the implementing class may either return null
51 * (in which case our java code will be executed) or may throw
52 * an exception.
53 */
54public class ImagingLib {
55
56 static boolean useLib = true;
57 static boolean verbose = false;
58
59 private static final int NUM_NATIVE_OPS = 3;
60 private static final int LOOKUP_OP = 0;
61 private static final int AFFINE_OP = 1;
62 private static final int CONVOLVE_OP = 2;
63
64 private static Class[] nativeOpClass = new Class[NUM_NATIVE_OPS];
65
66 /**
67 * Returned value indicates whether the library initailization was
68 * succeded.
69 *
70 * There could be number of reasons to failure:
71 * - failed to load library.
72 * - failed to get all required entry points.
73 */
74 private static native boolean init();
75
76 static public native int transformBI(BufferedImage src, BufferedImage dst,
77 double[] matrix, int interpType);
78 static public native int transformRaster(Raster src, Raster dst,
79 double[] matrix,
80 int interpType);
81 static public native int convolveBI(BufferedImage src, BufferedImage dst,
82 Kernel kernel, int edgeHint);
83 static public native int convolveRaster(Raster src, Raster dst,
84 Kernel kernel, int edgeHint);
85 static public native int lookupByteBI(BufferedImage src, BufferedImage dst,
86 byte[][] table);
87 static public native int lookupByteRaster(Raster src, Raster dst,
88 byte[][] table);
89
90 static {
91
92 PrivilegedAction<Boolean> doMlibInitialization =
93 new PrivilegedAction<Boolean>() {
94 public Boolean run() {
95 String arch = System.getProperty("os.arch");
96
97 if (arch == null || !arch.startsWith("sparc")) {
98 try {
99 System.loadLibrary("mlib_image");
100 } catch (UnsatisfiedLinkError e) {
101 return Boolean.FALSE;
102 }
103
104 }
105 boolean success = init();
106 return Boolean.valueOf(success);
107 }
108 };
109
110 useLib = AccessController.doPrivileged(doMlibInitialization);
111
112 //
113 // Cache the class references of the operations we know about
114 // at the time this class is initially loaded.
115 //
116 try {
117 nativeOpClass[LOOKUP_OP] =
118 Class.forName("java.awt.image.LookupOp");
119 } catch (ClassNotFoundException e) {
120 System.err.println("Could not find class: "+e);
121 }
122 try {
123 nativeOpClass[AFFINE_OP] =
124 Class.forName("java.awt.image.AffineTransformOp");
125 } catch (ClassNotFoundException e) {
126 System.err.println("Could not find class: "+e);
127 }
128 try {
129 nativeOpClass[CONVOLVE_OP] =
130 Class.forName("java.awt.image.ConvolveOp");
131 } catch (ClassNotFoundException e) {
132 System.err.println("Could not find class: "+e);
133 }
134
135 }
136
137 private static int getNativeOpIndex(Class opClass) {
138 //
139 // Search for this class in cached list of
140 // classes supplying native acceleration
141 //
142 int opIndex = -1;
143 for (int i=0; i<NUM_NATIVE_OPS; i++) {
144 if (opClass == nativeOpClass[i]) {
145 opIndex = i;
146 break;
147 }
148 }
149 return opIndex;
150 }
151
152
153 public static WritableRaster filter(RasterOp op, Raster src,
154 WritableRaster dst) {
155 if (useLib == false) {
156 return null;
157 }
158
159 // Create the destination tile
160 if (dst == null) {
161 dst = op.createCompatibleDestRaster(src);
162 }
163
164
165 WritableRaster retRaster = null;
166 switch (getNativeOpIndex(op.getClass())) {
167
168 case LOOKUP_OP:
169 // REMIND: Fix this!
170 LookupTable table = ((LookupOp)op).getTable();
171 if (table.getOffset() != 0) {
172 // Right now the native code doesn't support offsets
173 return null;
174 }
175 if (table instanceof ByteLookupTable) {
176 ByteLookupTable bt = (ByteLookupTable) table;
177 if (lookupByteRaster(src, dst, bt.getTable()) > 0) {
178 retRaster = dst;
179 }
180 }
181 break;
182
183 case AFFINE_OP:
184 AffineTransformOp bOp = (AffineTransformOp) op;
185 double[] matrix = new double[6];
186 bOp.getTransform().getMatrix(matrix);
187 if (transformRaster(src, dst, matrix,
188 bOp.getInterpolationType()) > 0) {
189 retRaster = dst;
190 }
191 break;
192
193 case CONVOLVE_OP:
194 ConvolveOp cOp = (ConvolveOp) op;
195 if (convolveRaster(src, dst,
196 cOp.getKernel(), cOp.getEdgeCondition()) > 0) {
197 retRaster = dst;
198 }
199 break;
200
201 default:
202 break;
203 }
204
205 if (retRaster != null) {
206 SunWritableRaster.markDirty(retRaster);
207 }
208
209 return retRaster;
210 }
211
212
213 public static BufferedImage filter(BufferedImageOp op, BufferedImage src,
214 BufferedImage dst)
215 {
216 if (verbose) {
217 System.out.println("in filter and op is "+op
218 + "bufimage is "+src+" and "+dst);
219 }
220
221 if (useLib == false) {
222 return null;
223 }
224
225 // Create the destination image
226 if (dst == null) {
227 dst = op.createCompatibleDestImage(src, null);
228 }
229
230 BufferedImage retBI = null;
231 switch (getNativeOpIndex(op.getClass())) {
232
233 case LOOKUP_OP:
234 // REMIND: Fix this!
235 LookupTable table = ((LookupOp)op).getTable();
236 if (table.getOffset() != 0) {
237 // Right now the native code doesn't support offsets
238 return null;
239 }
240 if (table instanceof ByteLookupTable) {
241 ByteLookupTable bt = (ByteLookupTable) table;
242 if (lookupByteBI(src, dst, bt.getTable()) > 0) {
243 retBI = dst;
244 }
245 }
246 break;
247
248 case AFFINE_OP:
249 AffineTransformOp bOp = (AffineTransformOp) op;
250 double[] matrix = new double[6];
251 AffineTransform xform = bOp.getTransform();
252 bOp.getTransform().getMatrix(matrix);
253
254 if (transformBI(src, dst, matrix,
255 bOp.getInterpolationType())>0) {
256 retBI = dst;
257 }
258 break;
259
260 case CONVOLVE_OP:
261 ConvolveOp cOp = (ConvolveOp) op;
262 if (convolveBI(src, dst, cOp.getKernel(),
263 cOp.getEdgeCondition()) > 0) {
264 retBI = dst;
265 }
266 break;
267
268 default:
269 break;
270 }
271
272 if (retBI != null) {
273 SunWritableRaster.markDirty(retBI);
274 }
275
276 return retBI;
277 }
278}