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