1 /* 2 * Copyright (c) 1997, 2021, 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 @SuppressWarnings("removal") 55 public class ImagingLib { 56 57 static boolean useLib = true; 58 static boolean verbose = false; 59 60 private static final int NUM_NATIVE_OPS = 3; 61 private static final int LOOKUP_OP = 0; 62 private static final int AFFINE_OP = 1; 63 private static final int CONVOLVE_OP = 2; 64 65 private static Class<?>[] nativeOpClass = new Class<?>[NUM_NATIVE_OPS]; 66 67 /** 68 * Returned value indicates whether the library initailization was 69 * succeded. 70 * 71 * There could be number of reasons to failure: 72 * - failed to load library. 73 * - failed to get all required entry points. 74 */ init()75 private static native boolean init(); 76 transformBI(BufferedImage src, BufferedImage dst, double[] matrix, int interpType)77 public static native int transformBI(BufferedImage src, BufferedImage dst, 78 double[] matrix, int interpType); transformRaster(Raster src, Raster dst, double[] matrix, int interpType)79 public static native int transformRaster(Raster src, Raster dst, 80 double[] matrix, 81 int interpType); convolveBI(BufferedImage src, BufferedImage dst, Kernel kernel, int edgeHint)82 public static native int convolveBI(BufferedImage src, BufferedImage dst, 83 Kernel kernel, int edgeHint); convolveRaster(Raster src, Raster dst, Kernel kernel, int edgeHint)84 public static native int convolveRaster(Raster src, Raster dst, 85 Kernel kernel, int edgeHint); lookupByteBI(BufferedImage src, BufferedImage dst, byte[][] table)86 public static native int lookupByteBI(BufferedImage src, BufferedImage dst, 87 byte[][] table); lookupByteRaster(Raster src, Raster dst, byte[][] table)88 public static native int lookupByteRaster(Raster src, Raster dst, 89 byte[][] table); 90 91 static { 92 93 PrivilegedAction<Boolean> doMlibInitialization = 94 new PrivilegedAction<Boolean>() { 95 public Boolean run() { 96 String arch = System.getProperty("os.arch"); 97 98 try { 99 System.loadLibrary("mlib_image"); 100 } catch (UnsatisfiedLinkError e) { 101 return Boolean.FALSE; 102 } 103 boolean success = init(); 104 return Boolean.valueOf(success); 105 } 106 }; 107 108 useLib = AccessController.doPrivileged(doMlibInitialization); 109 110 // 111 // Cache the class references of the operations we know about 112 // at the time this class is initially loaded. 113 // 114 try { 115 nativeOpClass[LOOKUP_OP] = 116 Class.forName("java.awt.image.LookupOp"); 117 } catch (ClassNotFoundException e) { 118 System.err.println("Could not find class: "+e); 119 } 120 try { 121 nativeOpClass[AFFINE_OP] = 122 Class.forName("java.awt.image.AffineTransformOp"); 123 } catch (ClassNotFoundException e) { 124 System.err.println("Could not find class: "+e); 125 } 126 try { 127 nativeOpClass[CONVOLVE_OP] = 128 Class.forName("java.awt.image.ConvolveOp"); 129 } catch (ClassNotFoundException e) { 130 System.err.println("Could not find class: "+e); 131 } 132 133 } 134 getNativeOpIndex(Class<?> opClass)135 private static int getNativeOpIndex(Class<?> opClass) { 136 // 137 // Search for this class in cached list of 138 // classes supplying native acceleration 139 // 140 int opIndex = -1; 141 for (int i=0; i<NUM_NATIVE_OPS; i++) { 142 if (opClass == nativeOpClass[i]) { 143 opIndex = i; 144 break; 145 } 146 } 147 return opIndex; 148 } 149 150 filter(RasterOp op, Raster src, WritableRaster dst)151 public static WritableRaster filter(RasterOp op, Raster src, 152 WritableRaster dst) { 153 if (useLib == false) { 154 return null; 155 } 156 157 // Create the destination tile 158 if (dst == null) { 159 dst = op.createCompatibleDestRaster(src); 160 } 161 162 163 WritableRaster retRaster = null; 164 switch (getNativeOpIndex(op.getClass())) { 165 166 case LOOKUP_OP: 167 // REMIND: Fix this! 168 LookupTable table = ((LookupOp)op).getTable(); 169 if (table.getOffset() != 0) { 170 // Right now the native code doesn't support offsets 171 return null; 172 } 173 if (table instanceof ByteLookupTable) { 174 ByteLookupTable bt = (ByteLookupTable) table; 175 if (lookupByteRaster(src, dst, bt.getTable()) > 0) { 176 retRaster = dst; 177 } 178 } 179 break; 180 181 case AFFINE_OP: 182 AffineTransformOp bOp = (AffineTransformOp) op; 183 double[] matrix = new double[6]; 184 bOp.getTransform().getMatrix(matrix); 185 if (transformRaster(src, dst, matrix, 186 bOp.getInterpolationType()) > 0) { 187 retRaster = dst; 188 } 189 break; 190 191 case CONVOLVE_OP: 192 ConvolveOp cOp = (ConvolveOp) op; 193 if (convolveRaster(src, dst, 194 cOp.getKernel(), cOp.getEdgeCondition()) > 0) { 195 retRaster = dst; 196 } 197 break; 198 199 default: 200 break; 201 } 202 203 if (retRaster != null) { 204 SunWritableRaster.markDirty(retRaster); 205 } 206 207 return retRaster; 208 } 209 210 filter(BufferedImageOp op, BufferedImage src, BufferedImage dst)211 public static BufferedImage filter(BufferedImageOp op, BufferedImage src, 212 BufferedImage dst) 213 { 214 if (verbose) { 215 System.out.println("in filter and op is "+op 216 + "bufimage is "+src+" and "+dst); 217 } 218 219 if (useLib == false) { 220 return null; 221 } 222 223 // Create the destination image 224 if (dst == null) { 225 dst = op.createCompatibleDestImage(src, null); 226 } 227 228 BufferedImage retBI = null; 229 switch (getNativeOpIndex(op.getClass())) { 230 231 case LOOKUP_OP: 232 // REMIND: Fix this! 233 LookupTable table = ((LookupOp)op).getTable(); 234 if (table.getOffset() != 0) { 235 // Right now the native code doesn't support offsets 236 return null; 237 } 238 if (table instanceof ByteLookupTable) { 239 ByteLookupTable bt = (ByteLookupTable) table; 240 if (lookupByteBI(src, dst, bt.getTable()) > 0) { 241 retBI = dst; 242 } 243 } 244 break; 245 246 case AFFINE_OP: 247 AffineTransformOp bOp = (AffineTransformOp) op; 248 double[] matrix = new double[6]; 249 AffineTransform xform = bOp.getTransform(); 250 bOp.getTransform().getMatrix(matrix); 251 252 if (transformBI(src, dst, matrix, 253 bOp.getInterpolationType())>0) { 254 retBI = dst; 255 } 256 break; 257 258 case CONVOLVE_OP: 259 ConvolveOp cOp = (ConvolveOp) op; 260 if (convolveBI(src, dst, cOp.getKernel(), 261 cOp.getEdgeCondition()) > 0) { 262 retBI = dst; 263 } 264 break; 265 266 default: 267 break; 268 } 269 270 if (retBI != null) { 271 SunWritableRaster.markDirty(retBI); 272 } 273 274 return retBI; 275 } 276 } 277