From 4f9533c7722fa07511a94d005227961f4a4dec23 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 18 May 2006 17:29:21 +0000 Subject: Imported GNU Classpath 0.90 Imported GNU Classpath 0.90 * scripts/makemake.tcl: LocaleData.java moved to gnu/java/locale. * sources.am: Regenerated. * gcj/javaprims.h: Regenerated. * Makefile.in: Regenerated. * gcj/Makefile.in: Regenerated. * include/Makefile.in: Regenerated. * testsuite/Makefile.in: Regenerated. * gnu/java/lang/VMInstrumentationImpl.java: New override. * gnu/java/net/local/LocalSocketImpl.java: Likewise. * gnu/classpath/jdwp/VMMethod.java: Likewise. * gnu/classpath/jdwp/VMVirtualMachine.java: Update to latest interface. * java/lang/Thread.java: Add UncaughtExceptionHandler. * java/lang/reflect/Method.java: Implements GenericDeclaration and isSynthetic(), * java/lang/reflect/Field.java: Likewise. * java/lang/reflect/Constructor.java * java/lang/Class.java: Implements Type, GenericDeclaration, getSimpleName() and getEnclosing*() methods. * java/lang/Class.h: Add new public methods. * java/lang/Math.java: Add signum(), ulp() and log10(). * java/lang/natMath.cc (log10): New function. * java/security/VMSecureRandom.java: New override. * java/util/logging/Logger.java: Updated to latest classpath version. * java/util/logging/LogManager.java: New override. From-SVN: r113887 --- .../java/awt/image/AffineTransformOp.java | 2 +- .../java/awt/image/AreaAveragingScaleFilter.java | 291 +++++-- .../classpath/java/awt/image/BandCombineOp.java | 8 +- libjava/classpath/java/awt/image/ColorModel.java | 14 +- .../java/awt/image/ComponentSampleModel.java | 886 +++++++++++++++------ libjava/classpath/java/awt/image/ConvolveOp.java | 14 +- .../classpath/java/awt/image/DirectColorModel.java | 2 +- libjava/classpath/java/awt/image/LookupOp.java | 14 +- .../java/awt/image/ReplicateScaleFilter.java | 1 - libjava/classpath/java/awt/image/RescaleOp.java | 2 +- libjava/classpath/java/awt/image/SampleModel.java | 412 +++++----- .../image/renderable/RenderableImageProducer.java | 93 ++- 12 files changed, 1198 insertions(+), 541 deletions(-) (limited to 'libjava/classpath/java/awt/image') diff --git a/libjava/classpath/java/awt/image/AffineTransformOp.java b/libjava/classpath/java/awt/image/AffineTransformOp.java index f11066e..bb4b795 100644 --- a/libjava/classpath/java/awt/image/AffineTransformOp.java +++ b/libjava/classpath/java/awt/image/AffineTransformOp.java @@ -347,7 +347,7 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp * @param dstPt destination point * @return the location of the transformed source point. */ - public Point2D getPoint2D (Point2D srcPt, Point2D dstPt) + public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) { return transform.transform (srcPt, dstPt); } diff --git a/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java b/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java index 6333ce9..44d5cec 100644 --- a/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java +++ b/libjava/classpath/java/awt/image/AreaAveragingScaleFilter.java @@ -1,5 +1,5 @@ /* AreaAveragingScaleFilter.java -- Java class for filtering images - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999,2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,86 +45,225 @@ package java.awt.image; * points should give the desired results although Sun does not * specify what the exact algorithm should be. *
- * FIXME: Currently this filter does nothing and needs to be implemented. * * @author C. Brian Jones (cbj@gnu.org) */ public class AreaAveragingScaleFilter extends ReplicateScaleFilter { - /** - * Construct an instance of AreaAveragingScaleFilter which - * should be used in conjunction with a FilteredImageSource - * object. - * - * @param width the width of the destination image - * @param height the height of the destination image - */ - public AreaAveragingScaleFilter(int width, int height) { - super(width, height); - } - - /** - * The ImageProducer should call this method with a - * bit mask of hints from any of RANDOMPIXELORDER, - * TOPDOWNLEFTRIGHT, COMPLETESCANLINES, - * SINGLEPASS, SINGLEFRAME from the - * ImageConsumer interface. - *
- * FIXME - more than likely Sun's implementation desires - * TOPDOWNLEFTRIGHT order and this method is overloaded here - * in order to assure that mask is part of the hints added to - * the consumer. - * - * @param flags a bit mask of hints - * @see ImageConsumer - */ - public void setHints(int flags) - { - if (consumer != null) - consumer.setHints(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). - * - * @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 model the ColorModel used to translate the pixels - * @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 void setPixels(int x, int y, int w, int h, - ColorModel model, byte[] pixels, int offset, int scansize) - { - if (consumer != null) - consumer.setPixels(x, y, w, h, model, pixels, offset, 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). - * - * @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 model the ColorModel used to translate the pixels - * @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 void setPixels(int x, int y, int w, int h, - ColorModel model, int[] pixels, int offset, int scansize) - { - if (consumer != null) - consumer.setPixels(x, y, w, h, model, pixels, offset, scansize); - } + /** + * Construct an instance of AreaAveragingScaleFilter which + * should be used in conjunction with a FilteredImageSource + * object. + * + * @param width the width of the destination image + * @param height the height of the destination image + */ + public AreaAveragingScaleFilter(int width, int height) { + super(width, height); + } + /** + * The ImageProducer should call this method with a + * bit mask of hints from any of RANDOMPIXELORDER, + * TOPDOWNLEFTRIGHT, COMPLETESCANLINES, + * SINGLEPASS, SINGLEFRAME from the + * ImageConsumer interface. + *
+ * FIXME - more than likely Sun's implementation desires + * TOPDOWNLEFTRIGHT order and this method is overloaded here + * in order to assure that mask is part of the hints added to + * the consumer. + * + * @param flags a bit mask of hints + * @see ImageConsumer + */ + public void setHints(int flags) + { + if (consumer != null) + consumer.setHints(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). + * + * @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 model the ColorModel used to translate the pixels + * @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 void setPixels(int x, int y, int w, int h, + ColorModel model, byte[] pixels, int offset, int scansize) + { + double rx = ((double) srcWidth) / destWidth; + double ry = ((double) srcHeight) / destHeight; + + int destScansize = (int) Math.round(scansize / rx); + + byte[] destPixels = averagePixels(x, y, w, h, + model, pixels, offset, scansize, + rx, ry, destScansize); + + if (consumer != null) + consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry), + (int) Math.ceil(w/rx), (int) Math.ceil(h/ry), + model, destPixels, 0, destScansize); + } + + /** + * 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). + * + * @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 model the ColorModel used to translate the pixels + * @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 void setPixels(int x, int y, int w, int h, + ColorModel model, int[] pixels, int offset, int scansize) + { + double rx = ((double) srcWidth) / destWidth; + double ry = ((double) srcHeight) / destHeight; + + int destScansize = (int) Math.round(scansize / rx); + + int[] destPixels = averagePixels(x, y, w, h, + model, pixels, offset, scansize, + rx, ry, destScansize); + + if (consumer != null) + consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry), + (int) Math.ceil(w/rx), (int) Math.ceil(h/ry), + model, destPixels, 0, destScansize); + } + + /** + * This is a really terrible implementation, + * since it uses the nearest-neighbor method. This filter is rarely used though. + * + * @param srcx, srcy - Source rectangle upper-left corner + * @param srcw, srch - Source rectangle width and height + * @param model - Pixel color model + * @param srcPixels - Source pixel data. + * @param srcOffset - Starting offset into the source pixel data array. + * @param srcScansize - Source array scanline size. + * @param rx,ry - Scaling factor. + * @param dstScansize - Destination array scanline size. + */ + private byte[] averagePixels(int srcx, int srcy, int srcw, int srch, + ColorModel model, byte[] srcPixels, + int srcOffset, int srcScansize, + double rx, double ry, int destScansize) + { + int destW = (int) Math.ceil(srcw/rx); + int destH = (int) Math.ceil(srch/ry); + byte[] destPixels = new byte[ destW * destH ]; + int sx, sy; + + int w = (int)Math.ceil(rx); + int h = (int)Math.ceil(ry); + + for(int x = 0; x < destW; x++) + for(int y = 0; y < destH; y++) + { + sx = (int) (x * rx); + sy = (int) (y * ry); + + int r,g,b,a; + r = g = b = a = 0; + + for(int i = 0; i < w; i++) + { + for(int j = 0; j < h; j++) + { + int idx = srcx + sx + i + (srcy + sy + j)*srcScansize; + r += model.getRed(srcPixels[ idx ]); + g += model.getGreen(srcPixels[ idx ]); + b += model.getBlue(srcPixels[ idx ]); + a += model.getAlpha(srcPixels[ idx ]); + } + } + + r = r / (w * h); + g = g / (w * h); + b = b / (w * h); + a = a / (w * h); + + // Does this really work? + destPixels[x + destScansize*y] = (byte)model.getDataElement + (new int[]{r, g, b, a}, 0); + } + + return destPixels; + } + + /** + * This is a really terrible implementation, + * since it uses the nearest-neighbor method. This filter is rarely used though. + * + * @param srcx, srcy - Source rectangle upper-left corner + * @param srcw, srch - Source rectangle width and height + * @param model - Pixel color model + * @param srcPixels - Source pixel data. + * @param srcOffset - Starting offset into the source pixel data array. + * @param srcScansize - Source array scanline size. + * @param rx,ry - Scaling factor. + * @param dstScansize - Destination array scanline size. + */ + private int[] averagePixels(int srcx, int srcy, int srcw, int srch, + ColorModel model, int[] srcPixels, + int srcOffset, int srcScansize, + double rx, double ry, int destScansize) + { + int destW = (int) Math.ceil(srcw/rx); + int destH = (int) Math.ceil(srch/ry); + int[] destPixels = new int[ destW * destH ]; + int sx, sy; + + int w = (int)Math.ceil(rx); + int h = (int)Math.ceil(ry); + + for(int x = 0; x < destW; x++) + for(int y = 0; y < destH; y++) + { + sx = (int) (x * rx); + sy = (int) (y * ry); + + int r,g,b,a; + r = g = b = a = 0; + + for(int i = 0; i < w; i++) + { + for(int j = 0; j < h; j++) + { + int idx = srcx + sx + i + (srcy + sy + j)*srcScansize; + r += model.getRed(srcPixels[ idx ]); + g += model.getGreen(srcPixels[ idx ]); + b += model.getBlue(srcPixels[ idx ]); + a += model.getAlpha(srcPixels[ idx ]); + } + } + + r = r / (w * h); + g = g / (w * h); + b = b / (w * h); + a = a / (w * h); + + destPixels[x + destScansize*y] = model.getDataElement + (new int[]{r, g, b, a}, 0); + } + + return destPixels; + } } diff --git a/libjava/classpath/java/awt/image/BandCombineOp.java b/libjava/classpath/java/awt/image/BandCombineOp.java index 79efb02..634125e 100644 --- a/libjava/classpath/java/awt/image/BandCombineOp.java +++ b/libjava/classpath/java/awt/image/BandCombineOp.java @@ -118,7 +118,7 @@ public class BandCombineOp implements RasterOp /* (non-Javadoc) * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster) */ - public Rectangle2D getBounds2D(Raster src) + public final Rectangle2D getBounds2D(Raster src) { return src.getBounds(); } @@ -144,7 +144,7 @@ public class BandCombineOp implements RasterOp * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, *java.awt.geom.Point2D) */ - public Point2D getPoint2D(Point2D src, Point2D dst) + public final Point2D getPoint2D(Point2D src, Point2D dst) { if (dst == null) return (Point2D)src.clone(); dst.setLocation(src); @@ -154,13 +154,13 @@ public class BandCombineOp implements RasterOp /* (non-Javadoc) * @see java.awt.image.RasterOp#getRenderingHints() */ - public RenderingHints getRenderingHints() + public final RenderingHints getRenderingHints() { return hints; } /** Return the matrix for this Op. */ - public float[][] getMatrix() + public final float[][] getMatrix() { return matrix; } diff --git a/libjava/classpath/java/awt/image/ColorModel.java b/libjava/classpath/java/awt/image/ColorModel.java index 1ced2a0..40307f2 100644 --- a/libjava/classpath/java/awt/image/ColorModel.java +++ b/libjava/classpath/java/awt/image/ColorModel.java @@ -452,8 +452,14 @@ public abstract class ColorModel implements Transparency * This method is typically overriden in subclasses to provide a * more efficient implementation. * - * @param array of transferType containing a single pixel. The - * pixel should be encoded in the natural way of the color model. + * @param pixel an array of transferType containing a single pixel. The + * pixel should be encoded in the natural way of the color model. If + * this argument is not an array, as expected, a {@link ClassCastException} + * will be thrown. + * @param components an array that will be filled with the color component + * of the pixel. If this is null, a new array will be allocated + * @param offset index into the components array at which the result + * will be stored * * @return arrays of unnormalized component samples of single * pixel. The scale and multiplication state of the samples are @@ -521,8 +527,8 @@ public abstract class ColorModel implements Transparency float[] normComponents, int normOffset) { - // subclasses has to implement this method. - throw new UnsupportedOperationException(); + int[] components = getComponents(pixel, null, 0); + return getNormalizedComponents(components, 0, normComponents, normOffset); } /** diff --git a/libjava/classpath/java/awt/image/ComponentSampleModel.java b/libjava/classpath/java/awt/image/ComponentSampleModel.java index 5cf06e4..b4e9450 100644 --- a/libjava/classpath/java/awt/image/ComponentSampleModel.java +++ b/libjava/classpath/java/awt/image/ComponentSampleModel.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* Copyright (C) 2000, 2002, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -38,6 +38,8 @@ package java.awt.image; import gnu.java.awt.Buffers; +import java.util.Arrays; + /* FIXME: This class does not yet support data type TYPE_SHORT */ /** @@ -60,11 +62,14 @@ import gnu.java.awt.Buffers; */ public class ComponentSampleModel extends SampleModel { + /** The offsets to the first sample for each band. */ protected int[] bandOffsets; + + /** The indices of the bank used to store each band in a data buffer. */ protected int[] bankIndices; /** - * Number of bands in the image described. + * The number of bands in the image. * @specnote This field shadows the protected numBands in SampleModel. */ protected int numBands; @@ -72,42 +77,128 @@ public class ComponentSampleModel extends SampleModel /** Used when creating data buffers. */ protected int numBanks; + /** + * The number of data elements between a sample in one row and the + * corresponding sample in the next row. + */ protected int scanlineStride; + /** + * The number of data elements between a sample for one pixel and the + * corresponding sample for the next pixel in the same row. + */ protected int pixelStride; private boolean tightPixelPacking = false; + /** + * Creates a new sample model that assumes that all bands are stored in a + * single bank of the {@link DataBuffer}. + *

+ * Note that the bandOffsets array is copied to internal storage + * to prevent subsequent changes to the array from affecting this object. + * + * @param dataType the data type (one of {@link DataBuffer#TYPE_BYTE}, + * {@link DataBuffer#TYPE_USHORT}, {@link DataBuffer#TYPE_SHORT}, + * {@link DataBuffer#TYPE_INT}, {@link DataBuffer#TYPE_FLOAT} or + * {@link DataBuffer#TYPE_DOUBLE}). + * @param w the width in pixels. + * @param h the height in pixels. + * @param pixelStride the number of data elements in the step from a sample + * in one pixel to the corresponding sample in the next pixel. + * @param scanlineStride the number of data elements in the step from a + * sample in a pixel to the corresponding sample in the pixel in the next + * row. + * @param bandOffsets the offset to the first element for each band, with + * the size of the array defining the number of bands (null + * not permitted). + * + * @throws IllegalArgumentException if dataType is not one of + * the specified values. + * @throws IllegalArgumentException if w is less than or equal + * to zero. + * @throws IllegalArgumentException if h is less than or equal + * to zero. + * @throws IllegalArgumentException if w * h exceeds + * {@link Integer#MAX_VALUE}. + * @throws IllegalArgumentException if pixelStride is negative. + * @throws IllegalArgumentException if scanlineStride is less + * than or equal to zero. + * @throws IllegalArgumentException if bandOffsets has zero + * length. + */ public ComponentSampleModel(int dataType, - int w, int h, - int pixelStride, - int scanlineStride, - int[] bandOffsets) + int w, int h, + int pixelStride, + int scanlineStride, + int[] bandOffsets) { this(dataType, w, h, pixelStride, scanlineStride, - new int[bandOffsets.length], bandOffsets); + new int[bandOffsets.length], bandOffsets); } + /** + * Creates a new sample model that assumes that all bands are stored in a + * single bank of the {@link DataBuffer}. + * + * @param dataType the data type (one of {@link DataBuffer#TYPE_BYTE}, + * {@link DataBuffer#TYPE_USHORT}, {@link DataBuffer#TYPE_SHORT}, + * {@link DataBuffer#TYPE_INT}, {@link DataBuffer#TYPE_FLOAT} or + * {@link DataBuffer#TYPE_DOUBLE}). + * @param w the width in pixels. + * @param h the height in pixels. + * @param pixelStride the number of data elements in the step from a sample + * in one pixel to the corresponding sample in the next pixel. + * @param scanlineStride the number of data elements in the step from a + * sample in a pixel to the corresponding sample in the pixel in the next + * row. + * @param bankIndices the index of the bank in which each band is stored + * (null not permitted). This array is copied to internal + * storage so that subsequent updates to the array do not affect the sample + * model. + * @param bandOffsets the offset to the first element for each band, with + * the size of the array defining the number of bands (null + * not permitted). This array is copied to internal storage so that + * subsequent updates to the array do not affect the sample model. + * + * @throws IllegalArgumentException if dataType is not one of + * the specified values. + * @throws IllegalArgumentException if w is less than or equal + * to zero. + * @throws IllegalArgumentException if h is less than or equal + * to zero. + * @throws IllegalArgumentException if w * h exceeds + * {@link Integer#MAX_VALUE}. + * @throws IllegalArgumentException if pixelStride is negative. + * @throws IllegalArgumentException if scanlineStride is less + * than or equal to zero. + * @throws IllegalArgumentException if bandOffsets has zero + * length. + */ public ComponentSampleModel(int dataType, - int w, int h, - int pixelStride, - int scanlineStride, - int[] bankIndices, - int[] bandOffsets) + int w, int h, + int pixelStride, + int scanlineStride, + int[] bankIndices, + int[] bandOffsets) { super(dataType, w, h, bandOffsets.length); - if ((pixelStride<0) || (scanlineStride<0) || - (bandOffsets.length<1) || - (bandOffsets.length != bankIndices.length)) + + // super permits DataBuffer.TYPE_UNDEFINED but this class doesn't... + if (dataType == DataBuffer.TYPE_UNDEFINED) + throw new IllegalArgumentException("Unsupported dataType."); + + if ((pixelStride < 0) || (scanlineStride < 0) || (bandOffsets.length < 1) + || (bandOffsets.length != bankIndices.length)) throw new IllegalArgumentException(); - this.bandOffsets = bandOffsets; - this.bankIndices = bankIndices; + this.bandOffsets = (int[]) bandOffsets.clone(); + this.bankIndices = (int[]) bankIndices.clone(); this.numBands = bandOffsets.length; this.numBanks = 0; - for (int b=0; bnull not permitted). + * + * @return The new sample model. + */ public SampleModel createSubsetSampleModel(int[] bands) { int numBands = bands.length; int[] bankIndices = new int[numBands]; int[] bandOffsets = new int[numBands]; - for (int b=0; b(x, y). This offset can be used to read a sample value from + * a {@link DataBuffer}. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * + * @return The offset. + * + * @see #getOffset(int, int, int) + */ public int getOffset(int x, int y) { return getOffset(x, y, 0); } + /** + * Returns the offset of the sample in band b for the pixel at + * location (x, y). This offset can be used to read a sample + * value from a {@link DataBuffer}. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param b the band index. + * + * @return The offset. + */ public int getOffset(int x, int y, int b) { - return bandOffsets[b] + pixelStride*x + scanlineStride*y; + return bandOffsets[b] + pixelStride * x + scanlineStride * y; } + /** + * Returns the size in bits for each sample (one per band). For this sample + * model, each band has the same sample size and this is determined by the + * data type for the sample model. + * + * @return The sample sizes. + * + * @see SampleModel#getDataType() + */ public final int[] getSampleSize() { int size = DataBuffer.getDataTypeSize(getDataType()); @@ -187,39 +332,101 @@ public class ComponentSampleModel extends SampleModel return sizes; } + /** + * Returns the size in bits for the samples in the specified band. In this + * class, the sample size is the same for every band and is determined from + * the data type for the model. + * + * @param band the band index (ignored here). + * + * @return The sample size in bits. + * + * @see SampleModel#getDataType() + */ public final int getSampleSize(int band) { return DataBuffer.getDataTypeSize(getDataType()); } + /** + * Returns the indices of the bank(s) in the {@link DataBuffer} used to + * store the samples for each band. The returned array is a copy, so that + * altering it will not impact the sample model. + * + * @return The bank indices. + */ public final int[] getBankIndices() { - return bankIndices; + return (int[]) bankIndices.clone(); } + /** + * Returns the offsets to the first sample in each band. The returned array + * is a copy, so that altering it will not impact the sample model. + * + * @return The offsets. + */ public final int[] getBandOffsets() { - return bandOffsets; + return (int[]) bandOffsets.clone(); } + /** + * Returns the distance (in terms of element indices) between the sample for + * one pixel and the corresponding sample for the equivalent pixel in the + * next row. This is used in the calculation of the element offset for + * retrieving samples from a {@link DataBuffer}. + * + * @return The distance between pixel samples in consecutive rows. + */ public final int getScanlineStride() { return scanlineStride; } + /** + * Returns the distance (in terms of element indices) between the sample for + * one pixel and the corresponding sample for the next pixel in a row. This + * is used in the calculation of the element offset for retrieving samples + * from a {@link DataBuffer}. + * + * @return The distance between pixel samples in the same row. + */ public final int getPixelStride() { return pixelStride; } + /** + * Returns the number of data elements used to store the samples for one + * pixel. In this model, this is the same as the number of bands. + * + * @return The number of data elements used to store the samples for one + * pixel. + */ public final int getNumDataElements() { return numBands; } + /** + * Returns the samples for the pixel at location (x, y) in + * a primitive array (the array type is determined by the data type for + * this model). The obj argument provides an option to supply + * an existing array to hold the result, if this is null a new + * array will be allocated. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param obj a primitive array that, if not null, will be + * used to store and return the sample values. + * @param data the data buffer (null not permitted). + * + * @return An array of sample values for the specified pixel. + */ public Object getDataElements(int x, int y, Object obj, DataBuffer data) { - int xyOffset = pixelStride*x + scanlineStride*y; + int xyOffset = pixelStride * x + scanlineStride * y; int[] totalBandDataOffsets = new int[numBands]; @@ -235,124 +442,147 @@ public class ComponentSampleModel extends SampleModel int[] bankOffsets = data.getOffsets(); - for (int b=0; b(x, y, w, h) in a primitive array (the array type is + * determined by the data type for this model). The obj + * argument provides an option to supply an existing array to hold the + * result, if this is null a new array will be allocated. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param w the width. + * @param h the height. + * @param obj a primitive array that, if not null, will be + * used to store and return the sample values. + * @param data the data buffer (null not permitted). + * + * @return An array of sample values for the specified pixels. + * + * @see #setDataElements(int, int, int, int, Object, DataBuffer) + */ public Object getDataElements(int x, int y, int w, int h, Object obj, - DataBuffer data) + DataBuffer data) { if (!tightPixelPacking) { - return super.getDataElements(x, y, w, h, obj, data); + return super.getDataElements(x, y, w, h, obj, data); } // using get speedup // We can copy whole rows - int rowSize = w*numBands; - int dataSize = rowSize*h; + int rowSize = w * numBands; + int dataSize = rowSize * h; - DataBuffer transferBuffer = - Buffers.createBuffer(getTransferType(), obj, dataSize); + DataBuffer transferBuffer = Buffers.createBuffer(getTransferType(), obj, + dataSize); obj = Buffers.getData(transferBuffer); - int inOffset = - pixelStride*x + - scanlineStride*y + - data.getOffset(); // Assumes only one band is used + int inOffset = pixelStride * x + scanlineStride * y + data.getOffset(); + // Assumes only one band is used /* We don't add band offsets since we assume that bands have offsets 0, 1, 2, ... */ @@ -360,189 +590,345 @@ public class ComponentSampleModel extends SampleModel // See if we can copy everything in one go if (scanlineStride == rowSize) { - // Collapse scan lines: - rowSize *= h; - // We ignore scanlineStride since it won't be of any use - h = 1; + // Collapse scan lines: + rowSize *= h; + // We ignore scanlineStride since it won't be of any use + h = 1; } int outOffset = 0; Object inArray = Buffers.getData(data); - for (int yd = 0; yd(x, y, w, h) from a supplied primitive array (the array type + * must be consistent with the data type for this model). + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param w the width. + * @param h the height. + * @param obj a primitive array containing the sample values. + * @param data the data buffer (null not permitted). + * + * @see #getDataElements(int, int, int, int, Object, DataBuffer) + */ public void setDataElements(int x, int y, int w, int h, - Object obj, DataBuffer data) + Object obj, DataBuffer data) { if (!tightPixelPacking) { - super.setDataElements(x, y, w, h, obj, data); - return; + super.setDataElements(x, y, w, h, obj, data); + return; } // using set speedup, we can copy whole rows - int rowSize = w*numBands; - int dataSize = rowSize*h; + int rowSize = w * numBands; + int dataSize = rowSize * h; - DataBuffer transferBuffer = - Buffers.createBufferFromData(getTransferType(), obj, dataSize); + DataBuffer transferBuffer + = Buffers.createBufferFromData(getTransferType(), obj, dataSize); int[] bankOffsets = data.getOffsets(); - int outOffset = - pixelStride*x + - scanlineStride*y + - bankOffsets[0]; // same assuptions as in get... + int outOffset = pixelStride * x + scanlineStride * y + bankOffsets[0]; + // same assumptions as in get... // See if we can copy everything in one go if (scanlineStride == rowSize) { - // Collapse scan lines: - rowSize *= h; - h = 1; + // Collapse scan lines: + rowSize *= h; + h = 1; } int inOffset = 0; Object outArray = Buffers.getData(data); - for (int yd = 0; yd(x, y) + * stored in the specified data buffer. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param iArray an array that will be populated with the sample values and + * returned as the result. The size of this array should be equal to the + * number of bands in the model. If the array is null, a new + * array is created. + * @param data the data buffer (null not permitted). + * + * @return The samples for the specified pixel. + * + * @see #setPixel(int, int, int[], DataBuffer) + */ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data) { - int offset = pixelStride*x + scanlineStride*y; - if (iArray == null) iArray = new int[numBands]; - for (int b=0; bnull will be populated + * with the sample values and returned as the result. + * @param data the data buffer (null not permitted). + * + * @return The samples for all the pixels in the rectangle. + */ public int[] getPixels(int x, int y, int w, int h, int[] iArray, - DataBuffer data) + DataBuffer data) { - int offset = pixelStride*x + scanlineStride*y; - if (iArray == null) iArray = new int[numBands*w*h]; + int offset = pixelStride * x + scanlineStride * y; + if (iArray == null) + iArray = new int[numBands * w * h]; int outOffset = 0; - for (y=0; yb of the pixel at + * (x, y) that is stored in the specified data buffer. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param b the band index. + * @param data the data buffer (null not permitted). + * + * @return The sample value. + * + * @see #setSample(int, int, int, int, DataBuffer) + */ public int getSample(int x, int y, int b, DataBuffer data) { return data.getElem(bankIndices[b], getOffset(x, y, b)); } + /** + * Sets the samples for the pixel at location (x, y) from the + * supplied primitive array (the array type must be consistent with the data + * type for this model). + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param obj a primitive array containing the pixel's sample values. + * @param data the data buffer (null not permitted). + * + * @see #setDataElements(int, int, Object, DataBuffer) + */ public void setDataElements(int x, int y, Object obj, DataBuffer data) { - int offset = pixelStride*x + scanlineStride*y; + int offset = pixelStride * x + scanlineStride * y; int[] totalBandDataOffsets = new int[numBands]; int[] bankOffsets = data.getOffsets(); - for (int b=0; b(x, y) + * stored in the specified data buffer. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param iArray the pixel sample values (null not permitted). + * @param data the data buffer (null not permitted). + * + * @see #getPixel(int, int, int[], DataBuffer) + */ public void setPixel(int x, int y, int[] iArray, DataBuffer data) { - int offset = pixelStride*x + scanlineStride*y; - for (int b=0; bb of the pixel at location + * (x, y) in the specified data buffer. + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * @param b the band index. + * @param s the sample value. + * @param data the data buffer (null not permitted). + * + * @see #getSample(int, int, int, DataBuffer) + */ public void setSample(int x, int y, int b, int s, DataBuffer data) { data.setElem(bankIndices[b], getOffset(x, y, b), s); } + + /** + * Tests this sample model for equality with an arbitrary object. Returns + * true if and only if: + *

+ * + * @param obj the object to test (null permitted). + * + * @return true if this sample model is equal to + * obj, and false otherwise. + */ + public boolean equals(Object obj) + { + if (obj == null) + return false; + if (! (obj instanceof ComponentSampleModel)) + return false; + ComponentSampleModel that = (ComponentSampleModel) obj; + if (this.dataType != that.dataType) + return false; + if (this.width != that.width) + return false; + if (this.height != that.height) + return false; + if (this.pixelStride != that.pixelStride) + return false; + if (this.scanlineStride != that.scanlineStride) + return false; + if (! Arrays.equals(this.bandOffsets, that.bandOffsets)) + return false; + if (! Arrays.equals(this.bankIndices, that.bankIndices)) + return false; + // couldn't find any difference, so... + return true; + } + + /** + * Returns a hash code for this sample model. + * + * @return The hash code. + */ + public int hashCode() + { + // this computation is based on the method described in Chapter 3 + // of Joshua Bloch's Effective Java... + int result = 17; + result = 37 * result + dataType; + result = 37 * result + width; + result = 37 * result + height; + result = 37 * result + pixelStride; + result = 37 * result + scanlineStride; + for (int i = 0; i < bandOffsets.length; i++) + result = 37 * result + bandOffsets[i]; + for (int i = 0; i < bankIndices.length; i++) + result = 37 * result + bankIndices[i]; + return result; + } } diff --git a/libjava/classpath/java/awt/image/ConvolveOp.java b/libjava/classpath/java/awt/image/ConvolveOp.java index 49ca2a6..1f73f75 100644 --- a/libjava/classpath/java/awt/image/ConvolveOp.java +++ b/libjava/classpath/java/awt/image/ConvolveOp.java @@ -110,7 +110,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, * java.awt.image.BufferedImage) */ - public BufferedImage filter(BufferedImage src, BufferedImage dst) + public final BufferedImage filter(BufferedImage src, BufferedImage dst) { if (src == dst) throw new IllegalArgumentException(); @@ -163,7 +163,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.RasterOp#getRenderingHints() */ - public RenderingHints getRenderingHints() + public final RenderingHints getRenderingHints() { return hints; } @@ -181,7 +181,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp * * @return The convolution kernel. */ - public Kernel getKernel() + public final Kernel getKernel() { return (Kernel) kernel.clone(); } @@ -190,7 +190,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, * java.awt.image.WritableRaster) */ - public WritableRaster filter(Raster src, WritableRaster dest) { + public final WritableRaster filter(Raster src, WritableRaster dest) { if (src == dest) throw new IllegalArgumentException(); if (src.getWidth() < kernel.getWidth() || @@ -309,7 +309,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage) */ - public Rectangle2D getBounds2D(BufferedImage src) + public final Rectangle2D getBounds2D(BufferedImage src) { return src.getRaster().getBounds(); } @@ -317,7 +317,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster) */ - public Rectangle2D getBounds2D(Raster src) + public final Rectangle2D getBounds2D(Raster src) { return src.getBounds(); } @@ -330,7 +330,7 @@ public class ConvolveOp implements BufferedImageOp, RasterOp * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, * java.awt.geom.Point2D) */ - public Point2D getPoint2D(Point2D src, Point2D dst) + public final Point2D getPoint2D(Point2D src, Point2D dst) { if (dst == null) return (Point2D)src.clone(); dst.setLocation(src); diff --git a/libjava/classpath/java/awt/image/DirectColorModel.java b/libjava/classpath/java/awt/image/DirectColorModel.java index 4f37151..579dc97 100644 --- a/libjava/classpath/java/awt/image/DirectColorModel.java +++ b/libjava/classpath/java/awt/image/DirectColorModel.java @@ -167,7 +167,7 @@ public class DirectColorModel extends PackedColorModel private int extractAndNormalizeSample(int pixel, int component) { int value = extractAndScaleSample(pixel, component); - if (hasAlpha() && isAlphaPremultiplied()) + if (hasAlpha() && isAlphaPremultiplied() && getAlpha(pixel) != 0) value = value*255/getAlpha(pixel); return value; } diff --git a/libjava/classpath/java/awt/image/LookupOp.java b/libjava/classpath/java/awt/image/LookupOp.java index f131daa..46e72fe 100644 --- a/libjava/classpath/java/awt/image/LookupOp.java +++ b/libjava/classpath/java/awt/image/LookupOp.java @@ -81,7 +81,7 @@ public class LookupOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage) */ - public BufferedImage filter(BufferedImage src, BufferedImage dst) + public final BufferedImage filter(BufferedImage src, BufferedImage dst) { if (src.getColorModel() instanceof IndexColorModel) throw new IllegalArgumentException("LookupOp.filter: IndexColorModel " @@ -149,7 +149,7 @@ public class LookupOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage) */ - public Rectangle2D getBounds2D(BufferedImage src) + public final Rectangle2D getBounds2D(BufferedImage src) { return src.getRaster().getBounds(); } @@ -173,7 +173,7 @@ public class LookupOp implements BufferedImageOp, RasterOp * @param dst The destination point. * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D) */ - public Point2D getPoint2D(Point2D src, Point2D dst) + public final Point2D getPoint2D(Point2D src, Point2D dst) { if (dst == null) return (Point2D) src.clone(); @@ -183,7 +183,7 @@ public class LookupOp implements BufferedImageOp, RasterOp } /** Return the LookupTable for this op. */ - public LookupTable getTable() + public final LookupTable getTable() { return lut; } @@ -191,7 +191,7 @@ public class LookupOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.RasterOp#getRenderingHints() */ - public RenderingHints getRenderingHints() + public final RenderingHints getRenderingHints() { return hints; } @@ -209,7 +209,7 @@ public class LookupOp implements BufferedImageOp, RasterOp * component but not the same as src and dest. * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster) */ - public WritableRaster filter(Raster src, WritableRaster dest) + public final WritableRaster filter(Raster src, WritableRaster dest) { if (dest == null) // Allocate a raster if needed @@ -236,7 +236,7 @@ public class LookupOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster) */ - public Rectangle2D getBounds2D(Raster src) + public final Rectangle2D getBounds2D(Raster src) { return src.getBounds(); } diff --git a/libjava/classpath/java/awt/image/ReplicateScaleFilter.java b/libjava/classpath/java/awt/image/ReplicateScaleFilter.java index d76f9db..6d5099d 100644 --- a/libjava/classpath/java/awt/image/ReplicateScaleFilter.java +++ b/libjava/classpath/java/awt/image/ReplicateScaleFilter.java @@ -46,7 +46,6 @@ import java.util.Hashtable; * exact method is not defined by Sun but some sort of fast Box filter should * probably be correct. *
- * Currently this filter does nothing and needs to be implemented. * * @author C. Brian Jones (cbj@gnu.org) */ diff --git a/libjava/classpath/java/awt/image/RescaleOp.java b/libjava/classpath/java/awt/image/RescaleOp.java index 35b42f7..d5b2969 100644 --- a/libjava/classpath/java/awt/image/RescaleOp.java +++ b/libjava/classpath/java/awt/image/RescaleOp.java @@ -93,7 +93,7 @@ public class RescaleOp implements BufferedImageOp, RasterOp /* (non-Javadoc) * @see java.awt.image.BufferedImageOp#getRenderingHints() */ - public RenderingHints getRenderingHints() + public final RenderingHints getRenderingHints() { return hints; } diff --git a/libjava/classpath/java/awt/image/SampleModel.java b/libjava/classpath/java/awt/image/SampleModel.java index 1159662..6e3fd40 100644 --- a/libjava/classpath/java/awt/image/SampleModel.java +++ b/libjava/classpath/java/awt/image/SampleModel.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation +/* Copyright (C) 2000, 2001, 2002, 2005, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -57,15 +57,43 @@ public abstract class SampleModel */ protected int dataType; + /** + * Creates a new sample model with the specified attributes. + * + * @param dataType the data type (one of {@link DataBuffer#TYPE_BYTE}, + * {@link DataBuffer#TYPE_USHORT}, {@link DataBuffer#TYPE_SHORT}, + * {@link DataBuffer#TYPE_INT}, {@link DataBuffer#TYPE_FLOAT}, + * {@link DataBuffer#TYPE_DOUBLE} or {@link DataBuffer#TYPE_UNDEFINED}). + * @param w the width in pixels (must be greater than zero). + * @param h the height in pixels (must be greater than zero). + * @param numBands the number of bands (must be greater than zero). + * + * @throws IllegalArgumentException if dataType is not one of + * the listed values. + * @throws IllegalArgumentException if w is less than or equal + * to zero. + * @throws IllegalArgumentException if h is less than or equal + * to zero. + * @throws IllegalArgumentException if w * h is greater than + * {@link Integer#MAX_VALUE}. + */ public SampleModel(int dataType, int w, int h, int numBands) { + if (dataType != DataBuffer.TYPE_UNDEFINED) + if (dataType < DataBuffer.TYPE_BYTE || dataType > DataBuffer.TYPE_DOUBLE) + throw new IllegalArgumentException("Unrecognised 'dataType' argument."); + if ((w <= 0) || (h <= 0)) throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok") - +(h <= 0 ? " height<=0" : " height is ok")); - - // FIXME: How can an int be greater than Integer.MAX_VALUE? - // FIXME: How do we identify an unsupported data type? - + + (h <= 0 ? " height<=0" : " height is ok")); + + long area = (long) w * (long) h; + if (area > Integer.MAX_VALUE) + throw new IllegalArgumentException("w * h exceeds Integer.MAX_VALUE."); + + if (numBands <= 0) + throw new IllegalArgumentException("Requires numBands > 0."); + this.dataType = dataType; this.width = w; this.height = h; @@ -102,8 +130,10 @@ public abstract class SampleModel public int[] getPixel(int x, int y, int[] iArray, DataBuffer data) { - if (iArray == null) iArray = new int[numBands]; - for (int b=0; b