/* 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();
  }
}
