From ef8f9342adc610b1e8fcfb71c5b2400d29f1c8fa Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Sun, 23 Jul 2006 21:28:32 +0000 Subject: 2006-07-23 Andrew John Hughes * Merge of HEAD to generics-branch for 2006-07-16 to 2006-07-23. --- java/awt/Component.java | 2 + java/awt/Graphics2D.java | 12 +- java/awt/GridLayout.java | 12 +- java/awt/LightweightDispatcher.java | 14 +- java/awt/dnd/DragSource.java | 27 +- java/awt/dnd/DropTarget.java | 17 +- java/awt/dnd/DropTargetDragEvent.java | 14 + java/awt/image/BandedSampleModel.java | 13 + java/awt/image/BufferedImageOp.java | 58 +- java/awt/image/ByteLookupTable.java | 17 +- java/awt/image/ComponentSampleModel.java | 13 +- java/awt/image/ConvolveOp.java | 178 +++--- java/awt/image/Kernel.java | 62 +- java/awt/image/MultiPixelPackedSampleModel.java | 187 ++---- java/awt/image/Raster.java | 780 +++++++++++++++++------ java/awt/image/RasterOp.java | 50 +- java/awt/image/ShortLookupTable.java | 39 +- java/awt/image/SinglePixelPackedSampleModel.java | 53 +- java/awt/image/WritableRaster.java | 346 +++++++--- java/lang/Iterable.java | 3 +- java/lang/StrictMath.java | 144 ++++- java/lang/management/MemoryMXBean.java | 28 + java/lang/management/MemoryNotificationInfo.java | 30 +- java/lang/management/MemoryPoolMXBean.java | 8 + java/net/Inet6Address.java | 171 ++++- 25 files changed, 1693 insertions(+), 585 deletions(-) (limited to 'java') diff --git a/java/awt/Component.java b/java/awt/Component.java index 879d57211..6167f8f14 100644 --- a/java/awt/Component.java +++ b/java/awt/Component.java @@ -3856,6 +3856,8 @@ public abstract class Component the peer. For efficiency, the peer can choose not to invalidate if it is happy with the current dimensions, etc. */ + if (dropTarget != null) + dropTarget.addNotify(peer); } } diff --git a/java/awt/Graphics2D.java b/java/awt/Graphics2D.java index a833038c3..e0a1b4756 100644 --- a/java/awt/Graphics2D.java +++ b/java/awt/Graphics2D.java @@ -53,23 +53,21 @@ import java.util.Map; /** * An abstract class defining a device independent two-dimensional vector * graphics API. Concrete subclasses implement this API for output of - * vector graphics to: (*) + * vector graphics to: *

*

*

- * (*) Support for this API is not fully implemented in GNU Classpath yet. - *

* Third party libraries provide support for output to other formats via this * API, including encapsulated postscript (EPS), portable document format (PDF), * and scalable vector graphics (SVG). diff --git a/java/awt/GridLayout.java b/java/awt/GridLayout.java index 80d964142..a6836681d 100644 --- a/java/awt/GridLayout.java +++ b/java/awt/GridLayout.java @@ -254,14 +254,11 @@ public class GridLayout implements LayoutManager, Serializable this.cols = newCols; } - /** Set the horizontal gap + /** Set the horizontal gap. An Exception is not thrown if hgap < 0. * @param hgap The horizontal gap - * @exception IllegalArgumentException If the hgap value is less than zero. */ public void setHgap (int hgap) { - if (hgap < 0) - throw new IllegalArgumentException ("horizontal gap must be nonnegative"); this.hgap = hgap; } @@ -280,21 +277,18 @@ public class GridLayout implements LayoutManager, Serializable this.rows = newRows; } - /** Set the vertical gap. + /** Set the vertical gap. An Exception is not thrown if vgap < 0. * @param vgap The vertical gap - * @exception IllegalArgumentException If the vgap value is less than zero. */ public void setVgap (int vgap) { - if (vgap < 0) - throw new IllegalArgumentException ("vertical gap must be nonnegative"); this.vgap = vgap; } /** Return String description of this object. */ public String toString () { - return ("[" + getClass ().getName () + return (getClass ().getName () + "[" + ",hgap=" + hgap + ",vgap=" + vgap + ",rows=" + rows + ",cols=" + cols + "]"); diff --git a/java/awt/LightweightDispatcher.java b/java/awt/LightweightDispatcher.java index e777145b0..05f88dcf6 100644 --- a/java/awt/LightweightDispatcher.java +++ b/java/awt/LightweightDispatcher.java @@ -152,8 +152,11 @@ class LightweightDispatcher target = findTarget(parent, loc); while (target == null && parent != null) { - if (parent.getMouseListeners().length > 0 - || parent.getMouseMotionListeners().length > 0) + if (parent.mouseListener != null + || parent.mouseMotionListener != null + || (parent.eventMask + & (AWTEvent.MOUSE_EVENT_MASK + | AWTEvent.MOUSE_MOTION_EVENT_MASK)) != 0) { target = parent; } @@ -297,8 +300,11 @@ class LightweightDispatcher if (child.isShowing()) { if (child.contains(loc.x - child.getX(), loc.y - child.getY()) - && (child.getMouseListeners().length > 0 - || child.getMouseMotionListeners().length > 0)) + && (child.mouseListener != null + || child.mouseMotionListener != null + || (child.eventMask + & (AWTEvent.MOUSE_EVENT_MASK + | AWTEvent.MOUSE_MOTION_EVENT_MASK)) != 0)) { target = child; break; diff --git a/java/awt/dnd/DragSource.java b/java/awt/dnd/DragSource.java index 90b62b5db..2ab748270 100644 --- a/java/awt/dnd/DragSource.java +++ b/java/awt/dnd/DragSource.java @@ -51,7 +51,6 @@ import java.awt.datatransfer.FlavorMap; import java.awt.datatransfer.SystemFlavorMap; import java.awt.datatransfer.Transferable; import java.awt.dnd.peer.DragSourceContextPeer; -import java.awt.event.MouseMotionListener; import java.io.Serializable; import java.util.EventListener; @@ -77,6 +76,8 @@ public class DragSource implements Serializable private transient DragSourceMotionListener dragSourceMotionListener; private static DragSource ds; + private DragSourceContextPeer peer; + private DragSourceContext context; /** * Initializes the drag source. @@ -140,12 +141,17 @@ public class DragSource implements Serializable // it to the peer, passing itself as a parameter. Now, the native system has // access to the Transferable through the context. + // FIXME: Add check to determine if dragging. + try { flavorMap = map; - DragSourceContextPeer peer = Toolkit.getDefaultToolkit(). - createDragSourceContextPeer(trigger); - DragSourceContext context = createDragSourceContext(peer, trigger, + + if (peer == null) + peer = Toolkit.getDefaultToolkit().createDragSourceContextPeer(trigger); + + if (context == null) + context = createDragSourceContext(peer, trigger, dragCursor, dragImage, imageOffset, trans, @@ -307,4 +313,17 @@ public class DragSource implements Serializable // Return an empty EventListener array. return (T[]) new EventListener [0]; } + + /** + * TODO + * @return + * + * @since 1.5 + */ + public static int getDragThreshold() + throws NotImplementedException + { + // FIXME: Not implemented. + return 4; + } } // class DragSource diff --git a/java/awt/dnd/DropTarget.java b/java/awt/dnd/DropTarget.java index 2698b1dae..a3650567f 100644 --- a/java/awt/dnd/DropTarget.java +++ b/java/awt/dnd/DropTarget.java @@ -49,6 +49,7 @@ import java.awt.dnd.peer.DropTargetPeer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.peer.ComponentPeer; +import java.awt.peer.LightweightPeer; import java.io.Serializable; import java.util.EventListener; import java.util.TooManyListenersException; @@ -160,12 +161,15 @@ public class DropTarget if (GraphicsEnvironment.isHeadless ()) throw new HeadlessException (); - component = c; - actions = i; + setComponent(c); + setDefaultActions(i); dropTargetListener = dtl; flavorMap = fm; setActive (b); + + if (c != null) + c.setDropTarget(this); } /** @@ -275,9 +279,16 @@ public class DropTarget public void addNotify(ComponentPeer p) { + Component c = component; + while (c != null && p instanceof LightweightPeer) + { + p = c.getPeer(); + c = c.getParent(); + } + if (p instanceof DropTargetPeer) { - peer = (DropTargetPeer) p; + peer = ((DropTargetPeer) p); peer.addDropTarget(this); } else diff --git a/java/awt/dnd/DropTargetDragEvent.java b/java/awt/dnd/DropTargetDragEvent.java index ea5b682d1..838141ec3 100644 --- a/java/awt/dnd/DropTargetDragEvent.java +++ b/java/awt/dnd/DropTargetDragEvent.java @@ -40,6 +40,7 @@ package java.awt.dnd; import java.awt.Point; import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; import java.util.List; /** @@ -136,4 +137,17 @@ public class DropTargetDragEvent extends DropTargetEvent { context.rejectDrag (); } + + /** + * TODO + * + * @return + * + * @since 1.5 + */ + public Transferable getTransferable() + { + // FIXME: Not implemented + return null; + } } // class DropTargetDragEvent diff --git a/java/awt/image/BandedSampleModel.java b/java/awt/image/BandedSampleModel.java index ed6abcf4f..a346cf6af 100644 --- a/java/awt/image/BandedSampleModel.java +++ b/java/awt/image/BandedSampleModel.java @@ -36,6 +36,8 @@ exception statement from your version. */ package java.awt.image; +import gnu.java.awt.Buffers; + /** * A sample model that reads each sample value from a separate band in the * {@link DataBuffer}. @@ -89,6 +91,17 @@ public final class BandedSampleModel extends ComponentSampleModel { super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets); } + + /** + * Creates a new data buffer that is compatible with this sample model. + * + * @return The new data buffer. + */ + public DataBuffer createDataBuffer() + { + int size = scanlineStride * height; + return Buffers.createBuffer(getDataType(), size, numBanks); + } /** * Creates a new SampleModel that is compatible with this diff --git a/java/awt/image/BufferedImageOp.java b/java/awt/image/BufferedImageOp.java index 2ecbec056..f6a24c976 100644 --- a/java/awt/image/BufferedImageOp.java +++ b/java/awt/image/BufferedImageOp.java @@ -1,5 +1,5 @@ /* BufferedImageOp.java -- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,13 +43,65 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** - * NEEDS DOCUMENTATION + * An operation that is performed on one BufferedImage (the + * source) producing a new BufferedImage (the destination). */ public interface BufferedImageOp { + /** + * Performs an operation on the source image, returning the result in a + * BufferedImage. If dest is null, a + * new BufferedImage will be created by calling the + * {@link #createCompatibleDestImage} method. If dest + * is not null, the result is written to dest then + * returned (this avoids creating a new BufferedImage each + * time this method is called). + * + * @param src the source image. + * @param dst the destination image (null permitted). + * + * @return The filterd image. + */ BufferedImage filter(BufferedImage src, BufferedImage dst); + + /** + * Returns the bounds of the destination image on the basis of this + * BufferedImageOp being applied to the specified source image. + * + * @param src the source image. + * + * @return The destination bounds. + */ Rectangle2D getBounds2D(BufferedImage src); + + /** + * Returns a new BufferedImage that can be used by this + * BufferedImageOp as the destination image when filtering + * the specified source image. + * + * @param src the source image. + * @param dstCM the color model for the destination image. + * + * @return A new image that can be used as the destination image. + */ BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM); + + /** + * Returns the point on the destination image that corresponds to the given + * point on the source image. + * + * @param src the source point. + * @param dst the destination point (null permitted). + * + * @return The destination point. + */ Point2D getPoint2D(Point2D src, Point2D dst); + + /** + * Returns the rendering hints for this operation. + * + * @return The rendering hints. + */ RenderingHints getRenderingHints(); -} // interface BufferedImageOp + +} diff --git a/java/awt/image/ByteLookupTable.java b/java/awt/image/ByteLookupTable.java index df02d0a1b..ecc0023af 100644 --- a/java/awt/image/ByteLookupTable.java +++ b/java/awt/image/ByteLookupTable.java @@ -1,5 +1,5 @@ /* ByteLookupTable.java -- Java class for a pixel translation table. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -60,14 +60,20 @@ public class ByteLookupTable extends LookupTable * components. * * @param offset Offset to be subtracted. - * @param data Array of lookup tables. + * @param data Array of lookup tables (null not permitted). * @exception IllegalArgumentException if offset < 0 or data.length < 1. */ public ByteLookupTable(int offset, byte[][] data) throws IllegalArgumentException { super(offset, data.length); - this.data = data; + + // tests show that Sun's implementation creates a new array to store the + // references from the incoming 'data' array - not sure why, but we'll + // match that behaviour just in case it matters... + this.data = new byte[data.length][]; + for (int i = 0; i < data.length; i++) + this.data[i] = data[i]; } /** @@ -77,13 +83,16 @@ public class ByteLookupTable extends LookupTable * table. The same table is applied to all pixel components. * * @param offset Offset to be subtracted. - * @param data Lookup table for all components. + * @param data Lookup table for all components (null not + * permitted). * @exception IllegalArgumentException if offset < 0. */ public ByteLookupTable(int offset, byte[] data) throws IllegalArgumentException { super(offset, 1); + if (data == null) + throw new NullPointerException("Null 'data' argument."); this.data = new byte[][] {data}; } diff --git a/java/awt/image/ComponentSampleModel.java b/java/awt/image/ComponentSampleModel.java index b4e9450b0..bccabbbca 100644 --- a/java/awt/image/ComponentSampleModel.java +++ b/java/awt/image/ComponentSampleModel.java @@ -272,9 +272,7 @@ public class ComponentSampleModel extends SampleModel // Maybe this value should be precalculated in the constructor? int highestOffset = 0; for (int b = 0; b < numBands; b++) - { - highestOffset = Math.max(highestOffset, bandOffsets[b]); - } + highestOffset = Math.max(highestOffset, bandOffsets[b]); int size = pixelStride * (width - 1) + scanlineStride * (height - 1) + highestOffset + 1; @@ -678,6 +676,9 @@ public class ComponentSampleModel extends SampleModel */ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data) { + if (x < 0 || x >= width || y < 0 || y >= height) + throw new ArrayIndexOutOfBoundsException("Pixel (" + x + ", " + y + + ") is out of bounds."); int offset = pixelStride * x + scanlineStride * y; if (iArray == null) iArray = new int[numBands]; @@ -736,10 +737,16 @@ public class ComponentSampleModel extends SampleModel * * @return The sample value. * + * @throws ArrayIndexOutOfBoundsException if (x, y) is outside + * the bounds [0, 0, width, height]. + * * @see #setSample(int, int, int, int, DataBuffer) */ public int getSample(int x, int y, int b, DataBuffer data) { + if (x < 0 || x >= width || y < 0 || y >= height) + throw new ArrayIndexOutOfBoundsException("Sample (" + x + ", " + y + + ") is out of bounds."); return data.getElem(bankIndices[b], getOffset(x, y, b)); } diff --git a/java/awt/image/ConvolveOp.java b/java/awt/image/ConvolveOp.java index 1f73f75b2..ffb834874 100644 --- a/java/awt/image/ConvolveOp.java +++ b/java/awt/image/ConvolveOp.java @@ -1,5 +1,5 @@ /* ConvolveOp.java -- - Copyright (C) 2004, 2005 Free Software Foundation -- ConvolveOp + Copyright (C) 2004, 2005, 2006, Free Software Foundation -- ConvolveOp This file is part of GNU Classpath. @@ -42,7 +42,6 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import java.util.Arrays; /** * Convolution filter. @@ -190,112 +189,101 @@ public class ConvolveOp implements BufferedImageOp, RasterOp * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, * java.awt.image.WritableRaster) */ - public final 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() || - src.getHeight() < kernel.getHeight()) - throw new ImagingOpException(null); - + throw new IllegalArgumentException("src == dest is not allowed."); + if (kernel.getWidth() > src.getWidth() + || kernel.getHeight() > src.getHeight()) + throw new ImagingOpException("The kernel is too large."); if (dest == null) dest = createCompatibleDestRaster(src); - else if (src.numBands != dest.numBands) - throw new ImagingOpException(null); + else if (src.getNumBands() != dest.getNumBands()) + throw new ImagingOpException("src and dest have different band counts."); - // Deal with bottom edge - if (edge == EDGE_ZERO_FILL) - { - float[] zeros = new float[src.getNumBands() * src.getWidth() - * (kernel.getYOrigin() - 1)]; - Arrays.fill(zeros, 0); - dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(), - kernel.getYOrigin() - 1, zeros); - } - else - { - float[] vals = new float[src.getNumBands() * src.getWidth() - * (kernel.getYOrigin() - 1)]; - src.getPixels(src.getMinX(), src.getMinY(), src.getWidth(), - kernel.getYOrigin() - 1, vals); - dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(), - kernel.getYOrigin() - 1, vals); - } + // calculate the borders that the op can't reach... + int kWidth = kernel.getWidth(); + int kHeight = kernel.getHeight(); + int left = kernel.getXOrigin(); + int right = Math.max(kWidth - left - 1, 0); + int top = kernel.getYOrigin(); + int bottom = Math.max(kHeight - top - 1, 0); - // Handle main section + // process the region that is reachable... + int regionW = src.width - left - right; + int regionH = src.height - top - bottom; float[] kvals = kernel.getKernelData(null); + float[] tmp = new float[kWidth * kHeight]; - float[] tmp = new float[kernel.getWidth() * kernel.getHeight()]; - for (int y = src.getMinY() + kernel.getYOrigin(); - y < src.getMinY() + src.getHeight() - kernel.getYOrigin() / 2; y++) - { - // Handle unfiltered edge pixels at start of line - float[] t1 = new float[(kernel.getXOrigin() - 1) * src.getNumBands()]; - if (edge == EDGE_ZERO_FILL) - Arrays.fill(t1, 0); - else - src.getPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1); - dest.setPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1); - - for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++) + for (int x = 0; x < regionW; x++) { - // FIXME: This needs a much more efficient implementation - for (int b = 0; b < src.getNumBands(); b++) - { - float v = 0; - src.getSamples(x, y, kernel.getWidth(), kernel.getHeight(), b, tmp); - for (int i=0; i < tmp.length; i++) - v += tmp[i] * kvals[i]; - dest.setSample(x, y, b, v); - } + for (int y = 0; y < regionH; y++) + { + // FIXME: This needs a much more efficient implementation + for (int b = 0; b < src.getNumBands(); b++) + { + float v = 0; + src.getSamples(x, y, kWidth, kHeight, b, tmp); + for (int i = 0; i < tmp.length; i++) + v += tmp[tmp.length - i - 1] * kvals[i]; + // FIXME: in the above line, I've had to reverse the order of + // the samples array to make the tests pass. I haven't worked + // out why this is necessary. + dest.setSample(x + kernel.getXOrigin(), y + kernel.getYOrigin(), + b, v); + } + } } - - // Handle unfiltered edge pixels at end of line - float[] t2 = new float[(kernel.getWidth() / 2) * src.getNumBands()]; - if (edge == EDGE_ZERO_FILL) - Arrays.fill(t2, 0); - else - src.getPixels(src.getMinX() + src.getWidth() - - (kernel.getWidth() / 2), - y, kernel.getWidth() / 2, 1, t2); - dest.setPixels(src.getMinX() + src.getWidth() - (kernel.getWidth() / 2), - y, kernel.getWidth() / 2, 1, t2); - } - for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++) - for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++) + + // fill in the top border + fillEdge(src, dest, 0, 0, src.width, top, edge); + + // fill in the bottom border + fillEdge(src, dest, 0, src.height - bottom, src.width, bottom, edge); + + // fill in the left border + fillEdge(src, dest, 0, top, left, regionH, edge); + + // fill in the right border + fillEdge(src, dest, src.width - right, top, right, regionH, edge); + + return dest; + } + + /** + * Fills a range of pixels (typically at the edge of a raster) with either + * zero values (if edgeOp is EDGE_ZERO_FILL) or the + * corresponding pixel values from the source raster (if edgeOp + * is EDGE_NO_OP). This utility method is called by the + * {@link #fillEdge(Raster, WritableRaster, int, int, int, int, int)} method. + * + * @param src the source raster. + * @param dest the destination raster. + * @param x the x-coordinate of the top left pixel in the range. + * @param y the y-coordinate of the top left pixel in the range. + * @param w the width of the pixel range. + * @param h the height of the pixel range. + * @param edgeOp indicates how to determine the values for the range + * (either {@link #EDGE_ZERO_FILL} or {@link #EDGE_NO_OP}). + */ + private void fillEdge(Raster src, WritableRaster dest, int x, int y, int w, + int h, int edgeOp) + { + if (w <= 0) + return; + if (h <= 0) + return; + if (edgeOp == EDGE_ZERO_FILL) // fill region with zeroes { - + float[] zeros = new float[src.getNumBands() * w * h]; + dest.setPixels(x, y, w, h, zeros); } - for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++) - for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++) + else // copy pixels from source { - + float[] pixels = new float[src.getNumBands() * w * h]; + src.getPixels(x, y, w, h, pixels); + dest.setPixels(x, y, w, h, pixels); } - - // Handle top edge - if (edge == EDGE_ZERO_FILL) - { - float[] zeros = new float[src.getNumBands() * src.getWidth() * - (kernel.getHeight() / 2)]; - Arrays.fill(zeros, 0); - dest.setPixels(src.getMinX(), - src.getHeight() + src.getMinY() - (kernel.getHeight() / 2), - src.getWidth(), kernel.getHeight() / 2, zeros); - } - else - { - float[] vals = new float[src.getNumBands() * src.getWidth() * - (kernel.getHeight() / 2)]; - src.getPixels(src.getMinX(), - src.getHeight() + src.getMinY() - - (kernel.getHeight() / 2), - src.getWidth(), kernel.getHeight() / 2, vals); - dest.setPixels(src.getMinX(), - src.getHeight() + src.getMinY() - - (kernel.getHeight() / 2), - src.getWidth(), kernel.getHeight() / 2, vals); - } - - return dest; } /* (non-Javadoc) diff --git a/java/awt/image/Kernel.java b/java/awt/image/Kernel.java index f7c29c3cd..8361c0cf9 100644 --- a/java/awt/image/Kernel.java +++ b/java/awt/image/Kernel.java @@ -1,5 +1,5 @@ /* Kernel.java -- Java class for an image processing kernel - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,21 +44,32 @@ package java.awt.image; * values representing a 2-dimensional array in row-major order. * * @author Jerry Quinn (jlquinn@optonline.net) - * @version 1.0 */ public class Kernel implements Cloneable { + /** The kernel width. */ private final int width; + + /** The kernel height. */ private final int height; + + /** Internal storage for the kernel's values. */ private final float[] data; /** - * Creates a new Kernel instance. + * Creates a new Kernel instance with the specified dimensions + * and values. The first width * height values in the specified + * data array are copied to internal storage. * - * @param width The 2D width of data. - * @param height The 2D height of data. - * @param data The source data array. - * @exception IllegalArgumentException if width * height < data.length. + * @param width the kernel width. + * @param height the kernel height. + * @param data the source data array (null not permitted). + * + * @throws IllegalArgumentException if data.length is less than + * width * height. + * @throws IllegalArgumentException if width or + * height is less than zero. + * @throws NullPointerException if data is null. */ public Kernel(int width, int height, float[] data) throws IllegalArgumentException @@ -72,7 +83,10 @@ public class Kernel implements Cloneable } /** - * Return the X origin: (width - 1) / 2 + * Returns the x-origin for the kernel, which is calculated as + * (width - 1) / 2. + * + * @return The x-origin for the kernel. */ public final int getXOrigin() { @@ -80,7 +94,10 @@ public class Kernel implements Cloneable } /** - * Return the Y origin: (height - 1) / 2 + * Returns the y-origin for the kernel, which is calculated as + * (height - 1) / 2. + * + * @return The y-origin for the kernel. */ public final int getYOrigin() { @@ -88,6 +105,8 @@ public class Kernel implements Cloneable } /** + * Returns the kernel width (as supplied to the constructor). + * * @return The kernel width. */ public final int getWidth() @@ -96,6 +115,8 @@ public class Kernel implements Cloneable } /** + * Returns the kernel height (as supplied to the constructor). + * * @return The kernel height. */ public final int getHeight() @@ -104,20 +125,25 @@ public class Kernel implements Cloneable } /** - * Return the kernel data. + * Returns an array containing a copy of the kernel data. If the + * data argument is non-null, the kernel values + * are copied into it and then data is returned as the result. + * If the data argument is null, this method + * allocates a new array then populates and returns it. * - * If data is null, allocates a new array and returns it. Otherwise, the - * kernel values are copied into data. - * - * @param data Array to copy values into, or null. + * @param data an array to copy the return values into (if + * null, a new array is allocated). + * * @return The array with copied values. - * @exception IllegalArgumentException if data != null and too small. + * + * @throws IllegalArgumentException if data.length is less than + * the kernel's width * height. */ public final float[] getKernelData(float[] data) throws IllegalArgumentException { if (data == null) - return (float[])this.data.clone(); + return (float[]) this.data.clone(); if (data.length < this.data.length) throw new IllegalArgumentException(); @@ -127,13 +153,15 @@ public class Kernel implements Cloneable } /** + * Returns a clone of this kernel. + * * @return a clone of this Kernel. */ public Object clone() { try { - return super.clone(); + return super.clone(); } catch (CloneNotSupportedException e) { diff --git a/java/awt/image/MultiPixelPackedSampleModel.java b/java/awt/image/MultiPixelPackedSampleModel.java index ddd38208d..8732e5765 100644 --- a/java/awt/image/MultiPixelPackedSampleModel.java +++ b/java/awt/image/MultiPixelPackedSampleModel.java @@ -231,10 +231,12 @@ public class MultiPixelPackedSampleModel extends SampleModel * @param y the y-coordinate. * * @return The index in the data buffer that stores the pixel at (x, y). + * + * @see #getBitOffset(int) */ public int getOffset(int x, int y) { - return scanlineStride * y + ((dataBitOffset + x*numberOfBits) / elemBits); + return scanlineStride * y + ((dataBitOffset + x * numberOfBits) / elemBits); } /** @@ -247,7 +249,7 @@ public class MultiPixelPackedSampleModel extends SampleModel */ public int getBitOffset(int x) { - return (dataBitOffset + x*numberOfBits) % elemBits; + return (dataBitOffset + x * numberOfBits) % elemBits; } /** @@ -331,35 +333,41 @@ public class MultiPixelPackedSampleModel extends SampleModel * array obj, since there is only one band. If obj is null, a new array of * getTransferType() is created. * - * @param x The x-coordinate of the pixel rectangle to store in obj. - * @param y The y-coordinate of the pixel rectangle to store in obj. - * @param obj The primitive array to store the pixels into or null to force creation. + * @param x The x-coordinate of the pixel rectangle to store in + * obj. + * @param y The y-coordinate of the pixel rectangle to store in + * obj. + * @param obj The primitive array to store the pixels into or null to force + * creation. * @param data The DataBuffer that is the source of the pixel data. * @return The primitive array containing the pixel data. - * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer) + * @see java.awt.image.SampleModel#getDataElements(int, int, Object, + * DataBuffer) */ - public Object getDataElements(int x, int y, Object obj, - DataBuffer data) + public Object getDataElements(int x, int y, Object obj, DataBuffer data) { int pixel = getSample(x, y, 0, data); switch (getTransferType()) - { - case DataBuffer.TYPE_BYTE: - if (obj == null) obj = new byte[1]; - ((byte[])obj)[0] = (byte)pixel; - return obj; - case DataBuffer.TYPE_USHORT: - if (obj == null) obj = new short[1]; - ((short[])obj)[0] = (short)pixel; - return obj; - case DataBuffer.TYPE_INT: - if (obj == null) obj = new int[1]; - ((int[])obj)[0] = pixel; - return obj; - default: - // Seems like the only sensible thing to do. - throw new ClassCastException(); - } + { + case DataBuffer.TYPE_BYTE: + if (obj == null) + obj = new byte[1]; + ((byte[]) obj)[0] = (byte) pixel; + return obj; + case DataBuffer.TYPE_USHORT: + if (obj == null) + obj = new short[1]; + ((short[]) obj)[0] = (short) pixel; + return obj; + case DataBuffer.TYPE_INT: + if (obj == null) + obj = new int[1]; + ((int[]) obj)[0] = pixel; + return obj; + default: + // Seems like the only sensible thing to do. + throw new ClassCastException(); + } } /** @@ -381,54 +389,12 @@ public class MultiPixelPackedSampleModel extends SampleModel */ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data) { - if (iArray == null) iArray = new int[1]; + if (iArray == null) + iArray = new int[1]; iArray[0] = getSample(x, y, 0, data); - return iArray; } - /** - * Returns an array containing the samples for the pixels in the region - * specified by (x, y, w, h) in the specified data buffer. If - * iArray is not null, it will be populated with - * the sample values and returned as the result of this function (this - * avoids allocating a new array instance). - * - * @param x the x-coordinate of the top-left pixel. - * @param y the y-coordinate of the top-left pixel. - * @param w the width of the region of pixels. - * @param h the height of the region of pixels. - * @param iArray an array to populate with the sample values and return as - * the result (if null, a new array will be allocated). - * @param data the data buffer (null not permitted). - * - * @return The pixel sample values. - * - * @throws NullPointerException if data is null. - */ - public int[] getPixels(int x, int y, int w, int h, int[] iArray, - DataBuffer data) - { - int offset = getOffset(x, y); - if (iArray == null) iArray = new int[w*h]; - int outOffset = 0; - for (y=0; y>> bitOffsets[b]; - x++; - } - } - offset += scanlineStride; - } - return iArray; - } - /** * Returns the sample value for the pixel at (x, y) in the specified data * buffer. @@ -460,66 +426,49 @@ public class MultiPixelPackedSampleModel extends SampleModel * @param y The y-coordinate of the data elements in obj. * @param obj The primitive array containing the data elements to set. * @param data The DataBuffer to store the data elements into. - * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer) */ public void setDataElements(int x, int y, Object obj, DataBuffer data) { int transferType = getTransferType(); - if (getTransferType() != data.getDataType()) - { - throw new IllegalArgumentException("transfer type ("+ - getTransferType()+"), "+ - "does not match data "+ - "buffer type (" + - data.getDataType() + - ")."); - } - - int offset = getOffset(x, y); - try { - switch (transferType) - { - case DataBuffer.TYPE_BYTE: - { - DataBufferByte out = (DataBufferByte) data; - byte[] in = (byte[]) obj; - out.getData()[offset] = in[0]; - return; - } - case DataBuffer.TYPE_USHORT: - { - DataBufferUShort out = (DataBufferUShort) data; - short[] in = (short[]) obj; - out.getData()[offset] = in[0]; - return; - } - case DataBuffer.TYPE_INT: - { - DataBufferInt out = (DataBufferInt) data; - int[] in = (int[]) obj; - out.getData()[offset] = in[0]; - return; - } - default: - throw new ClassCastException("Unsupported data type"); - } + switch (transferType) + { + case DataBuffer.TYPE_BYTE: + { + byte[] in = (byte[]) obj; + setSample(x, y, 0, in[0] & 0xFF, data); + return; + } + case DataBuffer.TYPE_USHORT: + { + short[] in = (short[]) obj; + setSample(x, y, 0, in[0] & 0xFFFF, data); + return; + } + case DataBuffer.TYPE_INT: + { + int[] in = (int[]) obj; + setSample(x, y, 0, in[0], data); + return; + } + default: + throw new ClassCastException("Unsupported data type"); + } } catch (ArrayIndexOutOfBoundsException aioobe) { - String msg = "While writing data elements" + - ", x="+x+", y="+y+ - ", width="+width+", height="+height+ - ", scanlineStride="+scanlineStride+ - ", offset="+offset+ - ", data.getSize()="+data.getSize()+ - ", data.getOffset()="+data.getOffset()+ - ": " + - aioobe; - throw new ArrayIndexOutOfBoundsException(msg); + String msg = "While writing data elements" + + ", x=" + x + ", y=" + y + + ", width=" + width + ", height=" + height + + ", scanlineStride=" + scanlineStride + + ", offset=" + getOffset(x, y) + + ", data.getSize()=" + data.getSize() + + ", data.getOffset()=" + data.getOffset() + + ": " + aioobe; + throw new ArrayIndexOutOfBoundsException(msg); } - } + } /** * Sets the sample value for the pixel at (x, y) in the specified data diff --git a/java/awt/image/Raster.java b/java/awt/image/Raster.java index 4af958a17..160f8be8b 100644 --- a/java/awt/image/Raster.java +++ b/java/awt/image/Raster.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2002, 2003 Free Software Foundation +/* Copyright (C) 2000, 2002, 2003, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -41,39 +41,80 @@ import java.awt.Point; import java.awt.Rectangle; /** + * A rectangular collection of pixels composed from a {@link DataBuffer} which + * stores the pixel values, and a {@link SampleModel} which is used to retrieve + * the pixel values. + * * @author Rolf W. Rasmussen (rolfwr@ii.uib.no) */ public class Raster { + /** The sample model used to access the pixel values. */ protected SampleModel sampleModel; + + /** The data buffer used to store the pixel values. */ protected DataBuffer dataBuffer; + + /** The x-coordinate of the top left corner of the raster. */ protected int minX; + + /** The y-coordinate of the top left corner of the raster. */ protected int minY; + + /** The width of the raster. */ protected int width; + + /** The height of the raster. */ protected int height; + protected int sampleModelTranslateX; + protected int sampleModelTranslateY; + + /** The number of bands. */ protected int numBands; + protected int numDataElements; + + /** The raster's parent. */ protected Raster parent; + /** + * Creates a new raster. + * + * @param sampleModel the sample model. + * @param origin the origin. + */ protected Raster(SampleModel sampleModel, Point origin) { this(sampleModel, sampleModel.createDataBuffer(), origin); } + /** + * Creates a new raster. + * + * @param sampleModel the sample model. + * @param dataBuffer the data buffer. + * @param origin the origin. + */ protected Raster(SampleModel sampleModel, DataBuffer dataBuffer, - Point origin) + Point origin) { - this(sampleModel, dataBuffer, - new Rectangle(origin.x, origin.y, - sampleModel.getWidth(), sampleModel.getHeight()), - origin, null); + this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, + sampleModel.getWidth(), sampleModel.getHeight()), origin, null); } + /** + * Creates a new raster. + * + * @param sampleModel the sample model. + * @param dataBuffer the data buffer. + * @param aRegion the raster's bounds. + * @param sampleModelTranslate the translation (null permitted). + * @param parent the raster's parent. + */ protected Raster(SampleModel sampleModel, DataBuffer dataBuffer, - Rectangle aRegion, - Point sampleModelTranslate, Raster parent) + Rectangle aRegion, Point sampleModelTranslate, Raster parent) { this.sampleModel = sampleModel; this.dataBuffer = dataBuffer; @@ -95,70 +136,127 @@ public class Raster this.parent = parent; } + /** + * Creates an interleaved raster using the specified data type. + * + * @param dataType the data type. + * @param w the width. + * @param h the height. + * @param bands the number of bands. + * @param location + * + * @return The new raster. + */ public static WritableRaster createInterleavedRaster(int dataType, - int w, int h, - int bands, - Point location) + int w, int h, int bands, Point location) { int[] bandOffsets = new int[bands]; // TODO: Maybe not generate this every time. - for (int b=0; b getTypeBits(dataType))) throw new IllegalArgumentException(); @@ -166,135 +264,238 @@ public class Raster SampleModel sm; if (bands == 1) - sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand); + sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand); else { - int[] bandMasks = new int[bands]; - int mask = 0x1; - for (int bits = bitsPerBand; --bits != 0;) - mask = (mask << 1) | 0x1; - for (int i = 0; i < bands; i++) - { - bandMasks[i] = mask; - mask <<= bitsPerBand; - } - - sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks); + int[] bandMasks = new int[bands]; + int mask = 0x1; + for (int bits = bitsPerBand; --bits != 0;) + mask = (mask << 1) | 0x1; + for (int i = 0; i < bands; i++) + { + bandMasks[i] = mask; + mask <<= bitsPerBand; + } + + sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks); } return createWritableRaster(sm, location); } - public static WritableRaster - createInterleavedRaster(DataBuffer dataBuffer, int w, int h, - int scanlineStride, int pixelStride, - int[] bandOffsets, Point location) + /** + * Creates a new interleaved raster. + * + * @param dataBuffer the data buffer. + * @param w the width. + * @param h the height. + * @param scanlineStride the number of data elements from a sample on one + * row to the corresponding sample on the next row. + * @param pixelStride the number of elements from a sample in one pixel to + * the corresponding sample in the next pixel. + * @param bandOffsets the offset for each band. + * @param location + * + * @return The new raster. + */ + public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, + int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets, + Point location) { SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(), - w, h, - scanlineStride, - pixelStride, - bandOffsets); + w, h, scanlineStride, pixelStride, bandOffsets); return createWritableRaster(sm, dataBuffer, location); } - public static - WritableRaster createBandedRaster(DataBuffer dataBuffer, - int w, int h, - int scanlineStride, - int[] bankIndices, - int[] bandOffsets, - Point location) + /** + * Creates a new banded raster. + * + * @param dataBuffer the data buffer. + * @param w the width. + * @param h the height. + * @param scanlineStride the number of data elements from a sample on one + * row to the corresponding sample on the next row. + * @param bankIndices the index for each bank. + * @param bandOffsets the band offsets. + * @param location + * + * @return The new raster. + */ + public static WritableRaster createBandedRaster(DataBuffer dataBuffer, + int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets, + Point location) { SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(), - w, h, scanlineStride, - bankIndices, bandOffsets); + w, h, scanlineStride, bankIndices, bandOffsets); return createWritableRaster(sm, dataBuffer, location); } - public static WritableRaster - createPackedRaster(DataBuffer dataBuffer, - int w, int h, - int scanlineStride, - int[] bandMasks, - Point location) + /** + * Creates a new packed raster. + * + * @param dataBuffer the data buffer. + * @param w the width. + * @param h the height. + * @param scanlineStride the number of data elements from a sample on one + * row to the corresponding sample on the next row. + * @param bandMasks the bit mask for each band. + * @param location + * + * @return The new raster. + */ + public static WritableRaster createPackedRaster(DataBuffer dataBuffer, + int w, int h, int scanlineStride, int[] bandMasks, Point location) { - SampleModel sm = - new SinglePixelPackedSampleModel(dataBuffer.getDataType(), - w, h, - scanlineStride, - bandMasks); + SampleModel sm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(), + w, h, scanlineStride, bandMasks); return createWritableRaster(sm, dataBuffer, location); } - public static WritableRaster - createPackedRaster(DataBuffer dataBuffer, - int w, int h, - int bitsPerPixel, - Point location) - { - SampleModel sm = - new MultiPixelPackedSampleModel(dataBuffer.getDataType(), - w, h, - bitsPerPixel); + /** + * Creates a new packed raster. + * + * @param dataBuffer the data buffer. + * @param w the width. + * @param h the height. + * @param bitsPerPixel the number of bits per pixel. + * @param location + * + * @return The new raster. + */ + public static WritableRaster createPackedRaster(DataBuffer dataBuffer, + int w, int h, int bitsPerPixel, Point location) + { + SampleModel sm = new MultiPixelPackedSampleModel(dataBuffer.getDataType(), + w, h, bitsPerPixel); return createWritableRaster(sm, dataBuffer, location); } + /** + * Creates a new raster. + * + * @param sm the sample model. + * @param db the data buffer. + * @param location + * + * @return The new raster. + */ public static Raster createRaster(SampleModel sm, DataBuffer db, - Point location) + Point location) { return new Raster(sm, db, location); } + /** + * Creates a new writable raster. + * + * @param sm the sample model. + * @param location + * + * @return The new writable raster. + */ public static WritableRaster createWritableRaster(SampleModel sm, - Point location) + Point location) { return new WritableRaster(sm, location); } + /** + * Creates a new writable raster. + * + * @param sm the sample model. + * @param db the data buffer. + * @param location + * + * @return The new writable raster. + */ public static WritableRaster createWritableRaster(SampleModel sm, - DataBuffer db, - Point location) + DataBuffer db, Point location) { return new WritableRaster(sm, db, location); } + /** + * Returns the raster's parent. + * + * @return The raster's parent. + */ public Raster getParent() { return parent; } + /** + * Returns the x-translation. + * + * @return The x-translation. + */ public final int getSampleModelTranslateX() { return sampleModelTranslateX; } + /** + * Returns the y-translation. + * + * @return The y-translation. + */ public final int getSampleModelTranslateY() { return sampleModelTranslateY; } + /** + * Creates a new writable raster that is compatible with this raster. + * + * @return A new writable raster. + */ public WritableRaster createCompatibleWritableRaster() { return new WritableRaster(getSampleModel(), new Point(minX, minY)); } + /** + * Creates a new writable raster that is compatible with this raster. + * + * @param w the width. + * @param h the height. + * + * @return A new writable raster. + */ public WritableRaster createCompatibleWritableRaster(int w, int h) { return createCompatibleWritableRaster(minX, minY, w, h); } + /** + * Creates a new writable raster that is compatible with this raster, with + * the specified bounds. + * + * @param rect the raster bounds. + * + * @return A new writable raster. + */ public WritableRaster createCompatibleWritableRaster(Rectangle rect) { return createCompatibleWritableRaster(rect.x, rect.y, - rect.width, rect.height); + rect.width, rect.height); } + /** + * Creates a new writable raster that is compatible with this raster, with + * the specified bounds. + * + * @param x the x-coordinate of the top-left corner of the raster. + * @param y the y-coordinate of the top-left corner of the raster. + * @param w the raster width. + * @param h the raster height. + * + * @return A new writable raster. + */ public WritableRaster createCompatibleWritableRaster(int x, int y, - int w, int h) + int w, int h) { SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h); - return new WritableRaster(sm, sm.createDataBuffer(), - new Point(x, y)); + return new WritableRaster(sm, sm.createDataBuffer(), new Point(x, y)); } public Raster createTranslatedChild(int childMinX, int childMinY) { @@ -302,15 +503,13 @@ public class Raster int tcy = sampleModelTranslateY - minY + childMinY; return new Raster(sampleModel, dataBuffer, - new Rectangle(childMinX, childMinY, - width, height), - new Point(tcx, tcy), - this); + new Rectangle(childMinX, childMinY, width, height), + new Point(tcx, tcy), this); } public Raster createChild(int parentX, int parentY, int width, - int height, int childMinX, int childMinY, - int[] bandList) + int height, int childMinX, int childMinY, + int[] bandList) { /* FIXME: Throw RasterFormatException if child bounds extends beyond the bounds of this raster. */ @@ -343,38 +542,67 @@ public class Raster */ return new Raster(sm, dataBuffer, - new Rectangle(childMinX, childMinY, - width, height), - new Point(sampleModelTranslateX+childMinX-parentX, - sampleModelTranslateY+childMinY-parentY), - this); + new Rectangle(childMinX, childMinY, width, height), + new Point(sampleModelTranslateX + childMinX - parentX, + sampleModelTranslateY + childMinY - parentY), + this); } + /** + * Returns a new rectangle containing the bounds of this raster. + * + * @return A new rectangle containing the bounds of this raster. + */ public Rectangle getBounds() { return new Rectangle(minX, minY, width, height); } + /** + * Returns the x-coordinate of the top left corner of the raster. + * + * @return The x-coordinate of the top left corner of the raster. + */ public final int getMinX() { return minX; } + /** + * Returns the t-coordinate of the top left corner of the raster. + * + * @return The t-coordinate of the top left corner of the raster. + */ public final int getMinY() { return minY; } + /** + * Returns the width of the raster. + * + * @return The width of the raster. + */ public final int getWidth() { return width; } + /** + * Returns the height of the raster. + * + * @return The height of the raster. + */ public final int getHeight() { return height; } + /** + * Returns the number of bands for this raster. + * + * @return The number of bands. + */ public final int getNumBands() { return numBands; @@ -384,17 +612,34 @@ public class Raster { return numDataElements; } - + + /** + * Returns the transfer type for the raster (this is determined by the + * raster's sample model). + * + * @return The transfer type. + */ public final int getTransferType() { return sampleModel.getTransferType(); } + /** + * Returns the data buffer that stores the pixel data for this raster. + * + * @return The data buffer. + */ public DataBuffer getDataBuffer() { return dataBuffer; } + /** + * Returns the sample model that accesses the data buffer (to extract pixel + * data) for this raster. + * + * @return The sample model. + */ public SampleModel getSampleModel() { return sampleModel; @@ -402,112 +647,275 @@ public class Raster public Object getDataElements(int x, int y, Object outData) { - return sampleModel.getDataElements(x-sampleModelTranslateX, - y-sampleModelTranslateY, - outData, dataBuffer); + return sampleModel.getDataElements(x - sampleModelTranslateX, + y - sampleModelTranslateY, outData, dataBuffer); } - public Object getDataElements(int x, int y, int w, int h, - Object outData) + public Object getDataElements(int x, int y, int w, int h, Object outData) { - return sampleModel.getDataElements(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, outData, dataBuffer); + return sampleModel.getDataElements(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, outData, dataBuffer); } + /** + * Returns an array containing the samples for the pixel at (x, y) in the + * raster. If iArray is not null, it will be + * populated with the sample values and returned as the result of + * this function (this avoids allocating a new array instance). + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param iArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The pixel sample values. + */ public int[] getPixel(int x, int y, int[] iArray) { - return sampleModel.getPixel(x-sampleModelTranslateX, - y-sampleModelTranslateY, - iArray, dataBuffer); + return sampleModel.getPixel(x - sampleModelTranslateX, + y - sampleModelTranslateY, iArray, dataBuffer); } + /** + * Returns an array containing the samples for the pixel at (x, y) in the + * raster. If fArray is not null, it will be + * populated with the sample values and returned as the result of + * this function (this avoids allocating a new array instance). + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param fArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The pixel sample values. + */ public float[] getPixel(int x, int y, float[] fArray) { - return sampleModel.getPixel(x-sampleModelTranslateX, - y-sampleModelTranslateY, - fArray, dataBuffer); + return sampleModel.getPixel(x - sampleModelTranslateX, + y - sampleModelTranslateY, fArray, dataBuffer); } + /** + * Returns an array containing the samples for the pixel at (x, y) in the + * raster. If dArray is not null, it will be + * populated with the sample values and returned as the result of + * this function (this avoids allocating a new array instance). + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param dArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The pixel sample values. + */ public double[] getPixel(int x, int y, double[] dArray) { - return sampleModel.getPixel(x-sampleModelTranslateX, - y-sampleModelTranslateY, - dArray, dataBuffer); + return sampleModel.getPixel(x - sampleModelTranslateX, + y - sampleModelTranslateY, dArray, dataBuffer); } + /** + * Returns an array containing the samples for the pixels in the region + * specified by (x, y, w, h) in the raster. The array is ordered by pixels + * (that is, all the samples for the first pixel are grouped together, + * followed by all the samples for the second pixel, and so on). + * If iArray is not null, it will be populated + * with the sample values and returned as the result of this function (this + * avoids allocating a new array instance). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param iArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The pixel sample values. + */ public int[] getPixels(int x, int y, int w, int h, int[] iArray) { - return sampleModel.getPixels(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, iArray, dataBuffer); + return sampleModel.getPixels(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, iArray, dataBuffer); } - public float[] getPixels(int x, int y, int w, int h, - float[] fArray) + /** + * Returns an array containing the samples for the pixels in the region + * specified by (x, y, w, h) in the raster. The array is ordered by pixels + * (that is, all the samples for the first pixel are grouped together, + * followed by all the samples for the second pixel, and so on). + * If fArray is not null, it will be populated + * with the sample values and returned as the result of this function (this + * avoids allocating a new array instance). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param fArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The pixel sample values. + */ + public float[] getPixels(int x, int y, int w, int h, float[] fArray) { - return sampleModel.getPixels(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, fArray, dataBuffer); + return sampleModel.getPixels(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, fArray, dataBuffer); } - public double[] getPixels(int x, int y, int w, int h, - double[] dArray) + /** + * Returns an array containing the samples for the pixels in the region + * specified by (x, y, w, h) in the raster. The array is ordered by pixels + * (that is, all the samples for the first pixel are grouped together, + * followed by all the samples for the second pixel, and so on). + * If dArray is not null, it will be populated + * with the sample values and returned as the result of this function (this + * avoids allocating a new array instance). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param dArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The pixel sample values. + */ + public double[] getPixels(int x, int y, int w, int h, double[] dArray) { - return sampleModel.getPixels(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, dArray, dataBuffer); + return sampleModel.getPixels(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, dArray, dataBuffer); } + /** + * Returns the sample value for the pixel at (x, y) in the raster. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * + * @return The sample value. + */ public int getSample(int x, int y, int b) { - return sampleModel.getSample(x-sampleModelTranslateX, - y-sampleModelTranslateY, - b, dataBuffer); + return sampleModel.getSample(x - sampleModelTranslateX, + y - sampleModelTranslateY, b, dataBuffer); } + /** + * Returns the sample value for the pixel at (x, y) in the raster. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * + * @return The sample value. + * + * @see #getSample(int, int, int) + */ public float getSampleFloat(int x, int y, int b) { - return sampleModel.getSampleFloat(x-sampleModelTranslateX, - y-sampleModelTranslateY, - b, dataBuffer); + return sampleModel.getSampleFloat(x - sampleModelTranslateX, + y - sampleModelTranslateY, b, dataBuffer); } + /** + * Returns the sample value for the pixel at (x, y) in the raster. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * + * @return The sample value. + * + * @see #getSample(int, int, int) + */ public double getSampleDouble(int x, int y, int b) { - return sampleModel.getSampleDouble(x-sampleModelTranslateX, - y-sampleModelTranslateY, - b, dataBuffer); + return sampleModel.getSampleDouble(x - sampleModelTranslateX, + y - sampleModelTranslateY, b, dataBuffer); } + /** + * Returns an array containing the samples from one band for the pixels in + * the region specified by (x, y, w, h) in the raster. If + * iArray is not null, it will be + * populated with the sample values and returned as the result of this + * function (this avoids allocating a new array instance). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param iArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The sample values. + */ public int[] getSamples(int x, int y, int w, int h, int b, - int[] iArray) + int[] iArray) { - return sampleModel.getSamples(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, b, iArray, dataBuffer); + return sampleModel.getSamples(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, b, iArray, dataBuffer); } - public float[] getSamples(int x, int y, int w, int h, int b, - float[] fArray) - { - return sampleModel.getSamples(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, b, fArray, dataBuffer); + /** + * Returns an array containing the samples from one band for the pixels in + * the region specified by (x, y, w, h) in the raster. If + * fArray is not null, it will be + * populated with the sample values and returned as the result of this + * function (this avoids allocating a new array instance). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param fArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The sample values. + */ + public float[] getSamples(int x, int y, int w, int h, int b, float[] fArray) + { + return sampleModel.getSamples(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, b, fArray, dataBuffer); } - public double[] getSamples(int x, int y, int w, int h, int b, - double[] dArray) + /** + * Returns an array containing the samples from one band for the pixels in + * the region specified by (x, y, w, h) in the raster. If + * dArray is not null, it will be + * populated with the sample values and returned as the result of this + * function (this avoids allocating a new array instance). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param dArray an array to populate with the sample values and return as + * the result (if null, a new array will be allocated). + * + * @return The sample values. + */ + public double[] getSamples(int x, int y, int w, int h, int b, + double[] dArray) { - return sampleModel.getSamples(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, b, dArray, dataBuffer); + return sampleModel.getSamples(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, b, dArray, dataBuffer); } /** - * Create a String representing the stat of this Raster. + * Create a String representing the state of this Raster. + * * @return A String representing the stat of this Raster. - * @see java.lang.Object#toString() */ public String toString() { @@ -524,23 +932,39 @@ public class Raster return result.toString(); } - // Map from datatype to bits + /** + * Returns the number of bits used to represent the specified data type. + * Valid types are: + *

+ * This method returns 0 for invalid data types. + * + * @param dataType the data type. + * + * @return The number of bits used to represent the specified data type. + */ private static int getTypeBits(int dataType) { switch (dataType) { case DataBuffer.TYPE_BYTE: - return 8; + return 8; case DataBuffer.TYPE_USHORT: case DataBuffer.TYPE_SHORT: - return 16; + return 16; case DataBuffer.TYPE_INT: case DataBuffer.TYPE_FLOAT: - return 32; + return 32; case DataBuffer.TYPE_DOUBLE: - return 64; + return 64; default: - return 0; + return 0; } } } diff --git a/java/awt/image/RasterOp.java b/java/awt/image/RasterOp.java index e081ca3d2..656370e8b 100644 --- a/java/awt/image/RasterOp.java +++ b/java/awt/image/RasterOp.java @@ -1,5 +1,5 @@ /* RasterOp.java -- - Copyright (C) 2000, 2002, 2004, 2005 Free Software Foundation + Copyright (C) 2000, 2002, 2004, 2005, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -42,16 +42,64 @@ import java.awt.RenderingHints; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +/** + * An operation that is performed on one raster (the source) producing a new + * raster (the destination). + */ public interface RasterOp { + /** + * Performs an operation on the source raster, returning the result in a + * writable raster. If dest is null, a new + * WritableRaster will be created by calling the + * {@link #createCompatibleDestRaster(Raster)} method. If dest + * is not null, the result is written to dest then + * returned (this avoids creating a new WritableRaster each + * time this method is called). + * + * @param src the source raster. + * @param dest the destination raster (null permitted). + * + * @return The filtered raster. + */ WritableRaster filter(Raster src, WritableRaster dest); + /** + * Returns the bounds of the destination raster on the basis of this + * RasterOp being applied to the specified source raster. + * + * @param src the source raster. + * + * @return The destination bounds. + */ Rectangle2D getBounds2D(Raster src); + /** + * Returns a raster that can be used by this RasterOp as the + * destination raster when operating on the specified source raster. + * + * @param src the source raster. + * + * @return A new writable raster that can be used as the destination raster. + */ WritableRaster createCompatibleDestRaster(Raster src); + /** + * Returns the point on the destination raster that corresponds to the given + * point on the source raster. + * + * @param srcPoint the source point. + * @param destPoint the destination point (null permitted). + * + * @return The destination point. + */ Point2D getPoint2D(Point2D srcPoint, Point2D destPoint); + /** + * Returns the rendering hints for this operation. + * + * @return The rendering hints. + */ RenderingHints getRenderingHints(); } diff --git a/java/awt/image/ShortLookupTable.java b/java/awt/image/ShortLookupTable.java index 5915a7939..858818cf2 100644 --- a/java/awt/image/ShortLookupTable.java +++ b/java/awt/image/ShortLookupTable.java @@ -1,5 +1,5 @@ /* ShortLookupTable.java -- Java class for a pixel translation table. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -67,7 +67,13 @@ public class ShortLookupTable extends LookupTable throws IllegalArgumentException { super(offset, data.length); - this.data = data; + + // tests show that Sun's implementation creates a new array to store the + // references from the incoming 'data' array - not sure why, but we'll + // match that behaviour just in case it matters... + this.data = new short[data.length][]; + for (int i = 0; i < data.length; i++) + this.data[i] = data[i]; } /** @@ -77,17 +83,25 @@ public class ShortLookupTable extends LookupTable * table. The same table is applied to all pixel components. * * @param offset Offset to be subtracted. - * @param data Lookup table for all components. + * @param data Lookup table for all components (null not + * permitted). * @exception IllegalArgumentException if offset < 0. */ public ShortLookupTable(int offset, short[] data) throws IllegalArgumentException { super(offset, 1); + if (data == null) + throw new NullPointerException("Null 'data' argument."); this.data = new short[][] {data}; } - /** Return the lookup tables. */ + /** + * Return the lookup tables. This is a reference to the actual table, so + * modifying the contents of the returned array will modify the lookup table. + * + * @return The lookup table. + */ public final short[][] getTable() { return data; @@ -117,11 +131,11 @@ public class ShortLookupTable extends LookupTable dst = new int[src.length]; if (data.length == 1) - for (int i=0; i < src.length; i++) - dst[i] = data[0][src[i] - offset]; + for (int i = 0; i < src.length; i++) + dst[i] = data[0][src[i] - offset]; else - for (int i=0; i < src.length; i++) - dst[i] = data[i][src[i] - offset]; + for (int i = 0; i < src.length; i++) + dst[i] = data[i][src[i] - offset]; return dst; } @@ -142,6 +156,7 @@ public class ShortLookupTable extends LookupTable * @param src Component values of a pixel. * @param dst Destination array for values, or null. * @return Translated values for the pixel. + * */ public short[] lookupPixel(short[] src, short[] dst) throws ArrayIndexOutOfBoundsException @@ -150,11 +165,11 @@ public class ShortLookupTable extends LookupTable dst = new short[src.length]; if (data.length == 1) - for (int i=0; i < src.length; i++) - dst[i] = data[0][((int)src[i]) - offset]; + for (int i = 0; i < src.length; i++) + dst[i] = data[0][((int) src[i]) - offset]; else - for (int i=0; i < src.length; i++) - dst[i] = data[i][((int)src[i]) - offset]; + for (int i = 0; i < src.length; i++) + dst[i] = data[i][((int) src[i]) - offset]; return dst; diff --git a/java/awt/image/SinglePixelPackedSampleModel.java b/java/awt/image/SinglePixelPackedSampleModel.java index 548865a40..a37fc0bba 100644 --- a/java/awt/image/SinglePixelPackedSampleModel.java +++ b/java/awt/image/SinglePixelPackedSampleModel.java @@ -171,7 +171,7 @@ public class SinglePixelPackedSampleModel extends SampleModel */ public int[] getSampleSize() { - return sampleSize; + return (int[]) sampleSize.clone(); } /** @@ -187,6 +187,14 @@ public class SinglePixelPackedSampleModel extends SampleModel return sampleSize[band]; } + /** + * Returns the index in the data buffer that stores the pixel at (x, y). + * + * @param x the x-coordinate. + * @param y the y-coordinate. + * + * @return The index in the data buffer that stores the pixel at (x, y). + */ public int getOffset(int x, int y) { return scanlineStride*y + x; @@ -202,14 +210,34 @@ public class SinglePixelPackedSampleModel extends SampleModel return bitMasks; } + /** + * Returns the number of data elements from a pixel in one row to the + * corresponding pixel in the next row. + * + * @return The scanline stride. + */ public int getScanlineStride() { return scanlineStride; } + /** + * Creates a new SinglePixelPackedSampleModel that accesses + * the specified subset of bands. + * + * @param bands an array containing band indices (null not + * permitted). + * + * @return A new sample model. + * + * @throws NullPointerException if bands is null. + * @throws RasterFormatException if bands.length is greater + * than the number of bands in this model. + */ public SampleModel createSubsetSampleModel(int[] bands) { - // FIXME: Is this the right way to interpret bands? + if (bands.length > numBands) + throw new RasterFormatException("Too many bands."); int numBands = bands.length; @@ -618,6 +646,27 @@ public class SinglePixelPackedSampleModel extends SampleModel return true; } + /** + * Returns a hash code for this SinglePixelPackedSampleModel. + * + * @return A hash code. + */ + public int hashCode() + { + // this hash code won't match Sun's, but that shouldn't matter... + int result = 193; + result = 37 * result + dataType; + result = 37 * result + width; + result = 37 * result + height; + result = 37 * result + numBands; + result = 37 * result + scanlineStride; + for (int i = 0; i < bitMasks.length; i++) + result = 37 * result + bitMasks[i]; + for (int i = 0; i < bitOffsets.length; i++) + result = 37 * result + bitOffsets[i]; + return result; + } + /** * Creates a String with some information about this SampleModel. * @return A String describing this SampleModel. diff --git a/java/awt/image/WritableRaster.java b/java/awt/image/WritableRaster.java index 2e5462fd9..473c6fe41 100644 --- a/java/awt/image/WritableRaster.java +++ b/java/awt/image/WritableRaster.java @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2002, 2003 Free Software Foundation +/* Copyright (C) 2000, 2002, 2003, 2006, Free Software Foundation This file is part of GNU Classpath. @@ -41,61 +41,98 @@ import java.awt.Point; import java.awt.Rectangle; /** + * A raster with methods to support updating pixel values. + * * @author Rolf W. Rasmussen (rolfwr@ii.uib.no) */ public class WritableRaster extends Raster { + /** + * Creates a new WritableRaster. + * + * @param sampleModel the sample model. + * @param origin the origin. + */ protected WritableRaster(SampleModel sampleModel, Point origin) { this(sampleModel, sampleModel.createDataBuffer(), origin); } - protected WritableRaster(SampleModel sampleModel, - DataBuffer dataBuffer, Point origin) + /** + * Creates a new WritableRaster instance. + * + * @param sampleModel the sample model. + * @param dataBuffer the data buffer. + * @param origin the origin. + */ + protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, + Point origin) { this(sampleModel, dataBuffer, - new Rectangle(origin != null ? origin.x : 0, + new Rectangle(origin != null ? origin.x : 0, origin != null ? origin.y : 0, - sampleModel.getWidth(), sampleModel.getHeight()), - origin, - null); + sampleModel.getWidth(), sampleModel.getHeight()), + origin, null); } + /** + * Creates a new WritableRaster instance. + * + * @param sampleModel the sample model. + * @param dataBuffer the data buffer. + * @param aRegion the raster's bounds. + * @param sampleModelTranslate the translation. + * @param parent the parent. + */ protected WritableRaster(SampleModel sampleModel, - DataBuffer dataBuffer, - Rectangle aRegion, - Point sampleModelTranslate, - WritableRaster parent) + DataBuffer dataBuffer, + Rectangle aRegion, + Point sampleModelTranslate, + WritableRaster parent) { - super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, - parent); + super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent); } + /** + * Returns the raster's parent, cast as a {@link WritableRaster}. + * + * @return The raster's parent. + */ public WritableRaster getWritableParent() { return (WritableRaster) getParent(); } + /** + * @param childMinX + * @param childMinY + * @return + */ public WritableRaster createWritableTranslatedChild(int childMinX, - int childMinY) + int childMinY) { // This mirrors the code from the super class int tcx = sampleModelTranslateX - minX + childMinX; int tcy = sampleModelTranslateY - minY + childMinY; return new WritableRaster(sampleModel, dataBuffer, - new Rectangle(childMinX, childMinY, - width, height), - new Point(tcx, tcy), - this); + new Rectangle(childMinX, childMinY, width, height), + new Point(tcx, tcy), this); } - public WritableRaster createWritableChild(int parentX, - int parentY, - int w, int h, - int childMinX, - int childMinY, - int[] bandList) + /** + * + * @param parentX + * @param parentY + * @param w + * @param h + * @param childMinX + * @param childMinY + * @param bandList + * @return + */ + public WritableRaster createWritableChild(int parentX, int parentY, + int w, int h, int childMinX, int childMinY, int[] bandList) { // This mirrors the code from the super class @@ -106,51 +143,52 @@ public class WritableRaster extends Raster sampleModel : sampleModel.createSubsetSampleModel(bandList); - return new - WritableRaster(sm, dataBuffer, - new Rectangle(childMinX, childMinY, - w, h), - new Point(sampleModelTranslateX+childMinX-parentX, - sampleModelTranslateY+childMinY-parentY), - this); + return new WritableRaster(sm, dataBuffer, + new Rectangle(childMinX, childMinY, w, h), + new Point(sampleModelTranslateX + childMinX - parentX, + sampleModelTranslateY + childMinY - parentY), + this); } public void setDataElements(int x, int y, Object inData) { - sampleModel.setDataElements(x-sampleModelTranslateX, - y-sampleModelTranslateY, - inData, dataBuffer); + sampleModel.setDataElements(x - sampleModelTranslateX, + y - sampleModelTranslateY, inData, dataBuffer); } public void setDataElements(int x, int y, Raster inRaster) { - Object dataElements = getDataElements(0, 0, - inRaster.getWidth(), - inRaster.getHeight(), - null); + Object dataElements = getDataElements(0, 0, inRaster.getWidth(), + inRaster.getHeight(), null); setDataElements(x, y, dataElements); } - public void setDataElements(int x, int y, int w, int h, - Object inData) + public void setDataElements(int x, int y, int w, int h, Object inData) { - sampleModel.setDataElements(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, inData, dataBuffer); + sampleModel.setDataElements(x - sampleModelTranslateX, + y - sampleModelTranslateY, w, h, inData, dataBuffer); } + /** + * + * @param srcRaster + */ public void setRect(Raster srcRaster) { setRect(0, 0, srcRaster); } + /** + * + * @param dx + * @param dy + * @param srcRaster + */ public void setRect(int dx, int dy, Raster srcRaster) { - Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX()+dx, - srcRaster.getMinY()+dy, - srcRaster.getWidth(), - srcRaster.getHeight()); - + Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX() + dx, + srcRaster.getMinY() + dy, srcRaster.getWidth(), srcRaster.getHeight()); + Rectangle target = getBounds().intersection(targetUnclipped); if (target.isEmpty()) return; @@ -169,97 +207,225 @@ public class WritableRaster extends Raster But this is probably not the place to consider such optimizations.*/ - int[] pixels = srcRaster.getPixels(sx, sy, - target.width, target.height, - (int[]) null); + int[] pixels = srcRaster.getPixels(sx, sy, target.width, target.height, + (int[]) null); setPixels(target.x, target.y, target.width, target.height, pixels); } + /** + * Sets the samples for the pixel at (x, y) in the raster to the specified + * values. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param iArray the sample values (null not permitted). + * + * @throws NullPointerException if iArray is null. + */ public void setPixel(int x, int y, int[] iArray) { - sampleModel.setPixel(x-sampleModelTranslateX, - y-sampleModelTranslateY, - iArray, dataBuffer); + sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, + iArray, dataBuffer); } + /** + * Sets the samples for the pixel at (x, y) in the raster to the specified + * values. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param fArray the sample values (null not permitted). + * + * @throws NullPointerException if fArray is null. + */ public void setPixel(int x, int y, float[] fArray) { - sampleModel.setPixel(x-sampleModelTranslateX, - y-sampleModelTranslateY, - fArray, dataBuffer); + sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, + fArray, dataBuffer); } + /** + * Sets the samples for the pixel at (x, y) in the raster to the specified + * values. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param dArray the sample values (null not permitted). + * + * @throws NullPointerException if dArray is null. + */ public void setPixel(int x, int y, double[] dArray) { - sampleModel.setPixel(x-sampleModelTranslateX, - y-sampleModelTranslateY, - dArray, dataBuffer); + sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, + dArray, dataBuffer); } + /** + * Sets the sample values for the pixels in the region specified by + * (x, y, w, h) in the raster. The array is ordered by pixels (that is, all + * the samples for the first pixel are grouped together, followed by all the + * samples for the second pixel, and so on). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param iArray the pixel sample values (null not permitted). + * + * @throws NullPointerException if iArray is null. + */ public void setPixels(int x, int y, int w, int h, int[] iArray) { - sampleModel.setPixels(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, iArray, dataBuffer); + sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, + w, h, iArray, dataBuffer); } + /** + * Sets the sample values for the pixels in the region specified by + * (x, y, w, h) in the raster. The array is ordered by pixels (that is, all + * the samples for the first pixel are grouped together, followed by all the + * samples for the second pixel, and so on). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param fArray the pixel sample values (null not permitted). + * + * @throws NullPointerException if fArray is null. + */ public void setPixels(int x, int y, int w, int h, float[] fArray) { - sampleModel.setPixels(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, fArray, dataBuffer); + sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, + w, h, fArray, dataBuffer); } + /** + * Sets the sample values for the pixels in the region specified by + * (x, y, w, h) in the raster. The array is ordered by pixels (that is, all + * the samples for the first pixel are grouped together, followed by all the + * samples for the second pixel, and so on). + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param dArray the pixel sample values (null not permitted). + * + * @throws NullPointerException if dArray is null. + */ public void setPixels(int x, int y, int w, int h, double[] dArray) { - sampleModel.setPixels(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, dArray, dataBuffer); + sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, + w, h, dArray, dataBuffer); } + /** + * Sets the sample value for a band for the pixel at (x, y) in the raster. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param s the sample value. + */ public void setSample(int x, int y, int b, int s) { - sampleModel.setSample(x-sampleModelTranslateX, - y-sampleModelTranslateY, - b, s, dataBuffer); + sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, + b, s, dataBuffer); } + /** + * Sets the sample value for a band for the pixel at (x, y) in the raster. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param s the sample value. + */ public void setSample(int x, int y, int b, float s) { - sampleModel.setSample(x-sampleModelTranslateX, - y-sampleModelTranslateY, - b, s, dataBuffer); + sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, + b, s, dataBuffer); } + /** + * Sets the sample value for a band for the pixel at (x, y) in the raster. + * + * @param x the x-coordinate of the pixel. + * @param y the y-coordinate of the pixel. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param s the sample value. + */ public void setSample(int x, int y, int b, double s) { - sampleModel.setSample(x-sampleModelTranslateX, - y-sampleModelTranslateY, - b, s, dataBuffer); + sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, + b, s, dataBuffer); } + /** + * Sets the sample values for one band for the pixels in the region + * specified by (x, y, w, h) in the raster. + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param iArray the sample values (null not permitted). + * + * @throws NullPointerException if iArray is null. + */ public void setSamples(int x, int y, int w, int h, int b, - int[] iArray) + int[] iArray) { - sampleModel.setSamples(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, b, iArray, dataBuffer); + sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, + w, h, b, iArray, dataBuffer); } + /** + * Sets the sample values for one band for the pixels in the region + * specified by (x, y, w, h) in the raster. + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param fArray the sample values (null not permitted). + * + * @throws NullPointerException if fArray is null. + */ public void setSamples(int x, int y, int w, int h, int b, - float[] fArray) + float[] fArray) { - sampleModel.setSamples(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, b, fArray, dataBuffer); + sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, + w, h, b, fArray, dataBuffer); } + /** + * Sets the sample values for one band for the pixels in the region + * specified by (x, y, w, h) in the raster. + * + * @param x the x-coordinate of the top-left pixel. + * @param y the y-coordinate of the top-left pixel. + * @param w the width of the region of pixels. + * @param h the height of the region of pixels. + * @param b the band (in the range 0 to + * getNumBands() - 1). + * @param dArray the sample values (null not permitted). + * + * @throws NullPointerException if dArray is null. + */ public void setSamples(int x, int y, int w, int h, int b, - double[] dArray) + double[] dArray) { - sampleModel.setSamples(x-sampleModelTranslateX, - y-sampleModelTranslateY, - w, h, b, dArray, dataBuffer); + sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, + w, h, b, dArray, dataBuffer); } } diff --git a/java/lang/Iterable.java b/java/lang/Iterable.java index 38f478ba7..ea593e88e 100644 --- a/java/lang/Iterable.java +++ b/java/lang/Iterable.java @@ -38,7 +38,8 @@ exception statement from your version. */ package java.lang; -import java.util.Iterator; +// We only need Iterator, but we import * to support lib/mkcollections.pl +import java.util.*; /** * This interface is used to indicate that a given class can be diff --git a/java/lang/StrictMath.java b/java/lang/StrictMath.java index 548a6f1c1..7fd37df8b 100644 --- a/java/lang/StrictMath.java +++ b/java/lang/StrictMath.java @@ -1,5 +1,5 @@ /* java.lang.StrictMath -- common mathematical functions, strict Java - Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -632,6 +632,131 @@ public final strictfp class StrictMath return y > 0 ? PI - (z - PI_L) : z - PI_L - PI; } + /** + * Returns the lower two words of a long. This is intended to be + * used like this: + * getLowDWord(Double.doubleToLongBits(x)). + */ + private static int getLowDWord(long x) + { + return (int) (x & 0x00000000ffffffffL); + } + + /** + * Returns the higher two words of a long. This is intended to be + * used like this: + * getHighDWord(Double.doubleToLongBits(x)). + */ + private static int getHighDWord(long x) + { + return (int) ((x & 0xffffffff00000000L) >> 32); + } + + /** + * Returns a double with the IEEE754 bit pattern given in the lower + * and higher two words lowDWord and highDWord. + */ + private static double buildDouble(int lowDWord, int highDWord) + { + return Double.longBitsToDouble((((long) highDWord & 0xffffffffL) << 32) + | ((long) lowDWord & 0xffffffffL)); + } + + /** + * Returns the cube root of x. The sign of the cube root + * is equal to the sign of x. + * + * Special cases: + * + * + * @param x the number to take the cube root of + * @return the cube root of x + * @see #sqrt(double) + * + * @since 1.5 + */ + public static double cbrt(double x) + { + boolean negative = (x < 0); + double r; + double s; + double t; + double w; + + long bits; + int l; + int h; + + // handle the special cases + if (x != x) + return Double.NaN; + if (x == Double.POSITIVE_INFINITY) + return Double.POSITIVE_INFINITY; + if (x == Double.NEGATIVE_INFINITY) + return Double.NEGATIVE_INFINITY; + if (x == 0) + return x; + + x = abs(x); + bits = Double.doubleToLongBits(x); + + if (bits < 0x0010000000000000L) // subnormal number + { + t = TWO_54; + t *= x; + + // __HI(t)=__HI(t)/3+B2; + bits = Double.doubleToLongBits(t); + h = getHighDWord(bits); + l = getLowDWord(bits); + + h = h / 3 + CBRT_B2; + + t = buildDouble(l, h); + } + else + { + // __HI(t)=__HI(x)/3+B1; + h = getHighDWord(bits); + l = 0; + + h = h / 3 + CBRT_B1; + t = buildDouble(l, h); + } + + // new cbrt to 23 bits + r = t * t / x; + s = CBRT_C + r * t; + t *= CBRT_G + CBRT_F / (s + CBRT_E + CBRT_D / s); + + // chopped to 20 bits and make it larger than cbrt(x) + bits = Double.doubleToLongBits(t); + h = getHighDWord(bits); + + // __LO(t)=0; + // __HI(t)+=0x00000001; + l = 0; + h += 1; + t = buildDouble(l, h); + + // one step newton iteration to 53 bits with error less than 0.667 ulps + s = t * t; // t * t is exact + r = x / s; + w = t + t; + r = (r - t) / (w + r); // r - s is exact + t = t + t * r; + + return negative ? -t : t; + } + /** * Take ea. The opposite of log(). If the * argument is NaN, the result is NaN; if the argument is positive infinity, @@ -1428,6 +1553,23 @@ public final strictfp class StrictMath AT9 = -0.036531572744216916, // Long bits 0xbfa2b4442c6a6c2fL. AT10 = 0.016285820115365782; // Long bits 0x3f90ad3ae322da11L. + /** + * Constants for computing {@link #cbrt(double)}. + */ + private static final int + CBRT_B1 = 715094163, // B1 = (682-0.03306235651)*2**20 + CBRT_B2 = 696219795; // B2 = (664-0.03306235651)*2**20 + + /** + * Constants for computing {@link #cbrt(double)}. + */ + private static final double + CBRT_C = 5.42857142857142815906e-01, // Long bits 0x3fe15f15f15f15f1L + CBRT_D = -7.05306122448979611050e-01, // Long bits 0xbfe691de2532c834L + CBRT_E = 1.41428571428571436819e+00, // Long bits 0x3ff6a0ea0ea0ea0fL + CBRT_F = 1.60714285714285720630e+00, // Long bits 0x3ff9b6db6db6db6eL + CBRT_G = 3.57142857142857150787e-01; // Long bits 0x3fd6db6db6db6db7L + /** * Helper function for reducing an angle to a multiple of pi/2 within * [-pi/4, pi/4]. diff --git a/java/lang/management/MemoryMXBean.java b/java/lang/management/MemoryMXBean.java index 33d211c9b..4d9e5ff1c 100644 --- a/java/lang/management/MemoryMXBean.java +++ b/java/lang/management/MemoryMXBean.java @@ -70,6 +70,34 @@ package java.lang.management; * either change (either expanding or contracting) or stay * the same. *

+ *

Notifications

+ *

+ * Implementations of this interface also conform to the + * {@link javax.management.NotificationEmitter} interface, + * and supply two notifications reflecting memory usage. + * These notifications occur when a usage threshold is + * exceeded; for more details of these, see the documentation + * of {@link MemoryPoolMXBean}. If threshold monitoring + * is supported, then a notification will be emitted each time + * the threshold is crossed. Another notification will not + * be emitted unless the usage level has dropped below the + * threshold again in the meantime. + *

+ *

+ * The emitted notifications are instances of + * {@link javax.management.Notification}, with a type of + * either + * {@link java.lang.management.MemoryNotificationInfo#MEMORY_THRESHOLD_EXCEEDED} + * or + * {@link java.lang.management.MemoryNotificationInfo#MEMORY_COLLECTION_THRESHOLD_EXCEEDED} + * (depending on whether the notification refers to the general + * usage threshold or the garbage collection threshold) and an instance + * of {@link java.lang.management.MemoryNotificationInfo} contained + * in the user data section. This is wrapped inside an instance + * of {@link javax.management.openmbean.CompositeData}, as explained + * in the documentation for + * {@link java.lang.management.MemoryNotificationInfo}. + *

* * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.5 diff --git a/java/lang/management/MemoryNotificationInfo.java b/java/lang/management/MemoryNotificationInfo.java index c97fe6bb5..adb38b06f 100644 --- a/java/lang/management/MemoryNotificationInfo.java +++ b/java/lang/management/MemoryNotificationInfo.java @@ -37,10 +37,10 @@ exception statement from your version. */ package java.lang.management; +import gnu.java.lang.management.MemoryMXBeanImpl; + import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; /** @@ -168,31 +168,7 @@ public class MemoryNotificationInfo return null; CompositeType type = data.getCompositeType(); ThreadInfo.checkAttribute(type, "poolName", SimpleType.STRING); - try - { - CompositeType uType = - new CompositeType(MemoryUsage.class.getName(), - "Describes the usage levels of a pool", - new String[] { "init", "used", - "committed", "max" - }, - new String[] { "Initial level", - "Used level", - "Committed level", - "Maximum level" - }, - new OpenType[] { - SimpleType.LONG, SimpleType.LONG, - SimpleType.LONG, SimpleType.LONG - }); - ThreadInfo.checkAttribute(type, "usage", uType); - } - catch (OpenDataException e) - { - throw new IllegalStateException("Something went wrong in creating " + - "the composite data type for the " + - "memory usage element.", e); - } + ThreadInfo.checkAttribute(type, "usage", MemoryMXBeanImpl.usageType); ThreadInfo.checkAttribute(type, "count", SimpleType.LONG); MemoryUsage usage = MemoryUsage.from((CompositeData) data.get("usage")); return new MemoryNotificationInfo(((String) data.get("poolName")), diff --git a/java/lang/management/MemoryPoolMXBean.java b/java/lang/management/MemoryPoolMXBean.java index 29b438c29..5b04c64d3 100644 --- a/java/lang/management/MemoryPoolMXBean.java +++ b/java/lang/management/MemoryPoolMXBean.java @@ -156,6 +156,14 @@ public interface MemoryPoolMXBean */ MemoryUsage getPeakUsage(); + /** + * Returns the type of memory used by this pool. This can be + * either heap or non-heap memory. + * + * @return the type of this pool. + */ + String getType(); + /** * Returns memory usage statistics for the current memory usage * of the pool. The return value may be null if diff --git a/java/net/Inet6Address.java b/java/net/Inet6Address.java index 0d62fe919..8d834a6fd 100644 --- a/java/net/Inet6Address.java +++ b/java/net/Inet6Address.java @@ -39,13 +39,16 @@ exception statement from your version. */ package java.net; import java.util.Arrays; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; /* * Written using on-line Java Platform 1.4 API Specification and * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt) * * @author Michael Koch - * @status Believed complete and correct. + * @status Updated to 1.5. Serialization compatibility is tested. */ public final class Inet6Address extends InetAddress { @@ -56,6 +59,39 @@ public final class Inet6Address extends InetAddress */ byte[] ipaddress; + /** + * The scope ID, if any. + * @since 1.5 + * @serial + */ + private int scope_id; + + /** + * The scope ID, if any. + * @since 1.5 + * @serial + */ + private boolean scope_id_set; + + /** + * Whether ifname is set or not. + * @since 1.5 + * @serial + */ + private boolean scope_ifname_set; + + /** + * Name of the network interface, used only by the serialization methods + * @since 1.5 + * @serial + */ + private String ifname; + + /** + * Scope network interface, or null. + */ + private transient NetworkInterface nif; + /** * Create an Inet6Address object * @@ -67,6 +103,10 @@ public final class Inet6Address extends InetAddress super(addr, host); // Super constructor clones the addr. Get a reference to the clone. this.ipaddress = this.addr; + ifname = null; + scope_ifname_set = scope_id_set = false; + scope_id = 0; + nif = null; } /** @@ -198,6 +238,75 @@ public final class Inet6Address extends InetAddress return (byte[]) ipaddress.clone(); } + /** + * Creates a scoped Inet6Address where the scope has an integer id. + * + * @throws UnkownHostException if the address is an invalid number of bytes. + * @since 1.5 + */ + public static Inet6Address getByAddress(String host, byte[] addr, + int scopeId) + throws UnknownHostException + { + if( addr.length != 16 ) + throw new UnknownHostException("Illegal address length: " + addr.length + + " bytes."); + Inet6Address ip = new Inet6Address( addr, host ); + ip.scope_id = scopeId; + ip.scope_id_set = true; + return ip; + } + + /** + * Creates a scoped Inet6Address where the scope is a given + * NetworkInterface. + * + * @throws UnkownHostException if the address is an invalid number of bytes. + * @since 1.5 + */ + public static Inet6Address getByAddress(String host, byte[] addr, + NetworkInterface nif) + throws UnknownHostException + { + if( addr.length != 16 ) + throw new UnknownHostException("Illegal address length: " + addr.length + + " bytes."); + Inet6Address ip = new Inet6Address( addr, host ); + ip.nif = nif; + + return ip; + } + + /** + * Returns the NetworkInterface of the address scope + * if it is a scoped address and the scope is given in the form of a + * NetworkInterface. + * (I.e. the address was created using the + * getByAddress(String, byte[], NetworkInterface) method) + * Otherwise this method returns null. + * @since 1.5 + */ + public NetworkInterface getScopedInterface() + { + return nif; + } + + /** + * Returns the scope ID of the address scope if it is a scoped adress using + * an integer to identify the scope. + * + * Otherwise this method returns 0. + * @since 1.5 + */ + public int getScopeId() + { + // check scope_id_set because some JDK-serialized objects seem to have + // scope_id set to a nonzero value even when scope_id_set == false + if( scope_id_set ) + return scope_id; + return 0; + } + /** * Returns the IP address string in textual presentation */ @@ -214,12 +323,17 @@ public final class Inet6Address extends InetAddress sbuf.append(Integer.toHexString(x)); } + if( nif != null ) + sbuf.append( "%" + nif.getName() ); + else if( scope_id_set ) + sbuf.append( "%" + scope_id ); return sbuf.toString(); } /** * Returns a hashcode for this IP address + * (The hashcode is independent of scope) */ public int hashCode() { @@ -234,10 +348,23 @@ public final class Inet6Address extends InetAddress if (! (obj instanceof Inet6Address)) return false; - // this.ipaddress is never set in this class except to - // the value of the super class' addr. The super classes - // equals(Object) will do the compare. - return super.equals(obj); + Inet6Address ip = (Inet6Address)obj; + if (ipaddress.length != ip.ipaddress.length) + return false; + + for (int i = 0; i < ip.ipaddress.length; i++) + if (ipaddress[i] != ip.ipaddress[i]) + return false; + + if( ip.nif != null && nif != null ) + return nif.equals( ip.nif ); + if( ip.nif != nif ) + return false; + if( ip.scope_id_set != scope_id_set ) + return false; + if( scope_id_set ) + return (scope_id == ip.scope_id); + return true; } /** @@ -258,4 +385,38 @@ public final class Inet6Address extends InetAddress return true; } + + /** + * Required for 1.5-compatible serialization. + * @since 1.5 + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + try + { + if( scope_ifname_set ) + nif = NetworkInterface.getByName( ifname ); + } + catch( SocketException se ) + { + // FIXME: Ignore this? or throw an IOException? + } + } + + /** + * Required for 1.5-compatible serialization. + * @since 1.5 + */ + private void writeObject(ObjectOutputStream s) + throws IOException + { + if( nif != null ) + { + ifname = nif.getName(); + scope_ifname_set = true; + } + s.defaultWriteObject(); + } } -- cgit v1.2.1