1 /* 2 * Copyright (c) 1997, 2007, 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 26 package sun.awt.image; 27 28 import java.awt.geom.AffineTransform; 29 import java.awt.image.AffineTransformOp; 30 import java.awt.image.BufferedImage; 31 import java.awt.image.BufferedImageOp; 32 import java.awt.image.ByteLookupTable; 33 import java.awt.image.ConvolveOp; 34 import java.awt.image.Kernel; 35 import java.awt.image.LookupOp; 36 import java.awt.image.LookupTable; 37 import java.awt.image.RasterOp; 38 import java.awt.image.Raster; 39 import java.awt.image.WritableRaster; 40 import java.security.AccessController; 41 import 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 */ 54 public 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 public static native int transformBI(BufferedImage src, BufferedImage dst, 77 double[] matrix, int interpType); 78 public static native int transformRaster(Raster src, Raster dst, 79 double[] matrix, 80 int interpType); 81 public static native int convolveBI(BufferedImage src, BufferedImage dst, 82 Kernel kernel, int edgeHint); 83 public static native int convolveRaster(Raster src, Raster dst, 84 Kernel kernel, int edgeHint); 85 public static native int lookupByteBI(BufferedImage src, BufferedImage dst, 86 byte[][] table); 87 public static 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 }