1 /* 2 * Copyright (c) 2013, 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 package sun.awt.image; 26 27 import java.awt.EventQueue; 28 import java.awt.Image; 29 import java.awt.Toolkit; 30 import java.awt.image.ImageObserver; 31 import java.awt.image.ImageProducer; 32 import java.net.URL; 33 import javax.swing.ImageIcon; 34 import javax.swing.SwingUtilities; 35 import sun.misc.SoftCache; 36 37 public class ToolkitImageUtil { 38 39 private static final SoftCache imgCache = new SoftCache(); 40 41 private static Image getImageFromCache(Toolkit tk, URL url) { 42 43 checkPermissions(url); 44 45 synchronized (imgCache) { 46 Image img = (Image) imgCache.get(url); 47 if (img == null) { 48 try { 49 img = tk.createImage(new URLImageSource(url)); 50 imgCache.put(url, img); 51 } catch (Exception e) { 52 } 53 } 54 return img; 55 } 56 } 57 58 private static Image getImageFromCache(Toolkit tk, String filename) { 59 60 checkPermissions(filename); 61 62 synchronized (imgCache) { 63 Image img = (Image) imgCache.get(filename); 64 if (img == null) { 65 try { 66 img = tk.createImage(new FileImageSource(filename)); 67 imgCache.put(filename, img); 68 } catch (Exception e) { 69 } 70 } 71 return img; 72 } 73 } 74 75 public static Image getImage(Toolkit toolkit, String filename) { 76 return getImageFromCache(toolkit, filename); 77 } 78 79 public static Image getImage(Toolkit toolkit, URL url) { 80 return getImageFromCache(toolkit, url); 81 } 82 83 public static Image getImageWithResolutionVariant(Toolkit toolkit, String fileName, String resolutionVariantName) { 84 synchronized (imgCache) { 85 Image image = getImage(toolkit, fileName); 86 Image resolutionVariant = getImage(toolkit, resolutionVariantName); 87 if (loadImage(resolutionVariant)) { 88 image = createImageWithResolutionVariant(image, resolutionVariant); 89 imgCache.put(fileName, image); 90 } 91 return image; 92 } 93 } 94 95 public static Image getImageWithResolutionVariant(Toolkit toolkit, URL url, URL resolutionVariantURL) { 96 synchronized (imgCache) { 97 Image image = getImage(toolkit, url); 98 Image resolutionVariant = getImage(toolkit, resolutionVariantURL); 99 if (loadImage(resolutionVariant)) { 100 image = createImageWithResolutionVariant(image, resolutionVariant); 101 imgCache.put(url, image); 102 } 103 return image; 104 } 105 } 106 107 public static Image createImageWithResolutionVariant(Image image, Image resolutionVariant) { 108 return new MultiResolutionToolkitImage(image, resolutionVariant); 109 } 110 111 public static Image createImage(String filename) { 112 checkPermissions(filename); 113 return createImage(new FileImageSource(filename)); 114 } 115 116 public static Image createImage(URL url) { 117 checkPermissions(url); 118 return createImage(new URLImageSource(url)); 119 } 120 121 public static Image createImage(ImageProducer producer) { 122 return new ToolkitImage(producer); 123 } 124 125 public static Image createImage(byte[] data, int offset, int length) { 126 return createImage(new ByteArrayImageSource(data, offset, length)); 127 } 128 129 private static void checkPermissions(String filename) { 130 SecurityManager security = System.getSecurityManager(); 131 if (security != null) { 132 security.checkRead(filename); 133 } 134 } 135 136 private static void checkPermissions(URL url) { 137 SecurityManager sm = System.getSecurityManager(); 138 if (sm != null) { 139 try { 140 java.security.Permission perm 141 = url.openConnection().getPermission(); 142 if (perm != null) { 143 try { 144 sm.checkPermission(perm); 145 } catch (SecurityException se) { 146 // fallback to checkRead/checkConnect for pre 1.2 147 // security managers 148 if ((perm instanceof java.io.FilePermission) 149 && perm.getActions().indexOf("read") != -1) { 150 sm.checkRead(perm.getName()); 151 } else if ((perm instanceof java.net.SocketPermission) 152 && perm.getActions().indexOf("connect") != -1) { 153 sm.checkConnect(url.getHost(), url.getPort()); 154 } else { 155 throw se; 156 } 157 } 158 } 159 } catch (java.io.IOException ioe) { 160 sm.checkConnect(url.getHost(), url.getPort()); 161 } 162 } 163 } 164 165 private static volatile ImageLoader imageLoader; 166 167 static ImageLoader getImageLoader() { 168 if (imageLoader == null) { 169 synchronized (imgCache) { 170 if (imageLoader == null) { 171 if (EventQueue.isDispatchThread()) { 172 imageLoader = new ImageLoader(); 173 } else { 174 try { 175 SwingUtilities.invokeAndWait(new Runnable() { 176 177 @Override 178 public void run() { 179 imageLoader = new ImageLoader(); 180 } 181 }); 182 } catch (Exception e) { 183 throw new RuntimeException(e); 184 } 185 } 186 } 187 } 188 } 189 return imageLoader; 190 } 191 192 static boolean loadImage(Image image) { 193 ImageLoader loader = getImageLoader(); 194 loader.loadImage(image); 195 return loader.isImageLoaded(); 196 } 197 198 static class ImageLoader extends ImageIcon implements ImageObserver { 199 200 private boolean imageLoaded; 201 202 public ImageLoader() { 203 setImageObserver(this); 204 } 205 206 public boolean isImageLoaded() { 207 return imageLoaded; 208 } 209 210 @Override 211 public void loadImage(Image image) { 212 imageLoaded = true; 213 super.loadImage(image); 214 } 215 216 @Override 217 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 218 // Image should have been already loaded 219 imageLoaded = (infoflags & ALLBITS) != 0; 220 return false; 221 } 222 } 223 }