- /*
- * @(#)RenderableImageProducer.java 1.8 00/02/02
- *
- * Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the proprietary information of Sun Microsystems, Inc.
- * Use is subject to license terms.
- *
- */
-
- /* ********************************************************************
- **********************************************************************
- **********************************************************************
- *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
- *** As an unpublished work pursuant to Title 17 of the United ***
- *** States Code. All rights reserved. ***
- **********************************************************************
- **********************************************************************
- **********************************************************************/
-
- package java.awt.image.renderable;
- import java.awt.color.ColorSpace;
- import java.awt.image.ColorModel;
- import java.awt.image.DataBuffer;
- import java.awt.image.DirectColorModel;
- import java.awt.image.ImageConsumer;
- import java.awt.image.ImageProducer;
- import java.awt.image.Raster;
- import java.awt.image.RenderedImage;
- import java.awt.image.SampleModel;
- import java.util.Enumeration;
- import java.util.Vector;
-
- /**
- * An adapter class that implements ImageProducer to allow the
- * asynchronous production of a RenderableImage. The size of the
- * ImageConsumer is determined by the scale factor of the usr2dev
- * transform in the RenderContext. If the RenderContext is null, the
- * default rendering of the RenderableImage is used. This class
- * implements an asynchronous production that produces the image in
- * one thread at one resolution. This class may be subclassed to
- * implement versions that will render the image using several
- * threads. These threads could render either the same image at
- * progressively better quality, or different sections of the image at
- * a single resolution.
- */
- public class RenderableImageProducer implements ImageProducer, Runnable {
-
- /** The RenderableImage source for the producer. */
- RenderableImage rdblImage;
-
- /** The RenderContext to use for producing the image. */
- RenderContext rc;
-
- /** A Vector of image consumers. */
- Vector ics = new Vector();
-
- /**
- * Constructs a new RenderableImageProducer from a RenderableImage
- * and a RenderContext.
- *
- * @param rdblImage the RenderableImage to be rendered.
- * @param rc the RenderContext to use for producing the pixels.
- */
- public RenderableImageProducer(RenderableImage rdblImage,
- RenderContext rc) {
- this.rdblImage = rdblImage;
- this.rc = rc;
- }
-
- /**
- * Sets a new RenderContext to use for the next startProduction() call.
- *
- * @param rc the new RenderContext.
- */
- public synchronized void setRenderContext(RenderContext rc) {
- this.rc = rc;
- }
-
- /**
- * Adds an ImageConsumer to the list of consumers interested in
- * data for this image.
- *
- * @param ic an ImageConsumer to be added to the interest list.
- */
- public synchronized void addConsumer(ImageConsumer ic) {
- if (!ics.contains(ic)) {
- ics.addElement(ic);
- }
- }
-
- /**
- * Determine if an ImageConsumer is on the list of consumers
- * currently interested in data for this image.
- *
- * @param ic the ImageConsumer to be checked.
- * @return true if the ImageConsumer is on the list; false otherwise.
- */
- public synchronized boolean isConsumer(ImageConsumer ic) {
- return ics.contains(ic);
- }
-
- /**
- * Remove an ImageConsumer from the list of consumers interested in
- * data for this image.
- *
- * @param ic the ImageConsumer to be removed.
- */
- public synchronized void removeConsumer(ImageConsumer ic) {
- ics.removeElement(ic);
- }
-
- /**
- * Adds an ImageConsumer to the list of consumers interested in
- * data for this image, and immediately starts delivery of the
- * image data through the ImageConsumer interface.
- *
- * @param ic the ImageConsumer to be added to the list of consumers.
- */
- public synchronized void startProduction(ImageConsumer ic) {
- addConsumer(ic);
- // Need to build a runnable object for the Thread.
- Thread thread = new Thread(this, "RenderableImageProducer Thread");
- thread.start();
- }
-
- /**
- * Requests that a given ImageConsumer have the image data delivered
- * one more time in top-down, left-right order.
- *
- * @param ic the ImageConsumer requesting the resend.
- */
- public void requestTopDownLeftRightResend(ImageConsumer ic) {
- // So far, all pixels are already sent in TDLR order
- }
-
- /**
- * The runnable method for this class. This will produce an image using
- * the current RenderableImage and RenderContext and send it to all the
- * ImageConsumer currently registered with this class.
- */
- public void run() {
- // First get the rendered image
- RenderedImage rdrdImage;
- if (rc != null) {
- rdrdImage = rdblImage.createRendering(rc);
- } else {
- rdrdImage = rdblImage.createDefaultRendering();
- }
-
- // And its ColorModel
- ColorModel colorModel = rdrdImage.getColorModel();
- Raster raster = rdrdImage.getData();
- SampleModel sampleModel = raster.getSampleModel();
- DataBuffer dataBuffer = raster.getDataBuffer();
-
- if (colorModel == null) {
- colorModel = ColorModel.getRGBdefault();
- }
- int minX = raster.getMinX();
- int minY = raster.getMinY();
- int width = raster.getWidth();
- int height = raster.getHeight();
-
- Enumeration icList;
- ImageConsumer ic;
- // Set up the ImageConsumers
- icList = ics.elements();
- while (icList.hasMoreElements()) {
- ic = (ImageConsumer)icList.nextElement();
- ic.setDimensions(width,height);
- ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
- ImageConsumer.COMPLETESCANLINES |
- ImageConsumer.SINGLEPASS |
- ImageConsumer.SINGLEFRAME);
- }
-
- // Get RGB pixels from the raster scanline by scanline and
- // send to consumers.
- int pix[] = new int[width];
- int i,j;
- int numBands = sampleModel.getNumBands();
- int tmpPixel[] = new int[numBands];
- for (j = 0; j < height; j++) {
- for(i = 0; i < width; i++) {
- sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
- pix[i] = colorModel.getDataElement(tmpPixel, 0);
- }
- // Now send the scanline to the Consumers
- icList = ics.elements();
- while (icList.hasMoreElements()) {
- ic = (ImageConsumer)icList.nextElement();
- ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
- }
- }
-
- // Now tell the consumers we're done.
- icList = ics.elements();
- while (icList.hasMoreElements()) {
- ic = (ImageConsumer)icList.nextElement();
- ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
- }
- }
- }