001: /*
002: * Copyright 1995-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.image;
027:
028: import java.util.Hashtable;
029: import java.awt.image.ImageConsumer;
030: import java.awt.image.ImageProducer;
031: import java.awt.image.Raster;
032: import java.awt.image.WritableRaster;
033: import java.awt.image.ColorModel;
034: import java.awt.image.IndexColorModel;
035: import java.awt.image.DirectColorModel;
036: import java.awt.image.BufferedImage;
037: import java.awt.image.DataBuffer;
038:
039: public class OffScreenImageSource implements ImageProducer {
040: BufferedImage image;
041: int width;
042: int height;
043: Hashtable properties;
044:
045: public OffScreenImageSource(BufferedImage image,
046: Hashtable properties) {
047: this .image = image;
048: if (properties != null) {
049: this .properties = properties;
050: } else {
051: this .properties = new Hashtable();
052: }
053: width = image.getWidth();
054: height = image.getHeight();
055: }
056:
057: public OffScreenImageSource(BufferedImage image) {
058: this (image, null);
059: }
060:
061: // We can only have one consumer since we immediately return the data...
062: private ImageConsumer theConsumer;
063:
064: public synchronized void addConsumer(ImageConsumer ic) {
065: theConsumer = ic;
066: produce();
067: }
068:
069: public synchronized boolean isConsumer(ImageConsumer ic) {
070: return (ic == theConsumer);
071: }
072:
073: public synchronized void removeConsumer(ImageConsumer ic) {
074: if (theConsumer == ic) {
075: theConsumer = null;
076: }
077: }
078:
079: public void startProduction(ImageConsumer ic) {
080: addConsumer(ic);
081: }
082:
083: public void requestTopDownLeftRightResend(ImageConsumer ic) {
084: }
085:
086: private void sendPixels() {
087: ColorModel cm = image.getColorModel();
088: WritableRaster raster = image.getRaster();
089: int numDataElements = raster.getNumDataElements();
090: int dataType = raster.getDataBuffer().getDataType();
091: int[] scanline = new int[width * numDataElements];
092: boolean needToCvt = true;
093:
094: if (cm instanceof IndexColorModel) {
095: byte[] pixels = new byte[width];
096: theConsumer.setColorModel(cm);
097:
098: if (raster instanceof ByteComponentRaster) {
099: needToCvt = false;
100: for (int y = 0; y < height; y++) {
101: raster.getDataElements(0, y, width, 1, pixels);
102: theConsumer.setPixels(0, y, width, 1, cm, pixels,
103: 0, width);
104: }
105: } else if (raster instanceof BytePackedRaster) {
106: needToCvt = false;
107: // Binary image. Need to unpack it
108: for (int y = 0; y < height; y++) {
109: raster.getPixels(0, y, width, 1, scanline);
110: for (int x = 0; x < width; x++) {
111: pixels[x] = (byte) scanline[x];
112: }
113: theConsumer.setPixels(0, y, width, 1, cm, pixels,
114: 0, width);
115: }
116: } else if (dataType == DataBuffer.TYPE_SHORT
117: || dataType == DataBuffer.TYPE_INT) {
118: // Probably a short or int "GRAY" image
119: needToCvt = false;
120: for (int y = 0; y < height; y++) {
121: raster.getPixels(0, y, width, 1, scanline);
122: theConsumer.setPixels(0, y, width, 1, cm, scanline,
123: 0, width);
124: }
125: }
126: } else if (cm instanceof DirectColorModel) {
127: theConsumer.setColorModel(cm);
128: needToCvt = false;
129: switch (dataType) {
130: case DataBuffer.TYPE_INT:
131: for (int y = 0; y < height; y++) {
132: raster.getDataElements(0, y, width, 1, scanline);
133: theConsumer.setPixels(0, y, width, 1, cm, scanline,
134: 0, width);
135: }
136: break;
137: case DataBuffer.TYPE_BYTE:
138: byte[] bscanline = new byte[width];
139: for (int y = 0; y < height; y++) {
140: raster.getDataElements(0, y, width, 1, bscanline);
141: for (int x = 0; x < width; x++) {
142: scanline[x] = bscanline[x] & 0xff;
143: }
144: theConsumer.setPixels(0, y, width, 1, cm, scanline,
145: 0, width);
146: }
147: break;
148: case DataBuffer.TYPE_USHORT:
149: short[] sscanline = new short[width];
150: for (int y = 0; y < height; y++) {
151: raster.getDataElements(0, y, width, 1, sscanline);
152: for (int x = 0; x < width; x++) {
153: scanline[x] = sscanline[x] & 0xffff;
154: }
155: theConsumer.setPixels(0, y, width, 1, cm, scanline,
156: 0, width);
157: }
158: break;
159: default:
160: needToCvt = true;
161: }
162: }
163:
164: if (needToCvt) {
165: // REMIND: Need to add other types of CMs here
166: ColorModel newcm = ColorModel.getRGBdefault();
167: theConsumer.setColorModel(newcm);
168:
169: for (int y = 0; y < height; y++) {
170: for (int x = 0; x < width; x++) {
171: scanline[x] = image.getRGB(x, y);
172: }
173: theConsumer.setPixels(0, y, width, 1, newcm, scanline,
174: 0, width);
175: }
176: }
177: }
178:
179: private void produce() {
180: try {
181: theConsumer.setDimensions(image.getWidth(), image
182: .getHeight());
183: theConsumer.setProperties(properties);
184: sendPixels();
185: theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
186: } catch (NullPointerException e) {
187: if (theConsumer != null) {
188: theConsumer.imageComplete(ImageConsumer.IMAGEERROR);
189: }
190: }
191: }
192: }
|