/* PixelGrabber.java -- retrieve a subset of an image's data
   Copyright (C) 1999, 2003, 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt.image;

import java.awt.Image;
import java.util.Hashtable;

/**
 * PixelGrabber is an ImageConsumer that extracts a rectangular region
 * of pixels from an Image.
 */
public class PixelGrabber implements ImageConsumer
{
  int x, y, offset;
  int width = -1;
  int height = -1;
  int scansize = -1;
  boolean forceRGB = true;

  ColorModel model = ColorModel.getRGBdefault();
  int hints;
  Hashtable props;

  int int_pixel_buffer[];
  boolean ints_delivered = false;
  byte byte_pixel_buffer[];
  boolean bytes_delivered = false;

  ImageProducer ip;
  int observerStatus;
  int consumerStatus;

  private Thread grabberThread;
  boolean grabbing = false;

  /**
   * Construct a PixelGrabber that will retrieve RGB data from a given
   * Image.
   *
   * The RGB data will be retrieved from a rectangular region
   * <code>(x, y, w, h)</code> within the image.  The data will be
   * stored in the provided <code>pix</code> array, which must have
   * been initialized to a size of at least <code>w * h</code>.  The
   * data for a pixel (m, n) in the grab rectangle will be stored at
   * <code>pix[(n - y) * scansize + (m - x) + off]</code>.
   *
   * @param img the Image from which to grab pixels
   * @param x the x coordinate, relative to <code>img</code>'s
   * top-left corner, of the grab rectangle's top-left pixel
   * @param y the y coordinate, relative to <code>img</code>'s
   * top-left corner, of the grab rectangle's top-left pixel
   * @param w the width of the grab rectangle, in pixels
   * @param h the height of the grab rectangle, in pixels
   * @param pix the array in which to store grabbed RGB pixel data
   * @param off the offset into the <code>pix</code> array at which to
   * start storing RGB data
   * @param scansize a set of <code>scansize</code> consecutive
   * elements in the <code>pix</code> array represents one row of
   * pixels in the grab rectangle
   */
  public PixelGrabber(Image img, int x, int y, int w, int h,
		      int pix[], int off, int scansize)
  {
    this (img.getSource(), x, y, w, h, pix, off, scansize);
  }

  /**
   * Construct a PixelGrabber that will retrieve RGB data from a given
   * ImageProducer.
   *
   * The RGB data will be retrieved from a rectangular region
   * <code>(x, y, w, h)</code> within the image produced by
   * <code>ip</code>.  The data will be stored in the provided
   * <code>pix</code> array, which must have been initialized to a
   * size of at least <code>w * h</code>.  The data for a pixel (m, n)
   * in the grab rectangle will be stored at
   * <code>pix[(n - y) * scansize + (m - x) + off]</code>.
   *
   * @param ip the ImageProducer from which to grab pixels. This can
   * be null.
   * @param x the x coordinate of the grab rectangle's top-left pixel,
   * specified relative to the top-left corner of the image produced
   * by <code>ip</code>
   * @param y the y coordinate of the grab rectangle's top-left pixel,
   * specified relative to the top-left corner of the image produced
   * by <code>ip</code>
   * @param w the width of the grab rectangle, in pixels
   * @param h the height of the grab rectangle, in pixels
   * @param pix the array in which to store grabbed RGB pixel data
   * @param off the offset into the <code>pix</code> array at which to
   * start storing RGB data
   * @param scansize a set of <code>scansize</code> consecutive
   * elements in the <code>pix</code> array represents one row of
   * pixels in the grab rectangle
   */
  public PixelGrabber(ImageProducer ip, int x, int y, int w, int h,
		      int pix[], int off, int scansize)
  {
    this.ip = ip;
    this.x = x;
    this.y = y;
    this.width = w;
    this.height = h;
    this.offset = off;
    this.scansize = scansize;

    int_pixel_buffer = pix;
    // Initialize the byte array in case ip sends us byte-formatted
    // pixel data.
    byte_pixel_buffer = new byte[pix.length * 4];
  }

  /**
   * Construct a PixelGrabber that will retrieve data from a given
   * Image.
   *
   * The RGB data will be retrieved from a rectangular region
   * <code>(x, y, w, h)</code> within the image.  The data will be
   * stored in an internal array which can be accessed by calling
   * <code>getPixels</code>.  The data for a pixel (m, n) in the grab
   * rectangle will be stored in the returned array at index
   * <code>(n - y) * scansize + (m - x) + off</code>.
   * If forceRGB is false, then the returned data will be not be
   * converted to RGB from its format in <code>img</code>.
   *
   * If <code>w</code> is negative, the width of the grab region will
   * be from x to the right edge of the image.  Likewise, if
   * <code>h</code> is negative, the height of the grab region will be
   * from y to the bottom edge of the image.
   *
   * @param img the Image from which to grab pixels
   * @param x the x coordinate, relative to <code>img</code>'s
   * top-left corner, of the grab rectangle's top-left pixel
   * @param y the y coordinate, relative to <code>img</code>'s
   * top-left corner, of the grab rectangle's top-left pixel
   * @param w the width of the grab rectangle, in pixels
   * @param h the height of the grab rectangle, in pixels
   * @param forceRGB true to force conversion of the rectangular
   * region's pixel data to RGB
   */
  public PixelGrabber(Image img,
		      int x, int y,
		      int w, int h,
		      boolean forceRGB)
  {
    this.ip = img.getSource();

    if (this.ip == null)
      throw new NullPointerException("The ImageProducer must not be null.");

    this.x = x;
    this.y = y;
    width = w;
    height = h;
    // If width or height is negative, postpone pixel buffer
    // initialization until setDimensions is called back by ip.
    if (width >= 0 && height >= 0)
      {
	int_pixel_buffer = new int[width * height];
	byte_pixel_buffer = new byte[width * height];
      }
    this.forceRGB = forceRGB;
  }

  /**
   * Start grabbing pixels.
   *
   * Spawns an image production thread that calls back to this
   * PixelGrabber's ImageConsumer methods.
   */
  public synchronized void startGrabbing()
  {
    // Make sure we're not already grabbing.
    if (grabbing == false)
      {
	grabbing = true;
	grabberThread = new Thread ()
	  {
	    public void run ()
	    {
              try
                {
                  ip.startProduction (PixelGrabber.this);
                }
              catch (Exception ex)
                {
                  imageComplete(ImageConsumer.IMAGEABORTED);
                }
	    }
	  };
	grabberThread.start ();
      }
  }

  /**
   * Abort pixel grabbing.
   */
  public synchronized void abortGrabbing()
  {
    if (grabbing)
      {
	// Interrupt the grabbing thread.
        Thread moribund = grabberThread;
        grabberThread = null;
        moribund.interrupt();

	imageComplete (ImageConsumer.IMAGEABORTED);
      }
  }

  /**
   * Have our Image or ImageProducer start sending us pixels via our
   * ImageConsumer methods and wait for all pixels in the grab
   * rectangle to be delivered.
   *
   * @return true if successful, false on abort or error
   *
   * @throws InterruptedException if interrupted by another thread.
   */
  public synchronized boolean grabPixels() throws InterruptedException
  {
    return grabPixels(0);
  }

  /**
   * grabPixels's behavior depends on the value of <code>ms</code>.
   *
   * If ms < 0, return true if all pixels from the source image have
   * been delivered, false otherwise.  Do not wait.
   *
   * If ms >= 0 then we request that our Image or ImageProducer start
   * delivering pixels to us via our ImageConsumer methods.
   *
   * If ms > 0, wait at most <code>ms</code> milliseconds for
   * delivery of all pixels within the grab rectangle.
   *
   * If ms == 0, wait until all pixels have been delivered.
   *
   * @return true if all pixels from the source image have been
   * delivered, false otherwise
   *
   * @throws InterruptedException if this thread is interrupted while
   * we are waiting for pixels to be delivered
   */
  public synchronized boolean grabPixels(long ms) throws InterruptedException
  {
    if (ms < 0)
      return ((observerStatus & (ImageObserver.FRAMEBITS
				 | ImageObserver.ALLBITS)) != 0);

    // Spawn a new ImageProducer thread to send us the image data via
    // our ImageConsumer methods.
    startGrabbing();

    if (ms > 0)
      {
	long stop_time = System.currentTimeMillis() + ms;
	long time_remaining;
	while (grabbing)
	  {
	    time_remaining = stop_time - System.currentTimeMillis();
	    if (time_remaining <= 0)
	      break;
	    wait (time_remaining);
	  }
	abortGrabbing ();
      }
    else
      wait ();

    // If consumerStatus is non-zero then the image is done loading or
    // an error has occurred.
    if (consumerStatus != 0)
      return setObserverStatus ();

    return ((observerStatus & (ImageObserver.FRAMEBITS
			       | ImageObserver.ALLBITS)) != 0);
  }

  // Set observer status flags based on the current consumer status
  // flags.  Return true if the consumer flags indicate that the
  // image was loaded successfully, or false otherwise.
  private synchronized boolean setObserverStatus ()
  {
    boolean retval = false;

    if ((consumerStatus & IMAGEERROR) != 0)
      observerStatus |= ImageObserver.ERROR;

    if ((consumerStatus & IMAGEABORTED) != 0)
      observerStatus |= ImageObserver.ABORT;

    if ((consumerStatus & STATICIMAGEDONE) != 0)
      {
	observerStatus |= ImageObserver.ALLBITS;
	retval = true;
      }

    if ((consumerStatus & SINGLEFRAMEDONE) != 0)
      {
	observerStatus |= ImageObserver.FRAMEBITS;
	retval = true;
      }

    return retval;
  }

  /**
   * @return the status of the pixel grabbing thread, represented by a
   * bitwise OR of ImageObserver flags
   */
  public synchronized int getStatus()
  {
    return observerStatus;
  }

  /**
   * @return the width of the grab rectangle in pixels, or a negative
   * number if the ImageProducer has not yet called our setDimensions
   * method
   */
  public synchronized int getWidth()
  {
    return width;
  }

  /**
   * @return the height of the grab rectangle in pixels, or a negative
   * number if the ImageProducer has not yet called our setDimensions
   * method
   */
  public synchronized int getHeight()
  {
    return height;
  }

  /**
   * @return a byte array of pixel data if ImageProducer delivered
   * pixel data using the byte[] variant of setPixels, or an int array
   * otherwise
   */
  public synchronized Object getPixels()
  {
    if (ints_delivered)
      return int_pixel_buffer;
    else if (bytes_delivered)
      return byte_pixel_buffer;
    else
      return null;
  }

  /**
   * @return the ColorModel currently being used for the majority of
   * pixel data conversions
   */
  public synchronized ColorModel getColorModel()
  {
    return model;
  }

  /**
   * Our <code>ImageProducer</code> calls this method to indicate the
   * size of the image being produced.
   *
   * setDimensions is an ImageConsumer method.  None of PixelGrabber's
   * ImageConsumer methods should be called by code that instantiates
   * a PixelGrabber.  They are only made public so they can be called
   * by the PixelGrabber's ImageProducer.
   * 
   * @param width the width of the image
   * @param height the height of the image
   */
  public synchronized void setDimensions(int width, int height)
  {
    // Our width wasn't set when we were constructed.  Set our width
    // so that the grab region includes all pixels from x to the right
    // edge of the source image.
    if (this.width < 0)
      this.width = width - x;

    // Our height wasn't set when we were constructed.  Set our height
    // so that the grab region includes all pixels from y to the
    // bottom edge of the source image.
    if (this.height < 0)
      this.height = height - y;

    if (scansize < 0)
      scansize = this.width;

    if (int_pixel_buffer == null)
      int_pixel_buffer = new int[this.width * this.height];

    if (byte_pixel_buffer == null)
      byte_pixel_buffer = new byte[this.width * this.height];
  }

  /**
   * Our <code>ImageProducer</code> may call this method to send us a
   * list of its image's properties.
   *
   * setProperties is an ImageConsumer method.  None of PixelGrabber's
   * ImageConsumer methods should be called by code that instantiates
   * a PixelGrabber.  They are only made public so they can be called
   * by the PixelGrabber's ImageProducer.
   *
   * @param props a list of properties associated with the image being
   * produced
   */
  public synchronized void setProperties(Hashtable props)
  {
    this.props = props;
  }

  /**
   * Our ImageProducer will call <code>setColorModel</code> to
   * indicate the model used by the majority of calls to
   * <code>setPixels</code>.  Each call to <code>setPixels</code>
   * could however indicate a different <code>ColorModel</code>.
   *
   * setColorModel is an ImageConsumer method.  None of PixelGrabber's
   * ImageConsumer methods should be called by code that instantiates
   * a PixelGrabber.  They are only made public so they can be called
   * by the PixelGrabber's ImageProducer.
   *
   * @param model the color model to be used most often by setPixels
   *
   * @see ColorModel
   */
  public synchronized void setColorModel(ColorModel model)
  {
    this.model = model;
  }

  /**
   * Our <code>ImageProducer</code> may call this method with a
   * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
   * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
   * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code>.
   * 
   * setHints is an ImageConsumer method.  None of PixelGrabber's
   * ImageConsumer methods should be called by code that instantiates
   * a PixelGrabber.  They are only made public so they can be called
   * by the PixelGrabber's ImageProducer.
   *
   * @param flags a bit mask of hints
   */
  public synchronized void setHints(int flags)
  {
    hints = flags;
  }

  /**
   * Our ImageProducer calls setPixels to deliver a subset of its
   * pixels.
   *
   * Each element of the pixels array represents one pixel.  The
   * pixel data is formatted according to the color model model.
   * The x and y parameters are the coordinates of the rectangular
   * region of pixels being delivered to this ImageConsumer,
   * specified relative to the top left corner of the image being
   * produced.  Likewise, w and h are the pixel region's dimensions.
   *
   * @param x x coordinate of pixel block
   * @param y y coordinate of pixel block
   * @param w width of pixel block
   * @param h height of pixel block
   * @param model color model used to interpret pixel data
   * @param pixels pixel block data
   * @param offset offset into pixels array
   * @param scansize width of one row in the pixel block
   */
  public synchronized void setPixels(int x, int y, int w, int h, 
				     ColorModel model, byte[] pixels,
				     int offset, int scansize)
  {
    ColorModel currentModel;
    if (model != null)
      currentModel = model;
    else
      currentModel = this.model;

    for(int yp = y; yp < (y + h); yp++)
      {
	for(int xp = x; xp < (x + w); xp++)
	  {
	    // Check if the coordinates (xp, yp) are within the
	    // pixel block that we are grabbing.
	    if(xp >= this.x
	       && yp >= this.y
	       && xp < (this.x + this.width)
	       && yp < (this.y + this.height))
	      {
		int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
		int p = (yp - y) * scansize + (xp - x) + offset;
		if (forceRGB)
		  {
		    ints_delivered = true;

		    int_pixel_buffer[i] = currentModel.getRGB (pixels[p] & 0xFF);
		  }
		else
		  {
		    bytes_delivered = true;

		    byte_pixel_buffer[i] = pixels[p];
		  }
	      }
	  }
      }
  }

  /**
   * Our ImageProducer calls setPixels to deliver a subset of its
   * pixels.
   *
   * Each element of the pixels array represents one pixel.  The
   * pixel data is formatted according to the color model model.
   * The x and y parameters are the coordinates of the rectangular
   * region of pixels being delivered to this ImageConsumer,
   * specified relative to the top left corner of the image being
   * produced.  Likewise, w and h are the pixel region's dimensions.
   *
   * @param x x coordinate of pixel block
   * @param y y coordinate of pixel block
   * @param w width of pixel block
   * @param h height of pixel block
   * @param model color model used to interpret pixel data
   * @param pixels pixel block data
   * @param offset offset into pixels array
   * @param scansize width of one row in the pixel block
   */
  public synchronized void setPixels(int x, int y, int w, int h, 
				     ColorModel model, int[] pixels,
				     int offset, int scansize)
  {
    ColorModel currentModel;
    if (model != null)
      currentModel = model;
    else
      currentModel = this.model;

    ints_delivered = true;

    for(int yp = y; yp < (y + h); yp++)
      {
	for(int xp = x; xp < (x + w); xp++)
	  {
	    // Check if the coordinates (xp, yp) are within the
	    // pixel block that we are grabbing.
	    if(xp >= this.x
	       && yp >= this.y
	       && xp < (this.x + this.width)
	       && yp < (this.y + this.height))
	      {
		int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
		int p = (yp - y) * scansize + (xp - x) + offset;
		if (forceRGB)
		  int_pixel_buffer[i] = currentModel.getRGB (pixels[p]);
		else
		  int_pixel_buffer[i] = pixels[p];
	      }
	  }
      }
  }

  /**
   * Our <code>ImageProducer</code> calls this method to inform us
   * that a single frame or the entire image is complete.  The method
   * is also used to inform us of an error in loading or producing the
   * image.
   *
   * @param status the status of image production, represented by a
   * bitwise OR of ImageConsumer flags
   */
  public synchronized void imageComplete(int status)
  {
    consumerStatus = status;
    setObserverStatus ();
    grabbing = false;
    if (ip != null)
      ip.removeConsumer (this);

    notifyAll ();
  }

  /**
   * @return the return value of getStatus
   *
   * @specnote The newer getStatus should be used in place of status.
   */
  public synchronized int status()
  {
    return getStatus();
  }
}
