001: /*
002: * @(#)Image.java 1.58 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.awt.image;
029:
030: import java.util.Hashtable;
031: import java.util.Enumeration;
032: import java.awt.Component;
033: import java.awt.Color;
034: import java.awt.Graphics;
035: import java.awt.image.ImageProducer;
036: import java.awt.image.ImageConsumer;
037: import java.awt.image.ImageObserver;
038:
039: public abstract class Image extends java.awt.Image {
040: /**
041: * The object which is used to reconstruct the original image data
042: * as needed.
043: */
044: ImageProducer source;
045: InputStreamImageSource src;
046: ImageRepresentation imagerep;
047:
048: protected Image() {
049: }
050:
051: /**
052: * Construct an image for offscreen rendering to be used with a
053: * given Component.
054: */
055: protected Image(Component c, int w, int h) {
056: if (w <= 0 || h <= 0)
057: throw new IllegalArgumentException(
058: "width and height must be > 0");
059: OffScreenImageSource osis = new OffScreenImageSource(c, w, h);
060: source = osis;
061: width = w;
062: height = h;
063: properties = new Hashtable();
064: availinfo |= (ImageObserver.WIDTH | ImageObserver.HEIGHT | ImageObserver.PROPERTIES);
065: imagerep = makeImageRep();
066: imagerep.offscreen = true;
067: imagerep.setDimensions(w, h);
068: if (c != null)
069: imagerep.offscreenInit(c.getBackground());
070: osis.setImageRep(imagerep);
071: }
072:
073: /**
074: * Construct an image from an ImageProducer object.
075: */
076: protected Image(ImageProducer is) {
077: source = is;
078: if (is instanceof InputStreamImageSource) {
079: src = (InputStreamImageSource) is;
080: }
081: }
082:
083: public ImageProducer getSource() {
084: if (src != null) {
085: src.checkSecurity(null, false);
086: }
087: return source;
088: }
089:
090: protected void initGraphics(Graphics g) {
091: OffScreenImageSource osis = (OffScreenImageSource) source;
092: g.setColor(osis.target.getForeground());
093: g.setFont(osis.target.getFont());
094: }
095:
096: public Color getBackground() {
097: OffScreenImageSource osis = (OffScreenImageSource) source;
098: return osis.target.getBackground();
099: }
100:
101: private int width = -1;
102: private int height = -1;
103: private Hashtable properties;
104: private int availinfo;
105:
106: /**
107: * Return the width of the original image source.
108: * If the width isn't known, then the image is reconstructed.
109: */
110: public int getWidth() {
111: if (src != null) {
112: src.checkSecurity(null, false);
113: }
114: if ((availinfo & ImageObserver.WIDTH) == 0) {
115: reconstruct(ImageObserver.WIDTH);
116: }
117: return width;
118: }
119:
120: /**
121: * Return the width of the original image source.
122: * If the width isn't known, then the ImageObserver object will be
123: * notified when the data is available.
124: */
125: public synchronized int getWidth(ImageObserver iw) {
126: if (src != null) {
127: src.checkSecurity(null, false);
128: }
129: if ((availinfo & ImageObserver.WIDTH) == 0) {
130: addWatcher(iw, true);
131: if ((availinfo & ImageObserver.WIDTH) == 0) {
132: return -1;
133: }
134: }
135: return width;
136: }
137:
138: /**
139: * Return the height of the original image source.
140: * If the height isn't known, then the image is reconstructed.
141: */
142: public int getHeight() {
143: if (src != null) {
144: src.checkSecurity(null, false);
145: }
146: if ((availinfo & ImageObserver.HEIGHT) == 0) {
147: reconstruct(ImageObserver.HEIGHT);
148: }
149: return height;
150: }
151:
152: /**
153: * Return the height of the original image source.
154: * If the height isn't known, then the ImageObserver object will be
155: * notified when the data is available.
156: */
157: public synchronized int getHeight(ImageObserver iw) {
158: if (src != null) {
159: src.checkSecurity(null, false);
160: }
161: if ((availinfo & ImageObserver.HEIGHT) == 0) {
162: addWatcher(iw, true);
163: if ((availinfo & ImageObserver.HEIGHT) == 0) {
164: return -1;
165: }
166: }
167: return height;
168: }
169:
170: /**
171: * Return a property of the image by name. Individual property names
172: * are defined by the various image formats. If a property is not
173: * defined for a particular image, then this method will return the
174: * UndefinedProperty object. If the properties for this image are
175: * not yet known, then this method will return null and the ImageObserver
176: * object will be notified later. The property name "comment" should
177: * be used to store an optional comment which can be presented to
178: * the user as a description of the image, its source, or its author.
179: */
180: public Object getProperty(String name, ImageObserver observer) {
181: if (src != null) {
182: src.checkSecurity(null, false);
183: }
184: if (properties == null) {
185: addWatcher(observer, true);
186: if (properties == null) {
187: return null;
188: }
189: }
190: Object o = properties.get(name);
191: if (o == null) {
192: o = Image.UndefinedProperty;
193: }
194: return o;
195: }
196:
197: public boolean hasError() {
198: if (src != null) {
199: src.checkSecurity(null, false);
200: }
201: return (availinfo & ImageObserver.ERROR) != 0;
202: }
203:
204: public int check(ImageObserver iw) {
205: if (src != null) {
206: src.checkSecurity(null, false);
207: }
208: if ((availinfo & ImageObserver.ERROR) == 0
209: && ((~availinfo) & (ImageObserver.WIDTH
210: | ImageObserver.HEIGHT | ImageObserver.PROPERTIES)) != 0) {
211: addWatcher(iw, false);
212: }
213: return availinfo;
214: }
215:
216: public void preload(ImageObserver iw) {
217: if (src != null) {
218: src.checkSecurity(null, false);
219: }
220: if ((availinfo & ImageObserver.ALLBITS) == 0) {
221: addWatcher(iw, true);
222: }
223: }
224:
225: private synchronized void addWatcher(ImageObserver iw, boolean load) {
226: if ((availinfo & ImageObserver.ERROR) != 0) {
227: if (iw != null) {
228: iw.imageUpdate(this , ImageObserver.ERROR
229: | ImageObserver.ABORT, -1, -1, -1, -1);
230: }
231: return;
232: }
233: ImageRepresentation ir = getImageRep();
234: ir.addWatcher(iw);
235: if (load) {
236: ir.startProduction();
237: }
238: }
239:
240: private synchronized void reconstruct(int flags) {
241: if ((flags & ~availinfo) != 0) {
242: if ((availinfo & ImageObserver.ERROR) != 0) {
243: return;
244: }
245: ImageRepresentation ir = getImageRep();
246: ir.startProduction();
247: while ((flags & ~availinfo) != 0) {
248: try {
249: wait();
250: } catch (InterruptedException e) {
251: Thread.currentThread().interrupt();
252: return;
253: }
254: if ((availinfo & ImageObserver.ERROR) != 0) {
255: return;
256: }
257: }
258: }
259: }
260:
261: synchronized void addInfo(int newinfo) {
262: availinfo |= newinfo;
263: notifyAll();
264: }
265:
266: void setDimensions(int w, int h) {
267: width = w;
268: height = h;
269: addInfo(ImageObserver.WIDTH | ImageObserver.HEIGHT);
270: }
271:
272: void setProperties(Hashtable props) {
273: if (props == null) {
274: props = new Hashtable();
275: }
276: properties = props;
277: addInfo(ImageObserver.PROPERTIES);
278: }
279:
280: synchronized void infoDone(int status) {
281: if (status == ImageConsumer.IMAGEERROR
282: || ((~availinfo) & (ImageObserver.WIDTH | ImageObserver.HEIGHT)) != 0) {
283: addInfo(ImageObserver.ERROR);
284: } else if ((availinfo & ImageObserver.PROPERTIES) == 0) {
285: setProperties(null);
286: }
287: }
288:
289: public void flush() {
290: if (src != null) {
291: src.checkSecurity(null, false);
292: }
293: if (!(source instanceof OffScreenImageSource)) {
294: ImageRepresentation ir;
295: synchronized (this ) {
296: availinfo &= ~ImageObserver.ERROR;
297: ir = imagerep;
298: imagerep = null;
299: }
300: if (ir != null) {
301: ir.abort();
302: }
303: if (src != null) {
304: src.flush();
305: }
306: }
307: }
308:
309: protected abstract ImageRepresentation makeImageRep();
310:
311: protected synchronized ImageRepresentation getImageRep() {
312: if (src != null) {
313: src.checkSecurity(null, false);
314: }
315: if (imagerep == null) {
316: imagerep = makeImageRep();
317: }
318: return imagerep;
319: }
320: }
|