001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Igor V. Stolyarov
019: * @version $Revision$
020: */package java.awt.image;
021:
022: import java.util.Hashtable;
023: import java.util.Vector;
024:
025: import org.apache.harmony.awt.internal.nls.Messages;
026:
027: public class MemoryImageSource implements ImageProducer {
028:
029: int width;
030: int height;
031: ColorModel cm;
032: byte bData[];
033: int iData[];
034: int offset;
035: int scanline;
036: Hashtable<?, ?> properties;
037: Vector<ImageConsumer> consumers;
038: boolean animated;
039: boolean fullbuffers;
040: int dataType;
041:
042: static final int DATA_TYPE_BYTE = 0;
043: static final int DATA_TYPE_INT = 1;
044:
045: public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
046: int off, int scan, Hashtable<?, ?> props) {
047: init(w, h, cm, pix, off, scan, props);
048: }
049:
050: public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
051: int off, int scan, Hashtable<?, ?> props) {
052: init(w, h, cm, pix, off, scan, props);
053: }
054:
055: public MemoryImageSource(int w, int h, int pix[], int off,
056: int scan, Hashtable<?, ?> props) {
057: init(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
058: }
059:
060: public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
061: int off, int scan) {
062: init(w, h, cm, pix, off, scan, null);
063: }
064:
065: public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
066: int off, int scan) {
067: init(w, h, cm, pix, off, scan, null);
068: }
069:
070: public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
071: init(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
072: }
073:
074: public synchronized boolean isConsumer(ImageConsumer ic) {
075: return consumers.contains(ic);
076: }
077:
078: public void startProduction(ImageConsumer ic) {
079: if (!isConsumer(ic) && ic != null) {
080: consumers.addElement(ic);
081: }
082: try {
083: setHeader(ic);
084: setPixels(ic, 0, 0, width, height);
085: if (animated) {
086: ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
087: } else {
088: ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
089: if (isConsumer(ic)) {
090: removeConsumer(ic);
091: }
092: }
093: } catch (Exception e) {
094: if (isConsumer(ic)) {
095: ic.imageComplete(ImageConsumer.IMAGEERROR);
096: }
097: if (isConsumer(ic)) {
098: removeConsumer(ic);
099: }
100: }
101: }
102:
103: public void requestTopDownLeftRightResend(ImageConsumer ic) {
104: }
105:
106: public synchronized void removeConsumer(ImageConsumer ic) {
107: consumers.removeElement(ic);
108: }
109:
110: public synchronized void addConsumer(ImageConsumer ic) {
111: if (ic == null || consumers.contains(ic)) {
112: return;
113: }
114: consumers.addElement(ic);
115: }
116:
117: public synchronized void newPixels(int newpix[],
118: ColorModel newmodel, int offset, int scansize) {
119: this .dataType = DATA_TYPE_INT;
120: this .iData = newpix;
121: this .cm = newmodel;
122: this .offset = offset;
123: this .scanline = scansize;
124: newPixels();
125: }
126:
127: public synchronized void newPixels(byte newpix[],
128: ColorModel newmodel, int offset, int scansize) {
129: this .dataType = DATA_TYPE_BYTE;
130: this .bData = newpix;
131: this .cm = newmodel;
132: this .offset = offset;
133: this .scanline = scansize;
134: newPixels();
135: }
136:
137: public synchronized void setFullBufferUpdates(boolean fullbuffers) {
138: if (this .fullbuffers == fullbuffers) {
139: return;
140: }
141: this .fullbuffers = fullbuffers;
142: if (animated) {
143: Object consAr[] = consumers.toArray();
144: for (Object element : consAr) {
145: ImageConsumer con = (ImageConsumer) element;
146: try {
147: if (fullbuffers) {
148: con.setHints(ImageConsumer.TOPDOWNLEFTRIGHT
149: | ImageConsumer.COMPLETESCANLINES);
150: } else {
151: con.setHints(ImageConsumer.RANDOMPIXELORDER);
152: }
153: } catch (Exception e) {
154: if (isConsumer(con)) {
155: con.imageComplete(ImageConsumer.IMAGEERROR);
156: }
157: if (isConsumer(con)) {
158: removeConsumer(con);
159: }
160: }
161: }
162: }
163: }
164:
165: public synchronized void setAnimated(boolean animated) {
166: if (this .animated == animated) {
167: return;
168: }
169: Object consAr[] = consumers.toArray();
170: for (Object element : consAr) {
171: ImageConsumer con = (ImageConsumer) element;
172: try {
173: con.imageComplete(ImageConsumer.STATICIMAGEDONE);
174: } catch (Exception e) {
175: if (isConsumer(con)) {
176: con.imageComplete(ImageConsumer.IMAGEERROR);
177: }
178: }
179: if (isConsumer(con)) {
180: removeConsumer(con);
181: }
182: }
183: this .animated = animated;
184: }
185:
186: public synchronized void newPixels(int x, int y, int w, int h,
187: boolean framenotify) {
188: if (animated) {
189: if (fullbuffers) {
190: x = 0;
191: y = 0;
192: w = width;
193: h = height;
194: } else {
195: if (x < 0) {
196: w += x;
197: x = 0;
198: }
199: if (w > width) {
200: w = width - x;
201: }
202: if (y < 0) {
203: h += y;
204: y = 0;
205: }
206: }
207: if (h > height) {
208: h = height - y;
209: }
210: Object consAr[] = consumers.toArray();
211: for (Object element : consAr) {
212: ImageConsumer con = (ImageConsumer) element;
213: try {
214: if (w > 0 && h > 0) {
215: setPixels(con, x, y, w, h);
216: }
217: if (framenotify) {
218: con
219: .imageComplete(ImageConsumer.SINGLEFRAMEDONE);
220: }
221: } catch (Exception ex) {
222: if (isConsumer(con)) {
223: con.imageComplete(ImageConsumer.IMAGEERROR);
224: }
225: if (isConsumer(con)) {
226: removeConsumer(con);
227: }
228: }
229: }
230: }
231: }
232:
233: public synchronized void newPixels(int x, int y, int w, int h) {
234: newPixels(x, y, w, h, true);
235: }
236:
237: public void newPixels() {
238: newPixels(0, 0, width, height, true);
239: }
240:
241: private void init(int width, int height, ColorModel model,
242: byte pixels[], int off, int scan, Hashtable<?, ?> prop) {
243:
244: this .width = width;
245: this .height = height;
246: this .cm = model;
247: this .bData = pixels;
248: this .offset = off;
249: this .scanline = scan;
250: this .properties = prop;
251: this .dataType = DATA_TYPE_BYTE;
252: this .consumers = new Vector<ImageConsumer>();
253:
254: }
255:
256: private void init(int width, int height, ColorModel model,
257: int pixels[], int off, int scan, Hashtable<?, ?> prop) {
258:
259: this .width = width;
260: this .height = height;
261: this .cm = model;
262: this .iData = pixels;
263: this .offset = off;
264: this .scanline = scan;
265: this .properties = prop;
266: this .dataType = DATA_TYPE_INT;
267: this .consumers = new Vector<ImageConsumer>();
268: }
269:
270: private void setPixels(ImageConsumer con, int x, int y, int w, int h) {
271: int pixelOff = scanline * y + offset + x;
272:
273: switch (dataType) {
274: case DATA_TYPE_BYTE:
275: con.setPixels(x, y, w, h, cm, bData, pixelOff, scanline);
276: break;
277: case DATA_TYPE_INT:
278: con.setPixels(x, y, w, h, cm, iData, pixelOff, scanline);
279: break;
280: default:
281: // awt.22A=Wrong type of pixels array
282: throw new IllegalArgumentException(Messages
283: .getString("awt.22A")); //$NON-NLS-1$
284: }
285: }
286:
287: private synchronized void setHeader(ImageConsumer con) {
288: con.setDimensions(width, height);
289: con.setProperties(properties);
290: con.setColorModel(cm);
291: con
292: .setHints(animated ? (fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES)
293: : ImageConsumer.RANDOMPIXELORDER)
294: : (ImageConsumer.TOPDOWNLEFTRIGHT
295: | ImageConsumer.COMPLETESCANLINES
296: | ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME));
297: }
298:
299: }
|