0N/A/*
2362N/A * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.image;
0N/A
0N/Aimport java.util.Hashtable;
0N/Aimport java.awt.image.ImageConsumer;
0N/Aimport java.awt.image.ImageProducer;
0N/Aimport java.awt.image.Raster;
0N/Aimport java.awt.image.WritableRaster;
0N/Aimport java.awt.image.ColorModel;
0N/Aimport java.awt.image.IndexColorModel;
0N/Aimport java.awt.image.DirectColorModel;
0N/Aimport java.awt.image.BufferedImage;
0N/Aimport java.awt.image.DataBuffer;
0N/A
0N/Apublic class OffScreenImageSource implements ImageProducer {
0N/A BufferedImage image;
0N/A int width;
0N/A int height;
0N/A Hashtable properties;
0N/A
0N/A public OffScreenImageSource(BufferedImage image,
0N/A Hashtable properties) {
0N/A this.image = image;
0N/A if (properties != null) {
0N/A this.properties = properties;
0N/A } else {
0N/A this.properties = new Hashtable();
0N/A }
0N/A width = image.getWidth();
0N/A height = image.getHeight();
0N/A }
0N/A
0N/A public OffScreenImageSource(BufferedImage image) {
0N/A this(image, null);
0N/A }
0N/A
0N/A // We can only have one consumer since we immediately return the data...
0N/A private ImageConsumer theConsumer;
0N/A
0N/A public synchronized void addConsumer(ImageConsumer ic) {
0N/A theConsumer = ic;
0N/A produce();
0N/A }
0N/A
0N/A public synchronized boolean isConsumer(ImageConsumer ic) {
0N/A return (ic == theConsumer);
0N/A }
0N/A
0N/A public synchronized void removeConsumer(ImageConsumer ic) {
0N/A if (theConsumer == ic) {
0N/A theConsumer = null;
0N/A }
0N/A }
0N/A
0N/A public void startProduction(ImageConsumer ic) {
0N/A addConsumer(ic);
0N/A }
0N/A
0N/A public void requestTopDownLeftRightResend(ImageConsumer ic) {
0N/A }
0N/A
0N/A private void sendPixels() {
0N/A ColorModel cm = image.getColorModel();
0N/A WritableRaster raster = image.getRaster();
0N/A int numDataElements = raster.getNumDataElements();
0N/A int dataType = raster.getDataBuffer().getDataType();
0N/A int[] scanline = new int[width*numDataElements];
0N/A boolean needToCvt = true;
0N/A
0N/A if (cm instanceof IndexColorModel) {
0N/A byte[] pixels = new byte[width];
0N/A theConsumer.setColorModel(cm);
0N/A
0N/A if (raster instanceof ByteComponentRaster) {
0N/A needToCvt = false;
0N/A for (int y=0; y < height; y++) {
0N/A raster.getDataElements(0, y, width, 1, pixels);
0N/A theConsumer.setPixels(0, y, width, 1, cm, pixels, 0,
0N/A width);
0N/A }
0N/A }
0N/A else if (raster instanceof BytePackedRaster) {
0N/A needToCvt = false;
0N/A // Binary image. Need to unpack it
0N/A for (int y=0; y < height; y++) {
0N/A raster.getPixels(0, y, width, 1, scanline);
0N/A for (int x=0; x < width; x++) {
0N/A pixels[x] = (byte) scanline[x];
0N/A }
0N/A theConsumer.setPixels(0, y, width, 1, cm, pixels, 0,
0N/A width);
0N/A }
0N/A }
0N/A else if (dataType == DataBuffer.TYPE_SHORT ||
0N/A dataType == DataBuffer.TYPE_INT)
0N/A {
0N/A // Probably a short or int "GRAY" image
0N/A needToCvt = false;
0N/A for (int y=0; y < height; y++) {
0N/A raster.getPixels(0, y, width, 1, scanline);
0N/A theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
0N/A width);
0N/A }
0N/A }
0N/A }
0N/A else if (cm instanceof DirectColorModel) {
0N/A theConsumer.setColorModel(cm);
0N/A needToCvt = false;
0N/A switch (dataType) {
0N/A case DataBuffer.TYPE_INT:
0N/A for (int y=0; y < height; y++) {
0N/A raster.getDataElements(0, y, width, 1, scanline);
0N/A theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
0N/A width);
0N/A }
0N/A break;
0N/A case DataBuffer.TYPE_BYTE:
0N/A byte[] bscanline = new byte[width];
0N/A for (int y=0; y < height; y++) {
0N/A raster.getDataElements(0, y, width, 1, bscanline);
0N/A for (int x=0; x < width; x++) {
0N/A scanline[x] = bscanline[x]&0xff;
0N/A }
0N/A theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
0N/A width);
0N/A }
0N/A break;
0N/A case DataBuffer.TYPE_USHORT:
0N/A short[] sscanline = new short[width];
0N/A for (int y=0; y < height; y++) {
0N/A raster.getDataElements(0, y, width, 1, sscanline);
0N/A for (int x=0; x < width; x++) {
0N/A scanline[x] = sscanline[x]&0xffff;
0N/A }
0N/A theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
0N/A width);
0N/A }
0N/A break;
0N/A default:
0N/A needToCvt = true;
0N/A }
0N/A }
0N/A
0N/A if (needToCvt) {
0N/A // REMIND: Need to add other types of CMs here
0N/A ColorModel newcm = ColorModel.getRGBdefault();
0N/A theConsumer.setColorModel(newcm);
0N/A
0N/A for (int y=0; y < height; y++) {
0N/A for (int x=0; x < width; x++) {
0N/A scanline[x] = image.getRGB(x, y);
0N/A }
0N/A theConsumer.setPixels(0, y, width, 1, newcm, scanline, 0,
0N/A width);
0N/A }
0N/A }
0N/A }
0N/A
0N/A private void produce() {
0N/A try {
0N/A theConsumer.setDimensions(image.getWidth(), image.getHeight());
0N/A theConsumer.setProperties(properties);
0N/A sendPixels();
0N/A theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
0N/A } catch (NullPointerException e) {
0N/A if (theConsumer != null) {
0N/A theConsumer.imageComplete(ImageConsumer.IMAGEERROR);
0N/A }
0N/A }
0N/A }
0N/A}