1 /* 2 * Copyright (c) 1995, 2020, 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 java.awt; 26 27 import java.awt.image.ImageProducer; 28 import java.awt.image.ImageObserver; 29 import java.awt.image.ImageFilter; 30 import java.awt.image.FilteredImageSource; 31 import java.awt.image.AreaAveragingScaleFilter; 32 import java.awt.image.ReplicateScaleFilter; 33 34 import sun.awt.image.SurfaceManager; 35 36 37 /** 38 * The abstract class {@code Image} is the superclass of all 39 * classes that represent graphical images. The image must be 40 * obtained in a platform-specific manner. 41 * 42 * @author Sami Shaio 43 * @author Arthur van Hoff 44 * @since 1.0 45 */ 46 public abstract class Image { 47 48 /** 49 * Constructor for subclasses to call. 50 */ 51 public Image() {} 52 53 /** 54 * convenience object; we can use this single static object for 55 * all images that do not create their own image caps; it holds the 56 * default (unaccelerated) properties. 57 */ 58 private static ImageCapabilities defaultImageCaps = 59 new ImageCapabilities(false); 60 61 /** 62 * Priority for accelerating this image. Subclasses are free to 63 * set different default priorities and applications are free to 64 * set the priority for specific images via the 65 * {@code setAccelerationPriority(float)} method. 66 * @since 1.5 67 */ 68 protected float accelerationPriority = .5f; 69 70 /** 71 * Determines the width of the image. If the width is not yet known, 72 * this method returns {@code -1} and the specified 73 * {@code ImageObserver} object is notified later. 74 * @param observer an object waiting for the image to be loaded. 75 * @return the width of this image, or {@code -1} 76 * if the width is not yet known. 77 * @see java.awt.Image#getHeight 78 * @see java.awt.image.ImageObserver 79 */ 80 public abstract int getWidth(ImageObserver observer); 81 82 /** 83 * Determines the height of the image. If the height is not yet known, 84 * this method returns {@code -1} and the specified 85 * {@code ImageObserver} object is notified later. 86 * @param observer an object waiting for the image to be loaded. 87 * @return the height of this image, or {@code -1} 88 * if the height is not yet known. 89 * @see java.awt.Image#getWidth 90 * @see java.awt.image.ImageObserver 91 */ 92 public abstract int getHeight(ImageObserver observer); 93 94 /** 95 * Gets the object that produces the pixels for the image. 96 * This method is called by the image filtering classes and by 97 * methods that perform image conversion and scaling. 98 * @return the image producer that produces the pixels 99 * for this image. 100 * @see java.awt.image.ImageProducer 101 */ 102 public abstract ImageProducer getSource(); 103 104 /** 105 * Creates a graphics context for drawing to an off-screen image. 106 * This method can only be called for off-screen images. 107 * @return a graphics context to draw to the off-screen image. 108 * @exception UnsupportedOperationException if called for a 109 * non-off-screen image. 110 * @see java.awt.Graphics 111 * @see java.awt.Component#createImage(int, int) 112 */ 113 public abstract Graphics getGraphics(); 114 115 /** 116 * Gets a property of this image by name. 117 * <p> 118 * Individual property names are defined by the various image 119 * formats. If a property is not defined for a particular image, this 120 * method returns the {@code UndefinedProperty} object. 121 * <p> 122 * If the properties for this image are not yet known, this method 123 * returns {@code null}, and the {@code ImageObserver} 124 * object is notified later. 125 * <p> 126 * The property name {@code "comment"} should be used to store 127 * an optional comment which can be presented to the application as a 128 * description of the image, its source, or its author. 129 * @param name a property name. 130 * @param observer an object waiting for this image to be loaded. 131 * @return the value of the named property. 132 * @throws NullPointerException if the property name is null. 133 * @see java.awt.image.ImageObserver 134 * @see java.awt.Image#UndefinedProperty 135 */ 136 public abstract Object getProperty(String name, ImageObserver observer); 137 138 /** 139 * The {@code UndefinedProperty} object should be returned whenever a 140 * property which was not defined for a particular image is fetched. 141 */ 142 public static final Object UndefinedProperty = new Object(); 143 144 /** 145 * Creates a scaled version of this image. 146 * A new {@code Image} object is returned which will render 147 * the image at the specified {@code width} and 148 * {@code height} by default. The new {@code Image} object 149 * may be loaded asynchronously even if the original source image 150 * has already been loaded completely. 151 * 152 * <p> 153 * 154 * If either {@code width} 155 * or {@code height} is a negative number then a value is 156 * substituted to maintain the aspect ratio of the original image 157 * dimensions. If both {@code width} and {@code height} 158 * are negative, then the original image dimensions are used. 159 * 160 * @param width the width to which to scale the image. 161 * @param height the height to which to scale the image. 162 * @param hints flags to indicate the type of algorithm to use 163 * for image resampling. 164 * @return a scaled version of the image. 165 * @exception IllegalArgumentException if {@code width} 166 * or {@code height} is zero. 167 * @see java.awt.Image#SCALE_DEFAULT 168 * @see java.awt.Image#SCALE_FAST 169 * @see java.awt.Image#SCALE_SMOOTH 170 * @see java.awt.Image#SCALE_REPLICATE 171 * @see java.awt.Image#SCALE_AREA_AVERAGING 172 * @since 1.1 173 */ 174 public Image getScaledInstance(int width, int height, int hints) { 175 ImageFilter filter; 176 if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) { 177 filter = new AreaAveragingScaleFilter(width, height); 178 } else { 179 filter = new ReplicateScaleFilter(width, height); 180 } 181 ImageProducer prod; 182 prod = new FilteredImageSource(getSource(), filter); 183 return Toolkit.getDefaultToolkit().createImage(prod); 184 } 185 186 /** 187 * Use the default image-scaling algorithm. 188 * @since 1.1 189 */ 190 public static final int SCALE_DEFAULT = 1; 191 192 /** 193 * Choose an image-scaling algorithm that gives higher priority 194 * to scaling speed than smoothness of the scaled image. 195 * @since 1.1 196 */ 197 public static final int SCALE_FAST = 2; 198 199 /** 200 * Choose an image-scaling algorithm that gives higher priority 201 * to image smoothness than scaling speed. 202 * @since 1.1 203 */ 204 public static final int SCALE_SMOOTH = 4; 205 206 /** 207 * Use the image scaling algorithm embodied in the 208 * {@code ReplicateScaleFilter} class. 209 * The {@code Image} object is free to substitute a different filter 210 * that performs the same algorithm yet integrates more efficiently 211 * into the imaging infrastructure supplied by the toolkit. 212 * @see java.awt.image.ReplicateScaleFilter 213 * @since 1.1 214 */ 215 public static final int SCALE_REPLICATE = 8; 216 217 /** 218 * Use the Area Averaging image scaling algorithm. The 219 * image object is free to substitute a different filter that 220 * performs the same algorithm yet integrates more efficiently 221 * into the image infrastructure supplied by the toolkit. 222 * @see java.awt.image.AreaAveragingScaleFilter 223 * @since 1.1 224 */ 225 public static final int SCALE_AREA_AVERAGING = 16; 226 227 /** 228 * Flushes all reconstructable resources being used by this Image object. 229 * This includes any pixel data that is being cached for rendering to 230 * the screen as well as any system resources that are being used 231 * to store data or pixels for the image if they can be recreated. 232 * The image is reset to a state similar to when it was first created 233 * so that if it is again rendered, the image data will have to be 234 * recreated or fetched again from its source. 235 * <p> 236 * Examples of how this method affects specific types of Image object: 237 * <ul> 238 * <li> 239 * BufferedImage objects leave the primary Raster which stores their 240 * pixels untouched, but flush any information cached about those 241 * pixels such as copies uploaded to the display hardware for 242 * accelerated blits. 243 * <li> 244 * Image objects created by the Component methods which take a 245 * width and height leave their primary buffer of pixels untouched, 246 * but have all cached information released much like is done for 247 * BufferedImage objects. 248 * <li> 249 * VolatileImage objects release all of their pixel resources 250 * including their primary copy which is typically stored on 251 * the display hardware where resources are scarce. 252 * These objects can later be restored using their 253 * {@link java.awt.image.VolatileImage#validate validate} 254 * method. 255 * <li> 256 * Image objects created by the Toolkit and Component classes which are 257 * loaded from files, URLs or produced by an {@link ImageProducer} 258 * are unloaded and all local resources are released. 259 * These objects can later be reloaded from their original source 260 * as needed when they are rendered, just as when they were first 261 * created. 262 * </ul> 263 */ 264 public void flush() { 265 if (surfaceManager != null) { 266 surfaceManager.flush(); 267 } 268 } 269 270 /** 271 * Returns an ImageCapabilities object which can be 272 * inquired as to the capabilities of this 273 * Image on the specified GraphicsConfiguration. 274 * This allows programmers to find 275 * out more runtime information on the specific Image 276 * object that they have created. For example, the user 277 * might create a BufferedImage but the system may have 278 * no video memory left for creating an image of that 279 * size on the given GraphicsConfiguration, so although the object 280 * may be acceleratable in general, it 281 * does not have that capability on this GraphicsConfiguration. 282 * @param gc a {@code GraphicsConfiguration} object. A value of null 283 * for this parameter will result in getting the image capabilities 284 * for the default {@code GraphicsConfiguration}. 285 * @return an {@code ImageCapabilities} object that contains 286 * the capabilities of this {@code Image} on the specified 287 * GraphicsConfiguration. 288 * @see java.awt.image.VolatileImage#getCapabilities() 289 * VolatileImage.getCapabilities() 290 * @since 1.5 291 */ 292 public ImageCapabilities getCapabilities(GraphicsConfiguration gc) { 293 if (surfaceManager != null) { 294 return surfaceManager.getCapabilities(gc); 295 } 296 // Note: this is just a default object that gets returned in the 297 // absence of any more specific information from a surfaceManager. 298 // Subclasses of Image should either override this method or 299 // make sure that they always have a non-null SurfaceManager 300 // to return an ImageCapabilities object that is appropriate 301 // for their given subclass type. 302 return defaultImageCaps; 303 } 304 305 /** 306 * Sets a hint for this image about how important acceleration is. 307 * This priority hint is used to compare to the priorities of other 308 * Image objects when determining how to use scarce acceleration 309 * resources such as video memory. When and if it is possible to 310 * accelerate this Image, if there are not enough resources available 311 * to provide that acceleration but enough can be freed up by 312 * de-accelerating some other image of lower priority, then that other 313 * Image may be de-accelerated in deference to this one. Images 314 * that have the same priority take up resources on a first-come, 315 * first-served basis. 316 * @param priority a value between 0 and 1, inclusive, where higher 317 * values indicate more importance for acceleration. A value of 0 318 * means that this Image should never be accelerated. Other values 319 * are used simply to determine acceleration priority relative to other 320 * Images. 321 * @throws IllegalArgumentException if {@code priority} is less 322 * than zero or greater than 1. 323 * @since 1.5 324 */ 325 public void setAccelerationPriority(float priority) { 326 if (priority < 0 || priority > 1) { 327 throw new IllegalArgumentException("Priority must be a value " + 328 "between 0 and 1, inclusive"); 329 } 330 accelerationPriority = priority; 331 if (surfaceManager != null) { 332 surfaceManager.setAccelerationPriority(accelerationPriority); 333 } 334 } 335 336 /** 337 * Returns the current value of the acceleration priority hint. 338 * @see #setAccelerationPriority(float priority) setAccelerationPriority 339 * @return value between 0 and 1, inclusive, which represents the current 340 * priority value 341 * @since 1.5 342 */ 343 public float getAccelerationPriority() { 344 return accelerationPriority; 345 } 346 347 SurfaceManager surfaceManager; 348 349 static { 350 SurfaceManager.setImageAccessor(new SurfaceManager.ImageAccessor() { 351 public SurfaceManager getSurfaceManager(Image img) { 352 return img.surfaceManager; 353 } 354 public void setSurfaceManager(Image img, SurfaceManager mgr) { 355 img.surfaceManager = mgr; 356 } 357 }); 358 } 359 }