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