Index: gnu/java/awt/peer/gtk/GtkImage.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkImage.java,v
retrieving revision 1.3
diff -u -r1.3 GtkImage.java
--- gnu/java/awt/peer/gtk/GtkImage.java 12 Nov 2003 00:37:33 -0000 1.3
+++ gnu/java/awt/peer/gtk/GtkImage.java 25 Nov 2003 03:59:01 -0000
@@ -1,5 +1,5 @@
/* GtkImage.java
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -168,13 +168,15 @@
for (int i = 0; i < widthObservers.size (); i++)
{
ImageObserver io = (ImageObserver) widthObservers.elementAt (i);
- io.imageUpdate (this, ImageObserver.WIDTH, -1, -1, width, height);
+ if (io != null)
+ io.imageUpdate (this, ImageObserver.WIDTH, -1, -1, width, height);
}
for (int i = 0; i < heightObservers.size (); i++)
{
ImageObserver io = (ImageObserver) heightObservers.elementAt (i);
- io.imageUpdate (this, ImageObserver.HEIGHT, -1, -1, width, height);
+ if (io != null)
+ io.imageUpdate (this, ImageObserver.HEIGHT, -1, -1, width, height);
}
if (observer != null)
@@ -192,7 +194,8 @@
for (int i = 0; i < propertyObservers.size (); i++)
{
ImageObserver io = (ImageObserver) propertyObservers.elementAt (i);
- io.imageUpdate (this, ImageObserver.PROPERTIES, -1, -1, width, height);
+ if (io != null)
+ io.imageUpdate (this, ImageObserver.PROPERTIES, -1, -1, width, height);
}
}
Index: java/awt/image/ImageConsumer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/ImageConsumer.java,v
retrieving revision 1.6
diff -u -r1.6 ImageConsumer.java
--- java/awt/image/ImageConsumer.java 11 Oct 2003 17:19:46 -0000 1.6
+++ java/awt/image/ImageConsumer.java 25 Nov 2003 03:59:01 -0000
@@ -1,5 +1,5 @@
/* ImageConsumer.java -- Java interface for image consumption
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -160,17 +160,45 @@
void setHints(int flags);
/**
- * This function delivers a rectangle of pixels where any
- * pixel(m,n) is stored in the array as a byte
at
- * index (n * scansize + m + offset).
+ * Deliver a subset of an ImageProducer's pixels to this ImageConsumer.
+ *
+ * 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 block of
+ * pixels being delivered to this ImageConsumer. They are
+ * specified relative to the top left corner of the image being
+ * produced. Likewise, w and h are the pixel block'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
*/
void setPixels(int x, int y, int w, int h,
ColorModel model, byte[] pixels, int offset, int scansize);
/**
- * This function delivers a rectangle of pixels where any
- * pixel(m,n) is stored in the array as an int
at
- * index (n * scansize + m + offset).
+ * Deliver a subset of an ImageProducer's pixels to this ImageConsumer.
+ *
+ * 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
*/
void setPixels(int x, int y, int w, int h,
ColorModel model, int[] pixels, int offset, int scansize);
@@ -180,7 +208,9 @@
* single frame or the entire image is complete. The method is
* also used to indicate an error in loading or producing the
* image.
+ *
+ * @param status the status of image production, represented by a
+ * bitwise OR of ImageConsumer flags
*/
void imageComplete(int status);
}
-
Index: java/awt/image/PixelGrabber.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/image/PixelGrabber.java,v
retrieving revision 1.4
diff -u -r1.4 PixelGrabber.java
--- java/awt/image/PixelGrabber.java 27 Jun 2003 20:53:01 -0000 1.4
+++ java/awt/image/PixelGrabber.java 25 Nov 2003 03:59:01 -0000
@@ -1,39 +1,39 @@
-/* PixelGrabber.java -- Java class for providing image data
- Copyright (C) 1999 Free Software Foundation, Inc.
+/* PixelGrabber.java -- retrieve a subset of an image's data
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
-This file is part of GNU Classpath.
+ 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., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 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. */
+ 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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;
@@ -42,309 +42,583 @@
import java.util.Hashtable;
/**
- PixelGrabber is an ImageConsumer designed to extract a rectangular region of pixels
- from an Image
+ * PixelGrabber is an ImageConsumer that extracts a rectangular region
+ * of pixels from an Image.
*/
-public class PixelGrabber implements ImageConsumer
+public class PixelGrabber implements ImageConsumer
{
- int x, y, width, height, status, scansize, offset;
- ColorModel model = ColorModel.getRGBdefault();
- //int hints;
- //Hashtable props;
- int pixel_bufferi[];
- byte pixel_bufferb[];
- boolean grabbing;
- ImageProducer ip;
-
- /**
- * Create a PixelGrabber used to grab pixels from the specified Image
- * in the specified rectangle
- *
- * @param img the Image to grab pixels from
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @param pixels the array of pixel values
- * @param offset the index of the first pixels in the pixels
array
- * @param scansize the width to use in extracting pixels from the pixels
array
- */
- 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 );
- }
-
- /**
- * Create a PixelGrabber used to grab pixels from the specified ImageProducer
- * in the specified rectangle
- *
- * @param ip the ImageProducer to grab pixels from
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @param pixels the array of pixel values
- * @param offset the index of the first pixels in the pixels
array
- * @param scansize the width to use in extracting pixels from the pixels
array
- */
- 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.pixel_bufferi = pix;
- this.offset = off;
- this.scansize = scansize;
- pixel_bufferb = new byte[pix.length * 4];
- }
-
-
- /**
- * Create a PixelGrabber used to grab pixels from the specified Image
- * in the specified rectangle
- *
- * @param img the Image to grab pixels from
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @param forceRGB true to force conversion to RGB
- */
- public PixelGrabber(Image img,
- int x, int y,
- int w, int h,
- boolean forceRGB)
- {
- //FIXME
- }
-
- /**
- Start Grabbing Pixels
- */
- public synchronized void startGrabbing()
- {
- if ( grabbing == false )
+ 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
+ * (x, y, w, h)
within the image. The data will be
+ * stored in the provided pix
array, which must have
+ * been initialized to a size of at least w * h
. The
+ * data for a pixel (m, n) in the grab rectangle will be stored at
+ * pix[(n - y) * scansize + (m - x) + off]
.
+ *
+ * @param img the Image from which to grab pixels
+ * @param x the x coordinate, relative to img
's
+ * top-left corner, of the grab rectangle's top-left pixel
+ * @param y the y coordinate, relative to img
'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 pix
array at which to
+ * start storing RGB data
+ * @param scansize a set of scansize
consecutive
+ * elements in the pix
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
+ * (x, y, w, h)
within the image produced by
+ * ip
. The data will be stored in the provided
+ * pix
array, which must have been initialized to a
+ * size of at least w * h
. The data for a pixel (m, n)
+ * in the grab rectangle will be stored at
+ * pix[(n - y) * scansize + (m - x) + off]
.
+ *
+ * @param ip the ImageProducer from which to grab pixels
+ * @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 ip
+ * @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 ip
+ * @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 pix
array at which to
+ * start storing RGB data
+ * @param scansize a set of scansize
consecutive
+ * elements in the pix
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
+ * (x, y, w, h)
within the image. The data will be
+ * stored in an internal array which can be accessed by calling
+ * getPixels
. The data for a pixel (m, n) in the grab
+ * rectangle will be stored in the returned array at index
+ * (n - y) * scansize + (m - x) + off
.
+ * If forceRGB is false, then the returned data will be not be
+ * converted to RGB from its format in img
.
+ *
+ * If w
is negative, the width of the grab region will
+ * be from x to the right edge of the image. Likewise, if
+ * h
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 img
's
+ * top-left corner, of the grab rectangle's top-left pixel
+ * @param y the y coordinate, relative to img
'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();
+ 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 ()
{
- grabbing = true;
- ip.startProduction( this );
+ ip.startProduction (PixelGrabber.this);
}
- }
-
- /**
- Abort the grabbing of pixels
- */
- public synchronized void abortGrabbing()
- {
- if ( grabbing == true )
- {
- grabbing = false;
- ip.removeConsumer( this );
- }
- }
-
- /**
- Grab the Pixels.
-
- @return true if successful
-
- @throws InterruptedException if interrupted by another thread.
- */
- public boolean grabPixels() throws InterruptedException
- {
- return grabPixels(0);
- }
-
- /**
- Grab the Pixels and abort if it takes too long
-
- @return true if successful
-
- @throws InterruptedException if interrupted by another thread.
- or time runs out
- */
- public synchronized boolean grabPixels(long ms) throws InterruptedException
- {
- startGrabbing();
-
- if (ms < 0)
- return (status == ImageObserver.ALLBITS);
-
- wait(ms);
-
- if (status == ImageObserver.ALLBITS)
- return true;
- else
- return false;
- }
-
- /**
- Get the status of the pixel grabbing representing by ImageObserver flags
-
- @return the status
- */
- public synchronized int getStatus()
- {
- return status;
- }
-
- /**
- Return width of pixel region
-
- @return width of region
- */
- public synchronized int getWidth()
- {
- return width;
- }
-
- /**
- Return height of pixel region
-
- @return height of region
- */
- public synchronized int getHeight()
- {
- return height;
- }
-
- /**
- Returns the grabbed pixel buffer
-
- @return a byte or int array
- */
- public synchronized Object getPixels()
- {
- if( pixel_bufferi != null )
- return pixel_bufferi;
- return pixel_bufferb;
- }
-
- /**
- Get the ColorModel of the image
-
- @return the ColorModel
- */
- public synchronized ColorModel getColorModel()
- {
- return model;
- }
-
- /**
- * An ImageProducer
indicates the size of the image
- * being produced using this method.
- *
- * @param width the width of the image
- * @param height the height of the image
- */
- public void setDimensions(int width, int height)
- {
- }
-
- /**
- * An ImageProducer
can set a list of properties
- * associated with this image by using this method.
- *
- * @param props the list of properties associated with this image
- */
- public void setProperties(Hashtable props)
- {
- //this.props = props; //FIXME - DO WE NEED THIS
- }
-
- /**
- * This ColorModel
should indicate the model used by
- * the majority of calls to setPixels
. Each call to
- * setPixels
could however indicate a different
- * ColorModel
.
- *
- * @param model the color model to be used most often by setPixels
- * @see ColorModel
- */
- public void setColorModel(ColorModel model)
- {
- this.model = model;
- }
-
- /**
- * The ImageProducer
should call this method with a
- * bit mask of hints from any of RANDOMPIXELORDER
,
- * TOPDOWNLEFTRIGHT
, COMPLETESCANLINES
,
- * SINGLEPASS
, SINGLEFRAME
.
- *
- * @param flags a bit mask of hints
- */
- public void setHints(int flags)
- {
- //hints = flags; // FIXME - DO NOT KNOW WHAT TO DO WITH THE HINTS
- }
-
- /**
- * This function delivers a rectangle of pixels where any
- * pixel(m,n) is stored in the array as a byte
at
- * index (n * scansize + m + offset).
- */
- public void setPixels(int x, int y, int w, int h,
- ColorModel model, byte[] pixels, int offset, int scansize)
- {
- //FIXME - I hate bytes
- int xp, yp;
- for( xp = x; xp < ( x + w); xp++ )
- for( yp = y; yp < (y + h); yp++ )
- if( xp >= this.x &&
- yp >= this.y &&
- xp <= ( this.x + this.width ) &&
- yp <= ( this.y + this.height ) ) {
- pixel_bufferb[(yp - this.y) * this.scansize + (xp - this.x) + this.offset] =
- pixels[ offset + yp * scansize + xp ];
- }
-
- }
-
- /**
- * This function delivers a rectangle of pixels where any
- * pixel(m,n) is stored in the array as an int
at
- * index (n * scansize + m + offset).
- */
- public void setPixels(int x, int y, int w, int h,
- ColorModel model, int[] pixels, int offset, int scansize)
- {
- int xp, yp;
- for( xp = x; xp < ( x + w); xp++ )
- for( yp = y; yp < (y + h); yp++ )
- if( xp >= this.x &&
- yp >= this.y &&
- xp <= ( this.x + this.width ) &&
- yp <= ( this.y + this.height ) ) {
- pixel_bufferi[(yp - this.y) * this.scansize + (xp - this.x) + this.offset] =
- pixels[ offset + yp * scansize + xp ];
- }
- }
-
- /**
- * The ImageProducer
calls this method to indicate a
- * single frame or the entire image is complete. The method is
- * also used to indicate an error in loading or producing the
- * image.
- */
- public synchronized void imageComplete(int status)
- {
- this.status = status;
- }
-
- /**
- Get the status of the pixel grabbing representing by ImageObserver flags
-
- @return the status
-
- @specnote This method is not deprecated but getStatus is preferred to use
- */
- public synchronized int status()
- {
- return getStatus();
- }
-
+ };
+ 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 ms
.
+ *
+ * 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 ms
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 ImageProducer
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 ImageProducer
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 setColorModel
to
+ * indicate the model used by the majority of calls to
+ * setPixels
. Each call to setPixels
+ * could however indicate a different ColorModel
.
+ *
+ * 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 ImageProducer
may call this method with a
+ * bit mask of hints from any of RANDOMPIXELORDER
,
+ * TOPDOWNLEFTRIGHT
, COMPLETESCANLINES
,
+ * SINGLEPASS
, SINGLEFRAME
.
+ *
+ * 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;
+
+ assert (i >= 0 && i < int_pixel_buffer.length);
+ assert (p >= 0 && p < pixels.length);
+ int_pixel_buffer[i] = currentModel.getRGB (pixels[p]);
+ }
+ else
+ {
+ bytes_delivered = true;
+
+ assert (i >= 0 && i < byte_pixel_buffer.length);
+ assert (p >= 0 && p < pixels.length);
+ 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;
+ assert (i >= 0 && i < int_pixel_buffer.length);
+ assert (p >= 0 && p < pixels.length);
+ if (forceRGB)
+ int_pixel_buffer[i] = currentModel.getRGB (pixels[p]);
+ else
+ int_pixel_buffer[i] = pixels[p];
+ }
+ }
+ }
+ }
+
+ /**
+ * Our ImageProducer
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;
+ 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();
+ }
}