001: /*
002: * @(#)ImageDecoder.java 1.23 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.io.InputStream;
032: import java.io.IOException;
033: import java.awt.image.*;
034: import java.security.AccessController;
035: import java.security.PrivilegedAction;
036:
037: public abstract class ImageDecoder {
038: protected InputStreamImageSource source;
039: protected InputStream input;
040: Thread feeder;
041: protected boolean aborted;
042: protected boolean finished;
043: protected ImageConsumerQueue queue;
044: ImageDecoder next;
045:
046: public ImageDecoder(InputStreamImageSource src, InputStream is) {
047: source = src;
048: input = is;
049: feeder = Thread.currentThread();
050: }
051:
052: public boolean isConsumer(ImageConsumer ic) {
053: return ImageConsumerQueue.isConsumer(queue, ic);
054: }
055:
056: public void removeConsumer(ImageConsumer ic) {
057: queue = ImageConsumerQueue.removeConsumer(queue, ic, false);
058: if (!finished && queue == null) {
059: abort();
060: }
061: }
062:
063: protected ImageConsumerQueue nextConsumer(ImageConsumerQueue cq) {
064: synchronized (source) {
065: if (aborted) {
066: return null;
067: }
068: cq = ((cq == null) ? queue : cq.next);
069: while (cq != null) {
070: if (cq.interested) {
071: return cq;
072: }
073: cq = cq.next;
074: }
075: }
076: return null;
077: }
078:
079: protected int setDimensions(int w, int h) {
080: ImageConsumerQueue cq = null;
081: int count = 0;
082: while ((cq = nextConsumer(cq)) != null) {
083: cq.consumer.setDimensions(w, h);
084: count++;
085: }
086: return count;
087: }
088:
089: protected int setProperties(Hashtable props) {
090: ImageConsumerQueue cq = null;
091: int count = 0;
092: while ((cq = nextConsumer(cq)) != null) {
093: cq.consumer.setProperties(props);
094: count++;
095: }
096: return count;
097: }
098:
099: protected int setColorModel(ColorModel model) {
100: ImageConsumerQueue cq = null;
101: int count = 0;
102: while ((cq = nextConsumer(cq)) != null) {
103: cq.consumer.setColorModel(model);
104: count++;
105: }
106: return count;
107: }
108:
109: protected int setHints(int hints) {
110: ImageConsumerQueue cq = null;
111: int count = 0;
112: while ((cq = nextConsumer(cq)) != null) {
113: cq.consumer.setHints(hints);
114: count++;
115: }
116: return count;
117: }
118:
119: protected void headerComplete() {
120: feeder.setPriority(ImageFetcher.LOW_PRIORITY);
121: }
122:
123: protected int setPixels(int x, int y, int w, int h,
124: ColorModel model, byte pix[], int off, int scansize) {
125: source.latchConsumers(this );
126: ImageConsumerQueue cq = null;
127: int count = 0;
128: while ((cq = nextConsumer(cq)) != null) {
129: cq.consumer
130: .setPixels(x, y, w, h, model, pix, off, scansize);
131: count++;
132: }
133: return count;
134: }
135:
136: protected int setPixels(int x, int y, int w, int h,
137: ColorModel model, int pix[], int off, int scansize) {
138: source.latchConsumers(this );
139: ImageConsumerQueue cq = null;
140: int count = 0;
141: while ((cq = nextConsumer(cq)) != null) {
142: cq.consumer
143: .setPixels(x, y, w, h, model, pix, off, scansize);
144: count++;
145: }
146: return count;
147: }
148:
149: protected int imageComplete(int status, boolean done) {
150: source.latchConsumers(this );
151: if (done) {
152: finished = true;
153: source.doneDecoding(this );
154: }
155: ImageConsumerQueue cq = null;
156: int count = 0;
157: while ((cq = nextConsumer(cq)) != null) {
158: cq.consumer.imageComplete(status);
159: count++;
160: }
161: return count;
162: }
163:
164: // J2SE
165: // Fixed 4522041: Redundant image data increases footprint
166: /*
167: public void replayConsumer(ImageConsumer ic) {}
168:
169: public abstract boolean catchupConsumer(InputStreamImageSource src,
170: ImageConsumer ic);
171: */
172:
173: public abstract void produceImage() throws IOException,
174: ImageFormatException;
175:
176: public void abort() {
177: aborted = true;
178: source.doneDecoding(this );
179: close();
180: AccessController.doPrivileged(new PrivilegedAction() {
181: public Object run() {
182: feeder.interrupt();
183: return null;
184: }
185: });
186: }
187:
188: public synchronized void close() {
189: if (input != null) {
190: try {
191: input.close();
192: } catch (IOException e) {
193: }
194: }
195: }
196: }
|