290N/A/*
2362N/A * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
290N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
290N/A *
290N/A * This code is free software; you can redistribute it and/or modify it
290N/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
290N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
290N/A *
290N/A * This code is distributed in the hope that it will be useful, but WITHOUT
290N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
290N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
290N/A * version 2 for more details (a copy is included in the LICENSE file that
290N/A * accompanied this code).
290N/A *
290N/A * You should have received a copy of the GNU General Public License version
290N/A * 2 along with this work; if not, write to the Free Software Foundation,
290N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
290N/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.
290N/A */
290N/A
290N/A/* ********************************************************************
290N/A **********************************************************************
290N/A **********************************************************************
290N/A *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
290N/A *** As an unpublished work pursuant to Title 17 of the United ***
290N/A *** States Code. All rights reserved. ***
290N/A **********************************************************************
290N/A **********************************************************************
290N/A **********************************************************************/
290N/A
290N/Apackage java.awt.image.renderable;
290N/Aimport java.awt.color.ColorSpace;
290N/Aimport java.awt.image.ColorModel;
290N/Aimport java.awt.image.DataBuffer;
290N/Aimport java.awt.image.DirectColorModel;
290N/Aimport java.awt.image.ImageConsumer;
290N/Aimport java.awt.image.ImageProducer;
290N/Aimport java.awt.image.Raster;
290N/Aimport java.awt.image.RenderedImage;
290N/Aimport java.awt.image.SampleModel;
290N/Aimport java.util.Enumeration;
290N/Aimport java.util.Vector;
290N/A
290N/A/**
290N/A * An adapter class that implements ImageProducer to allow the
290N/A * asynchronous production of a RenderableImage. The size of the
290N/A * ImageConsumer is determined by the scale factor of the usr2dev
290N/A * transform in the RenderContext. If the RenderContext is null, the
290N/A * default rendering of the RenderableImage is used. This class
290N/A * implements an asynchronous production that produces the image in
290N/A * one thread at one resolution. This class may be subclassed to
290N/A * implement versions that will render the image using several
290N/A * threads. These threads could render either the same image at
290N/A * progressively better quality, or different sections of the image at
290N/A * a single resolution.
290N/A */
290N/Apublic class RenderableImageProducer implements ImageProducer, Runnable {
290N/A
290N/A /** The RenderableImage source for the producer. */
290N/A RenderableImage rdblImage;
290N/A
290N/A /** The RenderContext to use for producing the image. */
290N/A RenderContext rc;
290N/A
290N/A /** A Vector of image consumers. */
290N/A Vector ics = new Vector();
290N/A
290N/A /**
290N/A * Constructs a new RenderableImageProducer from a RenderableImage
290N/A * and a RenderContext.
290N/A *
290N/A * @param rdblImage the RenderableImage to be rendered.
290N/A * @param rc the RenderContext to use for producing the pixels.
290N/A */
290N/A public RenderableImageProducer(RenderableImage rdblImage,
290N/A RenderContext rc) {
290N/A this.rdblImage = rdblImage;
290N/A this.rc = rc;
290N/A }
290N/A
290N/A /**
290N/A * Sets a new RenderContext to use for the next startProduction() call.
290N/A *
290N/A * @param rc the new RenderContext.
290N/A */
290N/A public synchronized void setRenderContext(RenderContext rc) {
290N/A this.rc = rc;
290N/A }
290N/A
290N/A /**
290N/A * Adds an ImageConsumer to the list of consumers interested in
290N/A * data for this image.
290N/A *
290N/A * @param ic an ImageConsumer to be added to the interest list.
290N/A */
290N/A public synchronized void addConsumer(ImageConsumer ic) {
290N/A if (!ics.contains(ic)) {
290N/A ics.addElement(ic);
290N/A }
290N/A }
290N/A
290N/A /**
290N/A * Determine if an ImageConsumer is on the list of consumers
290N/A * currently interested in data for this image.
290N/A *
290N/A * @param ic the ImageConsumer to be checked.
290N/A * @return true if the ImageConsumer is on the list; false otherwise.
290N/A */
290N/A public synchronized boolean isConsumer(ImageConsumer ic) {
290N/A return ics.contains(ic);
290N/A }
290N/A
290N/A /**
290N/A * Remove an ImageConsumer from the list of consumers interested in
290N/A * data for this image.
290N/A *
290N/A * @param ic the ImageConsumer to be removed.
290N/A */
290N/A public synchronized void removeConsumer(ImageConsumer ic) {
290N/A ics.removeElement(ic);
290N/A }
290N/A
290N/A /**
290N/A * Adds an ImageConsumer to the list of consumers interested in
290N/A * data for this image, and immediately starts delivery of the
290N/A * image data through the ImageConsumer interface.
290N/A *
290N/A * @param ic the ImageConsumer to be added to the list of consumers.
290N/A */
290N/A public synchronized void startProduction(ImageConsumer ic) {
290N/A addConsumer(ic);
290N/A // Need to build a runnable object for the Thread.
290N/A Thread thread = new Thread(this, "RenderableImageProducer Thread");
290N/A thread.start();
290N/A }
290N/A
290N/A /**
290N/A * Requests that a given ImageConsumer have the image data delivered
290N/A * one more time in top-down, left-right order.
290N/A *
290N/A * @param ic the ImageConsumer requesting the resend.
290N/A */
290N/A public void requestTopDownLeftRightResend(ImageConsumer ic) {
290N/A // So far, all pixels are already sent in TDLR order
290N/A }
290N/A
290N/A /**
290N/A * The runnable method for this class. This will produce an image using
290N/A * the current RenderableImage and RenderContext and send it to all the
290N/A * ImageConsumer currently registered with this class.
290N/A */
290N/A public void run() {
290N/A // First get the rendered image
290N/A RenderedImage rdrdImage;
290N/A if (rc != null) {
290N/A rdrdImage = rdblImage.createRendering(rc);
290N/A } else {
290N/A rdrdImage = rdblImage.createDefaultRendering();
290N/A }
290N/A
290N/A // And its ColorModel
290N/A ColorModel colorModel = rdrdImage.getColorModel();
290N/A Raster raster = rdrdImage.getData();
290N/A SampleModel sampleModel = raster.getSampleModel();
290N/A DataBuffer dataBuffer = raster.getDataBuffer();
290N/A
290N/A if (colorModel == null) {
290N/A colorModel = ColorModel.getRGBdefault();
290N/A }
290N/A int minX = raster.getMinX();
290N/A int minY = raster.getMinY();
290N/A int width = raster.getWidth();
290N/A int height = raster.getHeight();
290N/A
290N/A Enumeration icList;
290N/A ImageConsumer ic;
290N/A // Set up the ImageConsumers
290N/A icList = ics.elements();
290N/A while (icList.hasMoreElements()) {
290N/A ic = (ImageConsumer)icList.nextElement();
290N/A ic.setDimensions(width,height);
290N/A ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
290N/A ImageConsumer.COMPLETESCANLINES |
290N/A ImageConsumer.SINGLEPASS |
290N/A ImageConsumer.SINGLEFRAME);
290N/A }
290N/A
290N/A // Get RGB pixels from the raster scanline by scanline and
290N/A // send to consumers.
290N/A int pix[] = new int[width];
290N/A int i,j;
290N/A int numBands = sampleModel.getNumBands();
290N/A int tmpPixel[] = new int[numBands];
290N/A for (j = 0; j < height; j++) {
290N/A for(i = 0; i < width; i++) {
290N/A sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
290N/A pix[i] = colorModel.getDataElement(tmpPixel, 0);
290N/A }
290N/A // Now send the scanline to the Consumers
290N/A icList = ics.elements();
290N/A while (icList.hasMoreElements()) {
290N/A ic = (ImageConsumer)icList.nextElement();
290N/A ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
290N/A }
290N/A }
290N/A
290N/A // Now tell the consumers we're done.
290N/A icList = ics.elements();
290N/A while (icList.hasMoreElements()) {
290N/A ic = (ImageConsumer)icList.nextElement();
290N/A ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
290N/A }
290N/A }
290N/A}