Initial revision
From-SVN: r102074
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
/* AffineTransformOp.java -- This class performs affine
|
||||
transformation between two images or rasters in 2 dimensions.
|
||||
Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.NoninvertibleTransformException;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class performs affine transformation between two images or
|
||||
* rasters in 2 dimensions.
|
||||
*
|
||||
* @author Olga Rodimina (rodimina@redhat.com)
|
||||
*/
|
||||
public class AffineTransformOp implements BufferedImageOp, RasterOp
|
||||
{
|
||||
public static final int TYPE_NEAREST_NEIGHBOR = 1;
|
||||
|
||||
public static final int TYPE_BILINEAR = 2;
|
||||
|
||||
/**
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static final int TYPE_BICUBIC = 3;
|
||||
|
||||
private AffineTransform transform;
|
||||
private RenderingHints hints;
|
||||
|
||||
/**
|
||||
* Construct AffineTransformOp with the given xform and interpolationType.
|
||||
* Interpolation type can be TYPE_BILINEAR, TYPE_BICUBIC or
|
||||
* TYPE_NEAREST_NEIGHBOR.
|
||||
*
|
||||
* @param xform AffineTransform that will applied to the source image
|
||||
* @param interpolationType type of interpolation used
|
||||
*/
|
||||
public AffineTransformOp (AffineTransform xform, int interpolationType)
|
||||
{
|
||||
this.transform = xform;
|
||||
if (xform.getDeterminant() == 0)
|
||||
throw new ImagingOpException(null);
|
||||
|
||||
switch (interpolationType)
|
||||
{
|
||||
case TYPE_BILINEAR:
|
||||
hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
break;
|
||||
case TYPE_BICUBIC:
|
||||
hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
break;
|
||||
default:
|
||||
hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct AffineTransformOp with the given xform and rendering hints.
|
||||
*
|
||||
* @param xform AffineTransform that will applied to the source image
|
||||
* @param hints rendering hints that will be used during transformation
|
||||
*/
|
||||
public AffineTransformOp (AffineTransform xform, RenderingHints hints)
|
||||
{
|
||||
this.transform = xform;
|
||||
this.hints = hints;
|
||||
if (xform.getDeterminant() == 0)
|
||||
throw new ImagingOpException(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates empty BufferedImage with the size equal to that of the
|
||||
* transformed image and correct number of bands. The newly created
|
||||
* image is created with the specified ColorModel.
|
||||
* If the ColorModel is equal to null, then image is created
|
||||
* with the ColorModel of the source image.
|
||||
*
|
||||
* @param src source image
|
||||
* @param destCM color model for the destination image
|
||||
* @return new compatible destination image
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage (BufferedImage src,
|
||||
ColorModel destCM)
|
||||
{
|
||||
|
||||
// if destCm is not specified, use color model of the source image
|
||||
|
||||
if (destCM == null)
|
||||
destCM = src.getColorModel ();
|
||||
|
||||
return new BufferedImage (destCM,
|
||||
createCompatibleDestRaster (src.getRaster ()),
|
||||
src.isAlphaPremultiplied (),
|
||||
null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates empty WritableRaster with the size equal to the transformed
|
||||
* source raster and correct number of bands
|
||||
*
|
||||
* @param src source raster
|
||||
* @throws RasterFormatException if resulting width or height of raster is 0
|
||||
* @return new compatible raster
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster (Raster src)
|
||||
{
|
||||
Rectangle rect = (Rectangle) getBounds2D (src);
|
||||
|
||||
// throw RasterFormatException if resulting width or height of the
|
||||
// transformed raster is 0
|
||||
|
||||
if (rect.getWidth () == 0 || rect.getHeight () == 0)
|
||||
throw new RasterFormatException("width or height is 0");
|
||||
|
||||
return src.createCompatibleWritableRaster ((int) rect.getWidth (),
|
||||
(int) rect.getHeight ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms source image using transform specified at the constructor.
|
||||
* The resulting transformed image is stored in the destination image.
|
||||
*
|
||||
* @param src source image
|
||||
* @param dst destination image
|
||||
* @return transformed source image
|
||||
*/
|
||||
public final BufferedImage filter (BufferedImage src, BufferedImage dst)
|
||||
{
|
||||
|
||||
if (dst == src)
|
||||
throw new IllegalArgumentException ("src image cannot be the same as the dst image");
|
||||
|
||||
// If the destination image is null, then BufferedImage is
|
||||
// created with ColorModel of the source image
|
||||
|
||||
if (dst == null)
|
||||
dst = createCompatibleDestImage(src, src.getColorModel ());
|
||||
|
||||
// FIXME: Must check if color models of src and dst images are the same.
|
||||
// If it is not, then source image should be converted to color model
|
||||
// of the destination image
|
||||
|
||||
Graphics2D gr = (Graphics2D) dst.createGraphics ();
|
||||
gr.setRenderingHints (hints);
|
||||
gr.drawImage (src, transform, null);
|
||||
return dst;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms source raster using transform specified at the constructor.
|
||||
* The resulting raster is stored in the destination raster.
|
||||
*
|
||||
* @param src source raster
|
||||
* @param dst destination raster
|
||||
* @return transformed raster
|
||||
*/
|
||||
public final WritableRaster filter (Raster src, WritableRaster dst)
|
||||
{
|
||||
if (dst == src)
|
||||
throw new IllegalArgumentException("src image cannot be the same as"
|
||||
+ " the dst image");
|
||||
|
||||
if (dst == null)
|
||||
dst = createCompatibleDestRaster(src);
|
||||
|
||||
if (src.getNumBands() != dst.getNumBands())
|
||||
throw new IllegalArgumentException("src and dst must have same number"
|
||||
+ " of bands");
|
||||
|
||||
double[] dpts = new double[dst.getWidth() * 2];
|
||||
double[] pts = new double[dst.getWidth() * 2];
|
||||
for (int x = 0; x < dst.getWidth(); x++)
|
||||
{
|
||||
dpts[2 * x] = x + dst.getMinX();
|
||||
dpts[2 * x + 1] = x;
|
||||
}
|
||||
Rectangle srcbounds = src.getBounds();
|
||||
if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
|
||||
{
|
||||
for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
|
||||
{
|
||||
try {
|
||||
transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
// Can't happen since the constructor traps this
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (int x = 0; x < dst.getWidth(); x++)
|
||||
{
|
||||
if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
|
||||
continue;
|
||||
dst.setDataElements(x + dst.getMinX(), y,
|
||||
src.getDataElements((int)pts[2 * x],
|
||||
(int)pts[2 * x + 1],
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
|
||||
{
|
||||
double[] tmp = new double[4 * src.getNumBands()];
|
||||
for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
|
||||
{
|
||||
try {
|
||||
transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
// Can't happen since the constructor traps this
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (int x = 0; x < dst.getWidth(); x++)
|
||||
{
|
||||
if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
|
||||
continue;
|
||||
int xx = (int)pts[2 * x];
|
||||
int yy = (int)pts[2 * x + 1];
|
||||
double dx = (pts[2 * x] - xx);
|
||||
double dy = (pts[2 * x + 1] - yy);
|
||||
|
||||
// TODO write this more intelligently
|
||||
if (xx == src.getMinX() + src.getWidth() - 1 ||
|
||||
yy == src.getMinY() + src.getHeight() - 1)
|
||||
{
|
||||
// bottom or right edge
|
||||
Arrays.fill(tmp, 0);
|
||||
src.getPixel(xx, yy, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal case
|
||||
src.getPixels(xx, yy, 2, 2, tmp);
|
||||
for (int b = 0; b < src.getNumBands(); b++)
|
||||
tmp[b] = dx * dy * tmp[b]
|
||||
+ (1 - dx) * dy * tmp[b + src.getNumBands()]
|
||||
+ dx * (1 - dy) * tmp[b + 2 * src.getNumBands()]
|
||||
+ (1 - dx) * (1 - dy) * tmp[b + 3 * src.getNumBands()];
|
||||
}
|
||||
dst.setPixel(x, y, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bicubic
|
||||
throw new UnsupportedOperationException("not implemented yet");
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms source image using transform specified at the constructor and
|
||||
* returns bounds of the transformed image.
|
||||
*
|
||||
* @param src image to be transformed
|
||||
* @return bounds of the transformed image.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (BufferedImage src)
|
||||
{
|
||||
return getBounds2D (src.getRaster());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns bounds of the transformed raster.
|
||||
*
|
||||
* @param src raster to be transformed
|
||||
* @return bounds of the transformed raster.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (Raster src)
|
||||
{
|
||||
// determine new size for the transformed raster.
|
||||
// Need to calculate transformed coordinates of the lower right
|
||||
// corner of the raster. The upper left corner is always (0,0)
|
||||
|
||||
double x2 = (double) src.getWidth () + src.getMinX ();
|
||||
double y2 = (double) src.getHeight () + src.getMinY ();
|
||||
Point2D p2 = getPoint2D (new Point2D.Double (x2,y2), null);
|
||||
|
||||
Rectangle2D rect = new Rectangle (0, 0, (int) p2.getX (), (int) p2.getY ());
|
||||
return rect.getBounds ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns interpolation type used during transformations
|
||||
*
|
||||
* @return interpolation type
|
||||
*/
|
||||
public final int getInterpolationType ()
|
||||
{
|
||||
if(hints.containsValue (RenderingHints.VALUE_INTERPOLATION_BILINEAR))
|
||||
return TYPE_BILINEAR;
|
||||
else
|
||||
return TYPE_NEAREST_NEIGHBOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns location of the transformed source point. The resulting point
|
||||
* is stored in the dstPt if one is specified.
|
||||
*
|
||||
* @param srcPt point to be transformed
|
||||
* @param dstPt destination point
|
||||
* @return the location of the transformed source point.
|
||||
*/
|
||||
public Point2D getPoint2D (Point2D srcPt, Point2D dstPt)
|
||||
{
|
||||
return transform.transform (srcPt, dstPt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns rendering hints that are used during transformation.
|
||||
*
|
||||
* @return rendering hints
|
||||
*/
|
||||
public final RenderingHints getRenderingHints ()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns transform used in transformation between source and destination
|
||||
* image.
|
||||
*
|
||||
* @return transform
|
||||
*/
|
||||
public final AffineTransform getTransform ()
|
||||
{
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/* AreaAveragingScaleFilter.java -- Java class for filtering images
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This filter should produce images which do not have image artifacts
|
||||
* like broken lines which were originally unbroken. The cost is of
|
||||
* course speed. Using bi-linear interpolation here against 4 pixel
|
||||
* points should give the desired results although Sun does not
|
||||
* specify what the exact algorithm should be.
|
||||
* <br>
|
||||
* Currently this filter does nothing and needs to be implemented.
|
||||
*
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public class AreaAveragingScaleFilter extends ReplicateScaleFilter
|
||||
{
|
||||
/**
|
||||
* Construct an instance of <code>AreaAveragingScaleFilter</code> which
|
||||
* should be used in conjunction with a <code>FilteredImageSource</code>
|
||||
* object.
|
||||
*
|
||||
* @param width the width of the destination image
|
||||
* @param height the height of the destination image
|
||||
*/
|
||||
public AreaAveragingScaleFilter(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>ImageProducer</code> should call this method with a
|
||||
* bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
|
||||
* <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
|
||||
* <code>SINGLEPASS</code>, <code>SINGLEFRAME</code> from the
|
||||
* <code>ImageConsumer</code> interface.
|
||||
* <br>
|
||||
* FIXME - more than likely Sun's implementation desires
|
||||
* <code>TOPDOWNLEFTRIGHT</code> order and this method is overloaded here
|
||||
* in order to assure that mask is part of the hints added to
|
||||
* the consumer.
|
||||
*
|
||||
* @param flags a bit mask of hints
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public void setHints(int flags)
|
||||
{
|
||||
consumer.setHints(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as a <code>byte</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels, int offset, int scansize)
|
||||
{
|
||||
consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as an <code>int</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels, int offset, int scansize)
|
||||
{
|
||||
consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* Filter Raster pixels by applying a matrix.
|
||||
*
|
||||
* BandCombineOp applies a matrix to each pixel to produce new pixel values.
|
||||
* The width of the matrix must be the same or one more than the number of
|
||||
* bands in the source Raster. If one more, the pixels in the source are
|
||||
* assumed to contain an implicit 1.0 at the end.
|
||||
*
|
||||
* The rows of the matrix are multiplied by the pixel to produce the values
|
||||
* for the destination. Therefore the destination Raster must contain the
|
||||
* same number of bands as the number of rows in the filter matrix.
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
*/
|
||||
public class BandCombineOp implements RasterOp
|
||||
{
|
||||
private RenderingHints hints;
|
||||
private float[][] matrix;
|
||||
|
||||
/**
|
||||
* Construct a BandCombineOp.
|
||||
*
|
||||
* @param matrix The matrix to filter pixels with.
|
||||
* @param hints Rendering hints to apply. Ignored.
|
||||
*/
|
||||
public BandCombineOp(float[][] matrix, RenderingHints hints)
|
||||
{
|
||||
this.matrix = matrix;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter Raster pixels through a matrix.
|
||||
*
|
||||
* Applies the Op matrix to source pixes to produce dest pixels. Each row
|
||||
* of the matrix is multiplied by the src pixel components to produce the
|
||||
* dest pixel. If matrix is one more than the number of bands in the src,
|
||||
* the last element is implicitly multiplied by 1, i.e. added to the sum
|
||||
* for that dest component.
|
||||
*
|
||||
* If dest is null, a suitable Raster is created. This implementation uses
|
||||
* createCompatibleDestRaster.
|
||||
*
|
||||
* @param src The source Raster.
|
||||
* @param dest The destination Raster, or null.
|
||||
* @returns The destination Raster or an allocated Raster.
|
||||
* @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
|
||||
*java.awt.image.WritableRaster)
|
||||
*/
|
||||
public WritableRaster filter(Raster src, WritableRaster dest) {
|
||||
if (dest == null)
|
||||
dest = createCompatibleDestRaster(src);
|
||||
|
||||
// Filter the pixels
|
||||
float[] spix = new float[matrix[0].length];
|
||||
float[] dpix = new float[matrix.length];
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
|
||||
{
|
||||
// In case matrix rows have implicit translation
|
||||
spix[spix.length - 1] = 1.0f;
|
||||
src.getPixel(x, y, spix);
|
||||
for (int i = 0; i < matrix.length; i++)
|
||||
{
|
||||
dpix[i] = 0;
|
||||
for (int j = 0; j < matrix[0].length; j++)
|
||||
dpix[i] += spix[j] * matrix[i][j];
|
||||
}
|
||||
dest.setPixel(x, y, dpix);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
|
||||
*/
|
||||
public Rectangle2D getBounds2D(Raster src)
|
||||
{
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new WritableRaster that can be used as the destination for this
|
||||
* Op. This implementation creates a Banded Raster with data type FLOAT.
|
||||
* @see
|
||||
*java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src)
|
||||
{
|
||||
return Raster.createBandedRaster(DataBuffer.TYPE_FLOAT, src.getWidth(),
|
||||
src.getHeight(), matrix.length,
|
||||
new Point(src.getMinX(), src.getMinY()));
|
||||
}
|
||||
|
||||
/** Return corresponding destination point for source point.
|
||||
*
|
||||
* LookupOp will return the value of src unchanged.
|
||||
* @param src The source point.
|
||||
* @param dst The destination point.
|
||||
* @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D,
|
||||
*java.awt.geom.Point2D)
|
||||
*/
|
||||
public Point2D getPoint2D(Point2D src, Point2D dst)
|
||||
{
|
||||
if (dst == null) return (Point2D)src.clone();
|
||||
dst.setLocation(src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getRenderingHints()
|
||||
*/
|
||||
public RenderingHints getRenderingHints()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
/** Return the matrix for this Op. */
|
||||
public float[][] getMatrix()
|
||||
{
|
||||
return matrix;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
/* Copyright (C) 2004, 2005, Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* MultiPixelPackedSampleModel provides a single band model that supports
|
||||
* multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
|
||||
* per data element.
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
*/
|
||||
public final class BandedSampleModel extends ComponentSampleModel
|
||||
{
|
||||
private int[] bitMasks;
|
||||
private int[] bitOffsets;
|
||||
private int[] sampleSize;
|
||||
private int dataBitOffset;
|
||||
private int elemBits;
|
||||
private int numberOfBits;
|
||||
private int numElems;
|
||||
|
||||
private static int[] createBankArray(int size)
|
||||
{
|
||||
int[] result = new int[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
result[i] = i;
|
||||
return result;
|
||||
}
|
||||
|
||||
public BandedSampleModel(int dataType, int w, int h, int numBands)
|
||||
{
|
||||
this(dataType, w, h, w, createBankArray(numBands), new int[numBands]);
|
||||
}
|
||||
|
||||
public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
|
||||
int[] bankIndices, int[] bandOffsets)
|
||||
{
|
||||
super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
// NOTE: blackdown 1.4.1 sets all offsets to 0. Sun's 1.4.2 docs
|
||||
// disagree.
|
||||
|
||||
// Compress offsets so minimum is 0, others w*scanlineStride
|
||||
int[] newoffsets = new int[bandOffsets.length];
|
||||
int[] order = new int[bandOffsets.length];
|
||||
for (int i=0; i < bandOffsets.length; i++)
|
||||
order[i] = i;
|
||||
// FIXME: This is N^2, but not a big issue, unless there's a lot of
|
||||
// bands...
|
||||
for (int i=0; i < bandOffsets.length; i++)
|
||||
for (int j=i+1; j < bandOffsets.length; i++)
|
||||
if (bankIndices[order[i]] > bankIndices[order[j]]
|
||||
|| (bankIndices[order[i]] == bankIndices[order[j]]
|
||||
&& bandOffsets[order[i]] > bandOffsets[order[j]]))
|
||||
{
|
||||
int t = order[i]; order[i] = order[j]; order[j] = t;
|
||||
}
|
||||
int bank = 0;
|
||||
int offset = 0;
|
||||
for (int i=0; i < bandOffsets.length; i++)
|
||||
{
|
||||
if (bankIndices[order[i]] != bank)
|
||||
{
|
||||
bank = bankIndices[order[i]];
|
||||
offset = 0;
|
||||
}
|
||||
newoffsets[order[i]] = offset;
|
||||
offset += w * scanlineStride;
|
||||
}
|
||||
|
||||
return new BandedSampleModel(dataType, w, h, scanlineStride, bankIndices, newoffsets);
|
||||
}
|
||||
|
||||
|
||||
public SampleModel createSubsetSampleModel(int[] bands)
|
||||
{
|
||||
if (bands.length > bankIndices.length)
|
||||
throw new
|
||||
RasterFormatException("BandedSampleModel createSubsetSampleModel too"
|
||||
+" many bands");
|
||||
int[] newoff = new int[bands.length];
|
||||
int[] newbanks = new int[bands.length];
|
||||
for (int i=0; i < bands.length; i++)
|
||||
{
|
||||
int b = bands[i];
|
||||
newoff[i] = bandOffsets[b];
|
||||
newbanks[i] = bankIndices[b];
|
||||
}
|
||||
|
||||
return new BandedSampleModel(dataType, width, height, scanlineStride,
|
||||
newbanks, newoff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all samples of one pixel and return in an array of transfer type.
|
||||
*
|
||||
* Extracts the pixel at x, y from data and stores samples into the array
|
||||
* obj. If obj is null, a new array of getTransferType() is created.
|
||||
*
|
||||
* @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
|
||||
* @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
|
||||
* @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)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj,
|
||||
DataBuffer data)
|
||||
{
|
||||
int pixel = getSample(x, y, 0, data);
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
{
|
||||
byte[] b = (byte[])obj;
|
||||
if (b == null) b = new byte[numBands];
|
||||
for (int i=0; i < numBands; i++)
|
||||
b[i] = (byte)getSample(x, y, i, data);
|
||||
return b;
|
||||
}
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
{
|
||||
short[] b = (short[])obj;
|
||||
if (b == null) b = new short[numBands];
|
||||
for (int i=0; i < numBands; i++)
|
||||
b[i] = (short)getSample(x, y, i, data);
|
||||
return b;
|
||||
}
|
||||
case DataBuffer.TYPE_INT:
|
||||
{
|
||||
int[] b = (int[])obj;
|
||||
if (b == null) b = new int[numBands];
|
||||
for (int i=0; i < numBands; i++)
|
||||
b[i] = getSample(x, y, i, data);
|
||||
return b;
|
||||
}
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
{
|
||||
float[] b = (float[])obj;
|
||||
if (b == null) b = new float[numBands];
|
||||
for (int i=0; i < numBands; i++)
|
||||
b[i] = getSampleFloat(x, y, i, data);
|
||||
return b;
|
||||
}
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
{
|
||||
double[] b = (double[])obj;
|
||||
if (b == null) b = new double[numBands];
|
||||
for (int i=0; i < numBands; i++)
|
||||
b[i] = getSample(x, y, i, data);
|
||||
return b;
|
||||
}
|
||||
|
||||
default:
|
||||
// Seems like the only sensible thing to do.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
if (iArray == null) iArray = new int[numBands];
|
||||
for (int i=0; i < numBands; i++)
|
||||
iArray[i] = getSample(x, y, i, data);
|
||||
|
||||
return iArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy pixels from a region into an array.
|
||||
*
|
||||
* Copies the samples of the pixels in the rectangle starting at x, y that
|
||||
* is w pixels wide and h scanlines high. When there is more than one band,
|
||||
* the samples stored in order before the next pixel. This ordering isn't
|
||||
* well specified in Sun's docs as of 1.4.2.
|
||||
*
|
||||
* If iArray is null, a new array is allocated, filled, and returned.
|
||||
*
|
||||
* @param x The x-coordinate of the pixel rectangle to store in
|
||||
* <code>iArray</code>.
|
||||
* @param y The y-coordinate of the pixel rectangle to store in
|
||||
* <code>iArray</code>.
|
||||
* @param w The width in pixels of the rectangle.
|
||||
* @param h The height in pixels of the rectangle.
|
||||
* @param iArray The int 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.
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
if (iArray == null) iArray = new int[w*h*numBands];
|
||||
int outOffset = 0;
|
||||
int maxX = x + w;
|
||||
int maxY = y + h;
|
||||
for (int yy = x; yy < maxY; yy++)
|
||||
{
|
||||
for (int xx = x; xx < maxX; xx++)
|
||||
{
|
||||
for (int b = 0; b < numBands; b++)
|
||||
{
|
||||
int offset = bandOffsets[b] + yy * scanlineStride + xx;
|
||||
iArray[outOffset++] =
|
||||
data.getElem(bankIndices[b], offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public int getSample(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + x;
|
||||
return data.getElem(bankIndices[b], offset);
|
||||
}
|
||||
|
||||
public float getSampleFloat(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + x;
|
||||
return data.getElemFloat(bankIndices[b], offset);
|
||||
}
|
||||
|
||||
public double getSampleDouble(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + x;
|
||||
return data.getElemDouble(bankIndices[b], offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy one band's samples from a region into an array.
|
||||
*
|
||||
* Copies from one band the samples of the pixels in the rectangle starting
|
||||
* at x, y that is w pixels wide and h scanlines high.
|
||||
*
|
||||
* If iArray is null, a new array is allocated, filled, and returned.
|
||||
*
|
||||
* @param x The x-coordinate of the pixel rectangle to store in
|
||||
* <code>iArray</code>.
|
||||
* @param y The y-coordinate of the pixel rectangle to store in
|
||||
* <code>iArray</code>.
|
||||
* @param w The width in pixels of the rectangle.
|
||||
* @param h The height in pixels of the rectangle.
|
||||
* @param b The band to retrieve.
|
||||
* @param iArray The int 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.
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
if (iArray == null) iArray = new int[w*h];
|
||||
int outOffset = 0;
|
||||
int maxX = x + w;
|
||||
int maxY = y + h;
|
||||
for (int yy = y; yy < maxY; yy++)
|
||||
{
|
||||
for (int xx = x; xx < maxX; xx++)
|
||||
{
|
||||
int offset = bandOffsets[b] + yy * scanlineStride + xx;
|
||||
iArray[outOffset++] =
|
||||
data.getElem(bankIndices[b], offset);
|
||||
}
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the pixel at x, y to the value in the first element of the primitive
|
||||
* array obj.
|
||||
*
|
||||
* @param x The x-coordinate of the data elements in <code>obj</code>.
|
||||
* @param y The y-coordinate of the data elements in <code>obj</code>.
|
||||
* @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 = y * scanlineStride + x;
|
||||
|
||||
try
|
||||
{
|
||||
switch (transferType)
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
{
|
||||
DataBufferByte out = (DataBufferByte) data;
|
||||
byte[] in = (byte[]) obj;
|
||||
for (int i=0; i < numBands; i++)
|
||||
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
{
|
||||
DataBufferShort out = (DataBufferShort) data;
|
||||
short[] in = (short[]) obj;
|
||||
for (int i=0; i < numBands; i++)
|
||||
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
{
|
||||
DataBufferUShort out = (DataBufferUShort) data;
|
||||
short[] in = (short[]) obj;
|
||||
for (int i=0; i < numBands; i++)
|
||||
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_INT:
|
||||
{
|
||||
DataBufferInt out = (DataBufferInt) data;
|
||||
int[] in = (int[]) obj;
|
||||
for (int i=0; i < numBands; i++)
|
||||
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
{
|
||||
DataBufferFloat out = (DataBufferFloat) data;
|
||||
float[] in = (float[]) obj;
|
||||
for (int i=0; i < numBands; i++)
|
||||
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
{
|
||||
DataBufferDouble out = (DataBufferDouble) data;
|
||||
double[] in = (double[]) obj;
|
||||
for (int i=0; i < numBands; i++)
|
||||
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
for (int b=0; b < numBands; b++)
|
||||
data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
|
||||
iArray[b]);
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int inOffset = 0;
|
||||
for (int hh = 0; hh < h; hh++)
|
||||
{
|
||||
for (int ww = 0; ww < w; ww++)
|
||||
{
|
||||
int offset = y * scanlineStride + (x + ww);
|
||||
for (int b=0; b < numBands; b++)
|
||||
data.setElem(bankIndices[b], bandOffsets[b] + offset,
|
||||
iArray[inOffset++]);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, int s, DataBuffer data)
|
||||
{
|
||||
data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, float s, DataBuffer data)
|
||||
{
|
||||
data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, double s, DataBuffer data)
|
||||
{
|
||||
data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int inOffset = 0;
|
||||
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
{
|
||||
DataBufferByte out = (DataBufferByte) data;
|
||||
byte[] bank = out.getData(bankIndices[b]);
|
||||
for (int hh = 0; hh < h; hh++)
|
||||
{
|
||||
for (int ww = 0; ww < w; ww++)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
|
||||
bank[offset] = (byte)iArray[inOffset++];
|
||||
}
|
||||
y++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
{
|
||||
DataBufferShort out = (DataBufferShort) data;
|
||||
short[] bank = out.getData(bankIndices[b]);
|
||||
for (int hh = 0; hh < h; hh++)
|
||||
{
|
||||
for (int ww = 0; ww < w; ww++)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
|
||||
bank[offset] = (short)iArray[inOffset++];
|
||||
}
|
||||
y++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
{
|
||||
DataBufferShort out = (DataBufferShort) data;
|
||||
short[] bank = out.getData(bankIndices[b]);
|
||||
for (int hh = 0; hh < h; hh++)
|
||||
{
|
||||
for (int ww = 0; ww < w; ww++)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
|
||||
bank[offset] = (short)iArray[inOffset++];
|
||||
}
|
||||
y++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_INT:
|
||||
{
|
||||
DataBufferInt out = (DataBufferInt) data;
|
||||
int[] bank = out.getData(bankIndices[b]);
|
||||
for (int hh = 0; hh < h; hh++)
|
||||
{
|
||||
for (int ww = 0; ww < w; ww++)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
|
||||
bank[offset] = iArray[inOffset++];
|
||||
}
|
||||
y++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
break;
|
||||
default:
|
||||
throw new ClassCastException("Unsupported data type");
|
||||
}
|
||||
|
||||
// Default implementation probably slower for float and double
|
||||
for (int hh = 0; hh < h; hh++)
|
||||
{
|
||||
for (int ww = 0; ww < w; ww++)
|
||||
{
|
||||
int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
|
||||
data.setElem(bankIndices[b], offset, iArray[inOffset++]);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a String with some information about this SampleModel.
|
||||
* @return A String describing this SampleModel.
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append(getClass().getName());
|
||||
result.append("[");
|
||||
result.append("scanlineStride=").append(scanlineStride);
|
||||
for(int i=0; i < bitMasks.length; i+=1)
|
||||
{
|
||||
result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
|
||||
}
|
||||
|
||||
result.append("]");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/* BufferStrategy.java -- describes image buffering resources
|
||||
Copyright (C) 2002, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.BufferCapabilities;
|
||||
import java.awt.Graphics;
|
||||
|
||||
/**
|
||||
* This class describes a strategy for managing image buffering
|
||||
* resources on a Canvas or Window. A given buffer strategy may make
|
||||
* use of hardware acceleration or take advantage of features of the
|
||||
* native graphics system. Examples of buffering strategies are
|
||||
* double or triple buffering using either flipping or blitting. For
|
||||
* the details of these algorithms see BufferCapabilities.
|
||||
*
|
||||
* To use a buffer strategy, you retrieve it from either the current
|
||||
* GraphicsConfiguration or from the Component on which you'd like to
|
||||
* draw. Then you can query the strategy's capabilities to make sure
|
||||
* they're suitable.
|
||||
*
|
||||
* If the strategy's capabilities are suitable, you can obtain a
|
||||
* graphics object and use it to draw with this strategy. Drawing
|
||||
* with a buffer strategy requires extra care, however. You'll need
|
||||
* to manually cause the next buffer to be shown on the output device.
|
||||
* And since buffer strategies are usually implemented with a
|
||||
* VolatileImage, you must frequently check that the contents of the
|
||||
* buffer are valid and that the buffer still exists.
|
||||
*
|
||||
* A buffer strategy is usually implemented using a VolatileImage.
|
||||
*
|
||||
* @see VolatileImage
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class BufferStrategy
|
||||
{
|
||||
/**
|
||||
* Creates a new buffer strategy.
|
||||
*/
|
||||
public BufferStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the capabilities of this buffer strategy.
|
||||
*
|
||||
* @return this buffer strategy's capabilities
|
||||
*/
|
||||
public abstract BufferCapabilities getCapabilities();
|
||||
|
||||
/**
|
||||
* Retrieves a graphics object that can be used to draw using this
|
||||
* buffer strategy. This method may not be synchronized so be
|
||||
* careful when calling it from multiple threads. You also must
|
||||
* manually dispose of this graphics object.
|
||||
*
|
||||
* @return a graphics object that can be used to draw using this
|
||||
* buffer strategy
|
||||
*/
|
||||
public abstract Graphics getDrawGraphics();
|
||||
|
||||
/**
|
||||
* Returns whether or not the buffer's resources have been reclaimed
|
||||
* by the native graphics system. If the buffer resources have been
|
||||
* lost then you'll need to obtain new resources before drawing
|
||||
* again. For details, see the documentation for VolatileImage.
|
||||
*
|
||||
* @return true if the contents were lost, false otherwise
|
||||
*/
|
||||
public abstract boolean contentsLost();
|
||||
|
||||
/**
|
||||
* Returns whether or not the buffer's resources were re-created and
|
||||
* cleared to the default background color. If the buffer's
|
||||
* resources have recently been re-created and initialized then the
|
||||
* buffer's image may need to be re-rendered. For details, see the
|
||||
* documentation for VolatileImage.
|
||||
*
|
||||
* @return true if the contents were restored, false otherwise
|
||||
*/
|
||||
public abstract boolean contentsRestored();
|
||||
|
||||
/**
|
||||
* Applies this buffer strategy. In other words, this method brings
|
||||
* the contents of the back or intermediate buffers to the front
|
||||
* buffer.
|
||||
*/
|
||||
public abstract void show();
|
||||
}
|
||||
@@ -0,0 +1,693 @@
|
||||
/* BufferedImage.java --
|
||||
Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.ComponentDataBlitOp;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* A buffered image always starts at coordinates (0, 0).
|
||||
*
|
||||
* The buffered image is not subdivided into multiple tiles. Instead,
|
||||
* the image consists of one large tile (0,0) with the width and
|
||||
* height of the image. This tile is always considered to be checked
|
||||
* out.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public class BufferedImage extends Image
|
||||
implements WritableRenderedImage
|
||||
{
|
||||
public static final int TYPE_CUSTOM = 0,
|
||||
TYPE_INT_RGB = 1,
|
||||
TYPE_INT_ARGB = 2,
|
||||
TYPE_INT_ARGB_PRE = 3,
|
||||
TYPE_INT_BGR = 4,
|
||||
TYPE_3BYTE_BGR = 5,
|
||||
TYPE_4BYTE_ABGR = 6,
|
||||
TYPE_4BYTE_ABGR_PRE = 7,
|
||||
TYPE_USHORT_565_RGB = 8,
|
||||
TYPE_USHORT_555_RGB = 9,
|
||||
TYPE_BYTE_GRAY = 10,
|
||||
TYPE_USHORT_GRAY = 11,
|
||||
TYPE_BYTE_BINARY = 12,
|
||||
TYPE_BYTE_INDEXED = 13;
|
||||
|
||||
static final int[] bits3 = { 8, 8, 8 };
|
||||
static final int[] bits4 = { 8, 8, 8 };
|
||||
static final int[] bits1byte = { 8 };
|
||||
static final int[] bits1ushort = { 16 };
|
||||
|
||||
static final int[] masks_int = { 0x00ff0000,
|
||||
0x0000ff00,
|
||||
0x000000ff,
|
||||
DataBuffer.TYPE_INT };
|
||||
static final int[] masks_565 = { 0xf800,
|
||||
0x07e0,
|
||||
0x001f,
|
||||
DataBuffer.TYPE_USHORT};
|
||||
static final int[] masks_555 = { 0x7c00,
|
||||
0x03e0,
|
||||
0x001f,
|
||||
DataBuffer.TYPE_USHORT};
|
||||
|
||||
Vector observers;
|
||||
|
||||
public BufferedImage(int w, int h, int type)
|
||||
{
|
||||
ColorModel cm = null;
|
||||
|
||||
boolean alpha = false;
|
||||
boolean premultiplied = false;
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_4BYTE_ABGR_PRE:
|
||||
case TYPE_INT_ARGB_PRE:
|
||||
premultiplied = true;
|
||||
// fall through
|
||||
case TYPE_INT_ARGB:
|
||||
case TYPE_4BYTE_ABGR:
|
||||
alpha = true;
|
||||
}
|
||||
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_INT_RGB:
|
||||
case TYPE_INT_ARGB:
|
||||
case TYPE_INT_ARGB_PRE:
|
||||
case TYPE_USHORT_565_RGB:
|
||||
case TYPE_USHORT_555_RGB:
|
||||
int[] masks = null;
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_INT_RGB:
|
||||
case TYPE_INT_ARGB:
|
||||
case TYPE_INT_ARGB_PRE:
|
||||
masks = masks_int;
|
||||
break;
|
||||
case TYPE_USHORT_565_RGB:
|
||||
masks = masks_565;
|
||||
break;
|
||||
case TYPE_USHORT_555_RGB:
|
||||
masks = masks_555;
|
||||
break;
|
||||
}
|
||||
|
||||
cm = new DirectColorModel(cs,
|
||||
32, // 32 bits in an int
|
||||
masks[0], // r
|
||||
masks[1], // g
|
||||
masks[2], // b
|
||||
alpha ? 0xff000000 : 0,
|
||||
premultiplied,
|
||||
masks[3] // data type
|
||||
);
|
||||
break;
|
||||
|
||||
case TYPE_INT_BGR:
|
||||
String msg =
|
||||
"FIXME: Programmer is confused. Why (and how) does a " +
|
||||
"TYPE_INT_BGR image use ComponentColorModel to store " +
|
||||
"8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
|
||||
"is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
|
||||
throw new UnsupportedOperationException(msg);
|
||||
|
||||
case TYPE_3BYTE_BGR:
|
||||
case TYPE_4BYTE_ABGR:
|
||||
case TYPE_4BYTE_ABGR_PRE:
|
||||
case TYPE_BYTE_GRAY:
|
||||
case TYPE_USHORT_GRAY:
|
||||
int[] bits = null;
|
||||
int dataType = DataBuffer.TYPE_BYTE;
|
||||
switch (type) {
|
||||
case TYPE_3BYTE_BGR:
|
||||
bits = bits3;
|
||||
break;
|
||||
case TYPE_4BYTE_ABGR:
|
||||
case TYPE_4BYTE_ABGR_PRE:
|
||||
bits = bits4;
|
||||
break;
|
||||
case TYPE_BYTE_GRAY:
|
||||
bits = bits1byte;
|
||||
break;
|
||||
case TYPE_USHORT_GRAY:
|
||||
bits = bits1ushort;
|
||||
dataType = DataBuffer.TYPE_USHORT;
|
||||
break;
|
||||
}
|
||||
cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
|
||||
alpha ?
|
||||
Transparency.TRANSLUCENT:
|
||||
Transparency.OPAQUE,
|
||||
dataType);
|
||||
break;
|
||||
case TYPE_BYTE_BINARY:
|
||||
byte[] vals = { 0, (byte) 0xff };
|
||||
cm = new IndexColorModel(8, 2, vals, vals, vals);
|
||||
break;
|
||||
case TYPE_BYTE_INDEXED:
|
||||
String msg2 = "type not implemented yet";
|
||||
throw new UnsupportedOperationException(msg2);
|
||||
// FIXME: build color-cube and create color model
|
||||
}
|
||||
|
||||
init(cm,
|
||||
cm.createCompatibleWritableRaster(w, h),
|
||||
premultiplied,
|
||||
null, // no properties
|
||||
type
|
||||
);
|
||||
}
|
||||
|
||||
public BufferedImage(int w, int h, int type,
|
||||
IndexColorModel indexcolormodel)
|
||||
{
|
||||
if ((type != TYPE_BYTE_BINARY) && (type != TYPE_BYTE_INDEXED))
|
||||
throw new IllegalArgumentException("type must be binary or indexed");
|
||||
|
||||
init(indexcolormodel,
|
||||
indexcolormodel.createCompatibleWritableRaster(w, h),
|
||||
false, // not premultiplied (guess)
|
||||
null, // no properties
|
||||
type);
|
||||
}
|
||||
|
||||
public BufferedImage(ColorModel colormodel,
|
||||
WritableRaster writableraster,
|
||||
boolean premultiplied,
|
||||
Hashtable properties)
|
||||
{
|
||||
init(colormodel, writableraster, premultiplied, properties,
|
||||
TYPE_CUSTOM);
|
||||
// TODO: perhaps try to identify type?
|
||||
}
|
||||
|
||||
WritableRaster raster;
|
||||
ColorModel colorModel;
|
||||
Hashtable properties;
|
||||
boolean isPremultiplied;
|
||||
int type;
|
||||
|
||||
private void init(ColorModel cm,
|
||||
WritableRaster writableraster,
|
||||
boolean premultiplied,
|
||||
Hashtable properties,
|
||||
int type)
|
||||
{
|
||||
raster = writableraster;
|
||||
colorModel = cm;
|
||||
this.properties = properties;
|
||||
isPremultiplied = premultiplied;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
//public void addTileObserver(TileObserver tileobserver) {}
|
||||
|
||||
public void coerceData(boolean premultiplied)
|
||||
{
|
||||
colorModel = colorModel.coerceData(raster, premultiplied);
|
||||
}
|
||||
|
||||
public WritableRaster copyData(WritableRaster dest)
|
||||
{
|
||||
if (dest == null)
|
||||
dest = raster.createCompatibleWritableRaster(getMinX(), getMinY(),
|
||||
getWidth(),getHeight());
|
||||
|
||||
int x = dest.getMinX();
|
||||
int y = dest.getMinY();
|
||||
int w = dest.getWidth();
|
||||
int h = dest.getHeight();
|
||||
|
||||
// create a src child that has the right bounds...
|
||||
WritableRaster src =
|
||||
raster.createWritableChild(x, y, w, h, x, y,
|
||||
null // same bands
|
||||
);
|
||||
if (src.getSampleModel () instanceof ComponentSampleModel
|
||||
&& dest.getSampleModel () instanceof ComponentSampleModel)
|
||||
// Refer to ComponentDataBlitOp for optimized data blitting:
|
||||
ComponentDataBlitOp.INSTANCE.filter(src, dest);
|
||||
else
|
||||
{
|
||||
// slower path
|
||||
int samples[] = src.getPixels (x, y, w, h, (int [])null);
|
||||
dest.setPixels (x, y, w, h, samples);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
public Graphics2D createGraphics()
|
||||
{
|
||||
GraphicsEnvironment env;
|
||||
env = GraphicsEnvironment.getLocalGraphicsEnvironment ();
|
||||
return env.createGraphics (this);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
public WritableRaster getAlphaRaster()
|
||||
{
|
||||
return colorModel.getAlphaRaster(raster);
|
||||
}
|
||||
|
||||
public ColorModel getColorModel()
|
||||
{
|
||||
return colorModel;
|
||||
}
|
||||
|
||||
public Raster getData()
|
||||
{
|
||||
return copyData(null);
|
||||
/* TODO: this might be optimized by returning the same
|
||||
raster (not writable) as long as image data doesn't change. */
|
||||
}
|
||||
|
||||
public Raster getData(Rectangle rectangle)
|
||||
{
|
||||
WritableRaster dest =
|
||||
raster.createCompatibleWritableRaster(rectangle);
|
||||
return copyData(dest);
|
||||
}
|
||||
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
return createGraphics();
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return raster.getHeight();
|
||||
}
|
||||
|
||||
public int getHeight(ImageObserver imageobserver)
|
||||
{
|
||||
return getHeight();
|
||||
}
|
||||
|
||||
public int getMinTileX()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMinTileY()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMinX()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getMinY()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getNumXTiles()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getNumYTiles()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Object getProperty(String string)
|
||||
{
|
||||
if (properties == null)
|
||||
return null;
|
||||
return properties.get(string);
|
||||
}
|
||||
|
||||
public Object getProperty(String string, ImageObserver imageobserver)
|
||||
{
|
||||
return getProperty(string);
|
||||
}
|
||||
|
||||
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
// FIXME: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRGB(int x, int y)
|
||||
{
|
||||
Object rgbElem = raster.getDataElements(x, y,
|
||||
null // create as needed
|
||||
);
|
||||
return colorModel.getRGB(rgbElem);
|
||||
}
|
||||
|
||||
public int[] getRGB(int startX, int startY, int w, int h,
|
||||
int[] rgbArray,
|
||||
int offset, int scanlineStride)
|
||||
{
|
||||
if (rgbArray == null)
|
||||
{
|
||||
/*
|
||||
000000000000000000
|
||||
00000[#######----- [ = start
|
||||
-----########----- ] = end
|
||||
-----#######]00000
|
||||
000000000000000000 */
|
||||
int size = (h-1)*scanlineStride + w;
|
||||
rgbArray = new int[size];
|
||||
}
|
||||
|
||||
int endX = startX + w;
|
||||
int endY = startY + h;
|
||||
|
||||
/* *TODO*:
|
||||
Opportunity for optimization by examining color models...
|
||||
|
||||
Perhaps wrap the rgbArray up in a WritableRaster with packed
|
||||
sRGB color model and perform optimized rendering into the
|
||||
array. */
|
||||
|
||||
Object rgbElem = null;
|
||||
for (int y=startY; y<endY; y++)
|
||||
{
|
||||
int xoffset = offset;
|
||||
for (int x=startX; x<endX; x++)
|
||||
{
|
||||
int rgb;
|
||||
rgbElem = raster.getDataElements(x, y, rgbElem);
|
||||
rgb = colorModel.getRGB(rgbElem);
|
||||
rgbArray[xoffset++] = rgb;
|
||||
}
|
||||
offset += scanlineStride;
|
||||
}
|
||||
return rgbArray;
|
||||
}
|
||||
|
||||
public WritableRaster getRaster()
|
||||
{
|
||||
return raster;
|
||||
}
|
||||
|
||||
public SampleModel getSampleModel()
|
||||
{
|
||||
return raster.getSampleModel();
|
||||
}
|
||||
|
||||
public ImageProducer getSource()
|
||||
{
|
||||
return new ImageProducer() {
|
||||
|
||||
Vector consumers = new Vector();
|
||||
|
||||
public void addConsumer(ImageConsumer ic)
|
||||
{
|
||||
if(!consumers.contains(ic))
|
||||
consumers.add(ic);
|
||||
}
|
||||
|
||||
public boolean isConsumer(ImageConsumer ic)
|
||||
{
|
||||
return consumers.contains(ic);
|
||||
}
|
||||
|
||||
public void removeConsumer(ImageConsumer ic)
|
||||
{
|
||||
consumers.remove(ic);
|
||||
}
|
||||
|
||||
public void startProduction(ImageConsumer ic)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int stride = width;
|
||||
int offset = 0;
|
||||
int[] pixels = getRGB(x, y,
|
||||
width, height,
|
||||
(int[])null, offset, stride);
|
||||
ColorModel model = getColorModel();
|
||||
|
||||
consumers.add(ic);
|
||||
|
||||
for(int i=0;i<consumers.size();i++)
|
||||
{
|
||||
ImageConsumer c = (ImageConsumer) consumers.elementAt(i);
|
||||
c.setHints(ImageConsumer.SINGLEPASS);
|
||||
c.setDimensions(getWidth(), getHeight());
|
||||
c.setPixels(x, y, width, height, model, pixels, offset, stride);
|
||||
c.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic)
|
||||
{
|
||||
startProduction(ic);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public Vector getSources()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public BufferedImage getSubimage(int x, int y, int w, int h)
|
||||
{
|
||||
WritableRaster subRaster =
|
||||
getRaster().createWritableChild(x, y, w, h, 0, 0, null);
|
||||
|
||||
return new BufferedImage(getColorModel(),
|
||||
subRaster,
|
||||
isPremultiplied,
|
||||
properties);
|
||||
}
|
||||
|
||||
public Raster getTile(int tileX, int tileY)
|
||||
{
|
||||
return getWritableTile(tileX, tileY);
|
||||
}
|
||||
|
||||
public int getTileGridXOffset()
|
||||
{
|
||||
return 0; // according to javadocs
|
||||
}
|
||||
|
||||
public int getTileGridYOffset()
|
||||
{
|
||||
return 0; // according to javadocs
|
||||
}
|
||||
|
||||
public int getTileHeight()
|
||||
{
|
||||
return getHeight(); // image is one big tile
|
||||
}
|
||||
|
||||
public int getTileWidth()
|
||||
{
|
||||
return getWidth(); // image is one big tile
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return raster.getWidth();
|
||||
}
|
||||
|
||||
public int getWidth(ImageObserver imageobserver)
|
||||
{
|
||||
return getWidth();
|
||||
}
|
||||
|
||||
public WritableRaster getWritableTile(int tileX, int tileY)
|
||||
{
|
||||
isTileWritable(tileX, tileY); // for exception
|
||||
return raster;
|
||||
}
|
||||
|
||||
private static final Point[] tileIndices = { new Point() };
|
||||
|
||||
public Point[] getWritableTileIndices()
|
||||
{
|
||||
return tileIndices;
|
||||
}
|
||||
|
||||
public boolean hasTileWriters()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAlphaPremultiplied()
|
||||
{
|
||||
return isPremultiplied;
|
||||
}
|
||||
|
||||
public boolean isTileWritable(int tileX, int tileY)
|
||||
{
|
||||
if ((tileX != 0) || (tileY != 0))
|
||||
throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
|
||||
return true;
|
||||
}
|
||||
|
||||
public void releaseWritableTile(int tileX, int tileY)
|
||||
{
|
||||
isTileWritable(tileX, tileY); // for exception
|
||||
}
|
||||
|
||||
//public void removeTileObserver(TileObserver tileobserver) {}
|
||||
|
||||
public void setData(Raster src)
|
||||
{
|
||||
int x = src.getMinX();
|
||||
int y = src.getMinY();
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
|
||||
// create a dest child that has the right bounds...
|
||||
WritableRaster dest =
|
||||
raster.createWritableChild(x, y, w, h, x, y,
|
||||
null // same bands
|
||||
);
|
||||
|
||||
if (src.getSampleModel () instanceof ComponentSampleModel
|
||||
&& dest.getSampleModel () instanceof ComponentSampleModel)
|
||||
|
||||
// Refer to ComponentDataBlitOp for optimized data blitting:
|
||||
ComponentDataBlitOp.INSTANCE.filter(src, dest);
|
||||
else
|
||||
{
|
||||
// slower path
|
||||
int samples[] = src.getPixels (x, y, w, h, (int [])null);
|
||||
dest.setPixels (x, y, w, h, samples);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRGB(int x, int y, int argb)
|
||||
{
|
||||
Object rgbElem = colorModel.getDataElements(argb, null);
|
||||
raster.setDataElements(x, y, rgbElem);
|
||||
}
|
||||
|
||||
public void setRGB(int startX, int startY, int w, int h,
|
||||
int[] argbArray, int offset, int scanlineStride)
|
||||
{
|
||||
int endX = startX + w;
|
||||
int endY = startY + h;
|
||||
|
||||
Object rgbElem = null;
|
||||
for (int y=startY; y<endY; y++)
|
||||
{
|
||||
int xoffset = offset;
|
||||
for (int x=startX; x<endX; x++)
|
||||
{
|
||||
int argb = argbArray[xoffset++];
|
||||
rgbElem = colorModel.getDataElements(argb, rgbElem);
|
||||
raster.setDataElements(x, y, rgbElem);
|
||||
}
|
||||
offset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buf;
|
||||
|
||||
buf = new StringBuffer(/* estimated length */ 120);
|
||||
buf.append("BufferedImage@");
|
||||
buf.append(Integer.toHexString(hashCode()));
|
||||
buf.append(": type=");
|
||||
buf.append(type);
|
||||
buf.append(' ');
|
||||
buf.append(colorModel);
|
||||
buf.append(' ');
|
||||
buf.append(raster);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a tile observer. If the observer is already present, it receives
|
||||
* multiple notifications.
|
||||
*
|
||||
* @param to The TileObserver to add.
|
||||
*/
|
||||
public void addTileObserver (TileObserver to)
|
||||
{
|
||||
if (observers == null)
|
||||
observers = new Vector ();
|
||||
|
||||
observers.add (to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a tile observer. If the observer was not registered,
|
||||
* nothing happens. If the observer was registered for multiple
|
||||
* notifications, it is now registered for one fewer notification.
|
||||
*
|
||||
* @param to The TileObserver to remove.
|
||||
*/
|
||||
public void removeTileObserver (TileObserver to)
|
||||
{
|
||||
if (observers == null)
|
||||
return;
|
||||
|
||||
observers.remove (to);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* The BufferedImageFilter class wraps BufferedImageOp objects in a Filter.
|
||||
*
|
||||
* When pixels are pushed through the filter, we create a BufferedImage,
|
||||
* apply the BufferedImageOp, and pass the filtered pixels to the base class.
|
||||
*
|
||||
* @author jlquinn@optonline.net
|
||||
*/
|
||||
public class BufferedImageFilter extends ImageFilter implements Cloneable
|
||||
{
|
||||
private BufferedImageOp op;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public BufferedImageFilter(BufferedImageOp op)
|
||||
{
|
||||
super();
|
||||
if (op == null)
|
||||
throw new NullPointerException("BufferedImageFilter null"
|
||||
+ " op in constructor");
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the contained BufferedImageOp.
|
||||
*/
|
||||
public BufferedImageOp getBufferedImageOp()
|
||||
{
|
||||
return op;
|
||||
}
|
||||
|
||||
// FIXME: Definitely not sure this is the right thing. I'm not sure how to
|
||||
// create a compatible sample model that incorporates scansize != w. I
|
||||
// asume off is handled by the db itself.
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model,
|
||||
byte[] pixels, int off, int scansize)
|
||||
{
|
||||
// Create an input BufferedImage
|
||||
DataBufferByte db = new DataBufferByte(pixels, scansize * h + off, off);
|
||||
SampleModel sm = model.createCompatibleSampleModel(scansize, h);
|
||||
WritableRaster wr = new WritableRaster(sm, db, new Point(0, 0));
|
||||
BufferedImage in =
|
||||
new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
|
||||
BufferedImage out = op.createCompatibleDestImage(in, model);
|
||||
op.filter(in, out);
|
||||
DataBuffer dbout = out.getRaster().getDataBuffer();
|
||||
super.setPixels(0, 0, w, h, model, ((DataBufferByte)dbout).getData(), 0,
|
||||
scansize);
|
||||
}
|
||||
|
||||
// FIXME: Definitely not sure this is the right thing. I'm not sure how
|
||||
// to create a compatible sample model that incorporates
|
||||
// scansize != w. I asume off is handled by the db itself.
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model,
|
||||
int[] pixels, int off, int scansize)
|
||||
{
|
||||
// Create an input BufferedImage
|
||||
DataBufferInt db = new DataBufferInt(pixels, scansize * h + off, off);
|
||||
SampleModel sm = model.createCompatibleSampleModel(scansize, h);
|
||||
WritableRaster wr = new WritableRaster(sm, db, new Point(0, 0));
|
||||
BufferedImage in =
|
||||
new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
|
||||
BufferedImage out = op.createCompatibleDestImage(in, model);
|
||||
op.filter(in, out);
|
||||
DataBuffer dbout = out.getRaster().getDataBuffer();
|
||||
super.setPixels(0, 0, w, h, model, ((DataBufferInt)dbout).getData(), 0,
|
||||
scansize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* BufferedImageOp.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* NEEDS DOCUMENTATION
|
||||
*/
|
||||
public interface BufferedImageOp
|
||||
{
|
||||
BufferedImage filter(BufferedImage src, BufferedImage dst);
|
||||
Rectangle2D getBounds2D(BufferedImage src);
|
||||
BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM);
|
||||
Point2D getPoint2D(Point2D src, Point2D dst);
|
||||
RenderingHints getRenderingHints();
|
||||
} // interface BufferedImageOp
|
||||
@@ -0,0 +1,166 @@
|
||||
/* ByteLookupTable.java -- Java class for a pixel translation table.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* ByteLookupTable represents translation arrays for pixel values. It wraps
|
||||
* one or more data arrays for each layer (or component) in an image, such as
|
||||
* Alpha, R, G, and B. When doing translation, the offset is subtracted from
|
||||
* the pixel values to allow a subset of an array to be used.
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ByteLookupTable extends LookupTable
|
||||
{
|
||||
// Array of translation tables.
|
||||
private byte data[][];
|
||||
|
||||
/**
|
||||
* Creates a new <code>ByteLookupTable</code> instance.
|
||||
*
|
||||
* Offset is subtracted from pixel values when looking up in the translation
|
||||
* tables. If data.length is one, the same table is applied to all pixel
|
||||
* components.
|
||||
*
|
||||
* @param offset Offset to be subtracted.
|
||||
* @param data Array of lookup tables.
|
||||
* @exception IllegalArgumentException if offset < 0 or data.length < 1.
|
||||
*/
|
||||
public ByteLookupTable(int offset, byte[][] data)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
super(offset, data.length);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>ByteLookupTable</code> instance.
|
||||
*
|
||||
* Offset is subtracted from pixel values when looking up in the translation
|
||||
* table. The same table is applied to all pixel components.
|
||||
*
|
||||
* @param offset Offset to be subtracted.
|
||||
* @param data Lookup table for all components.
|
||||
* @exception IllegalArgumentException if offset < 0.
|
||||
*/
|
||||
public ByteLookupTable(int offset, byte[] data)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
super(offset, 1);
|
||||
this.data = new byte[][] {data};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the lookup tables.
|
||||
*
|
||||
* @return the tables
|
||||
*/
|
||||
public final byte[][] getTable()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return translated values for a pixel.
|
||||
*
|
||||
* For each value in the pixel src, use the value minus offset as an index
|
||||
* in the component array and copy the value there to the output for the
|
||||
* component. If dest is null, the output is a new array, otherwise the
|
||||
* translated values are written to dest. Dest can be the same array as
|
||||
* src.
|
||||
*
|
||||
* For example, if the pixel src is [2, 4, 3], and offset is 1, the output
|
||||
* is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
|
||||
* translation arrays.
|
||||
*
|
||||
* @param src Component values of a pixel.
|
||||
* @param dst Destination array for values, or null.
|
||||
* @return Translated values for the pixel.
|
||||
*/
|
||||
public int[] lookupPixel(int[] src, int[] dst)
|
||||
throws ArrayIndexOutOfBoundsException
|
||||
{
|
||||
if (dst == null)
|
||||
dst = new int[src.length];
|
||||
|
||||
if (data.length == 1)
|
||||
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];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return translated values for a pixel.
|
||||
*
|
||||
* For each value in the pixel src, use the value minus offset as an index
|
||||
* in the component array and copy the value there to the output for the
|
||||
* component. If dest is null, the output is a new array, otherwise the
|
||||
* translated values are written to dest. Dest can be the same array as
|
||||
* src.
|
||||
*
|
||||
* For example, if the pixel src is [2, 4, 3], and offset is 1, the output
|
||||
* is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
|
||||
* translation arrays.
|
||||
*
|
||||
* @param src Component values of a pixel.
|
||||
* @param dst Destination array for values, or null.
|
||||
* @return Translated values for the pixel.
|
||||
*/
|
||||
public byte[] lookupPixel(byte[] src, byte[] dst)
|
||||
throws ArrayIndexOutOfBoundsException
|
||||
{
|
||||
if (dst == null)
|
||||
dst = new byte[src.length];
|
||||
|
||||
if (data.length == 1)
|
||||
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];
|
||||
|
||||
return dst;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/* ColorModel.java --
|
||||
Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* ColorConvertOp is a filter for converting an image from one colorspace to
|
||||
* another colorspace. The filter can convert the image through a sequence
|
||||
* of colorspaces or just from source to destination.
|
||||
*
|
||||
* Color conversion is done on the color components without alpha. Thus
|
||||
* if a BufferedImage has alpha premultiplied, this is divided out before
|
||||
* color conversion, and premultiplication applied if the destination
|
||||
* requires it.
|
||||
*
|
||||
* Color rendering and dithering hints may be applied if specified. This is
|
||||
* likely platform-dependent.
|
||||
*
|
||||
* @author jlquinn@optonline.net
|
||||
*/
|
||||
public class ColorConvertOp implements BufferedImageOp, RasterOp
|
||||
{
|
||||
private ColorSpace srccs;
|
||||
private ColorSpace dstcs;
|
||||
private RenderingHints hints;
|
||||
private ICC_Profile[] profiles;
|
||||
private ColorSpace[] spaces;
|
||||
private boolean rasterValid;
|
||||
|
||||
|
||||
/**
|
||||
* Convert BufferedImage through a ColorSpace.
|
||||
*
|
||||
* This filter version is only valid for BufferedImages. The source image
|
||||
* is converted to cspace. If the destination is not null, it is then
|
||||
* converted to the destination colorspace. Normally this filter will only
|
||||
* be used with a null destination.
|
||||
*
|
||||
* @param cspace The target color space.
|
||||
* @param hints Rendering hints to use in conversion, or null.
|
||||
*/
|
||||
public ColorConvertOp(ColorSpace cspace, RenderingHints hints)
|
||||
{
|
||||
if (cspace == null)
|
||||
throw new NullPointerException();
|
||||
spaces = new ColorSpace[]{cspace};
|
||||
this.hints = hints;
|
||||
rasterValid = false;
|
||||
}
|
||||
|
||||
public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
|
||||
RenderingHints hints)
|
||||
{
|
||||
if (srcCspace == null || dstCspace == null)
|
||||
throw new NullPointerException();
|
||||
spaces = new ColorSpace[]{srcCspace, dstCspace};
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from a source image destination image color space.
|
||||
*
|
||||
* This constructor builds a ColorConvertOp from an array of ICC_Profiles.
|
||||
* The source image will be converted through the sequence of color spaces
|
||||
* defined by the profiles. If the sequence of profiles doesn't give a
|
||||
* well-defined conversion, throws IllegalArgumentException.
|
||||
*
|
||||
* NOTE: Sun's docs don't clearly define what a well-defined conversion is
|
||||
* - or perhaps someone smarter can come along and sort it out.
|
||||
*
|
||||
* For BufferedImages, when the first and last profiles match the
|
||||
* requirements of the source and destination color space respectively, the
|
||||
* corresponding conversion is unnecessary. TODO: code this up. I don't
|
||||
* yet understand how you determine this.
|
||||
*
|
||||
* For Rasters, the first and last profiles must have the same number of
|
||||
* bands as the source and destination Rasters, respectively. If this is
|
||||
* not the case, or there fewer than 2 profiles, an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* @param profiles
|
||||
* @param hints
|
||||
*/
|
||||
public ColorConvertOp(ICC_Profile[] profiles, RenderingHints hints)
|
||||
{
|
||||
if (profiles == null)
|
||||
throw new NullPointerException();
|
||||
this.hints = hints;
|
||||
this.profiles = profiles;
|
||||
// TODO: Determine if this is well-defined.
|
||||
// Create colorspace array with space for src and dest colorspace
|
||||
spaces = new ColorSpace[profiles.length];
|
||||
for (int i = 0; i < profiles.length; i++)
|
||||
spaces[i] = new ICC_ColorSpace(profiles[i]);
|
||||
}
|
||||
|
||||
/** Convert from source image color space to destination image color space.
|
||||
*
|
||||
* Only valid for BufferedImage objects, this Op converts from the source
|
||||
* color space to the destination color space. The destination can't be
|
||||
* null for this operation.
|
||||
*
|
||||
* @param hints Rendering hints to use during conversion, or null.
|
||||
*/
|
||||
public ColorConvertOp(RenderingHints hints)
|
||||
{
|
||||
this.hints = hints;
|
||||
srccs = null;
|
||||
dstcs = null;
|
||||
rasterValid = false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage,
|
||||
java.awt.image.BufferedImage)
|
||||
*/
|
||||
public final BufferedImage filter(BufferedImage src, BufferedImage dst)
|
||||
{
|
||||
// TODO: The plan is to create a scanline buffer for intermediate buffers.
|
||||
// For now we just suck it up and create intermediate buffers.
|
||||
|
||||
if (dst == null && spaces.length == 0)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
// Make sure input isn't premultiplied by alpha
|
||||
if (src.isAlphaPremultiplied())
|
||||
{
|
||||
BufferedImage tmp = createCompatibleDestImage(src, src.getColorModel());
|
||||
copyimage(src, tmp);
|
||||
tmp.coerceData(false);
|
||||
src = tmp;
|
||||
}
|
||||
|
||||
ColorModel scm = src.getColorModel();
|
||||
for (int i = 0; i < spaces.length; i++)
|
||||
{
|
||||
ColorModel cm = scm.cloneColorModel(spaces[i]);
|
||||
BufferedImage tmp = createCompatibleDestImage(src, cm);
|
||||
copyimage(src, tmp);
|
||||
src = tmp;
|
||||
}
|
||||
|
||||
// Intermediate conversions leave result in src
|
||||
if (dst == null)
|
||||
return src;
|
||||
|
||||
// Apply final conversion
|
||||
copyimage(src, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage(BufferedImage src,
|
||||
ColorModel dstCM)
|
||||
{
|
||||
// FIXME: set properties to those in src
|
||||
return new BufferedImage(dstCM,
|
||||
src.getRaster().createCompatibleWritableRaster(),
|
||||
src.isPremultiplied,
|
||||
null);
|
||||
}
|
||||
|
||||
public final ICC_Profile[] getICC_Profiles()
|
||||
{
|
||||
return profiles;
|
||||
}
|
||||
|
||||
/** Return the rendering hints for this op. */
|
||||
public final RenderingHints getRenderingHints()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
|
||||
*/
|
||||
public final WritableRaster filter(Raster src, WritableRaster dest)
|
||||
{
|
||||
if (!rasterValid)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
// Need to iterate through each color space - there must be at least 2
|
||||
for (int i = 1; i < spaces.length - 1; i++)
|
||||
{
|
||||
// FIXME: this is wrong. tmp needs to have the same number of bands as
|
||||
// spaces[i] has.
|
||||
WritableRaster tmp = createCompatibleDestRaster(src);
|
||||
copyraster(src, spaces[i - 1], tmp, spaces[i]);
|
||||
src = tmp;
|
||||
}
|
||||
|
||||
// FIXME: this is wrong. dst needs to have the same number of bands as
|
||||
// spaces[i] has.
|
||||
if (dest == null)
|
||||
dest = createCompatibleDestRaster(src);
|
||||
copyraster(src, spaces[spaces.length - 2],
|
||||
dest, spaces[spaces.length - 1]);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src)
|
||||
{
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
|
||||
/** Return corresponding destination point for source point.
|
||||
*
|
||||
* LookupOp will return the value of src unchanged.
|
||||
* @param src The source point.
|
||||
* @param dst The destination point.
|
||||
* @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
|
||||
*/
|
||||
public final Point2D getPoint2D(Point2D src, Point2D dst)
|
||||
{
|
||||
if (dst == null) return (Point2D)src.clone();
|
||||
dst.setLocation(src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
|
||||
*/
|
||||
public final Rectangle2D getBounds2D(BufferedImage src)
|
||||
{
|
||||
return src.getRaster().getBounds();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
|
||||
*/
|
||||
public final Rectangle2D getBounds2D(Raster src)
|
||||
{
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
// According to Sven de Marothy, we need to copy the src into the dest
|
||||
// using Graphics2D, in order to use the rendering hints.
|
||||
private void copyimage(BufferedImage src, BufferedImage dst)
|
||||
{
|
||||
Graphics2D gg = dst.createGraphics();
|
||||
gg.setRenderingHints(hints);
|
||||
gg.drawImage(src, 0, 0, null);
|
||||
gg.dispose();
|
||||
}
|
||||
|
||||
private void copyraster(Raster src, ColorSpace scs, WritableRaster dst,
|
||||
ColorSpace dcs)
|
||||
{
|
||||
float[] sbuf = new float[src.getNumBands()];
|
||||
|
||||
if (hints.get(RenderingHints.KEY_COLOR_RENDERING) ==
|
||||
RenderingHints.VALUE_COLOR_RENDER_QUALITY)
|
||||
{
|
||||
// use cie for accuracy
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
|
||||
dst.setPixel(x, y,
|
||||
dcs.fromCIEXYZ(scs.toCIEXYZ(src.getPixel(x, y, sbuf))));
|
||||
}
|
||||
else
|
||||
{
|
||||
// use rgb - it's probably faster
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
|
||||
dst.setPixel(x, y,
|
||||
dcs.fromRGB(scs.toRGB(src.getPixel(x, y, sbuf))));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,758 @@
|
||||
/* ColorModel.java --
|
||||
Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A color model operates with colors in several formats:
|
||||
*
|
||||
* <ul>
|
||||
* <li>normalized: component samples are in range [0.0, 1.0].</li>
|
||||
*
|
||||
* <li>color model pixel value: all the color component samples for a
|
||||
* sigle pixel packed/encoded in a way natural for the color
|
||||
* model.</li>
|
||||
*
|
||||
* <li>color model pixel int value: only makes sense if the natural
|
||||
* encoding of a single pixel can fit in a single int value.</li>
|
||||
*
|
||||
* <li>array of transferType containing a single pixel: the pixel is
|
||||
* encoded in the natural way of the color model, taking up as many
|
||||
* array elements as needed.</li>
|
||||
*
|
||||
* <li>sRGB pixel int value: a pixel in sRGB color space, encoded in
|
||||
* default 0xAARRGGBB format, assumed not alpha premultiplied.</li>
|
||||
*
|
||||
* <li>single [0, 255] scaled int samples from default sRGB color
|
||||
* space. These are always assumed to be alpha non-premultiplied.</li>
|
||||
*
|
||||
* <li>arrays of unnormalized component samples of single pixel: these
|
||||
* samples are scaled and multiplied according to the color model, but
|
||||
* is otherwise not packed or encoded. Each element of the array is one
|
||||
* separate component sample. The color model only operate on the
|
||||
* components from one pixel at a time, but using offsets, allows
|
||||
* manipulation of arrays that contain the components of more than one
|
||||
* pixel.</li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public abstract class ColorModel implements Transparency
|
||||
{
|
||||
protected int pixel_bits;
|
||||
protected int transferType;
|
||||
|
||||
int[] bits;
|
||||
ColorSpace cspace;
|
||||
int transparency;
|
||||
boolean hasAlpha;
|
||||
boolean isAlphaPremultiplied;
|
||||
|
||||
static int[] nArray(int value, int times)
|
||||
{
|
||||
int[] array = new int[times];
|
||||
java.util.Arrays.fill(array, value);
|
||||
return array;
|
||||
}
|
||||
|
||||
static byte[] nArray(byte value, int times)
|
||||
{
|
||||
byte[] array = new byte[times];
|
||||
java.util.Arrays.fill(array, value);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the default color model. The default color model
|
||||
* can be obtained by calling <code>getRGBdefault</code> of this
|
||||
* class.
|
||||
* @param bits the number of bits wide used for bit size of pixel values
|
||||
*/
|
||||
public ColorModel(int bits)
|
||||
{
|
||||
this(bits * 4, // total bits, sRGB, four channels
|
||||
nArray(bits, 4), // bits for each channel
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
|
||||
true, // has alpha
|
||||
false, // not premultiplied
|
||||
TRANSLUCENT,
|
||||
Buffers.smallestAppropriateTransferType(bits * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ColorModel that translates pixel values to
|
||||
* color/alpha components.
|
||||
*
|
||||
* @exception IllegalArgumentException If the length of the bit array is less
|
||||
* than the number of color or alpha components in this ColorModel, or if the
|
||||
* transparency is not a valid value, or if the sum of the number of bits in
|
||||
* bits is less than 1 or if any of the elements in bits is less than 0.
|
||||
*/
|
||||
protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
|
||||
boolean hasAlpha, boolean isAlphaPremultiplied,
|
||||
int transparency, int transferType)
|
||||
{
|
||||
int bits_sum = 0;
|
||||
for (int i = 0; i < bits.length; i++)
|
||||
{
|
||||
if (bits [i] < 0)
|
||||
throw new IllegalArgumentException ();
|
||||
|
||||
bits_sum |= bits [i];
|
||||
}
|
||||
|
||||
if ((bits.length < cspace.getNumComponents())
|
||||
|| (bits_sum < 1))
|
||||
throw new IllegalArgumentException ();
|
||||
|
||||
this.pixel_bits = pixel_bits;
|
||||
this.bits = bits;
|
||||
this.cspace = cspace;
|
||||
this.hasAlpha = hasAlpha;
|
||||
this.isAlphaPremultiplied = isAlphaPremultiplied;
|
||||
this.transparency = transparency;
|
||||
this.transferType = transferType;
|
||||
}
|
||||
|
||||
// This is a hook for ColorConvertOp to create a colormodel with
|
||||
// a new colorspace
|
||||
ColorModel cloneColorModel(ColorSpace cspace)
|
||||
{
|
||||
Class cls = this.getClass();
|
||||
ColorModel cm;
|
||||
try {
|
||||
// This constructor will exist.
|
||||
Constructor ctor =
|
||||
cls.getConstructor(new Class[]{int.class, int[].class,
|
||||
ColorSpace.class, boolean.class,
|
||||
boolean.class, int.class, int.class});
|
||||
cm = (ColorModel)ctor.
|
||||
newInstance(new Object[]{new Integer(pixel_bits),
|
||||
bits, cspace, Boolean.valueOf(hasAlpha),
|
||||
Boolean.valueOf(isAlphaPremultiplied),
|
||||
new Integer(transparency),
|
||||
new Integer(transferType)});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
public void finalize()
|
||||
{
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default color model which in Sun's case is an instance
|
||||
* of <code>DirectColorModel</code>.
|
||||
*/
|
||||
public static ColorModel getRGBdefault()
|
||||
{
|
||||
return new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
|
||||
}
|
||||
|
||||
public final boolean hasAlpha()
|
||||
{
|
||||
return hasAlpha;
|
||||
}
|
||||
|
||||
public final boolean isAlphaPremultiplied()
|
||||
{
|
||||
return isAlphaPremultiplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get get number of bits wide used for the bit size of pixel values
|
||||
*/
|
||||
public int getPixelSize()
|
||||
{
|
||||
return pixel_bits;
|
||||
}
|
||||
|
||||
public int getComponentSize(int componentIdx)
|
||||
{
|
||||
return bits[componentIdx];
|
||||
}
|
||||
|
||||
public int[] getComponentSize()
|
||||
{
|
||||
return bits;
|
||||
}
|
||||
|
||||
public int getTransparency()
|
||||
{
|
||||
return transparency;
|
||||
}
|
||||
|
||||
public int getNumComponents()
|
||||
{
|
||||
return getNumColorComponents() + (hasAlpha ? 1 : 0);
|
||||
}
|
||||
|
||||
public int getNumColorComponents()
|
||||
{
|
||||
return cspace.getNumComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pixel value to sRGB and extract red int sample scaled
|
||||
* to range [0, 255].
|
||||
*
|
||||
* @param pixel pixel value that will be interpreted according to
|
||||
* the color model, (assumed alpha premultiplied if color model says
|
||||
* so.)
|
||||
*
|
||||
* @return red sample scaled to range [0, 255], from default color
|
||||
* space sRGB, alpha non-premultiplied.
|
||||
*/
|
||||
public abstract int getRed(int pixel);
|
||||
|
||||
/**
|
||||
* Converts pixel value to sRGB and extract green int sample
|
||||
* scaled to range [0, 255].
|
||||
*
|
||||
* @see #getRed(int)
|
||||
*/
|
||||
public abstract int getGreen(int pixel);
|
||||
|
||||
/**
|
||||
* Converts pixel value to sRGB and extract blue int sample
|
||||
* scaled to range [0, 255].
|
||||
*
|
||||
* @see #getRed(int)
|
||||
*/
|
||||
public abstract int getBlue(int pixel);
|
||||
|
||||
/**
|
||||
* Extract alpha int sample from pixel value, scaled to [0, 255].
|
||||
*
|
||||
* @param pixel pixel value that will be interpreted according to
|
||||
* the color model.
|
||||
*
|
||||
* @return alpha sample, scaled to range [0, 255].
|
||||
*/
|
||||
public abstract int getAlpha(int pixel);
|
||||
|
||||
/**
|
||||
* Converts a pixel int value of the color space of the color
|
||||
* model to a sRGB pixel int value.
|
||||
*
|
||||
* This method is typically overriden in subclasses to provide a
|
||||
* more efficient implementation.
|
||||
*
|
||||
* @param pixel pixel value that will be interpreted according to
|
||||
* the color model.
|
||||
*
|
||||
* @return a pixel in sRGB color space, encoded in default
|
||||
* 0xAARRGGBB format. */
|
||||
public int getRGB(int pixel)
|
||||
{
|
||||
return
|
||||
((getAlpha(pixel) & 0xff) << 24) |
|
||||
(( getRed(pixel) & 0xff) << 16) |
|
||||
((getGreen(pixel) & 0xff) << 8) |
|
||||
(( getBlue(pixel) & 0xff) << 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In this color model we know that the whole pixel value will
|
||||
* always be contained within the first element of the pixel
|
||||
* array.
|
||||
*/
|
||||
final int getPixelFromArray(Object inData) {
|
||||
DataBuffer data =
|
||||
Buffers.createBufferFromData(transferType, inData, 1);
|
||||
Object da = Buffers.getData(data);
|
||||
|
||||
return data.getElem(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pixel in the given array to sRGB and extract blue int
|
||||
* sample scaled to range [0-255].
|
||||
*
|
||||
* This method is typically overriden in subclasses to provide a
|
||||
* more efficient implementation.
|
||||
*
|
||||
* @param inData array of transferType containing a single pixel. The
|
||||
* pixel should be encoded in the natural way of the color model.
|
||||
*/
|
||||
public int getRed(Object inData)
|
||||
{
|
||||
return getRed(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRed(Object)
|
||||
*/
|
||||
public int getGreen(Object inData)
|
||||
{
|
||||
return getGreen(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRed(Object)
|
||||
*/
|
||||
public int getBlue(Object inData) {
|
||||
return getBlue(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRed(Object)
|
||||
*/
|
||||
public int getAlpha(Object inData) {
|
||||
return getAlpha(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a pixel in the given array of the color space of the
|
||||
* color model to an sRGB pixel int value.
|
||||
*
|
||||
* <p>This method performs the inverse function of
|
||||
* <code>getDataElements(int rgb, Object pixel)</code>.
|
||||
* I.e. <code>(rgb == cm.getRGB(cm.getDataElements(rgb,
|
||||
* null)))</code>.
|
||||
*
|
||||
* @param inData array of transferType containing a single pixel. The
|
||||
* pixel should be encoded in the natural way of the color model.
|
||||
*
|
||||
* @return a pixel in sRGB color space, encoded in default
|
||||
* 0xAARRGGBB format.
|
||||
*
|
||||
* @see #getDataElements(int, Object)
|
||||
*/
|
||||
public int getRGB(Object inData)
|
||||
{
|
||||
return
|
||||
((getAlpha(inData) & 0xff) << 24) |
|
||||
(( getRed(inData) & 0xff) << 16) |
|
||||
((getGreen(inData) & 0xff) << 8) |
|
||||
(( getBlue(inData) & 0xff) << 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an sRGB pixel int value to an array containing a
|
||||
* single pixel of the color space of the color model.
|
||||
*
|
||||
* <p>This method performs the inverse function of
|
||||
* <code>getRGB(Object inData)</code>.
|
||||
*
|
||||
* Outline of conversion process:
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li>Convert rgb to normalized [0.0, 1.0] sRGB values.</li>
|
||||
*
|
||||
* <li>Convert to color space components using fromRGB in
|
||||
* ColorSpace.</li>
|
||||
*
|
||||
* <li>If color model has alpha and should be premultiplied,
|
||||
* multiply color space components with alpha value</li>
|
||||
*
|
||||
* <li>Scale the components to the correct number of bits.</li>
|
||||
*
|
||||
* <li>Arrange the components in the output array</li>
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* @param rgb The color to be converted to dataElements. A pixel
|
||||
* in sRGB color space, encoded in default 0xAARRGGBB format,
|
||||
* assumed not alpha premultiplied.
|
||||
*
|
||||
* @param pixel to avoid needless creation of arrays, an array to
|
||||
* use to return the pixel can be given. If null, a suitable array
|
||||
* will be created.
|
||||
*
|
||||
* @return An array of transferType values representing the color,
|
||||
* in the color model format. The color model defines whether the
|
||||
*
|
||||
* @see #getRGB(Object)
|
||||
*/
|
||||
public Object getDataElements(int rgb, Object pixel)
|
||||
{
|
||||
// subclasses has to implement this method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills an array with the unnormalized component samples from a
|
||||
* pixel value. I.e. decompose the pixel, but not perform any
|
||||
* color conversion.
|
||||
*
|
||||
* This method is typically overriden in subclasses to provide a
|
||||
* more efficient implementation.
|
||||
*
|
||||
* @param pixel pixel value encoded according to the color model.
|
||||
*
|
||||
* @return arrays of unnormalized component samples of single
|
||||
* pixel. The scale and multiplication state of the samples are
|
||||
* according to the color model. Each component sample is stored
|
||||
* as a separate element in the array.
|
||||
*/
|
||||
public int[] getComponents(int pixel, int[] components, int offset)
|
||||
{
|
||||
// subclasses has to implement this method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills an array with the unnormalized component samples from an
|
||||
* array of transferType containing a single pixel. I.e. decompose
|
||||
* the pixel, but not perform any color conversion.
|
||||
*
|
||||
* This method is typically overriden in subclasses to provide a
|
||||
* more efficient implementation.
|
||||
*
|
||||
* @param array of transferType containing a single pixel. The
|
||||
* pixel should be encoded in the natural way of the color model.
|
||||
*
|
||||
* @return arrays of unnormalized component samples of single
|
||||
* pixel. The scale and multiplication state of the samples are
|
||||
* according to the color model. Each component sample is stored
|
||||
* as a separate element in the array.
|
||||
*/
|
||||
public int[] getComponents(Object pixel, int[] components, int offset)
|
||||
{
|
||||
// subclasses has to implement this method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert normalized components to unnormalized components.
|
||||
*/
|
||||
public int[] getUnnormalizedComponents(float[] normComponents,
|
||||
int normOffset,
|
||||
int[] components,
|
||||
int offset)
|
||||
{
|
||||
int numComponents = getNumComponents();
|
||||
if (components == null)
|
||||
{
|
||||
components = new int[offset + numComponents];
|
||||
}
|
||||
|
||||
for (int i=0; i<numComponents; i++)
|
||||
{
|
||||
float in = normComponents[normOffset++];
|
||||
int out = (int) (in * ((1<<getComponentSize(i)) - 1));
|
||||
components[offset++] = out;
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert unnormalized components to normalized components.
|
||||
*/
|
||||
public float[] getNormalizedComponents(int[] components,
|
||||
int offset,
|
||||
float[] normComponents,
|
||||
int normOffset)
|
||||
{
|
||||
int numComponents = getNumComponents();
|
||||
if (normComponents == null)
|
||||
{
|
||||
normComponents = new float[normOffset + numComponents];
|
||||
}
|
||||
|
||||
for (int i=0; i<numComponents; i++)
|
||||
{
|
||||
float in = components[offset++];
|
||||
float out = in / ((1<<getComponentSize(i)) - 1);
|
||||
normComponents[normOffset++] = out;
|
||||
}
|
||||
return normComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert unnormalized components to normalized components.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public float[] getNormalizedComponents (Object pixel,
|
||||
float[] normComponents,
|
||||
int normOffset)
|
||||
{
|
||||
// subclasses has to implement this method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the unnormalized component samples from an array to a
|
||||
* pixel value. I.e. composes the pixel from component samples, but
|
||||
* does not perform any color conversion or scaling of the samples.
|
||||
*
|
||||
* This method performs the inverse function of
|
||||
* <code>getComponents(int pixel, int[] components,
|
||||
* int offset)</code>. I.e.
|
||||
*
|
||||
* <code>(pixel == cm.getDataElement(cm.getComponents(pixel, null,
|
||||
* 0), 0))</code>.
|
||||
*
|
||||
* This method is overriden in subclasses since this abstract class throws
|
||||
* UnsupportedOperationException().
|
||||
*
|
||||
* @param components Array of unnormalized component samples of single
|
||||
* pixel. The scale and multiplication state of the samples are according
|
||||
* to the color model. Each component sample is stored as a separate element
|
||||
* in the array.
|
||||
* @param offset Position of the first value of the pixel in components.
|
||||
*
|
||||
* @return pixel value encoded according to the color model.
|
||||
*/
|
||||
public int getDataElement(int[] components, int offset)
|
||||
{
|
||||
// subclasses have to implement this method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the normalized component samples from an array to a pixel
|
||||
* value. I.e. composes the pixel from component samples, but does not
|
||||
* perform any color conversion or scaling of the samples.
|
||||
*
|
||||
* This method is typically overriden in subclasses to provide a
|
||||
* more efficient implementation. The method provided by this abstract
|
||||
* class converts the components to unnormalized form and returns
|
||||
* getDataElement(int[], int).
|
||||
*
|
||||
* @param components Array of normalized component samples of single pixel.
|
||||
* The scale and multiplication state of the samples are according to the
|
||||
* color model. Each component sample is stored as a separate element in the
|
||||
* array.
|
||||
* @param offset Position of the first value of the pixel in components.
|
||||
*
|
||||
* @return pixel value encoded according to the color model.
|
||||
* @since 1.4
|
||||
*/
|
||||
public int getDataElement (float[] components, int offset)
|
||||
{
|
||||
return
|
||||
getDataElement(getUnnormalizedComponents(components, offset, null, 0),
|
||||
0);
|
||||
}
|
||||
|
||||
public Object getDataElements(int[] components, int offset, Object obj)
|
||||
{
|
||||
// subclasses have to implement this method.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the normalized component samples from an array to an array of
|
||||
* TransferType values. I.e. composes the pixel from component samples, but
|
||||
* does not perform any color conversion or scaling of the samples.
|
||||
*
|
||||
* If obj is null, a new array of TransferType is allocated and returned.
|
||||
* Otherwise the results are stored in obj and obj is returned. If obj is
|
||||
* not long enough, ArrayIndexOutOfBounds is thrown. If obj is not an array
|
||||
* of primitives, ClassCastException is thrown.
|
||||
*
|
||||
* This method is typically overriden in subclasses to provide a
|
||||
* more efficient implementation. The method provided by this abstract
|
||||
* class converts the components to unnormalized form and returns
|
||||
* getDataElement(int[], int, Object).
|
||||
*
|
||||
* @param components Array of normalized component samples of single pixel.
|
||||
* The scale and multiplication state of the samples are according to the
|
||||
* color model. Each component sample is stored as a separate element in the
|
||||
* array.
|
||||
* @param offset Position of the first value of the pixel in components.
|
||||
* @param obj Array of TransferType or null.
|
||||
*
|
||||
* @return pixel value encoded according to the color model.
|
||||
* @throws ArrayIndexOutOfBounds
|
||||
* @throws ClassCastException
|
||||
* @since 1.4
|
||||
*/
|
||||
public Object getDataElements(float[] components, int offset, Object obj)
|
||||
{
|
||||
return
|
||||
getDataElements(getUnnormalizedComponents(components, offset, null, 0),
|
||||
0, obj);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (!(obj instanceof ColorModel)) return false;
|
||||
|
||||
ColorModel o = (ColorModel) obj;
|
||||
return
|
||||
(pixel_bits == o.pixel_bits) &&
|
||||
(transferType == o.transferType) &&
|
||||
(transparency == o.transparency) &&
|
||||
(hasAlpha == o.hasAlpha) &&
|
||||
(isAlphaPremultiplied == o.isAlphaPremultiplied) &&
|
||||
Arrays.equals(bits, o.bits) &&
|
||||
(cspace.equals(o.cspace));
|
||||
}
|
||||
|
||||
public final ColorSpace getColorSpace()
|
||||
{
|
||||
return cspace;
|
||||
}
|
||||
|
||||
// Typically overridden
|
||||
public ColorModel coerceData(WritableRaster raster,
|
||||
boolean isAlphaPremultiplied)
|
||||
{
|
||||
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
|
||||
return this;
|
||||
|
||||
int w = raster.getWidth();
|
||||
int h = raster.getHeight();
|
||||
int x = raster.getMinX();
|
||||
int y = raster.getMinY();
|
||||
int size = w*h;
|
||||
int numColors = getNumColorComponents();
|
||||
int numComponents = getNumComponents();
|
||||
int alphaScale = (1<<getComponentSize(numColors)) - 1;
|
||||
double[] pixels = raster.getPixels(x, y, w, h, (double[]) null);
|
||||
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
double alpha = pixels[i*numComponents+numColors]*alphaScale;
|
||||
for (int c=0; c<numColors; c++)
|
||||
{
|
||||
int offset = i*numComponents+c;
|
||||
if (isAlphaPremultiplied)
|
||||
pixels[offset] = pixels[offset]/alpha;
|
||||
else
|
||||
pixels[offset] = pixels[offset]*alpha;
|
||||
}
|
||||
}
|
||||
|
||||
raster.setPixels(0, 0, w, h, pixels);
|
||||
|
||||
// FIXME: what can we return?
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given raster has a compatible data-layout (SampleModel).
|
||||
* @param raster The Raster to test.
|
||||
* @return true if raster is compatible.
|
||||
*/
|
||||
public boolean isCompatibleRaster(Raster raster)
|
||||
{
|
||||
SampleModel sampleModel = raster.getSampleModel();
|
||||
return isCompatibleSampleModel(sampleModel);
|
||||
}
|
||||
|
||||
// Typically overridden
|
||||
public WritableRaster createCompatibleWritableRaster(int w, int h)
|
||||
{
|
||||
return new WritableRaster(createCompatibleSampleModel(w, h),
|
||||
new Point(0, 0));
|
||||
}
|
||||
|
||||
// Typically overridden
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// Typically overridden
|
||||
public boolean isCompatibleSampleModel(SampleModel sm)
|
||||
{
|
||||
return sm.getTransferType() == transferType;
|
||||
}
|
||||
|
||||
public final int getTransferType ()
|
||||
{
|
||||
return transferType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must override this method if it is possible for the
|
||||
* color model to have an alpha channel.
|
||||
*
|
||||
* @return null, as per JDK 1.3 doc. Subclasses will only return
|
||||
* null if no alpha raster exists.
|
||||
*/
|
||||
public WritableRaster getAlphaRaster(WritableRaster raster)
|
||||
{
|
||||
return null;
|
||||
|
||||
/* It is a mystery to me why we couldn't use the following code...
|
||||
|
||||
|
||||
if (!hasAlpha()) return null;
|
||||
|
||||
SampleModel sm = raster.getSampleModel();
|
||||
int[] alphaBand = { sm.getNumBands() - 1 };
|
||||
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
|
||||
DataBuffer buffer = raster.getDataBuffer();
|
||||
Point origin = new Point(0, 0);
|
||||
return Raster.createWritableRaster(alphaModel, buffer, origin);
|
||||
|
||||
|
||||
...here, and avoided overriding the method in subclasses,
|
||||
but the Sun docs state that this method always will return
|
||||
null, and that overriding is required. Oh, well.
|
||||
*/
|
||||
}
|
||||
|
||||
String stringParam()
|
||||
{
|
||||
return "pixel_bits=" + pixel_bits +
|
||||
", cspace=" + cspace +
|
||||
", transferType=" + transferType +
|
||||
", transparency=" + transparency +
|
||||
", hasAlpha=" + hasAlpha +
|
||||
", isAlphaPremultiplied=" + isAlphaPremultiplied;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + "[" + stringParam() + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
/* ComponentColorModel.java --
|
||||
Copyright (C) 2000, 2002, 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.color.ColorSpace;
|
||||
|
||||
public class ComponentColorModel extends ColorModel
|
||||
{
|
||||
private static int sum(int[] values)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i=0; i<values.length; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
public ComponentColorModel(ColorSpace colorSpace, int[] bits,
|
||||
boolean hasAlpha,
|
||||
boolean isAlphaPremultiplied,
|
||||
int transparency, int transferType)
|
||||
{
|
||||
super(sum(bits), bits, colorSpace, hasAlpha, isAlphaPremultiplied,
|
||||
transparency, transferType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ComponentColorModel.
|
||||
*
|
||||
* This constructor makes all bits of each sample significant, so for a
|
||||
* transferType of DataBuffer.BYTE, the bits per sample is 8, etc. If
|
||||
* both hasAlpha and isAlphaPremultiplied are true, color samples are
|
||||
* assumed to be premultiplied by the alpha component. Transparency may be
|
||||
* one of OPAQUE, BITMASK, or TRANSLUCENT.
|
||||
*
|
||||
* @param colorSpace The colorspace for this color model.
|
||||
* @param hasAlpha True if there is an alpha component.
|
||||
* @param isAlphaPremultiplied True if colors are already multiplied by
|
||||
* alpha.
|
||||
* @param transparency The type of alpha values.
|
||||
* @param transferType Data type of pixel sample values.
|
||||
* @since 1.4
|
||||
*/
|
||||
public ComponentColorModel(ColorSpace colorSpace,
|
||||
boolean hasAlpha,
|
||||
boolean isAlphaPremultiplied,
|
||||
int transparency, int transferType)
|
||||
{
|
||||
this(colorSpace, null, hasAlpha, isAlphaPremultiplied,
|
||||
transparency, transferType);
|
||||
}
|
||||
|
||||
public int getRed(int pixel)
|
||||
{
|
||||
if (getNumComponents()>1) throw new IllegalArgumentException();
|
||||
return (int) getRGBFloat(pixel)[0];
|
||||
}
|
||||
|
||||
public int getGreen(int pixel)
|
||||
{
|
||||
if (getNumComponents()>1) throw new IllegalArgumentException();
|
||||
return (int) getRGBFloat(pixel)[0];
|
||||
}
|
||||
|
||||
public int getBlue(int pixel)
|
||||
{
|
||||
if (getNumComponents()>1) throw new IllegalArgumentException();
|
||||
return (int) getRGBFloat(pixel)[0];
|
||||
}
|
||||
|
||||
public int getAlpha(int pixel)
|
||||
{
|
||||
if (getNumComponents()>1) throw new IllegalArgumentException();
|
||||
int shift = 8 - getComponentSize(getNumColorComponents());
|
||||
if (shift >= 0) return pixel << shift;
|
||||
return pixel >> (-shift);
|
||||
}
|
||||
|
||||
public int getRGB(int pixel)
|
||||
{
|
||||
float[] rgb = getRGBFloat(pixel);
|
||||
int ret = getRGB(rgb);
|
||||
if (hasAlpha()) ret |= getAlpha(pixel) << 24;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Note, it's OK to pass a to large array to toRGB(). Extra
|
||||
elements are ignored. */
|
||||
|
||||
private float[] getRGBFloat(int pixel)
|
||||
{
|
||||
float[] data = { pixel };
|
||||
return cspace.toRGB(data);
|
||||
}
|
||||
|
||||
private float[] getRGBFloat(Object inData)
|
||||
{
|
||||
DataBuffer buffer =
|
||||
Buffers.createBufferFromData(transferType, inData,
|
||||
getNumComponents());
|
||||
int colors = getNumColorComponents();
|
||||
float[] data = new float[colors];
|
||||
|
||||
// FIXME: unpremultiply data that is premultiplied
|
||||
for (int i=0; i<colors; i++)
|
||||
{
|
||||
float maxValue = (1<<getComponentSize(i))-1;
|
||||
data[i] = buffer.getElemFloat(i)/maxValue;
|
||||
}
|
||||
float[] rgb = cspace.toRGB(data);
|
||||
return rgb;
|
||||
}
|
||||
|
||||
public int getRed(Object inData)
|
||||
{
|
||||
return (int) getRGBFloat(inData)[0]*255;
|
||||
}
|
||||
|
||||
public int getGreen(Object inData)
|
||||
{
|
||||
return (int) getRGBFloat(inData)[1]*255;
|
||||
}
|
||||
|
||||
public int getBlue(Object inData)
|
||||
{
|
||||
return (int) getRGBFloat(inData)[2]*255;
|
||||
}
|
||||
|
||||
public int getAlpha(Object inData)
|
||||
{
|
||||
DataBuffer buffer =
|
||||
Buffers.createBufferFromData(transferType, inData,
|
||||
getNumComponents());
|
||||
int shift = 8 - getComponentSize(getNumColorComponents());
|
||||
int alpha = buffer.getElem(getNumColorComponents());
|
||||
if (shift >= 0) return alpha << shift;
|
||||
return alpha >> (-shift);
|
||||
}
|
||||
|
||||
private int getRGB(float[] rgb)
|
||||
{
|
||||
/* NOTE: We could cast to byte instead of int here. This would
|
||||
avoid bits spilling over from one bit field to
|
||||
another. But, if we assume that floats are in the [0.0,
|
||||
1.0] range, this will never happen anyway. */
|
||||
|
||||
/* Remember to multiply BEFORE casting to int, otherwise, decimal
|
||||
point data will be lost. */
|
||||
int ret =
|
||||
(((int) (rgb[0]*255F)) << 16) |
|
||||
(((int) (rgb[1]*255F)) << 8) |
|
||||
(((int) (rgb[2]*255F)) << 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inData pixel data of transferType, as returned by the
|
||||
* getDataElements method in SampleModel.
|
||||
*/
|
||||
public int getRGB(Object inData)
|
||||
{
|
||||
float[] rgb = getRGBFloat(inData);
|
||||
int ret = getRGB(rgb);
|
||||
if (hasAlpha()) ret |= getAlpha(inData) << 24;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Object getDataElements(int rgb, Object pixel)
|
||||
{
|
||||
// Convert rgb to [0.0, 1.0] sRGB values.
|
||||
float[] rgbFloats = {
|
||||
((rgb >> 16)&0xff)/255.0F,
|
||||
((rgb >> 8)&0xff)/255.0F,
|
||||
((rgb >> 0)&0xff)/255.0F
|
||||
};
|
||||
|
||||
// Convert from rgb to color space components.
|
||||
float[] data = cspace.fromRGB(rgbFloats);
|
||||
DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
|
||||
getNumComponents());
|
||||
int numColors = getNumColorComponents();
|
||||
|
||||
if (hasAlpha())
|
||||
{
|
||||
float alpha = ((rgb >> 24)&0xff)/255.0F;
|
||||
|
||||
/* If color model has alpha and should be premultiplied, multiply
|
||||
color space components with alpha value. */
|
||||
if (isAlphaPremultiplied()) {
|
||||
for (int i=0; i<numColors; i++)
|
||||
data[i] *= alpha;
|
||||
}
|
||||
// Scale the alpha sample to the correct number of bits.
|
||||
alpha *= (1<<(bits[numColors]-1));
|
||||
// Arrange the alpha sample in the output array.
|
||||
buffer.setElemFloat(numColors, alpha);
|
||||
}
|
||||
for (int i=0; i<numColors; i++)
|
||||
{
|
||||
// Scale the color samples to the correct number of bits.
|
||||
float value = data[i]*(1<<(bits[i]-1));
|
||||
// Arrange the color samples in the output array.
|
||||
buffer.setElemFloat(i, value);
|
||||
}
|
||||
return Buffers.getData(buffer);
|
||||
}
|
||||
|
||||
public int[] getComponents(int pixel, int[] components, int offset)
|
||||
{
|
||||
if (getNumComponents()>1) throw new IllegalArgumentException();
|
||||
if (components == null)
|
||||
components = new int[getNumComponents() + offset];
|
||||
components[offset] = pixel;
|
||||
return components;
|
||||
}
|
||||
|
||||
public int[] getComponents(Object pixel, int[] components, int offset)
|
||||
{
|
||||
DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
|
||||
getNumComponents());
|
||||
int numComponents = getNumComponents();
|
||||
|
||||
if (components == null)
|
||||
components = new int[numComponents + offset];
|
||||
|
||||
for (int i=0; i<numComponents; i++)
|
||||
components[offset++] = buffer.getElem(i);
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
public int getDataElement(int[] components, int offset)
|
||||
{
|
||||
if (getNumComponents()>1) throw new IllegalArgumentException();
|
||||
return components[offset];
|
||||
}
|
||||
|
||||
public Object getDataElements(int[] components, int offset, Object obj)
|
||||
{
|
||||
DataBuffer buffer = Buffers.createBuffer(transferType, obj,
|
||||
getNumComponents());
|
||||
int numComponents = getNumComponents();
|
||||
|
||||
for (int i=0; i<numComponents; i++)
|
||||
buffer.setElem(i, components[offset++]);
|
||||
|
||||
return Buffers.getData(buffer);
|
||||
}
|
||||
|
||||
public ColorModel coerceData(WritableRaster raster,
|
||||
boolean isAlphaPremultiplied) {
|
||||
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
|
||||
return this;
|
||||
|
||||
/* TODO: provide better implementation based on the
|
||||
assumptions we can make due to the specific type of the
|
||||
color model. */
|
||||
super.coerceData(raster, isAlphaPremultiplied);
|
||||
|
||||
return new ComponentColorModel(cspace, bits, hasAlpha(),
|
||||
isAlphaPremultiplied, // argument
|
||||
transparency, transferType);
|
||||
}
|
||||
|
||||
public boolean isCompatibleRaster(Raster raster)
|
||||
{
|
||||
return super.isCompatibleRaster(raster);
|
||||
// FIXME: Should we test something more here? (Why override?)
|
||||
}
|
||||
|
||||
public WritableRaster createCompatibleWritableRaster(int w, int h)
|
||||
{
|
||||
SampleModel sm = createCompatibleSampleModel(w, h);
|
||||
Point origin = new Point(0, 0);
|
||||
return Raster.createWritableRaster(sm, origin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a <code>SampleModel</code> whose arrangement of pixel
|
||||
* data is compatible to this <code>ColorModel</code>.
|
||||
*
|
||||
* @param w the number of pixels in the horizontal direction.
|
||||
* @param h the number of pixels in the vertical direction.
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
int pixelStride, scanlineStride;
|
||||
int[] bandOffsets;
|
||||
|
||||
pixelStride = getNumComponents();
|
||||
scanlineStride = pixelStride * w;
|
||||
|
||||
/* We might be able to re-use the same bandOffsets array among
|
||||
* multiple calls to this method. However, this optimization does
|
||||
* not seem worthwile because setting up descriptive data
|
||||
* structures (such as SampleModels) is neglectible in comparision
|
||||
* to shuffling around masses of pixel data.
|
||||
*/
|
||||
bandOffsets = new int[pixelStride];
|
||||
for (int i = 0; i < pixelStride; i++)
|
||||
bandOffsets[i] = i;
|
||||
|
||||
/* FIXME: Think about whether it would make sense to return the
|
||||
* possibly more efficient PixelInterleavedSampleModel for other
|
||||
* transferTypes as well. It seems unlikely that this would break
|
||||
* any user applications, so the Mauve tests on this method
|
||||
* might be too restrictive.
|
||||
*/
|
||||
switch (transferType)
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
return new PixelInterleavedSampleModel(transferType, w, h,
|
||||
pixelStride,
|
||||
scanlineStride,
|
||||
bandOffsets);
|
||||
|
||||
default:
|
||||
return new ComponentSampleModel(transferType, w, h,
|
||||
pixelStride,
|
||||
scanlineStride,
|
||||
bandOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isCompatibleSampleModel(SampleModel sm)
|
||||
{
|
||||
return
|
||||
(sm instanceof ComponentSampleModel) &&
|
||||
super.isCompatibleSampleModel(sm);
|
||||
}
|
||||
|
||||
public WritableRaster getAlphaRaster(WritableRaster raster)
|
||||
{
|
||||
if (!hasAlpha()) return null;
|
||||
|
||||
SampleModel sm = raster.getSampleModel();
|
||||
int[] alphaBand = { sm.getNumBands() - 1 };
|
||||
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
|
||||
DataBuffer buffer = raster.getDataBuffer();
|
||||
Point origin = new Point(0, 0);
|
||||
return Raster.createWritableRaster(alphaModel, buffer, origin);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (!(obj instanceof ComponentColorModel)) return false;
|
||||
return super.equals(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
/* Copyright (C) 2000, 2002 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
/* FIXME: This class does not yet support data type TYPE_SHORT */
|
||||
|
||||
/**
|
||||
* ComponentSampleModel supports a flexible organization of pixel samples in
|
||||
* memory, permitting pixel samples to be interleaved by band, by scanline,
|
||||
* and by pixel.
|
||||
*
|
||||
* A DataBuffer for this sample model has K banks of data. Pixels have N
|
||||
* samples, so there are N bands in the DataBuffer. Each band is completely
|
||||
* contained in one bank of data, but a bank may contain more than one band.
|
||||
* Each pixel sample is stored in a single data element.
|
||||
*
|
||||
* Within a bank, each band begins at an offset stored in bandOffsets. The
|
||||
* banks containing the band is given by bankIndices. Within the bank, there
|
||||
* are three dimensions - band, pixel, and scanline. The dimension ordering
|
||||
* is controlled by bandOffset, pixelStride, and scanlineStride, which means
|
||||
* that any combination of interleavings is supported.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public class ComponentSampleModel extends SampleModel
|
||||
{
|
||||
protected int[] bandOffsets;
|
||||
protected int[] bankIndices;
|
||||
|
||||
// FIXME: Should we really shadow the numBands in the superclass?
|
||||
//protected int numBands;
|
||||
|
||||
/** Used when creating data buffers. */
|
||||
protected int numBanks;
|
||||
|
||||
protected int scanlineStride;
|
||||
|
||||
protected int pixelStride;
|
||||
|
||||
private boolean tightPixelPacking = false;
|
||||
|
||||
public ComponentSampleModel(int dataType,
|
||||
int w, int h,
|
||||
int pixelStride,
|
||||
int scanlineStride,
|
||||
int[] bandOffsets)
|
||||
{
|
||||
this(dataType, w, h, pixelStride, scanlineStride,
|
||||
new int[bandOffsets.length], bandOffsets);
|
||||
}
|
||||
|
||||
public ComponentSampleModel(int dataType,
|
||||
int w, int h,
|
||||
int pixelStride,
|
||||
int scanlineStride,
|
||||
int[] bankIndices,
|
||||
int[] bandOffsets)
|
||||
{
|
||||
super(dataType, w, h, bandOffsets.length);
|
||||
if ((pixelStride<0) || (scanlineStride<0) ||
|
||||
(bandOffsets.length<1) ||
|
||||
(bandOffsets.length != bankIndices.length))
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.bandOffsets = bandOffsets;
|
||||
this.bankIndices = bankIndices;
|
||||
|
||||
this.numBanks = 0;
|
||||
for (int b=0; b<bankIndices.length; b++)
|
||||
this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
|
||||
|
||||
this.scanlineStride = scanlineStride;
|
||||
this.pixelStride = pixelStride;
|
||||
|
||||
// See if we can use some speedups
|
||||
|
||||
/* FIXME: May these checks should be reserved for the
|
||||
PixelInterleavedSampleModel? */
|
||||
|
||||
if (pixelStride == numBands)
|
||||
{
|
||||
tightPixelPacking = true;
|
||||
for (int b=0; b<numBands; b++) {
|
||||
if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
|
||||
{
|
||||
tightPixelPacking = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
return new ComponentSampleModel(dataType, w, h, pixelStride,
|
||||
scanlineStride, bankIndices,
|
||||
bandOffsets);
|
||||
}
|
||||
|
||||
public SampleModel createSubsetSampleModel(int[] bands)
|
||||
{
|
||||
int numBands = bands.length;
|
||||
|
||||
int[] bankIndices = new int[numBands];
|
||||
int[] bandOffsets = new int[numBands];
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
bankIndices[b] = this.bankIndices[bands[b]];
|
||||
bandOffsets[b] = this.bandOffsets[bands[b]];
|
||||
}
|
||||
|
||||
return new ComponentSampleModel(dataType, width, height, pixelStride,
|
||||
scanlineStride, bankIndices,
|
||||
bandOffsets);
|
||||
}
|
||||
|
||||
public DataBuffer createDataBuffer()
|
||||
{
|
||||
// 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]);
|
||||
}
|
||||
int size = pixelStride*(width-1) + scanlineStride*(height-1) +
|
||||
highestOffset + 1;
|
||||
|
||||
return Buffers.createBuffer(getDataType(), size, numBanks);
|
||||
}
|
||||
|
||||
public int getOffset(int x, int y)
|
||||
{
|
||||
return getOffset(x, y, 0);
|
||||
}
|
||||
|
||||
public int getOffset(int x, int y, int b)
|
||||
{
|
||||
return bandOffsets[b] + pixelStride*x + scanlineStride*y;
|
||||
}
|
||||
|
||||
public final int[] getSampleSize()
|
||||
{
|
||||
int size = DataBuffer.getDataTypeSize(getDataType());
|
||||
int[] sizes = new int[numBands];
|
||||
|
||||
java.util.Arrays.fill(sizes, size);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
public final int getSampleSize(int band)
|
||||
{
|
||||
return DataBuffer.getDataTypeSize(getDataType());
|
||||
}
|
||||
|
||||
public final int[] getBankIndices()
|
||||
{
|
||||
return bankIndices;
|
||||
}
|
||||
|
||||
public final int[] getBandOffsets()
|
||||
{
|
||||
return bandOffsets;
|
||||
}
|
||||
|
||||
public final int getScanlineStride()
|
||||
{
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
public final int getPixelStride()
|
||||
{
|
||||
return pixelStride;
|
||||
}
|
||||
|
||||
public final int getNumDataElements()
|
||||
{
|
||||
return numBands;
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data)
|
||||
{
|
||||
int xyOffset = pixelStride*x + scanlineStride*y;
|
||||
|
||||
int[] totalBandDataOffsets = new int[numBands];
|
||||
|
||||
/* Notice that band and bank offsets are different. Band offsets
|
||||
are managed by the sample model, and bank offsets are managed
|
||||
by the data buffer. Both must be accounted for. */
|
||||
|
||||
/* FIXME: For single pixels, it is probably easier to simple
|
||||
call getElem instead of calculating the bank offset ourself.
|
||||
|
||||
On the other hand, then we need to push the value through
|
||||
the int type returned by the getElem method. */
|
||||
|
||||
int[] bankOffsets = data.getOffsets();
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
totalBandDataOffsets[b] =
|
||||
bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
DataBufferByte inByte = (DataBufferByte) data;
|
||||
byte[] outByte = (byte[]) obj;
|
||||
if (outByte == null) outByte = new byte[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
int dOffset = totalBandDataOffsets[b];
|
||||
outByte[b] = inByte.getData(bankIndices[b])[dOffset];
|
||||
}
|
||||
return outByte;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
DataBufferUShort inUShort = (DataBufferUShort) data;
|
||||
short[] outUShort = (short[]) obj;
|
||||
if (outUShort == null) outUShort = new short[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
int dOffset = totalBandDataOffsets[b];
|
||||
outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
|
||||
}
|
||||
return outUShort;
|
||||
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
DataBufferShort inShort = (DataBufferShort) data;
|
||||
short[] outShort = (short[]) obj;
|
||||
if (outShort == null) outShort = new short[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
int dOffset = totalBandDataOffsets[b];
|
||||
outShort[b] = inShort.getData(bankIndices[b])[dOffset];
|
||||
}
|
||||
return outShort;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
DataBufferInt inInt = (DataBufferInt) data;
|
||||
int[] outInt = (int[]) obj;
|
||||
if (outInt == null) outInt = new int[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
int dOffset = totalBandDataOffsets[b];
|
||||
outInt[b] = inInt.getData(bankIndices[b])[dOffset];
|
||||
}
|
||||
return outInt;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
DataBufferFloat inFloat = (DataBufferFloat) data;
|
||||
float[] outFloat = (float[]) obj;
|
||||
if (outFloat == null) outFloat = new float[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
int dOffset = totalBandDataOffsets[b];
|
||||
outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
|
||||
}
|
||||
return outFloat;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
DataBufferDouble inDouble = (DataBufferDouble) data;
|
||||
double[] outDouble = (double[]) obj;
|
||||
if (outDouble == null) outDouble = new double[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
int dOffset = totalBandDataOffsets[b];
|
||||
outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
|
||||
}
|
||||
return outDouble;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("unknown transfer type " +
|
||||
getTransferType());
|
||||
}
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException aioobe)
|
||||
{
|
||||
String msg = "While reading data elements, " +
|
||||
"x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
|
||||
", data.getSize()=" + data.getSize() + ": " + aioobe;
|
||||
throw new ArrayIndexOutOfBoundsException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, int w, int h, Object obj,
|
||||
DataBuffer data)
|
||||
{
|
||||
if (!tightPixelPacking)
|
||||
{
|
||||
return super.getDataElements(x, y, w, h, obj, data);
|
||||
}
|
||||
|
||||
// using get speedup
|
||||
|
||||
// We can copy whole rows
|
||||
int rowSize = w*numBands;
|
||||
int dataSize = rowSize*h;
|
||||
|
||||
DataBuffer transferBuffer =
|
||||
Buffers.createBuffer(getTransferType(), obj, dataSize);
|
||||
obj = Buffers.getData(transferBuffer);
|
||||
|
||||
int inOffset =
|
||||
pixelStride*x +
|
||||
scanlineStride*y +
|
||||
data.getOffset(); // Assumes only one band is used
|
||||
|
||||
/* We don't add band offsets since we assume that bands have
|
||||
offsets 0, 1, 2, ... */
|
||||
|
||||
// See if we can copy everything in one go
|
||||
if (scanlineStride == rowSize)
|
||||
{
|
||||
// Collapse scan lines:
|
||||
rowSize *= h;
|
||||
// We ignore scanlineStride since it won't be of any use
|
||||
h = 1;
|
||||
}
|
||||
|
||||
int outOffset = 0;
|
||||
Object inArray = Buffers.getData(data);
|
||||
for (int yd = 0; yd<h; yd++)
|
||||
{
|
||||
System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
|
||||
inOffset += scanlineStride;
|
||||
outOffset += rowSize;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void setDataElements(int x, int y, int w, int h,
|
||||
Object obj, DataBuffer data)
|
||||
{
|
||||
if (!tightPixelPacking)
|
||||
{
|
||||
super.setDataElements(x, y, w, h, obj, data);
|
||||
return;
|
||||
}
|
||||
|
||||
// using set speedup, we can copy whole rows
|
||||
int rowSize = w*numBands;
|
||||
int dataSize = rowSize*h;
|
||||
|
||||
DataBuffer transferBuffer =
|
||||
Buffers.createBufferFromData(getTransferType(), obj, dataSize);
|
||||
|
||||
int[] bankOffsets = data.getOffsets();
|
||||
|
||||
int outOffset =
|
||||
pixelStride*x +
|
||||
scanlineStride*y +
|
||||
bankOffsets[0]; // same assuptions as in get...
|
||||
|
||||
// See if we can copy everything in one go
|
||||
if (scanlineStride == rowSize)
|
||||
{
|
||||
// Collapse scan lines:
|
||||
rowSize *= h;
|
||||
h = 1;
|
||||
}
|
||||
|
||||
int inOffset = 0;
|
||||
Object outArray = Buffers.getData(data);
|
||||
for (int yd = 0; yd<h; yd++)
|
||||
{
|
||||
System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
|
||||
outOffset += scanlineStride;
|
||||
inOffset += rowSize;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
int offset = pixelStride*x + scanlineStride*y;
|
||||
if (iArray == null) iArray = new int[numBands];
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int offset = pixelStride*x + scanlineStride*y;
|
||||
if (iArray == null) iArray = new int[numBands*w*h];
|
||||
int outOffset = 0;
|
||||
for (y=0; y<h; y++)
|
||||
{
|
||||
int lineOffset = offset;
|
||||
for (x=0; x<w; x++)
|
||||
{
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
iArray[outOffset++] =
|
||||
data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
|
||||
}
|
||||
lineOffset += pixelStride;
|
||||
}
|
||||
offset += scanlineStride;
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public int getSample(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
return data.getElem(bankIndices[b], getOffset(x, y, b));
|
||||
}
|
||||
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data)
|
||||
{
|
||||
int offset = pixelStride*x + scanlineStride*y;
|
||||
int[] totalBandDataOffsets = new int[numBands];
|
||||
int[] bankOffsets = data.getOffsets();
|
||||
for (int b=0; b<numBands; b++)
|
||||
totalBandDataOffsets[b] =
|
||||
bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
|
||||
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
{
|
||||
DataBufferByte out = (DataBufferByte) data;
|
||||
byte[] in = (byte[]) obj;
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
|
||||
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
{
|
||||
DataBufferUShort out = (DataBufferUShort) data;
|
||||
short[] in = (short[]) obj;
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
|
||||
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
{
|
||||
DataBufferShort out = (DataBufferShort) data;
|
||||
short[] in = (short[]) obj;
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
|
||||
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_INT:
|
||||
{
|
||||
DataBufferInt out = (DataBufferInt) data;
|
||||
int[] in = (int[]) obj;
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
|
||||
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
{
|
||||
DataBufferFloat out = (DataBufferFloat) data;
|
||||
float[] in = (float[]) obj;
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
|
||||
|
||||
return;
|
||||
}
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
{
|
||||
DataBufferDouble out = (DataBufferDouble) data;
|
||||
double[] in = (double[]) obj;
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
|
||||
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throw new UnsupportedOperationException("transfer type not " +
|
||||
"implemented");
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
int offset = pixelStride*x + scanlineStride*y;
|
||||
for (int b=0; b<numBands; b++)
|
||||
data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, int s, DataBuffer data)
|
||||
{
|
||||
data.setElem(bankIndices[b], getOffset(x, y, b), s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
/* ConvolveOp.java --
|
||||
Copyright (C) 2004 Free Software Foundation -- ConvolveOp
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Convolution filter.
|
||||
*
|
||||
* ConvolveOp convolves the source image with a Kernel to generate a
|
||||
* destination image. This involves multiplying each pixel and its neighbors
|
||||
* with elements in the kernel to compute a new pixel.
|
||||
*
|
||||
* Each band in a Raster is convolved and copied to the destination Raster.
|
||||
*
|
||||
* For BufferedImages, convolution is applied to all components. If the
|
||||
* source is not premultiplied, the data will be premultiplied before
|
||||
* convolving. Premultiplication will be undone if the destination is not
|
||||
* premultiplied. Color conversion will be applied if needed.
|
||||
*
|
||||
* @author jlquinn@optonline.net
|
||||
*/
|
||||
public class ConvolveOp implements BufferedImageOp, RasterOp
|
||||
{
|
||||
/** Edge pixels are set to 0. */
|
||||
public static final int EDGE_ZERO_FILL = 0;
|
||||
|
||||
/** Edge pixels are copied from the source. */
|
||||
public static final int EDGE_NO_OP = 1;
|
||||
|
||||
private Kernel kernel;
|
||||
private int edge;
|
||||
private RenderingHints hints;
|
||||
|
||||
/**
|
||||
* Construct a ConvolveOp.
|
||||
*
|
||||
* The edge condition specifies that pixels outside the area that can be
|
||||
* filtered are either set to 0 or copied from the source image.
|
||||
*
|
||||
* @param kernel The kernel to convolve with.
|
||||
* @param edgeCondition Either EDGE_ZERO_FILL or EDGE_NO_OP.
|
||||
* @param hints Rendering hints for color conversion, or null.
|
||||
*/
|
||||
public ConvolveOp(Kernel kernel,
|
||||
int edgeCondition,
|
||||
RenderingHints hints)
|
||||
{
|
||||
this.kernel = kernel;
|
||||
edge = edgeCondition;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a ConvolveOp.
|
||||
*
|
||||
* The edge condition defaults to EDGE_ZERO_FILL.
|
||||
*
|
||||
* @param kernel The kernel to convolve with.
|
||||
*/
|
||||
public ConvolveOp(Kernel kernel)
|
||||
{
|
||||
this.kernel = kernel;
|
||||
edge = EDGE_ZERO_FILL;
|
||||
hints = null;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage,
|
||||
* java.awt.image.BufferedImage)
|
||||
*/
|
||||
public BufferedImage filter(BufferedImage src, BufferedImage dst)
|
||||
{
|
||||
if (src == dst)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
if (dst == null)
|
||||
dst = createCompatibleDestImage(src, src.getColorModel());
|
||||
|
||||
// Make sure source image is premultiplied
|
||||
BufferedImage src1 = src;
|
||||
if (!src.isPremultiplied)
|
||||
{
|
||||
src1 = createCompatibleDestImage(src, src.getColorModel());
|
||||
src.copyData(src1.getRaster());
|
||||
src1.coerceData(true);
|
||||
}
|
||||
|
||||
BufferedImage dst1 = dst;
|
||||
if (!src.getColorModel().equals(dst.getColorModel()))
|
||||
dst1 = createCompatibleDestImage(src, src.getColorModel());
|
||||
|
||||
filter(src1.getRaster(), dst1.getRaster());
|
||||
|
||||
if (dst1 != dst)
|
||||
{
|
||||
// Convert between color models.
|
||||
// TODO Check that premultiplied alpha is handled correctly here.
|
||||
Graphics2D gg = dst.createGraphics();
|
||||
gg.setRenderingHints(hints);
|
||||
gg.drawImage(dst1, 0, 0, null);
|
||||
gg.dispose();
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see
|
||||
* java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage,
|
||||
* java.awt.image.ColorModel)
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage(BufferedImage src,
|
||||
ColorModel dstCM)
|
||||
{
|
||||
// FIXME: set properties to those in src
|
||||
return new BufferedImage(dstCM,
|
||||
src.getRaster().createCompatibleWritableRaster(),
|
||||
src.isPremultiplied, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getRenderingHints()
|
||||
*/
|
||||
public RenderingHints getRenderingHints()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The edge condition.
|
||||
*/
|
||||
public int getEdgeCondition()
|
||||
{
|
||||
return edge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The convolution kernel.
|
||||
*/
|
||||
public Kernel getKernel()
|
||||
{
|
||||
return kernel;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
|
||||
* java.awt.image.WritableRaster)
|
||||
*/
|
||||
public WritableRaster filter(Raster src, WritableRaster dest) {
|
||||
if (src.numBands != dest.numBands)
|
||||
throw new ImagingOpException(null);
|
||||
if (src == dest)
|
||||
throw new IllegalArgumentException();
|
||||
if (src.getWidth() < kernel.getWidth() ||
|
||||
src.getHeight() < kernel.getHeight())
|
||||
throw new ImagingOpException(null);
|
||||
|
||||
if (dest == null)
|
||||
dest = createCompatibleDestRaster(src);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Handle main section
|
||||
float[] kvals = kernel.getKernelData(null);
|
||||
|
||||
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++)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
|
||||
}
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// 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)
|
||||
* @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src)
|
||||
{
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
|
||||
*/
|
||||
public Rectangle2D getBounds2D(BufferedImage src)
|
||||
{
|
||||
return src.getRaster().getBounds();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
|
||||
*/
|
||||
public Rectangle2D getBounds2D(Raster src)
|
||||
{
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
/** Return corresponding destination point for source point.
|
||||
*
|
||||
* ConvolveOp will return the value of src unchanged.
|
||||
* @param src The source point.
|
||||
* @param dst The destination point.
|
||||
* @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D,
|
||||
* java.awt.geom.Point2D)
|
||||
*/
|
||||
public Point2D getPoint2D(Point2D src, Point2D dst)
|
||||
{
|
||||
if (dst == null) return (Point2D)src.clone();
|
||||
dst.setLocation(src);
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/* CropImageFilter.java -- Java class for cropping image filter
|
||||
Copyright (C) 1999, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* Currently this filter does almost nothing and needs to be implemented.
|
||||
*
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public class CropImageFilter extends ImageFilter
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/**
|
||||
* Construct a new <code>CropImageFilter</code> instance.
|
||||
*
|
||||
* @param x the x-coordinate location of the top-left of the cropped rectangle
|
||||
* @param y the y-coordinate location of the top-left of the cropped rectangle
|
||||
* @param width the width of the cropped rectangle
|
||||
* @param height the height of the cropped rectangle
|
||||
*/
|
||||
public CropImageFilter(int x, int y, int width, int height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> indicates the size of the image
|
||||
* being produced using this method. This filter overrides this
|
||||
* method in order to set the dimentions to the size of the
|
||||
* cropped rectangle instead of the size of the image.
|
||||
*
|
||||
* @param width the width of the image
|
||||
* @param height the height of the image
|
||||
*/
|
||||
public void setDimensions(int width, int height)
|
||||
{
|
||||
consumer.setDimensions(this.width, this.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> can set a list of properties
|
||||
* associated with this image by using this method.
|
||||
* <br>
|
||||
* FIXME - What property is set for this class?
|
||||
*
|
||||
* @param props the list of properties associated with this image
|
||||
*/
|
||||
public void setProperties(Hashtable props)
|
||||
{
|
||||
props.put("filters", "CropImageFilter");
|
||||
consumer.setProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as a <code>byte</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels, int offset, int scansize)
|
||||
{
|
||||
Rectangle filterBounds = new Rectangle(this.x, this.y,
|
||||
this.width, this.height);
|
||||
Rectangle pixelBounds = new Rectangle(x, y, w, h);
|
||||
|
||||
if (filterBounds.intersects(pixelBounds))
|
||||
{
|
||||
Rectangle bounds = filterBounds.intersection(pixelBounds);
|
||||
|
||||
byte[] cropped = new byte[bounds.width * bounds.height];
|
||||
for (int i = 0; i < bounds.height; i++)
|
||||
{
|
||||
int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
|
||||
|
||||
for (int j = 0; j < bounds.width; j++)
|
||||
cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
|
||||
}
|
||||
|
||||
consumer.setPixels(bounds.x, bounds.y,
|
||||
bounds.width, bounds.height,
|
||||
model, cropped, 0, bounds.width);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as an <code>int</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels, int offset, int scansize)
|
||||
{
|
||||
Rectangle filterBounds = new Rectangle(this.x, this.y,
|
||||
this.width, this.height);
|
||||
Rectangle pixelBounds = new Rectangle(x, y, w, h);
|
||||
|
||||
if (filterBounds.intersects(pixelBounds))
|
||||
{
|
||||
Rectangle bounds = filterBounds.intersection(pixelBounds);
|
||||
|
||||
int[] cropped = new int[bounds.width * bounds.height];
|
||||
for (int i = 0; i < bounds.height; i++)
|
||||
{
|
||||
int start = (bounds.y - pixelBounds.y + i) * scansize + offset;
|
||||
|
||||
for (int j = 0; j < bounds.width; j++)
|
||||
cropped[i * bounds.width + j] = pixels[start + bounds.x + j];
|
||||
}
|
||||
|
||||
consumer.setPixels(bounds.x, bounds.y,
|
||||
bounds.width, bounds.height,
|
||||
model, cropped, 0, bounds.width);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
/* Copyright (C) 2000, 2002, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* Class that manages arrays of data elements. A data buffer consists
|
||||
* of one or more banks. A bank is a continuous region of data
|
||||
* elements.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public abstract class DataBuffer
|
||||
{
|
||||
/**
|
||||
* A constant representing a data type that uses <code>byte</code> primitives
|
||||
* as the storage unit.
|
||||
*/
|
||||
public static final int TYPE_BYTE = 0;
|
||||
|
||||
/**
|
||||
* A constant representing a data type that uses <code>short</code>
|
||||
* primitives as the storage unit.
|
||||
*/
|
||||
public static final int TYPE_USHORT = 1;
|
||||
|
||||
/**
|
||||
* A constant representing a data type that uses <code>short</code>
|
||||
* primitives as the storage unit.
|
||||
*/
|
||||
public static final int TYPE_SHORT = 2;
|
||||
|
||||
/**
|
||||
* A constant representing a data type that uses <code>int</code>
|
||||
* primitives as the storage unit.
|
||||
*/
|
||||
public static final int TYPE_INT = 3;
|
||||
|
||||
/**
|
||||
* A constant representing a data type that uses <code>float</code>
|
||||
* primitives as the storage unit.
|
||||
*/
|
||||
public static final int TYPE_FLOAT = 4;
|
||||
|
||||
/**
|
||||
* A constant representing a data type that uses <code>double</code>
|
||||
* primitives as the storage unit.
|
||||
*/
|
||||
public static final int TYPE_DOUBLE = 5;
|
||||
|
||||
/**
|
||||
* A constant representing an undefined data type.
|
||||
*/
|
||||
public static final int TYPE_UNDEFINED = 32;
|
||||
|
||||
/** The type of the data elements stored in the data buffer. */
|
||||
protected int dataType;
|
||||
|
||||
/** The number of banks in this buffer. */
|
||||
protected int banks = 1;
|
||||
|
||||
/** Offset into the default (0'th) bank). */
|
||||
protected int offset; // FIXME: Is offsets[0] always mirrored in offset?
|
||||
|
||||
/** The size of the banks. */
|
||||
protected int size;
|
||||
|
||||
/** Offset into each bank. */
|
||||
protected int[] offsets;
|
||||
|
||||
/**
|
||||
* Creates a new <code>DataBuffer</code> with the specified data type and
|
||||
* size. The <code>dataType</code> should be one of the constants
|
||||
* {@link #TYPE_BYTE}, {@link #TYPE_SHORT}, {@link #TYPE_USHORT},
|
||||
* {@link #TYPE_INT}, {@link #TYPE_FLOAT} and {@link #TYPE_DOUBLE}.
|
||||
* <p>
|
||||
* The physical (array-based) storage is allocated by a subclass.
|
||||
*
|
||||
* @param dataType the data type.
|
||||
* @param size the number of elements in the buffer.
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size)
|
||||
{
|
||||
this.dataType = dataType;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>DataBuffer</code> with the specified data type,
|
||||
* size and number of banks. The <code>dataType</code> should be one of
|
||||
* the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
|
||||
* {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
|
||||
* {@link #TYPE_DOUBLE}.
|
||||
* <p>
|
||||
* The physical (array-based) storage is allocated by a subclass.
|
||||
*
|
||||
* @param dataType the data type.
|
||||
* @param size the number of elements in the buffer.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks) {
|
||||
this(dataType, size);
|
||||
banks = numBanks;
|
||||
offsets = new int[numBanks];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>DataBuffer</code> with the specified data type,
|
||||
* size and number of banks. An offset (which applies to all banks) is
|
||||
* also specified. The <code>dataType</code> should be one of
|
||||
* the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
|
||||
* {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
|
||||
* {@link #TYPE_DOUBLE}.
|
||||
* <p>
|
||||
* The physical (array-based) storage is allocated by a subclass.
|
||||
*
|
||||
* @param dataType the data type.
|
||||
* @param size the number of elements in the buffer.
|
||||
* @param numBanks the number of data banks.
|
||||
* @param offset the offset to the first element for all banks.
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
|
||||
this(dataType, size, numBanks);
|
||||
|
||||
java.util.Arrays.fill(offsets, offset);
|
||||
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>DataBuffer</code> with the specified data type,
|
||||
* size and number of banks. An offset (which applies to all banks) is
|
||||
* also specified. The <code>dataType</code> should be one of
|
||||
* the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
|
||||
* {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
|
||||
* {@link #TYPE_DOUBLE}.
|
||||
* <p>
|
||||
* The physical (array-based) storage is allocated by a subclass.
|
||||
*
|
||||
* @param dataType the data type.
|
||||
* @param size the number of elements in the buffer.
|
||||
* @param numBanks the number of data banks.
|
||||
* @param offsets the offsets to the first element for all banks.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if
|
||||
* <code>numBanks != offsets.length</code>.
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
|
||||
this(dataType, size);
|
||||
if (numBanks != offsets.length)
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
|
||||
banks = numBanks;
|
||||
this.offsets = offsets;
|
||||
|
||||
offset = offsets[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size (number of bits) of the specified data type. Valid types
|
||||
* are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
|
||||
* {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
|
||||
* {@link #TYPE_DOUBLE}.
|
||||
*
|
||||
* @param dataType the data type.
|
||||
* @return The number of bits for the specified data type.
|
||||
* @throws IllegalArgumentException if <code>dataType < 0</code> or
|
||||
* <code>dataType > TYPE_DOUBLE</code>.
|
||||
*/
|
||||
public static int getDataTypeSize(int dataType) {
|
||||
// Maybe this should be a lookup table instead.
|
||||
switch (dataType)
|
||||
{
|
||||
case TYPE_BYTE:
|
||||
return 8;
|
||||
case TYPE_USHORT:
|
||||
case TYPE_SHORT:
|
||||
return 16;
|
||||
case TYPE_INT:
|
||||
case TYPE_FLOAT:
|
||||
return 32;
|
||||
case TYPE_DOUBLE:
|
||||
return 64;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the data elements in the data buffer. Valid types
|
||||
* are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
|
||||
* {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
|
||||
* {@link #TYPE_DOUBLE}.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public int getDataType()
|
||||
{
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the data buffer.
|
||||
*
|
||||
* @return The size.
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element offset for the first data bank.
|
||||
*
|
||||
* @return The element offset.
|
||||
*/
|
||||
public int getOffset()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offsets for all the data banks used by this
|
||||
* <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The offsets.
|
||||
*/
|
||||
public int[] getOffsets()
|
||||
{
|
||||
if (offsets == null)
|
||||
{
|
||||
// is this necessary?
|
||||
offsets = new int[1];
|
||||
offsets[0] = offset;
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data banks for this <code>DataBuffer</code>.
|
||||
* @return The number of data banks.
|
||||
*/
|
||||
public int getNumBanks()
|
||||
{
|
||||
return banks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return getElem(0, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public abstract int getElem(int bank, int i);
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
setElem(0, i, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public abstract void setElem(int bank, int i, int val);
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank, converted to a
|
||||
* <code>float</code>. The offset (specified in the constructor) is added
|
||||
* to <code>i</code> before accessing the underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public float getElemFloat(int i)
|
||||
{
|
||||
return getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank, converted to a
|
||||
* <code>float</code>. The offset (specified in the constructor) is
|
||||
* added to <code>i</code> before accessing the underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public float getElemFloat(int bank, int i)
|
||||
{
|
||||
return getElem(bank, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElemFloat(int i, float val)
|
||||
{
|
||||
setElem(i, (int) val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElemFloat(int bank, int i, float val)
|
||||
{
|
||||
setElem(bank, i, (int) val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank, converted to a
|
||||
* <code>double</code>. The offset (specified in the constructor) is added
|
||||
* to <code>i</code> before accessing the underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public double getElemDouble(int i)
|
||||
{
|
||||
return getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank, converted to a
|
||||
* <code>double</code>. The offset (specified in the constructor) is
|
||||
* added to <code>i</code> before accessing the underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public double getElemDouble(int bank, int i)
|
||||
{
|
||||
return getElem(bank, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElemDouble(int i, double val)
|
||||
{
|
||||
setElem(i, (int) val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElemDouble(int bank, int i, double val)
|
||||
{
|
||||
setElem(bank, i, (int) val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/* Copyright (C) 2000, 2002 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/* This is one of several classes that are nearly identical. Maybe we
|
||||
should have a central template and generate all these files. This
|
||||
is one of the cases where templates or macros would have been
|
||||
useful to have in Java.
|
||||
|
||||
This file has been created using search-replace. My only fear is
|
||||
that these classes will grow out-of-sync as of a result of changes
|
||||
that are not propagated to the other files. As always, mirroring
|
||||
code is a maintenance nightmare. */
|
||||
|
||||
/**
|
||||
* A {@link DataBuffer} that uses an array of <code>byte</code> primitives
|
||||
* to represent each of its banks.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public final class DataBufferByte extends DataBuffer
|
||||
{
|
||||
private byte[] data;
|
||||
private byte[][] bankData;
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with a single data bank containing the
|
||||
* specified number of <code>byte</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferByte(int size)
|
||||
{
|
||||
super(TYPE_BYTE, size, 1, 0);
|
||||
bankData = new byte[1][];
|
||||
data = new byte[size];
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with the specified number of data banks,
|
||||
* each containing the specified number of <code>byte</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
public DataBufferByte(int size, int numBanks)
|
||||
{
|
||||
super(TYPE_BYTE, size, numBanks);
|
||||
bankData = new byte[numBanks][size];
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferByte(byte[] dataArray, int size)
|
||||
{
|
||||
super(TYPE_BYTE, size, 1, 0);
|
||||
bankData = new byte[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank, with
|
||||
* the specified offset to the first element.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offset the offset to the first element in the array.
|
||||
*/
|
||||
public DataBufferByte(byte[] dataArray, int size, int offset)
|
||||
{
|
||||
super(TYPE_BYTE, size, 1, offset);
|
||||
bankData = new byte[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferByte(byte[][] dataArray, int size)
|
||||
{
|
||||
super(TYPE_BYTE, size, dataArray.length);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks, with
|
||||
* the specified offsets to the first element in each bank.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offsets the offsets to the first element in each data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferByte(byte[][] dataArray, int size, int[] offsets)
|
||||
{
|
||||
super(TYPE_BYTE, size, dataArray.length, offsets);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first data bank.
|
||||
*
|
||||
* @return The first data bank.
|
||||
*/
|
||||
public byte[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data bank.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @return A data bank.
|
||||
*/
|
||||
public byte[] getData(int bank)
|
||||
{
|
||||
return bankData[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array underlying this <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The data banks.
|
||||
*/
|
||||
public byte[][] getBankData()
|
||||
{
|
||||
return bankData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return data[i+offset] & 0xff; // get unsigned byte as int
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
// get unsigned byte as int
|
||||
return bankData[bank][i+offsets[bank]] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
data[i+offset] = (byte) val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = (byte) val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
/* Copyright (C) 2004, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/* This is one of several classes that are nearly identical. Maybe we
|
||||
should have a central template and generate all these files. This
|
||||
is one of the cases where templates or macros would have been
|
||||
useful to have in Java.
|
||||
|
||||
This file has been created using search-replace. My only fear is
|
||||
that these classes will grow out-of-sync as of a result of changes
|
||||
that are not propagated to the other files. As always, mirroring
|
||||
code is a maintenance nightmare. */
|
||||
|
||||
/**
|
||||
* A {@link DataBuffer} that uses an array of <code>double</code> primitives
|
||||
* to represent each of its banks.
|
||||
*
|
||||
* @since 1.4
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
* @author Sascha Brawer (brawer@dandelis.ch)
|
||||
*/
|
||||
public final class DataBufferDouble
|
||||
extends DataBuffer
|
||||
{
|
||||
private double[] data;
|
||||
private double[][] bankData;
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with a single data bank containing the
|
||||
* specified number of <code>double</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferDouble(int size)
|
||||
{
|
||||
super(TYPE_DOUBLE, size, 1, 0);
|
||||
bankData = new double[1][];
|
||||
data = new double[size];
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with the specified number of data banks,
|
||||
* each containing the specified number of <code>double</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
public DataBufferDouble(int size, int numBanks)
|
||||
{
|
||||
super(TYPE_DOUBLE, size, numBanks);
|
||||
bankData = new double[numBanks][size];
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferDouble(double[] dataArray, int size)
|
||||
{
|
||||
super(TYPE_DOUBLE, size, 1, 0);
|
||||
bankData = new double[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank, with
|
||||
* the specified offset to the first element.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offset the offset to the first element in the array.
|
||||
*/
|
||||
public DataBufferDouble(double[] dataArray, int size, int offset)
|
||||
{
|
||||
super(TYPE_DOUBLE, size, 1, offset);
|
||||
bankData = new double[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferDouble(double[][] dataArray, int size)
|
||||
{
|
||||
super(TYPE_DOUBLE, size, dataArray.length);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks, with
|
||||
* the specified offsets to the first element in each bank.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offsets the offsets to the first element in each data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferDouble(double[][] dataArray, int size, int[] offsets)
|
||||
{
|
||||
super(TYPE_DOUBLE, size, dataArray.length, offsets);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first data bank.
|
||||
*
|
||||
* @return The first data bank.
|
||||
*/
|
||||
public double[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data bank.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @return A data bank.
|
||||
*/
|
||||
public double[] getData(int bank)
|
||||
{
|
||||
return bankData[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array underlying this <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The data banks.
|
||||
*/
|
||||
public double[][] getBankData()
|
||||
{
|
||||
return bankData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return (int) data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
return (int) bankData[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
data[i+offset] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = val;
|
||||
}
|
||||
|
||||
public float getElemFloat(int i)
|
||||
{
|
||||
return (float) data[i+offset];
|
||||
}
|
||||
|
||||
public float getElemFloat(int bank, int i)
|
||||
{
|
||||
return (float) bankData[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemFloat(int i, float val)
|
||||
{
|
||||
data[i+offset] = val;
|
||||
}
|
||||
|
||||
public void setElemFloat(int bank, int i, float val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = val;
|
||||
}
|
||||
|
||||
public double getElemDouble(int i)
|
||||
{
|
||||
return data[i + offset];
|
||||
}
|
||||
|
||||
public double getElemDouble(int bank, int i)
|
||||
{
|
||||
return bankData[bank][i + offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemDouble(int i, double val)
|
||||
{
|
||||
data[i + offset] = val;
|
||||
}
|
||||
|
||||
public void setElemDouble(int bank, int i, double val)
|
||||
{
|
||||
bankData[bank][i + offsets[bank]] = val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
/* Copyright (C) 2004, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/* This is one of several classes that are nearly identical. Maybe we
|
||||
should have a central template and generate all these files. This
|
||||
is one of the cases where templates or macros would have been
|
||||
useful to have in Java.
|
||||
|
||||
This file has been created using search-replace. My only fear is
|
||||
that these classes will grow out-of-sync as of a result of changes
|
||||
that are not propagated to the other files. As always, mirroring
|
||||
code is a maintenance nightmare. */
|
||||
|
||||
/**
|
||||
* A {@link DataBuffer} that uses an array of <code>float</code> primitives
|
||||
* to represent each of its banks.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
* @author Sascha Brawer (brawer@dandelis.ch)
|
||||
*/
|
||||
public final class DataBufferFloat
|
||||
extends DataBuffer
|
||||
{
|
||||
private float[] data;
|
||||
private float[][] bankData;
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with a single data bank containing the
|
||||
* specified number of <code>float</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferFloat(int size)
|
||||
{
|
||||
super(TYPE_FLOAT, size, 1, 0);
|
||||
bankData = new float[1][];
|
||||
data = new float[size];
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with the specified number of data banks,
|
||||
* each containing the specified number of <code>float</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
public DataBufferFloat(int size, int numBanks)
|
||||
{
|
||||
super(TYPE_FLOAT, size, numBanks);
|
||||
bankData = new float[numBanks][size];
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferFloat(float[] dataArray, int size)
|
||||
{
|
||||
super(TYPE_FLOAT, size, 1, 0);
|
||||
bankData = new float[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank, with
|
||||
* the specified offset to the first element.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offset the offset to the first element in the array.
|
||||
*/
|
||||
public DataBufferFloat(float[] dataArray, int size, int offset)
|
||||
{
|
||||
super(TYPE_FLOAT, size, 1, offset);
|
||||
bankData = new float[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferFloat(float[][] dataArray, int size)
|
||||
{
|
||||
super(TYPE_FLOAT, size, dataArray.length);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks, with
|
||||
* the specified offsets to the first element in each bank.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offsets the offsets to the first element in each data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferFloat(float[][] dataArray, int size, int[] offsets)
|
||||
{
|
||||
super(TYPE_FLOAT, size, dataArray.length, offsets);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first data bank.
|
||||
*
|
||||
* @return The first data bank.
|
||||
*/
|
||||
public float[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data bank.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @return A data bank.
|
||||
*/
|
||||
public float[] getData(int bank)
|
||||
{
|
||||
return bankData[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array underlying this <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The data banks.
|
||||
*/
|
||||
public float[][] getBankData()
|
||||
{
|
||||
return bankData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return (int) data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
return (int) bankData[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
data[i+offset] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = val;
|
||||
}
|
||||
|
||||
public float getElemFloat(int i)
|
||||
{
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
public float getElemFloat(int bank, int i)
|
||||
{
|
||||
return bankData[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
public void setElemFloat(int i, float val)
|
||||
{
|
||||
data[i+offset] = val;
|
||||
}
|
||||
|
||||
public void setElemFloat(int bank, int i, float val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = val;
|
||||
}
|
||||
|
||||
public double getElemDouble(int i)
|
||||
{
|
||||
return getElemFloat(i);
|
||||
}
|
||||
|
||||
public double getElemDouble(int bank, int i)
|
||||
{
|
||||
return getElemFloat(bank, i);
|
||||
}
|
||||
|
||||
public void setElemDouble(int i, double val)
|
||||
{
|
||||
setElemFloat(i, (float) val);
|
||||
}
|
||||
|
||||
public void setElemDouble(int bank, int i, double val)
|
||||
{
|
||||
setElemFloat(bank, i, (float) val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
/* Copyright (C) 2000, 2002, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/* This is one of several classes that are nearly identical. Maybe we
|
||||
should have a central template and generate all these files. This
|
||||
is one of the cases where templates or macros would have been
|
||||
useful to have in Java.
|
||||
|
||||
This file has been created using search-replace. My only fear is
|
||||
that these classes will grow out-of-sync as of a result of changes
|
||||
that are not propagated to the other files. As always, mirroring
|
||||
code is a maintenance nightmare. */
|
||||
|
||||
/**
|
||||
* A {@link DataBuffer} that uses an array of <code>int</code> primitives
|
||||
* to represent each of its banks.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public final class DataBufferInt extends DataBuffer
|
||||
{
|
||||
private int[] data;
|
||||
private int[][] bankData;
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with a single data bank containing the
|
||||
* specified number of <code>int</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferInt(int size)
|
||||
{
|
||||
super(TYPE_INT, size, 1, 0);
|
||||
bankData = new int[1][];
|
||||
data = new int[size];
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with the specified number of data banks,
|
||||
* each containing the specified number of <code>int</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
public DataBufferInt(int size, int numBanks)
|
||||
{
|
||||
super(TYPE_INT, size, numBanks);
|
||||
bankData = new int[numBanks][size];
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferInt(int[] dataArray, int size)
|
||||
{
|
||||
super(TYPE_INT, size, 1, 0);
|
||||
bankData = new int[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank, with
|
||||
* the specified offset to the first element.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offset the offset to the first element in the array.
|
||||
*/
|
||||
public DataBufferInt(int[] dataArray, int size, int offset)
|
||||
{
|
||||
super(TYPE_INT, size, 1, offset);
|
||||
bankData = new int[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferInt(int[][] dataArray, int size)
|
||||
{
|
||||
super(TYPE_INT, size, dataArray.length);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks, with
|
||||
* the specified offsets to the first element in each bank.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offsets the offsets to the first element in each data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferInt(int[][] dataArray, int size, int[] offsets)
|
||||
{
|
||||
super(TYPE_INT, size, dataArray.length, offsets);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first data bank.
|
||||
*
|
||||
* @return The first data bank.
|
||||
*/
|
||||
public int[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data bank.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @return A data bank.
|
||||
*/
|
||||
public int[] getData(int bank)
|
||||
{
|
||||
return bankData[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array underlying this <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The data banks.
|
||||
*/
|
||||
public int[][] getBankData()
|
||||
{
|
||||
return bankData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The <code>offset</code> is
|
||||
* added to the specified index before accessing the underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The <code>offset</code>
|
||||
* is added to the specified index before accessing the underlying data
|
||||
* array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
// get unsigned int as int
|
||||
return bankData[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
data[i+offset] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/* DataBufferShort.java --
|
||||
Copyright (C) 2004, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/* This is one of several classes that are nearly identical. Maybe we
|
||||
should have a central template and generate all these files. This
|
||||
is one of the cases where templates or macros would have been
|
||||
useful to have in Java.
|
||||
|
||||
This file has been created using search-replace. My only fear is
|
||||
that these classes will grow out-of-sync as of a result of changes
|
||||
that are not propagated to the other files. As always, mirroring
|
||||
code is a maintenance nightmare. */
|
||||
|
||||
/**
|
||||
* A {@link DataBuffer} that uses an array of <code>short</code> primitives
|
||||
* to represent each of its banks.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public final class DataBufferShort extends DataBuffer
|
||||
{
|
||||
private short[] data;
|
||||
private short[][] bankData;
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with a single data bank containing the
|
||||
* specified number of <code>short</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferShort(int size)
|
||||
{
|
||||
super(TYPE_SHORT, size, 1, 0);
|
||||
bankData = new short[1][];
|
||||
data = new short[size];
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with the specified number of data banks,
|
||||
* each containing the specified number of <code>short</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
public DataBufferShort(int size, int numBanks)
|
||||
{
|
||||
super(TYPE_SHORT, size, numBanks);
|
||||
bankData = new short[numBanks][size];
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferShort(short[] dataArray, int size)
|
||||
{
|
||||
super(TYPE_SHORT, size, 1, 0);
|
||||
bankData = new short[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank, with
|
||||
* the specified offset to the first element.
|
||||
* <p>
|
||||
* Note: there is no exception when <code>dataArray</code> is
|
||||
* <code>null</code>, but in that case an exception will be thrown
|
||||
* later if you attempt to access the data buffer.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offset the offset to the first element in the array.
|
||||
*/
|
||||
public DataBufferShort(short[] dataArray, int size, int offset)
|
||||
{
|
||||
super(TYPE_SHORT, size, 1, offset);
|
||||
bankData = new short[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferShort(short[][] dataArray, int size)
|
||||
{
|
||||
super(TYPE_SHORT, size, dataArray.length);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks, with
|
||||
* the specified offsets to the first element in each bank.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offsets the offsets to the first element in each data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferShort(short[][] dataArray, int size, int[] offsets)
|
||||
{
|
||||
super(TYPE_SHORT, size, dataArray.length, offsets);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first data bank.
|
||||
*
|
||||
* @return The first data bank.
|
||||
*/
|
||||
public short[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data bank.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @return A data bank.
|
||||
*/
|
||||
public short[] getData(int bank)
|
||||
{
|
||||
return bankData[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array underlying this <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The data banks.
|
||||
*/
|
||||
public short[][] getBankData()
|
||||
{
|
||||
return bankData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
return bankData[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
data[i+offset] = (short) val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = (short) val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/* DataBufferUShort.java --
|
||||
Copyright (C) 2000, 2002, 2004, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/* This is one of several classes that are nearly identical. Maybe we
|
||||
should have a central template and generate all these files. This
|
||||
is one of the cases where templates or macros would have been
|
||||
useful to have in Java.
|
||||
|
||||
This file has been created using search-replace. My only fear is
|
||||
that these classes will grow out-of-sync as of a result of changes
|
||||
that are not propagated to the other files. As always, mirroring
|
||||
code is a maintenance nightmare. */
|
||||
|
||||
/**
|
||||
* A {@link DataBuffer} that uses an array of <code>short</code> primitives
|
||||
* to represent each of its banks.
|
||||
*
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public final class DataBufferUShort extends DataBuffer
|
||||
{
|
||||
private short[] data;
|
||||
private short[][] bankData;
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with a single data bank containing the
|
||||
* specified number of <code>short</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
*/
|
||||
public DataBufferUShort(int size)
|
||||
{
|
||||
super(TYPE_USHORT, size, 1, 0);
|
||||
bankData = new short[1][];
|
||||
data = new short[size];
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer with the specified number of data banks,
|
||||
* each containing the specified number of <code>short</code> elements.
|
||||
*
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param numBanks the number of data banks.
|
||||
*/
|
||||
public DataBufferUShort(int size, int numBanks)
|
||||
{
|
||||
super(TYPE_USHORT, size, numBanks);
|
||||
bankData = new short[numBanks][size];
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if dataArray is null
|
||||
*/
|
||||
public DataBufferUShort(short[] dataArray, int size)
|
||||
{
|
||||
super(TYPE_USHORT, size, 1, 0);
|
||||
if (dataArray == null)
|
||||
throw new NullPointerException();
|
||||
bankData = new short[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data bank, with
|
||||
* the specified offset to the first element.
|
||||
*
|
||||
* @param dataArray the data bank.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offset the offset to the first element in the array.
|
||||
*
|
||||
* @throws NullPointerException if dataArray is null
|
||||
*/
|
||||
public DataBufferUShort(short[] dataArray, int size, int offset)
|
||||
{
|
||||
super(TYPE_USHORT, size, 1, offset);
|
||||
if (dataArray == null)
|
||||
throw new NullPointerException();
|
||||
bankData = new short[1][];
|
||||
data = dataArray;
|
||||
bankData[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferUShort(short[][] dataArray, int size)
|
||||
{
|
||||
super(TYPE_USHORT, size, dataArray.length);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data buffer backed by the specified data banks, with
|
||||
* the specified offsets to the first element in each bank.
|
||||
*
|
||||
* @param dataArray the data banks.
|
||||
* @param size the number of elements in the data bank.
|
||||
* @param offsets the offsets to the first element in each data bank.
|
||||
*
|
||||
* @throws NullPointerException if <code>dataArray</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public DataBufferUShort(short[][] dataArray, int size, int[] offsets)
|
||||
{
|
||||
super(TYPE_USHORT, size, dataArray.length, offsets);
|
||||
bankData = dataArray;
|
||||
data = bankData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first data bank.
|
||||
*
|
||||
* @return The first data bank.
|
||||
*/
|
||||
public short[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data bank.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @return A data bank.
|
||||
*/
|
||||
public short[] getData(int bank)
|
||||
{
|
||||
return bankData[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array underlying this <code>DataBuffer</code>.
|
||||
*
|
||||
* @return The data banks.
|
||||
*/
|
||||
public short[][] getBankData()
|
||||
{
|
||||
return bankData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from the first data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int i)
|
||||
{
|
||||
return data[i+offset] & 0xffff; // get unsigned short as int
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element from a particular data bank. The offset (specified in
|
||||
* the constructor) is added to <code>i</code> before accessing the
|
||||
* underlying data array.
|
||||
*
|
||||
* @param bank the bank index.
|
||||
* @param i the element index.
|
||||
* @return The element.
|
||||
*/
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
// get unsigned short as int
|
||||
return bankData[bank][i+offsets[bank]] & 0xffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in the first data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int i, int val)
|
||||
{
|
||||
data[i+offset] = (short) val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an element in a particular data bank. The offset (specified in the
|
||||
* constructor) is added to <code>i</code> before updating the underlying
|
||||
* data array.
|
||||
*
|
||||
* @param bank the data bank index.
|
||||
* @param i the element index.
|
||||
* @param val the new element value.
|
||||
*/
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
bankData[bank][i+offsets[bank]] = (short) val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/* DirectColorModel.java --
|
||||
Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
|
||||
/**
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
* @author Mark Benvenuto (mcb54@columbia.edu)
|
||||
*/
|
||||
public class DirectColorModel extends PackedColorModel
|
||||
{
|
||||
/**
|
||||
* For the color model created with this constructor the pixels
|
||||
* will have fully opaque alpha components with a value of 255.
|
||||
* Each mask should describe a fully contiguous set of bits in the
|
||||
* most likely order of alpha, red, green, blue from the most significant
|
||||
* byte to the least significant byte.
|
||||
*
|
||||
* @param pixelBits the number of bits wide used for bit size of pixel values
|
||||
* @param rmask the bits describing the red component of a pixel
|
||||
* @param gmask the bits describing the green component of a pixel
|
||||
* @param bmask the bits describing the blue component of a pixel
|
||||
*/
|
||||
public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
|
||||
{
|
||||
this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
|
||||
rmask, gmask, bmask, 0,
|
||||
false, // not alpha premultiplied
|
||||
Buffers.smallestAppropriateTransferType(pixelBits) // find type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* For the color model created with this constructor the pixels
|
||||
* will have fully opaque alpha components with a value of 255.
|
||||
* Each mask should describe a fully contiguous set of bits in the
|
||||
* most likely order of red, green, blue from the most significant
|
||||
* byte to the least significant byte.
|
||||
*
|
||||
* @param pixelBits the number of bits wide used for bit size of pixel values
|
||||
* @param rmask the bits describing the red component of a pixel
|
||||
* @param gmask the bits describing the green component of a pixel
|
||||
* @param bmask the bits describing the blue component of a pixel
|
||||
* @param amask the bits describing the alpha component of a pixel
|
||||
*/
|
||||
public DirectColorModel(int pixelBits,
|
||||
int rmask, int gmask, int bmask, int amask)
|
||||
{
|
||||
this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
|
||||
rmask, gmask, bmask, amask,
|
||||
false, // not alpha premultiplied
|
||||
Buffers.smallestAppropriateTransferType(pixelBits) // find type
|
||||
);
|
||||
}
|
||||
|
||||
public DirectColorModel(ColorSpace cspace, int pixelBits,
|
||||
int rmask, int gmask, int bmask, int amask,
|
||||
boolean isAlphaPremultiplied,
|
||||
int transferType)
|
||||
{
|
||||
super(cspace, pixelBits,
|
||||
rmask, gmask, bmask, amask, isAlphaPremultiplied,
|
||||
((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
|
||||
transferType);
|
||||
}
|
||||
|
||||
public final int getRedMask()
|
||||
{
|
||||
return getMask(0);
|
||||
}
|
||||
|
||||
public final int getGreenMask()
|
||||
{
|
||||
return getMask(1);
|
||||
}
|
||||
|
||||
public final int getBlueMask()
|
||||
{
|
||||
return getMask(2);
|
||||
}
|
||||
|
||||
public final int getAlphaMask()
|
||||
{
|
||||
return hasAlpha() ? getMask(3) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the red component of the given pixel.
|
||||
* <br>
|
||||
*/
|
||||
public final int getRed(int pixel)
|
||||
{
|
||||
return extractAndNormalizeSample(pixel, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the green component of the given pixel.
|
||||
* <br>
|
||||
*/
|
||||
public final int getGreen(int pixel)
|
||||
{
|
||||
return extractAndNormalizeSample(pixel, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the blue component of the given pixel.
|
||||
* <br>
|
||||
*/
|
||||
public final int getBlue(int pixel)
|
||||
{
|
||||
return extractAndNormalizeSample(pixel, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alpha component of the given pixel.
|
||||
* <br>
|
||||
*/
|
||||
public final int getAlpha(int pixel)
|
||||
{
|
||||
if (!hasAlpha())
|
||||
return 255;
|
||||
return extractAndScaleSample(pixel, 3);
|
||||
}
|
||||
|
||||
private int extractAndNormalizeSample(int pixel, int component)
|
||||
{
|
||||
int value = extractAndScaleSample(pixel, component);
|
||||
if (hasAlpha() && isAlphaPremultiplied())
|
||||
value = value*255/getAlpha(pixel);
|
||||
return value;
|
||||
}
|
||||
|
||||
private int extractAndScaleSample(int pixel, int component)
|
||||
{
|
||||
int field = pixel & getMask(component);
|
||||
int to8BitShift =
|
||||
8 - shifts[component] - getComponentSize(component);
|
||||
return (to8BitShift>0) ?
|
||||
(field << to8BitShift) :
|
||||
(field >>> (-to8BitShift));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RGB color value of the given pixel using the default
|
||||
* RGB color model.
|
||||
* <br>
|
||||
*
|
||||
* @param pixel a pixel value
|
||||
*/
|
||||
public final int getRGB(int pixel)
|
||||
{
|
||||
/* FIXME: The Sun docs show that this method is overridden, but I
|
||||
don't see any way to improve on the superclass
|
||||
implementation. */
|
||||
return super.getRGB(pixel);
|
||||
}
|
||||
|
||||
public int getRed(Object inData)
|
||||
{
|
||||
return getRed(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
public int getGreen(Object inData)
|
||||
{
|
||||
return getGreen(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
public int getBlue(Object inData)
|
||||
{
|
||||
return getBlue(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
public int getAlpha(Object inData)
|
||||
{
|
||||
return getAlpha(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
public int getRGB(Object inData)
|
||||
{
|
||||
return getRGB(getPixelFromArray(inData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a normalized pixel int value in the sRGB color
|
||||
* space to an array containing a single pixel of the color space
|
||||
* of the color model.
|
||||
*
|
||||
* <p>This method performs the inverse function of
|
||||
* <code>getRGB(Object inData)</code>.
|
||||
*
|
||||
* @param rgb pixel as a normalized sRGB, 0xAARRGGBB value.
|
||||
*
|
||||
* @param pixel to avoid needless creation of arrays, an array to
|
||||
* use to return the pixel can be given. If null, a suitable array
|
||||
* will be created.
|
||||
*
|
||||
* @return array of transferType containing a single pixel. The
|
||||
* pixel should be encoded in the natural way of the color model.
|
||||
*
|
||||
* @see #getRGB(Object)
|
||||
*/
|
||||
public Object getDataElements(int rgb, Object pixel)
|
||||
{
|
||||
// FIXME: handle alpha multiply
|
||||
|
||||
int pixelValue = 0;
|
||||
int a = 0;
|
||||
if (hasAlpha()) {
|
||||
a = (rgb >>> 24) & 0xff;
|
||||
pixelValue = valueToField(a, 3, 8);
|
||||
}
|
||||
|
||||
if (hasAlpha() && isAlphaPremultiplied())
|
||||
{
|
||||
int r, g, b;
|
||||
/* if r=0xff and a=0xff, then resulting
|
||||
value will be (r*a)>>>8 == 0xfe... This seems wrong.
|
||||
We should divide by 255 rather than shifting >>>8 after
|
||||
multiplying.
|
||||
|
||||
Too bad, shifting is probably less expensive.
|
||||
r = ((rgb >>> 16) & 0xff)*a;
|
||||
g = ((rgb >>> 8) & 0xff)*a;
|
||||
b = ((rgb >>> 0) & 0xff)*a; */
|
||||
/* The r, g, b values we calculate are 16 bit. This allows
|
||||
us to avoid discarding the lower 8 bits obtained if
|
||||
multiplying with the alpha band. */
|
||||
|
||||
// using 16 bit values
|
||||
r = ((rgb >>> 8) & 0xff00)*a/255;
|
||||
g = ((rgb >>> 0) & 0xff00)*a/255;
|
||||
b = ((rgb << 8) & 0xff00)*a/255;
|
||||
pixelValue |=
|
||||
valueToField(r, 0, 16) | // Red
|
||||
valueToField(g, 1, 16) | // Green
|
||||
valueToField(b, 2, 16); // Blue
|
||||
}
|
||||
else
|
||||
{
|
||||
int r, g, b;
|
||||
// using 8 bit values
|
||||
r = (rgb >>> 16) & 0xff;
|
||||
g = (rgb >>> 8) & 0xff;
|
||||
b = (rgb >>> 0) & 0xff;
|
||||
|
||||
pixelValue |=
|
||||
valueToField(r, 0, 8) | // Red
|
||||
valueToField(g, 1, 8) | // Green
|
||||
valueToField(b, 2, 8); // Blue
|
||||
}
|
||||
|
||||
/* In this color model, the whole pixel fits in the first element
|
||||
of the array. */
|
||||
DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
|
||||
buffer.setElem(0, pixelValue);
|
||||
return Buffers.getData(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value to the correct field bits based on the
|
||||
* information derived from the field masks.
|
||||
*
|
||||
* @param highBit the position of the most significant bit in the
|
||||
* val parameter.
|
||||
*/
|
||||
private int valueToField(int val, int component, int highBit)
|
||||
{
|
||||
int toFieldShift =
|
||||
getComponentSize(component) + shifts[component] - highBit;
|
||||
int ret = (toFieldShift>0) ?
|
||||
(val << toFieldShift) :
|
||||
(val >>> (-toFieldShift));
|
||||
return ret & getMask(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a 16 bit value to the correct field bits based on the
|
||||
* information derived from the field masks.
|
||||
*/
|
||||
private int value16ToField(int val, int component)
|
||||
{
|
||||
int toFieldShift = getComponentSize(component) + shifts[component] - 16;
|
||||
return (toFieldShift>0) ?
|
||||
(val << toFieldShift) :
|
||||
(val >>> (-toFieldShift));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills an array with the unnormalized component samples from a
|
||||
* pixel value. I.e. decompose the pixel, but not perform any
|
||||
* color conversion.
|
||||
*/
|
||||
public final int[] getComponents(int pixel, int[] components, int offset)
|
||||
{
|
||||
int numComponents = getNumComponents();
|
||||
if (components == null) components = new int[offset + numComponents];
|
||||
|
||||
for (int b=0; b<numComponents; b++)
|
||||
components[offset++] = (pixel&getMask(b)) >>> shifts[b];
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
public final int[] getComponents(Object pixel, int[] components,
|
||||
int offset)
|
||||
{
|
||||
return getComponents(getPixelFromArray(pixel), components, offset);
|
||||
}
|
||||
|
||||
public final WritableRaster createCompatibleWritableRaster(int w, int h)
|
||||
{
|
||||
SampleModel sm = createCompatibleSampleModel(w, h);
|
||||
Point origin = new Point(0, 0);
|
||||
return Raster.createWritableRaster(sm, origin);
|
||||
}
|
||||
|
||||
public int getDataElement(int[] components, int offset)
|
||||
{
|
||||
int numComponents = getNumComponents();
|
||||
int pixelValue = 0;
|
||||
|
||||
for (int c=0; c<numComponents; c++)
|
||||
pixelValue |= (components[offset++] << shifts[c]) & getMask(c);
|
||||
|
||||
return pixelValue;
|
||||
}
|
||||
|
||||
public Object getDataElements(int[] components, int offset, Object obj)
|
||||
{
|
||||
/* In this color model, the whole pixel fits in the first element
|
||||
of the array. */
|
||||
int pixelValue = getDataElement(components, offset);
|
||||
|
||||
DataBuffer buffer = Buffers.createBuffer(transferType, obj, 1);
|
||||
buffer.setElem(0, pixelValue);
|
||||
return Buffers.getData(buffer);
|
||||
}
|
||||
|
||||
public final ColorModel coerceData (WritableRaster raster,
|
||||
boolean isAlphaPremultiplied)
|
||||
{
|
||||
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
|
||||
return this;
|
||||
|
||||
/* TODO: provide better implementation based on the
|
||||
assumptions we can make due to the specific type of the
|
||||
color model. */
|
||||
super.coerceData(raster, isAlphaPremultiplied);
|
||||
|
||||
return new ComponentColorModel(cspace, bits, hasAlpha(),
|
||||
isAlphaPremultiplied, // argument
|
||||
transparency, transferType);
|
||||
}
|
||||
|
||||
public boolean isCompatibleRaster(Raster raster)
|
||||
{
|
||||
/* FIXME: the Sun docs say this method is overridden here,
|
||||
but I don't see any way to improve upon the implementation
|
||||
in ColorModel. */
|
||||
return super.isCompatibleRaster(raster);
|
||||
}
|
||||
|
||||
String stringParam()
|
||||
{
|
||||
return super.stringParam() +
|
||||
", redMask=" + Integer.toHexString(getRedMask()) +
|
||||
", greenMask=" + Integer.toHexString(getGreenMask()) +
|
||||
", blueMask=" + Integer.toHexString(getBlueMask()) +
|
||||
", alphaMask=" + Integer.toHexString(getAlphaMask());
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
/* FIXME: Again, docs say override, but how do we improve upon the
|
||||
superclass implementation? */
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/* FilteredImageSource.java -- Java class for providing image data
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ImageConsumer
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public class FilteredImageSource implements ImageProducer
|
||||
{
|
||||
ImageProducer ip;
|
||||
ImageFilter filter;
|
||||
Hashtable consumers = new Hashtable();
|
||||
|
||||
/**
|
||||
* The given filter is applied to the given image producer
|
||||
* to create a new image producer.
|
||||
*/
|
||||
public FilteredImageSource(ImageProducer ip, ImageFilter filter) {
|
||||
this.ip = ip;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code>.
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic) {
|
||||
if (consumers.containsKey(ic))
|
||||
return;
|
||||
|
||||
ImageFilter f = filter.getFilterInstance(ic);
|
||||
consumers.put(ic, f);
|
||||
ip.addConsumer(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine if the given <code>ImageConsumer</code> is
|
||||
* already registered with this <code>ImageProducer</code>.
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic) {
|
||||
ImageFilter f = (ImageFilter)consumers.get(ic);
|
||||
if (f != null)
|
||||
return ip.isConsumer(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to remove an <code>ImageConsumer</code> from the list of
|
||||
* registered consumers for this <code>ImageProducer</code>.
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic) {
|
||||
ImageFilter f = (ImageFilter)consumers.remove(ic);
|
||||
if (f != null)
|
||||
ip.removeConsumer(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code> and then immediately start
|
||||
* reconstruction of the image data to be delivered to all
|
||||
* registered consumers.
|
||||
*/
|
||||
public void startProduction(ImageConsumer ic) {
|
||||
ImageFilter f;
|
||||
if (!(consumers.containsKey(ic))) {
|
||||
f = filter.getFilterInstance(ic);
|
||||
consumers.put(ic, f);
|
||||
ip.addConsumer(f);
|
||||
} else {
|
||||
f = (ImageFilter)consumers.get( ic );
|
||||
}
|
||||
ip.startProduction(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code> and then request that this producer
|
||||
* resend the image data in the order top-down, left-right.
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic) {
|
||||
ImageFilter f = (ImageFilter)consumers.get(ic);
|
||||
ip.requestTopDownLeftRightResend(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/* ImageConsumer.java -- Java interface for image consumption
|
||||
Copyright (C) 1999, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* An object implementing the <code>ImageProducer</code> interface can
|
||||
* use objects implementing this interface to deliver the image data.
|
||||
*
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public interface ImageConsumer
|
||||
{
|
||||
/**
|
||||
* The pixel order may be random. This should be
|
||||
* the default assumption of the <code>ImageConsumer</code>.
|
||||
*
|
||||
* @see #setHints
|
||||
*/
|
||||
int RANDOMPIXELORDER = 1;
|
||||
|
||||
/**
|
||||
* The pixel order is top-down, left-right.
|
||||
*
|
||||
* @see #setHints
|
||||
*/
|
||||
int TOPDOWNLEFTRIGHT = 2;
|
||||
|
||||
/**
|
||||
* The pixel order is in multiples of complete scanlines.
|
||||
*
|
||||
* @see #setHints
|
||||
*/
|
||||
int COMPLETESCANLINES = 4;
|
||||
|
||||
/**
|
||||
* The pixels will be delivered in a single pass. There is at
|
||||
* most one call to <code>setPixels</code> for any single pixel.
|
||||
*
|
||||
* @see #setHints
|
||||
* @see #setPixels
|
||||
*/
|
||||
int SINGLEPASS = 8;
|
||||
|
||||
/**
|
||||
* The pixels will be delivered with multiple calls to
|
||||
* <code>setPixels</code>. The image contains a single frame
|
||||
* which ends when <code>imageComplete</code> is called with the
|
||||
* <code>STATICIMAGEDONE</code> flag. If the image is constantly
|
||||
* changing such as with video then the end of each frame is
|
||||
* marked by a similar call to <code>imageComplete</code> with the
|
||||
* <code>SINGLEFRAMEDONE</code> flag.
|
||||
*
|
||||
* @see #setHints
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int SINGLEFRAME = 16;
|
||||
|
||||
/**
|
||||
* Indicates an error occurred while producing an image.
|
||||
*
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int IMAGEERROR = 1;
|
||||
|
||||
/**
|
||||
* A single frame is complete but more will follow.
|
||||
*
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int SINGLEFRAMEDONE = 2;
|
||||
|
||||
/**
|
||||
* The image is complete and no more pixels or frames will follow.
|
||||
*
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int STATICIMAGEDONE = 3;
|
||||
|
||||
/**
|
||||
* Production of the image has been aborted.
|
||||
*
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int IMAGEABORTED = 4;
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> indicates the size of the image
|
||||
* being produced using this method.
|
||||
*
|
||||
* @param width the width of the image
|
||||
* @param height the height of the image
|
||||
*/
|
||||
void setDimensions(int width, int height);
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> can set a list of properties
|
||||
* associated with this image by using this method.
|
||||
*
|
||||
* @param props the list of properties associated with this image
|
||||
*/
|
||||
void setProperties(Hashtable props);
|
||||
|
||||
/**
|
||||
* This <code>ColorModel</code> should indicate the model used by
|
||||
* the majority of calls to <code>setPixels</code>. Each call to
|
||||
* <code>setPixels</code> could however indicate a different
|
||||
* <code>ColorModel</code>.
|
||||
*
|
||||
* @param model the color model to be used most often by setPixels
|
||||
* @see ColorModel
|
||||
*/
|
||||
void setColorModel(ColorModel model);
|
||||
|
||||
/**
|
||||
* The <code>ImageProducer</code> should call this method with a
|
||||
* bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
|
||||
* <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
|
||||
* <code>SINGLEPASS</code>, <code>SINGLEFRAME</code>.
|
||||
*
|
||||
* @param flags a bit mask of hints
|
||||
*/
|
||||
void setHints(int flags);
|
||||
|
||||
/**
|
||||
* Deliver a subset of an ImageProducer's pixels to this ImageConsumer.
|
||||
*
|
||||
* Each element of the pixels array represents one pixel. The
|
||||
* pixel data is formatted according to the color model model.
|
||||
* The x and y parameters are the coordinates of the block of
|
||||
* pixels being delivered to this ImageConsumer. They are
|
||||
* specified relative to the top left corner of the image being
|
||||
* produced. Likewise, w and h are the pixel block's dimensions.
|
||||
*
|
||||
* @param x x coordinate of pixel block
|
||||
* @param y y coordinate of pixel block
|
||||
* @param w width of pixel block
|
||||
* @param h height of pixel block
|
||||
* @param model color model used to interpret pixel data
|
||||
* @param pixels pixel block data
|
||||
* @param offset offset into pixels array
|
||||
* @param scansize width of one row in the pixel block
|
||||
*/
|
||||
void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels, int offset, int scansize);
|
||||
|
||||
/**
|
||||
* Deliver a subset of an ImageProducer's pixels to this ImageConsumer.
|
||||
*
|
||||
* Each element of the pixels array represents one pixel. The
|
||||
* pixel data is formatted according to the color model model.
|
||||
* The x and y parameters are the coordinates of the rectangular
|
||||
* region of pixels being delivered to this ImageConsumer,
|
||||
* specified relative to the top left corner of the image being
|
||||
* produced. Likewise, w and h are the pixel region's dimensions.
|
||||
*
|
||||
* @param x x coordinate of pixel block
|
||||
* @param y y coordinate of pixel block
|
||||
* @param w width of pixel block
|
||||
* @param h height of pixel block
|
||||
* @param model color model used to interpret pixel data
|
||||
* @param pixels pixel block data
|
||||
* @param offset offset into pixels array
|
||||
* @param scansize width of one row in the pixel block
|
||||
*/
|
||||
void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels, int offset, int scansize);
|
||||
|
||||
/**
|
||||
* The <code>ImageProducer</code> calls this method to indicate a
|
||||
* single frame or the entire image is complete. The method is
|
||||
* also used to indicate an error in loading or producing the
|
||||
* image.
|
||||
*
|
||||
* @param status the status of image production, represented by a
|
||||
* bitwise OR of ImageConsumer flags
|
||||
*/
|
||||
void imageComplete(int status);
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/* ImageFilter.java -- Java class for filtering images
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* The <code>ImageFilter</code> class is a base class which can be
|
||||
* extended to provide different types of filters for an image. By
|
||||
* default this class does nothing to an image passing through it.
|
||||
*
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public class ImageFilter implements ImageConsumer, Cloneable
|
||||
{
|
||||
/**
|
||||
* The consumer this filter is filtering an image data stream for.
|
||||
* It is initialized in the method <code>getFilterInstance</code>.
|
||||
*/
|
||||
protected ImageConsumer consumer = null;
|
||||
|
||||
/**
|
||||
* The <code>ImageConsumer</code> can use this method to request
|
||||
* the pixels be delivered in top-down, left-right order.
|
||||
* <br>
|
||||
* The filter can respond in three different ways.
|
||||
* <ul>
|
||||
* <li>The default behavior is to forward the request to the
|
||||
* <code>ImageProducer</code>
|
||||
* using the method <code>requestTopDownLeftRightResend</code>
|
||||
* and using the filter as the consumer.</li>
|
||||
* <li>The filter has the pixels and can retransmit them in the
|
||||
* top-down, left-right order.</li>
|
||||
* <li>The filter can do nothing when this method is called.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void resendTopDownLeftRight(ImageProducer ip)
|
||||
{
|
||||
ip.requestTopDownLeftRightResend(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, returns a shallow copy of the object created by
|
||||
* <code>Object.clone()</code>
|
||||
*
|
||||
* @see java.lang.Object#clone ()
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
// This should never happen as this class implements the
|
||||
// Cloneable interface.
|
||||
throw new InternalError ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the only method which can set the
|
||||
* <code>ImageConsumer</code> for this filter. By default a clone
|
||||
* of this filter with the appropriate consumer set is returned.
|
||||
*
|
||||
* @see #clone ()
|
||||
*/
|
||||
public ImageFilter getFilterInstance(ImageConsumer ic)
|
||||
{
|
||||
if ( ic == null )
|
||||
throw new IllegalArgumentException("null argument for ImageFilter.getFilterInstance(ImageConsumer)");
|
||||
|
||||
consumer = ic;
|
||||
ImageFilter f = (ImageFilter)clone();
|
||||
consumer = null;
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> indicates the size of the image
|
||||
* being produced using this method. A filter can override this
|
||||
* method to intercept these calls from the producer in order to
|
||||
* change either the width or the height before in turn calling
|
||||
* the consumer's <code>setDimensions</code> method.
|
||||
*
|
||||
* @param width the width of the image
|
||||
* @param height the height of the image
|
||||
*/
|
||||
public void setDimensions(int width, int height)
|
||||
{
|
||||
consumer.setDimensions(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> can set a list of properties
|
||||
* associated with this image by using this method.
|
||||
*
|
||||
* @param props the list of properties associated with this image
|
||||
*/
|
||||
public void setProperties(Hashtable props)
|
||||
{
|
||||
props.put("filters", "ImageFilter");
|
||||
consumer.setProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to process calls to this method from the
|
||||
* <code>ImageProducer</code>. By default the <code>setColorModel</code>
|
||||
* method of the consumer is called with the specified <code>model</code>.
|
||||
*
|
||||
* @param model the color model to be used most often by setPixels
|
||||
* @see ColorModel */
|
||||
public void setColorModel(ColorModel model)
|
||||
{
|
||||
consumer.setColorModel(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>ImageProducer</code> should call this method with a
|
||||
* bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
|
||||
* <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
|
||||
* <code>SINGLEPASS</code>, <code>SINGLEFRAME</code> from the
|
||||
* <code>ImageConsumer</code> interface.
|
||||
*
|
||||
* @param flags a bit mask of hints
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public void setHints(int flags)
|
||||
{
|
||||
consumer.setHints(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as a <code>byte</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels, int offset, int scansize)
|
||||
{
|
||||
consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as an <code>int</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels, int offset, int scansize)
|
||||
{
|
||||
consumer.setPixels(x, y, w, h, model, pixels, offset, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>ImageProducer</code> calls this method to indicate a
|
||||
* single frame or the entire image is complete. The method is
|
||||
* also used to indicate an error in loading or producing the
|
||||
* image.
|
||||
*/
|
||||
public void imageComplete(int status)
|
||||
{
|
||||
consumer.imageComplete(status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/* ImageObserver.java -- Java interface for asynchronous updates to an image
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Image;
|
||||
|
||||
/**
|
||||
* An object implementing the <code>ImageObserver</code> interface can
|
||||
* receive updates on image construction from an
|
||||
* <code>ImageProducer</code> asynchronously.
|
||||
*
|
||||
* @see ImageProducer
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public interface ImageObserver
|
||||
{
|
||||
/**
|
||||
* The width of the image has been provided as the
|
||||
* <code>width</code> argument to <code>imageUpdate</code>.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int WIDTH = 1;
|
||||
|
||||
/**
|
||||
* The height of the image has been provided as the
|
||||
* <code>height</code> argument to <code>imageUpdate</code>.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int HEIGHT = 2;
|
||||
|
||||
/**
|
||||
* The properties of the image have been provided.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
* @see java.awt.Image#getProperty (java.lang.String, java.awt.image.ImageObserver)
|
||||
*/
|
||||
int PROPERTIES = 4;
|
||||
|
||||
/**
|
||||
* More pixels are now available for drawing a scaled variation of
|
||||
* the image.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int SOMEBITS = 8;
|
||||
|
||||
/**
|
||||
* All the pixels needed to draw a complete frame of a multi-frame
|
||||
* image are available.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int FRAMEBITS = 16;
|
||||
|
||||
/**
|
||||
* An image with a single frame, a static image, is complete.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int ALLBITS = 32;
|
||||
|
||||
/**
|
||||
* An error was encountered while producing the image.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int ERROR = 64;
|
||||
|
||||
/**
|
||||
* Production of the image was aborted.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
int ABORT = 128;
|
||||
|
||||
/**
|
||||
* This is a callback method for an asynchronous image producer to
|
||||
* provide updates on the production of the image as it happens.
|
||||
*
|
||||
* @param image the image the update refers to
|
||||
* @param flags a bit mask indicating what is provided with this update
|
||||
* @param x the x coordinate of the image
|
||||
* @param y the y coordinate of the image
|
||||
* @param width the width of the image
|
||||
* @param height the height of the image
|
||||
*
|
||||
* @see java.awt.Image
|
||||
*/
|
||||
boolean imageUpdate(Image image, int flags, int x,
|
||||
int y, int width, int height);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* ImageProducer.java -- Java interface for image production
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* An object implementing the <code>ImageProducer</code> interface can
|
||||
* produce data for images. Each image has a corresponding
|
||||
* <code>ImageProducer</code> which is needed for things such as
|
||||
* resizing the image.
|
||||
*
|
||||
* @see ImageConsumer
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public interface ImageProducer
|
||||
{
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code>.
|
||||
*/
|
||||
void addConsumer(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Used to determine if the given <code>ImageConsumer</code> is
|
||||
* already registered with this <code>ImageProducer</code>.
|
||||
*/
|
||||
boolean isConsumer(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Used to remove an <code>ImageConsumer</code> from the list of
|
||||
* registered consumers for this <code>ImageProducer</code>.
|
||||
*/
|
||||
void removeConsumer(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code> and then immediately start
|
||||
* reconstruction of the image data to be delivered to all
|
||||
* registered consumers.
|
||||
*/
|
||||
void startProduction(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code> and then request that this producer
|
||||
* resend the image data in the order top-down, left-right.
|
||||
*/
|
||||
void requestTopDownLeftRightResend(ImageConsumer ic);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/* ImagingOpException.java -- indicates an imaging filter failure
|
||||
Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This exception is thrown when <code>BufferedImageOp</code> or
|
||||
* <code>RasterOp</code> filters cannot process an image.
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @see BufferedImageOp
|
||||
* @see RasterOp
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class ImagingOpException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.0+.
|
||||
*/
|
||||
private static final long serialVersionUID = 8026288481846276658L;
|
||||
|
||||
/**
|
||||
* Create a new instance with a descriptive error message.
|
||||
*
|
||||
* @param message the descriptive error message
|
||||
*/
|
||||
public ImagingOpException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
} // class ImagingOpException
|
||||
@@ -0,0 +1,697 @@
|
||||
/* IndexColorModel.java -- Java class for interpreting Pixel objects
|
||||
Copyright (C) 1999, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Color model similar to pseudo visual in X11.
|
||||
* <br><br>
|
||||
* This color model maps linear pixel values to actual RGB and alpha colors.
|
||||
* Thus, pixel values are indexes into the color map. Each color component is
|
||||
* an 8-bit unsigned value.
|
||||
* <br><br>
|
||||
* The <code>IndexColorModel</code> supports a map of valid pixels, allowing
|
||||
* the representation of holes in the the color map. The valid map is
|
||||
* represented as a {@link BigInteger} where each bit indicates the validity
|
||||
* of the map entry with the same index.
|
||||
* <br><br>
|
||||
* Colors can have alpha components for transparency support. If alpha
|
||||
* component values aren't given, color values are opaque. The model also
|
||||
* supports a reserved pixel value to represent completely transparent colors,
|
||||
* no matter what the actual color component values are.
|
||||
* <br><br>
|
||||
* <code>IndexColorModel</code> supports anywhere from 1 to 16 bit index
|
||||
* values. The allowed transfer types are {@link DataBuffer#TYPE_BYTE} and
|
||||
* {@link DataBuffer#TYPE_USHORT}.
|
||||
*
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public class IndexColorModel extends ColorModel
|
||||
{
|
||||
private int map_size;
|
||||
private boolean opaque; // no alpha, but doesn't account for trans
|
||||
private int trans = -1;
|
||||
private int[] rgb;
|
||||
private BigInteger validBits = BigInteger.ZERO;
|
||||
|
||||
/**
|
||||
* Creates a new indexed color model for <code>size</code> color elements
|
||||
* with no alpha component. Each array must contain at least
|
||||
* <code>size</code> elements. For each array, the i-th color is described
|
||||
* by reds[i], greens[i] and blues[i].
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors.
|
||||
* @param size the number of colors in the color map.
|
||||
* @param reds the red component of all colors.
|
||||
* @param greens the green component of all colors.
|
||||
* @param blues the blue component of all colors.
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>bits</code> < 1 or
|
||||
* <code>bits</code> > 16.
|
||||
* @throws NullPointerException if any of the arrays is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater
|
||||
* than the length of the component arrays.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
|
||||
byte[] blues)
|
||||
{
|
||||
this(bits, size, reds, greens, blues, (byte[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new indexed color model for <code>size</code> color elements.
|
||||
* Each array must contain at least <code>size</code> elements. For each
|
||||
* array, the i-th color is described by reds[i], greens[i] and blues[i].
|
||||
* All the colors are opaque except for the transparent color.
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors
|
||||
* @param size the number of colors in the color map
|
||||
* @param reds the red component of all colors
|
||||
* @param greens the green component of all colors
|
||||
* @param blues the blue component of all colors
|
||||
* @param trans the index of the transparent color (use -1 for no
|
||||
* transparent color).
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>bits</code> < 1 or
|
||||
* <code>bits</code> > 16.
|
||||
* @throws NullPointerException if any of the arrays is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater
|
||||
* than the length of the component arrays.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
|
||||
byte[] blues, int trans)
|
||||
{
|
||||
super(bits, nArray(8, (0 <= trans && trans < size) ? 4 : 3),
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
(0 <= trans && trans < size), // hasAlpha
|
||||
false, OPAQUE,
|
||||
Buffers.smallestAppropriateTransferType(bits));
|
||||
if (bits < 1)
|
||||
throw new IllegalArgumentException("bits < 1");
|
||||
if (bits > 16)
|
||||
throw new IllegalArgumentException("bits > 16");
|
||||
if (size < 1)
|
||||
throw new IllegalArgumentException("size < 1");
|
||||
map_size = size;
|
||||
if (0 <= trans && trans < size) {
|
||||
this.trans = trans;
|
||||
transparency = BITMASK;
|
||||
}
|
||||
rgb = new int[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
rgb[i] = (0xff000000
|
||||
| ((reds[i] & 0xff) << 16)
|
||||
| ((greens[i] & 0xff) << 8)
|
||||
| (blues[i] & 0xff));
|
||||
}
|
||||
// Generate a bigint with 1's for every pixel
|
||||
validBits = validBits.setBit(size).subtract(BigInteger.ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new indexed color model for <code>size</code> color elements
|
||||
* including alpha. Each array must contain at least <code>size</code>
|
||||
* elements. For each array, the i-th color is described
|
||||
* by reds[i], greens[i], blues[i] and alphas[i].
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors.
|
||||
* @param size the number of colors in the color map.
|
||||
* @param reds the red component of all colors.
|
||||
* @param greens the green component of all colors.
|
||||
* @param blues the blue component of all colors.
|
||||
* @param alphas the alpha component of all colors (<code>null</code>
|
||||
* permitted).
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>bits</code> < 1 or
|
||||
* <code>bits</code> > 16.
|
||||
* @throws NullPointerException if <code>reds</code>, <code>greens</code> or
|
||||
* <code>blues</code> is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>size</code> is greater
|
||||
* than the length of the component arrays.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, byte[] reds, byte[] greens,
|
||||
byte[] blues, byte[] alphas)
|
||||
{
|
||||
super(bits, nArray(8, (alphas == null ? 3 : 4)),
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
(alphas != null), false, TRANSLUCENT,
|
||||
Buffers.smallestAppropriateTransferType(bits));
|
||||
if (bits < 1)
|
||||
throw new IllegalArgumentException("bits < 1");
|
||||
if (bits > 16)
|
||||
throw new IllegalArgumentException("bits > 16");
|
||||
if (size < 1)
|
||||
throw new IllegalArgumentException("size < 1");
|
||||
map_size = size;
|
||||
opaque = (alphas == null);
|
||||
|
||||
rgb = new int[size];
|
||||
if (alphas == null)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
rgb[i] = (0xff000000
|
||||
| ((reds[i] & 0xff) << 16)
|
||||
| ((greens[i] & 0xff) << 8)
|
||||
| (blues[i] & 0xff));
|
||||
}
|
||||
transparency = OPAQUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte alphaZero = (byte) 0x00;
|
||||
byte alphaOne = (byte) 0xFF;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
alphaZero = (byte) (alphaZero | alphas[i]);
|
||||
alphaOne = (byte) (alphaOne & alphas[i]);
|
||||
rgb[i] = ((alphas[i] & 0xff) << 24
|
||||
| ((reds[i] & 0xff) << 16)
|
||||
| ((greens[i] & 0xff) << 8)
|
||||
| (blues[i] & 0xff));
|
||||
}
|
||||
if ((alphaZero == (byte) 0x00) || (alphaOne == (byte) 0xFF))
|
||||
transparency = BITMASK;
|
||||
else
|
||||
transparency = TRANSLUCENT;
|
||||
}
|
||||
|
||||
// Generate a bigint with 1's for every pixel
|
||||
validBits = validBits.setBit(size).subtract(BigInteger.ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new indexed color model using the color components in
|
||||
* <code>cmap</code>. If <code>hasAlpha</code> is <code>true</code> then
|
||||
* <code>cmap</code> contains an alpha component after each of the red, green
|
||||
* and blue components.
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors
|
||||
* @param size the number of colors in the color map
|
||||
* @param cmap packed color components
|
||||
* @param start the offset of the first color component in <code>cmap</code>
|
||||
* @param hasAlpha <code>cmap</code> has alpha values
|
||||
* @throws IllegalArgumentException if bits < 1, bits > 16, or size
|
||||
* < 1.
|
||||
* @throws NullPointerException if <code>cmap</code> is <code>null</code>.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, byte[] cmap, int start,
|
||||
boolean hasAlpha)
|
||||
{
|
||||
this(bits, size, cmap, start, hasAlpha, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an IndexColorModel from an array of red, green, blue, and
|
||||
* optional alpha components. The component values are interleaved as RGB(A).
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors
|
||||
* @param size the number of colors in the color map
|
||||
* @param cmap interleaved color components
|
||||
* @param start the offset of the first color component in <code>cmap</code>
|
||||
* @param hasAlpha <code>cmap</code> has alpha values
|
||||
* @param trans the index of the transparent color
|
||||
* @throws IllegalArgumentException if bits < 1, bits > 16, or size
|
||||
* < 1.
|
||||
* @throws NullPointerException if <code>cmap</code> is <code>null</code>.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, byte[] cmap, int start,
|
||||
boolean hasAlpha, int trans)
|
||||
{
|
||||
super(bits, nArray(8, hasAlpha || (0 <= trans && trans < size) ? 4 : 3),
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
hasAlpha || (0 <= trans && trans < size), false, OPAQUE,
|
||||
Buffers.smallestAppropriateTransferType(bits));
|
||||
if (bits < 1)
|
||||
throw new IllegalArgumentException("bits < 1");
|
||||
if (bits > 16)
|
||||
throw new IllegalArgumentException("bits > 16");
|
||||
if (size < 1)
|
||||
throw new IllegalArgumentException("size < 1");
|
||||
map_size = size;
|
||||
opaque = !hasAlpha;
|
||||
if (0 <= trans && trans < size)
|
||||
this.trans = trans;
|
||||
|
||||
rgb = new int[size];
|
||||
if (hasAlpha)
|
||||
{
|
||||
int alpha;
|
||||
int alphaZero = 0x00; // use to detect all zeros
|
||||
int alphaOne = 0xff; // use to detect all ones
|
||||
for (int i = 0; i < size; i++) {
|
||||
alpha = cmap[4 * i + 3 + start] & 0xff;
|
||||
alphaZero = alphaZero | alpha;
|
||||
alphaOne = alphaOne & alpha;
|
||||
rgb[i] =
|
||||
( alpha << 24
|
||||
// red
|
||||
| ((cmap[4 * i + start] & 0xff) << 16)
|
||||
// green
|
||||
| ((cmap[4 * i + 1 + start] & 0xff) << 8)
|
||||
// blue
|
||||
| (cmap[4 * i + 2 + start] & 0xff));
|
||||
}
|
||||
if (alphaZero == 0)
|
||||
transparency = BITMASK;
|
||||
else if (alphaOne == 255)
|
||||
transparency = (trans != -1 ? BITMASK : OPAQUE);
|
||||
else
|
||||
transparency = TRANSLUCENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
rgb[i] = (0xff000000
|
||||
// red
|
||||
| ((cmap[3 * i + start] & 0xff) << 16)
|
||||
// green
|
||||
| ((cmap[3 * i + 1 + start] & 0xff) << 8)
|
||||
// blue
|
||||
| (cmap[3 * i + 2 + start] & 0xff));
|
||||
if (trans != -1)
|
||||
transparency = BITMASK;
|
||||
}
|
||||
|
||||
// Generate a bigint with 1's for every pixel
|
||||
validBits = validBits.setBit(size).subtract(BigInteger.ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an IndexColorModel from an array of <code>size</code> packed
|
||||
* colors. Each int element contains 8-bit red, green, blue, and optional
|
||||
* alpha values packed in order. If hasAlpha is false, then all the colors
|
||||
* are opaque except for the transparent color.
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors
|
||||
* @param size the number of colors in the color map
|
||||
* @param cmap packed color components
|
||||
* @param start the offset of the first color component in <code>cmap</code>
|
||||
* @param hasAlpha <code>cmap</code> has alpha values
|
||||
* @param trans the index of the transparent color
|
||||
* @param transferType {@link DataBuffer#TYPE_BYTE} or
|
||||
{@link DataBuffer#TYPE_USHORT}.
|
||||
* @throws IllegalArgumentException if bits < 1, bits > 16, or size
|
||||
* < 1.
|
||||
* @throws IllegalArgumentException if <code>transferType</code> is something
|
||||
* other than {@link DataBuffer#TYPE_BYTE} or
|
||||
* {@link DataBuffer#TYPE_USHORT}.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, int[] cmap, int start,
|
||||
boolean hasAlpha, int trans, int transferType)
|
||||
{
|
||||
super(bits,
|
||||
nArray(8, 4), // bits for each channel
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
|
||||
true, // has alpha
|
||||
false, // not premultiplied
|
||||
TRANSLUCENT, transferType);
|
||||
if (transferType != DataBuffer.TYPE_BYTE
|
||||
&& transferType != DataBuffer.TYPE_USHORT)
|
||||
throw new IllegalArgumentException();
|
||||
if (bits > 16)
|
||||
throw new IllegalArgumentException("bits > 16");
|
||||
if (size < 1)
|
||||
throw new IllegalArgumentException("size < 1");
|
||||
map_size = size;
|
||||
opaque = !hasAlpha;
|
||||
if (0 <= trans && trans < size)
|
||||
this.trans = trans;
|
||||
|
||||
rgb = new int[size];
|
||||
if (!hasAlpha)
|
||||
for (int i = 0; i < size; i++)
|
||||
rgb[i] = cmap[i + start] | 0xff000000;
|
||||
else
|
||||
System.arraycopy(cmap, start, rgb, 0, size);
|
||||
|
||||
// Generate a bigint with 1's for every pixel
|
||||
validBits = validBits.setBit(size).subtract(BigInteger.ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an IndexColorModel using a colormap with holes.
|
||||
* <br><br>
|
||||
* The IndexColorModel is built from the array of ints defining the
|
||||
* colormap. Each element contains red, green, blue, and alpha
|
||||
* components. The ColorSpace is sRGB. The transparency value is
|
||||
* automatically determined.
|
||||
* <br><br>
|
||||
* This constructor permits indicating which colormap entries are valid,
|
||||
* using the validBits argument. Each entry in cmap is valid if the
|
||||
* corresponding bit in validBits is set.
|
||||
*
|
||||
* @param bits the number of bits needed to represent <code>size</code>
|
||||
* colors.
|
||||
* @param size the number of colors in the color map.
|
||||
* @param cmap packed color components.
|
||||
* @param start the offset of the first color component in <code>cmap</code>.
|
||||
* @param transferType {@link DataBuffer#TYPE_BYTE} or
|
||||
* {@link DataBuffer#TYPE_USHORT}.
|
||||
* @param validBits a map of the valid entries in <code>cmap</code>.
|
||||
* @throws IllegalArgumentException if bits < 1, bits > 16, or size
|
||||
* < 1.
|
||||
* @throws IllegalArgumentException if transferType is something other than
|
||||
* {@link DataBuffer#TYPE_BYTE} or {@link DataBuffer#TYPE_USHORT}.
|
||||
*/
|
||||
public IndexColorModel(int bits, int size, int[] cmap, int start,
|
||||
int transferType, BigInteger validBits)
|
||||
{
|
||||
super(bits, // total bits, sRGB, four channels
|
||||
nArray(8, 4), // bits for each channel
|
||||
ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
|
||||
true, // has alpha
|
||||
false, // not premultiplied
|
||||
TRANSLUCENT, transferType);
|
||||
if (transferType != DataBuffer.TYPE_BYTE
|
||||
&& transferType != DataBuffer.TYPE_USHORT)
|
||||
throw new IllegalArgumentException();
|
||||
if (bits > 16)
|
||||
throw new IllegalArgumentException("bits > 16");
|
||||
if (size < 1)
|
||||
throw new IllegalArgumentException("size < 1");
|
||||
map_size = size;
|
||||
opaque = false;
|
||||
this.trans = -1;
|
||||
this.validBits = validBits;
|
||||
|
||||
rgb = new int[size];
|
||||
if (!hasAlpha)
|
||||
for (int i = 0; i < size; i++)
|
||||
rgb[i] = cmap[i + start] | 0xff000000;
|
||||
else
|
||||
System.arraycopy(cmap, start, rgb, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the color lookup table.
|
||||
*
|
||||
* @return The size of the color lookup table.
|
||||
*/
|
||||
public final int getMapSize()
|
||||
{
|
||||
return map_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the transparent color in this color model.
|
||||
*
|
||||
* @return The index of the color that is considered transparent, or -1 if
|
||||
* there is no transparent color.
|
||||
*/
|
||||
public final int getTransparentPixel()
|
||||
{
|
||||
return trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the supplied array with the red component of each color in the
|
||||
* lookup table.
|
||||
*
|
||||
* @param r an array that is at least as large as {@link #getMapSize()}.
|
||||
* @throws NullPointerException if <code>r</code> is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>r</code> has less
|
||||
* than {@link #getMapSize()} elements.
|
||||
*/
|
||||
public final void getReds(byte[] r)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < map_size; i++)
|
||||
r[i] = (byte) ((0x00FF0000 & rgb[i]) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the supplied array with the green component of each color in the
|
||||
* lookup table.
|
||||
*
|
||||
* @param g an array that is at least as large as {@link #getMapSize()}.
|
||||
* @throws NullPointerException if <code>g</code> is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>g</code> has less
|
||||
* than {@link #getMapSize()} elements.
|
||||
*/
|
||||
public final void getGreens(byte[] g)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < map_size; i++)
|
||||
g[i] = (byte) ((0x0000FF00 & rgb[i]) >> 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the supplied array with the blue component of each color in the
|
||||
* lookup table.
|
||||
*
|
||||
* @param b an array that is at least as large as {@link #getMapSize()}.
|
||||
* @throws NullPointerException if <code>b</code> is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>b</code> has less
|
||||
* than {@link #getMapSize()} elements.
|
||||
*/
|
||||
public final void getBlues(byte[] b)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < map_size; i++)
|
||||
b[i] = (byte) (0x000000FF & rgb[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the supplied array with the alpha component of each color in the
|
||||
* lookup table. If the model has a transparent pixel specified, the alpha
|
||||
* for that pixel will be 0.
|
||||
*
|
||||
* @param a an array that is at least as large as {@link #getMapSize()}.
|
||||
* @throws NullPointerException if <code>a</code> is <code>null</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>a</code> has less
|
||||
* than {@link #getMapSize()} elements.
|
||||
*/
|
||||
public final void getAlphas(byte[] a)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < map_size; i++)
|
||||
if (i == trans)
|
||||
a[i] = (byte) 0;
|
||||
else
|
||||
a[i] = (byte) ((0xFF000000 & rgb[i]) >> 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the red component of the color in the lookup table for the
|
||||
* given pixel value.
|
||||
*
|
||||
* @param pixel the pixel lookup value.
|
||||
*
|
||||
* @return The red component of the color in the lookup table.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
|
||||
*/
|
||||
public final int getRed(int pixel)
|
||||
{
|
||||
if (pixel < map_size)
|
||||
return (0x00FF0000 & rgb[pixel]) >> 16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the green component of the color in the lookup table for the
|
||||
* given pixel value.
|
||||
*
|
||||
* @param pixel the pixel lookup value.
|
||||
*
|
||||
* @return The green component of the color in the lookup table.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
|
||||
*/
|
||||
public final int getGreen(int pixel)
|
||||
{
|
||||
if (pixel < map_size)
|
||||
return (0x0000FF00 & rgb[pixel]) >> 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the blue component of the color in the lookup table for the
|
||||
* given pixel value.
|
||||
*
|
||||
* @param pixel the pixel lookup value.
|
||||
*
|
||||
* @return The blue component of the color in the lookup table.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
|
||||
*/
|
||||
public final int getBlue(int pixel)
|
||||
{
|
||||
if (pixel < map_size)
|
||||
return 0x000000FF & rgb[pixel];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alpha component of the color in the lookup table for the
|
||||
* given pixel value. If no alpha channel was specified when the color model
|
||||
* was created, then 255 is returned for all pixels except the transparent
|
||||
* pixel (if one is defined - see {@link #getTransparentPixel()}) which
|
||||
* returns an alpha of 0.
|
||||
*
|
||||
* @param pixel the pixel lookup value.
|
||||
*
|
||||
* @return The alpha component of the color in the lookup table (in the
|
||||
* range 0 to 255).
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
|
||||
*/
|
||||
public final int getAlpha(int pixel)
|
||||
{
|
||||
if (opaque && pixel != trans)
|
||||
return 255;
|
||||
if ((pixel == trans && trans != -1) || pixel >= map_size)
|
||||
return 0;
|
||||
|
||||
return (0xFF000000 & rgb[pixel]) >> 24;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RGB color value of the given pixel using the default
|
||||
* RGB color model.
|
||||
*
|
||||
* @param pixel the pixel lookup value.
|
||||
* @return The RGB color value.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>pixel</code> is negative.
|
||||
*/
|
||||
public final int getRGB(int pixel)
|
||||
{
|
||||
if (pixel >= 0 && pixel < map_size)
|
||||
return rgb[pixel];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RGB color values of all pixels in the map using the default
|
||||
* RGB color model.
|
||||
*
|
||||
* @param rgb The destination array.
|
||||
*/
|
||||
public final void getRGBs(int[] rgb)
|
||||
{
|
||||
System.arraycopy(this.rgb, 0, rgb, 0, map_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if the lookup table contains valid data for
|
||||
* <code>pixel</code>, and <code>false</code> otherwise.
|
||||
*
|
||||
* @param pixel the pixel value used to index the color lookup table.
|
||||
* @return <code>true</code> if <code>pixel</code> is valid,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isValid(int pixel)
|
||||
{
|
||||
if (pixel >= 0)
|
||||
return validBits.testBit(pixel);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if all pixels are valid, <code>false</code>
|
||||
* otherwise.
|
||||
*
|
||||
* @return <code>true</code> if all pixels are valid, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isValid()
|
||||
{
|
||||
// Generate a bigint with 1's for every pixel
|
||||
BigInteger allbits = new BigInteger("0");
|
||||
allbits = allbits.setBit(map_size);
|
||||
allbits = allbits.subtract(new BigInteger("1"));
|
||||
return allbits.equals(validBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a binary value ({@link BigInteger}) where each bit represents an
|
||||
* entry in the color lookup table. If the bit is on, the entry is valid.
|
||||
*
|
||||
* @return The binary value.
|
||||
*/
|
||||
public BigInteger getValidPixels()
|
||||
{
|
||||
return validBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link BufferedImage} with rgb pixel values from a
|
||||
* {@link Raster}.
|
||||
*
|
||||
* Constructs a new BufferedImage in which each pixel is an RGBA int from
|
||||
* a Raster with index-valued pixels. If this model has no alpha component
|
||||
* or transparent pixel, the type of the new BufferedImage is TYPE_INT_RGB.
|
||||
* Otherwise the type is TYPE_INT_ARGB. If forceARGB is true, the type is
|
||||
* forced to be TYPE_INT_ARGB no matter what.
|
||||
*
|
||||
* @param raster The source of pixel values.
|
||||
* @param forceARGB True if type must be TYPE_INT_ARGB.
|
||||
* @return New BufferedImage with RBGA int pixel values.
|
||||
*/
|
||||
public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB)
|
||||
{
|
||||
int type = forceARGB ? BufferedImage.TYPE_INT_ARGB
|
||||
: ((opaque && trans == -1) ? BufferedImage.TYPE_INT_RGB :
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
// FIXME: assuming that raster has only 1 band since pixels are supposed
|
||||
// to be int indexes.
|
||||
// FIXME: it would likely be more efficient to fetch a complete array,
|
||||
// but it would take much more memory.
|
||||
// FIXME: I'm not sure if transparent pixels or alpha values need special
|
||||
// handling here.
|
||||
BufferedImage im = new BufferedImage(raster.width, raster.height, type);
|
||||
for (int x = raster.minX; x < raster.width + raster.minX; x++)
|
||||
for (int y = raster.minY; y < raster.height + raster.minY; y++)
|
||||
im.setRGB(x, y, rgb[raster.getSample(x, y, 0)]);
|
||||
|
||||
return im;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/* Kernel.java -- Java class for an image processing kernel
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* Kernel represents an image processing kernel. It gets used to hold
|
||||
* convolution filters among other purposes. It stores an array of float
|
||||
* values representing a 2-dimensional array in row-major order.
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Kernel implements Cloneable
|
||||
{
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final float[] data;
|
||||
|
||||
/**
|
||||
* Creates a new <code>Kernel</code> instance.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public Kernel(int width, int height, float[] data)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
if (data.length < width * height || width < 0 || height < 0)
|
||||
throw new IllegalArgumentException();
|
||||
this.data = new float[width * height];
|
||||
System.arraycopy(data, 0, this.data, 0, width * height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the X origin: (width - 1) / 2
|
||||
*/
|
||||
public final int getXOrigin()
|
||||
{
|
||||
return (width - 1) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Y origin: (height - 1) / 2
|
||||
*/
|
||||
public final int getYOrigin()
|
||||
{
|
||||
return (height - 1) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The kernel width.
|
||||
*/
|
||||
public final int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The kernel height.
|
||||
*/
|
||||
public final int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the kernel data.
|
||||
*
|
||||
* 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.
|
||||
* @return The array with copied values.
|
||||
* @exception IllegalArgumentException if data != null and too small.
|
||||
*/
|
||||
public final float[] getKernelData(float[] data)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if (data == null)
|
||||
return (float[])this.data.clone();
|
||||
|
||||
if (data.length < this.data.length)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
System.arraycopy(this.data, 0, data, 0, this.data.length);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a clone of this Kernel.
|
||||
*/
|
||||
public Object clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
throw (Error) new InternalError().initCause(e); // Impossible
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/* LookupOp.java -- Filter that converts each pixel using a lookup table.
|
||||
Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* LookupOp is a filter that converts each pixel using a lookup table.
|
||||
*
|
||||
* For filtering Rasters, the lookup table must have either one component
|
||||
* that is applied to all bands, or one component for every band in the
|
||||
* Rasters.
|
||||
*
|
||||
* For BufferedImages, the lookup table may apply to both color and alpha
|
||||
* components. If the lookup table contains one component, or if there are
|
||||
* the same number of components as color components in the source, the table
|
||||
* applies to all color components. Otherwise the table applies to all
|
||||
* components including alpha. Alpha premultiplication is ignored during the
|
||||
* lookup filtering.
|
||||
*
|
||||
* After filtering, if color conversion is necessary, the conversion happens,
|
||||
* taking alpha premultiplication into account.
|
||||
*
|
||||
* @author jlquinn
|
||||
*/
|
||||
public class LookupOp implements BufferedImageOp, RasterOp
|
||||
{
|
||||
private LookupTable lut;
|
||||
private RenderingHints hints;
|
||||
|
||||
/** Construct a new LookupOp.
|
||||
*
|
||||
* @param lookup LookupTable to use.
|
||||
* @param hints Rendering hints (can be null).
|
||||
*/
|
||||
public LookupOp(LookupTable lookup, RenderingHints hints)
|
||||
{
|
||||
lut = lookup;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage)
|
||||
*/
|
||||
public BufferedImage filter(BufferedImage src, BufferedImage dst)
|
||||
{
|
||||
if (src.getColorModel() instanceof IndexColorModel)
|
||||
throw new IllegalArgumentException("LookupOp.filter: IndexColorModel "
|
||||
+ "not allowed");
|
||||
if (dst == null)
|
||||
dst = createCompatibleDestImage(src, src.getColorModel());
|
||||
|
||||
// Set up for potential colormodel mismatch
|
||||
BufferedImage tgt;
|
||||
if (dst.getColorModel().equals(src.getColorModel()))
|
||||
tgt = dst;
|
||||
else
|
||||
tgt = createCompatibleDestImage(src, src.getColorModel());
|
||||
|
||||
Raster sr = src.getRaster();
|
||||
WritableRaster dr = tgt.getRaster();
|
||||
|
||||
if (src.getColorModel().hasAlpha() &&
|
||||
(lut.getNumComponents() == 1 ||
|
||||
lut.getNumComponents() == src.getColorModel().getNumColorComponents()))
|
||||
{
|
||||
// Need to ignore alpha for lookup
|
||||
int[] dbuf = new int[src.getColorModel().getNumComponents()];
|
||||
int tmpBands = src.getColorModel().getNumColorComponents();
|
||||
int[] tmp = new int[tmpBands];
|
||||
|
||||
// Filter the pixels
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
|
||||
{
|
||||
// Filter only color components, but also copy alpha
|
||||
sr.getPixel(x, y, dbuf);
|
||||
System.arraycopy(dbuf, 0, tmp, 0, tmpBands);
|
||||
dr.setPixel(x, y, lut.lookupPixel(tmp, dbuf));
|
||||
}
|
||||
}
|
||||
else if (lut.getNumComponents() != 1
|
||||
&&
|
||||
lut.getNumComponents() != src.getColorModel().getNumComponents())
|
||||
throw new IllegalArgumentException("LookupOp.filter: "
|
||||
+ "Incompatible lookup "
|
||||
+ "table and source image");
|
||||
|
||||
// No alpha to ignore
|
||||
int[] dbuf = new int[src.getColorModel().getNumComponents()];
|
||||
|
||||
// Filter the pixels
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
|
||||
dr.setPixel(x, y, lut.lookupPixel(sr.getPixel(x, y, dbuf), dbuf));
|
||||
|
||||
if (tgt != dst)
|
||||
{
|
||||
// Convert between color models.
|
||||
// TODO Check that premultiplied alpha is handled correctly here.
|
||||
Graphics2D gg = dst.createGraphics();
|
||||
gg.setRenderingHints(hints);
|
||||
gg.drawImage(tgt, 0, 0, null);
|
||||
gg.dispose();
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
|
||||
*/
|
||||
public Rectangle2D getBounds2D(BufferedImage src)
|
||||
{
|
||||
return src.getRaster().getBounds();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage(BufferedImage src,
|
||||
ColorModel dstCM)
|
||||
{
|
||||
// FIXME: set properties to those in src
|
||||
return new BufferedImage(dstCM,
|
||||
src.getRaster().createCompatibleWritableRaster(),
|
||||
src.isPremultiplied, null);
|
||||
}
|
||||
|
||||
/** Return corresponding destination point for source point.
|
||||
*
|
||||
* LookupOp will return the value of src unchanged.
|
||||
* @param src The source point.
|
||||
* @param dst The destination point.
|
||||
* @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
|
||||
*/
|
||||
public Point2D getPoint2D(Point2D src, Point2D dst)
|
||||
{
|
||||
if (dst == null)
|
||||
return (Point2D) src.clone();
|
||||
|
||||
dst.setLocation(src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/** Return the LookupTable for this op. */
|
||||
public LookupTable getTable()
|
||||
{
|
||||
return lut;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getRenderingHints()
|
||||
*/
|
||||
public RenderingHints getRenderingHints()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
/** Filter a raster through a lookup table.
|
||||
*
|
||||
* Applies the lookup table for this Rasterop to each pixel of src and
|
||||
* puts the results in dest. If dest is null, a new Raster is created and
|
||||
* returned.
|
||||
*
|
||||
* @param src The source raster.
|
||||
* @param dest The destination raster.
|
||||
* @return The WritableRaster with the filtered pixels.
|
||||
* @throws IllegalArgumentException if lookup table has more than one
|
||||
* component but not the same as src and dest.
|
||||
* @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
|
||||
*/
|
||||
public WritableRaster filter(Raster src, WritableRaster dest)
|
||||
{
|
||||
if (dest == null)
|
||||
// Allocate a raster if needed
|
||||
dest = createCompatibleDestRaster(src);
|
||||
else
|
||||
if (src.getNumBands() != dest.getNumBands())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
if (lut.getNumComponents() != 1
|
||||
&& lut.getNumComponents() != src.getNumBands())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
|
||||
// Allocate pixel storage.
|
||||
int[] tmp = new int[src.getNumBands()];
|
||||
|
||||
// Filter the pixels
|
||||
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
|
||||
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
|
||||
dest.setPixel(x, y, lut.lookupPixel(src.getPixel(x, y, tmp), tmp));
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
|
||||
*/
|
||||
public Rectangle2D getBounds2D(Raster src)
|
||||
{
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src)
|
||||
{
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/* LookupTable.java -- Java class for a pixel translation table.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* LookupTable represents translation arrays for pixel values. It wraps one
|
||||
* or more data arrays for each layer (or component) in an image, such as
|
||||
* Alpha, R, G, and B. When doing translation, the offset is subtracted from
|
||||
* the pixel values to allow a subset of an array to be used.
|
||||
*
|
||||
* @see ByteLookupTable
|
||||
* @see ShortLookupTable
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class LookupTable
|
||||
{
|
||||
// Not protected since that's part of the public API.
|
||||
int offset;
|
||||
int numComponents;
|
||||
|
||||
/**
|
||||
* Creates a new <code>LookupTable</code> instance.
|
||||
*
|
||||
* If numComponents is 1, the same translation table is used for all pixel
|
||||
* components.
|
||||
*
|
||||
* @param offset Offset to be subtracted.
|
||||
* @param numComponents Number of image components.
|
||||
* @exception IllegalArgumentException if offset < 0 or numComponents < 1.
|
||||
*/
|
||||
protected LookupTable(int offset, int numComponents)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if (offset < 0 || numComponents < 1)
|
||||
throw new IllegalArgumentException();
|
||||
this.offset = offset;
|
||||
this.numComponents = numComponents;
|
||||
}
|
||||
|
||||
/** Return the number of components. */
|
||||
public int getNumComponents()
|
||||
{
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
/** Return the offset. */
|
||||
public int getOffset()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return translated values for a pixel.
|
||||
*
|
||||
* For each value in the pixel src, use the value minus offset as an index
|
||||
* in the component array and copy the value there to the output for the
|
||||
* component. If dest is null, the output is a new array, otherwise the
|
||||
* translated values are written to dest. Dest can be the same array as
|
||||
* src.
|
||||
*
|
||||
* For example, if the pixel src is [2, 4, 3], and offset is 1, the output
|
||||
* is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
|
||||
* translation arrays.
|
||||
*
|
||||
* @param src Component values of a pixel.
|
||||
* @param dest Destination array for values, or null.
|
||||
* @return Translated values for the pixel.
|
||||
*/
|
||||
public abstract int[] lookupPixel(int[] src, int[] dest);
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
/* MemoryImageSource.java -- Java class for providing image data
|
||||
Copyright (C) 1999, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
public class MemoryImageSource implements ImageProducer
|
||||
{
|
||||
private boolean animated = false;
|
||||
private boolean fullbuffers = false;
|
||||
private int[] pixeli;
|
||||
private int width;
|
||||
private int height;
|
||||
private int offset;
|
||||
private int scansize;
|
||||
private byte[] pixelb;
|
||||
private ColorModel cm;
|
||||
private Hashtable props = new Hashtable();
|
||||
private Vector consumers = new Vector();
|
||||
|
||||
/**
|
||||
* Construct an image producer that reads image data from a byte
|
||||
* array.
|
||||
*
|
||||
* @param w width of image
|
||||
* @param h height of image
|
||||
* @param cm the color model used to represent pixel values
|
||||
* @param pix a byte array of pixel values
|
||||
* @param off the offset into the array at which the first pixel is stored
|
||||
* @param scan the number of array elements that represents a single pixel row
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm, byte[] pix, int off,
|
||||
int scan)
|
||||
{
|
||||
this(w, h, cm, pix, off, scan, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer from memory
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm, byte[] pix, int off,
|
||||
int scan, Hashtable props)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
this.cm = cm;
|
||||
offset = off;
|
||||
scansize = scan;
|
||||
this.props = props;
|
||||
int max = ((scansize > width) ? scansize : width);
|
||||
pixelb = pix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an image producer that reads image data from an
|
||||
* integer array.
|
||||
*
|
||||
* @param w width of image
|
||||
* @param h height of image
|
||||
* @param cm the color model used to represent pixel values
|
||||
* @param pix an integer array of pixel values
|
||||
* @param off the offset into the array at which the first pixel is stored
|
||||
* @param scan the number of array elements that represents a single pixel row
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm, int[] pix, int off,
|
||||
int scan)
|
||||
{
|
||||
this(w, h, cm, pix, off, scan, null);
|
||||
}
|
||||
|
||||
/**
|
||||
Constructs an ImageProducer from memory
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm, int[] pix, int off,
|
||||
int scan, Hashtable props)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
this.cm = cm;
|
||||
offset = off;
|
||||
scansize = scan;
|
||||
this.props = props;
|
||||
int max = ((scansize > width) ? scansize : width);
|
||||
pixeli = pix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer from memory using the default RGB ColorModel
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, int[] pix, int off, int scan,
|
||||
Hashtable props)
|
||||
{
|
||||
this(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer from memory using the default RGB ColorModel
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, int[] pix, int off, int scan)
|
||||
{
|
||||
this(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code>.
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic)
|
||||
{
|
||||
if (consumers.contains(ic))
|
||||
return;
|
||||
|
||||
consumers.addElement(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine if the given <code>ImageConsumer</code> is
|
||||
* already registered with this <code>ImageProducer</code>.
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic)
|
||||
{
|
||||
if (consumers.contains(ic))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to remove an <code>ImageConsumer</code> from the list of
|
||||
* registered consumers for this <code>ImageProducer</code>.
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic)
|
||||
{
|
||||
consumers.removeElement(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code> and then immediately start
|
||||
* reconstruction of the image data to be delivered to all
|
||||
* registered consumers.
|
||||
*/
|
||||
public void startProduction(ImageConsumer ic)
|
||||
{
|
||||
if (! (consumers.contains(ic)))
|
||||
consumers.addElement(ic);
|
||||
|
||||
Vector list = (Vector) consumers.clone();
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
{
|
||||
ic = (ImageConsumer) list.elementAt(i);
|
||||
sendPicture(ic);
|
||||
if (animated)
|
||||
ic.imageComplete(ImageConsumer.SINGLEFRAME);
|
||||
else
|
||||
ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to register an <code>ImageConsumer</code> with this
|
||||
* <code>ImageProducer</code> and then request that this producer
|
||||
* resend the image data in the order top-down, left-right.
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic)
|
||||
{
|
||||
startProduction(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes a flag to indicate whether this MemoryImageSource supports
|
||||
* animations.
|
||||
*
|
||||
* @param animated A flag indicating whether this class supports animations
|
||||
*/
|
||||
public synchronized void setAnimated(boolean animated)
|
||||
{
|
||||
this.animated = animated;
|
||||
}
|
||||
|
||||
/**
|
||||
* A flag to indicate whether or not to send full buffer updates when
|
||||
* sending animation. If this flag is set then full buffers are sent
|
||||
* in the newPixels methods instead of just regions.
|
||||
*
|
||||
* @param fullbuffers - a flag indicating whether to send the full buffers
|
||||
*/
|
||||
public synchronized void setFullBufferUpdates(boolean fullbuffers)
|
||||
{
|
||||
this.fullbuffers = fullbuffers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an animation frame to the image consumers.
|
||||
*/
|
||||
public void newPixels()
|
||||
{
|
||||
if (animated == true)
|
||||
{
|
||||
ImageConsumer ic;
|
||||
Vector list = (Vector) consumers.clone();
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
{
|
||||
ic = (ImageConsumer) list.elementAt(i);
|
||||
sendPicture(ic);
|
||||
ic.imageComplete(ImageConsumer.SINGLEFRAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPicture(ImageConsumer ic)
|
||||
{
|
||||
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT);
|
||||
if (props != null)
|
||||
ic.setProperties(props);
|
||||
ic.setDimensions(width, height);
|
||||
ic.setColorModel(cm);
|
||||
if (pixeli != null)
|
||||
ic.setPixels(0, 0, width, height, cm, pixeli, offset, scansize);
|
||||
else
|
||||
ic.setPixels(0, 0, width, height, cm, pixelb, offset, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an animation frame to the image consumers containing the specified
|
||||
* pixels unless setFullBufferUpdates is set.
|
||||
*/
|
||||
public synchronized void newPixels(int x, int y, int w, int h)
|
||||
{
|
||||
if (animated == true)
|
||||
{
|
||||
if (fullbuffers)
|
||||
newPixels();
|
||||
else
|
||||
{
|
||||
ImageConsumer ic;
|
||||
Vector list = (Vector) consumers.clone();
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
{
|
||||
ic = (ImageConsumer) list.elementAt(i);
|
||||
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT);
|
||||
if (props != null)
|
||||
ic.setProperties(props);
|
||||
if (pixeli != null)
|
||||
{
|
||||
int[] pixelbuf = new int[w * h];
|
||||
for (int row = y; row < y + h; row++)
|
||||
System.arraycopy(pixeli, row * scansize + x + offset,
|
||||
pixelbuf, 0, w * h);
|
||||
ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] pixelbuf = new byte[w * h];
|
||||
for (int row = y; row < y + h; row++)
|
||||
System.arraycopy(pixelb, row * scansize + x + offset,
|
||||
pixelbuf, 0, w * h);
|
||||
|
||||
ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
|
||||
}
|
||||
ic.imageComplete(ImageConsumer.SINGLEFRAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an animation frame to the image consumers containing the specified
|
||||
* pixels unless setFullBufferUpdates is set.
|
||||
*
|
||||
* If framenotify is set then a notification is sent when the frame
|
||||
* is sent otherwise no status is sent.
|
||||
*/
|
||||
public synchronized void newPixels(int x, int y, int w, int h,
|
||||
boolean framenotify)
|
||||
{
|
||||
if (animated == true)
|
||||
{
|
||||
if (fullbuffers)
|
||||
newPixels();
|
||||
else
|
||||
{
|
||||
ImageConsumer ic;
|
||||
Vector list = (Vector) consumers.clone();
|
||||
for (int i = 0; i < list.size(); i++)
|
||||
{
|
||||
ic = (ImageConsumer) list.elementAt(i);
|
||||
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT);
|
||||
if (props != null)
|
||||
ic.setProperties(props);
|
||||
if (pixeli != null)
|
||||
{
|
||||
int[] pixelbuf = new int[w * h];
|
||||
for (int row = y; row < y + h; row++)
|
||||
System.arraycopy(pixeli, row * scansize + x + offset,
|
||||
pixelbuf, 0, w * h);
|
||||
ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] pixelbuf = new byte[w * h];
|
||||
for (int row = y; row < y + h; row++)
|
||||
System.arraycopy(pixelb, row * scansize + x + offset,
|
||||
pixelbuf, 0, w * h);
|
||||
ic.setPixels(x, y, w, h, cm, pixelbuf, 0, w);
|
||||
}
|
||||
if (framenotify == true)
|
||||
ic.imageComplete(ImageConsumer.SINGLEFRAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void newPixels(byte[] newpix, ColorModel newmodel,
|
||||
int offset, int scansize)
|
||||
{
|
||||
pixeli = null;
|
||||
pixelb = newpix;
|
||||
cm = newmodel;
|
||||
this.offset = offset;
|
||||
this.scansize = scansize;
|
||||
if (animated == true)
|
||||
newPixels();
|
||||
}
|
||||
|
||||
public synchronized void newPixels(int[] newpix, ColorModel newmodel,
|
||||
int offset, int scansize)
|
||||
{
|
||||
pixelb = null;
|
||||
pixeli = newpix;
|
||||
cm = newmodel;
|
||||
this.offset = offset;
|
||||
this.scansize = scansize;
|
||||
if (animated == true)
|
||||
newPixels();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
/**
|
||||
* MultiPixelPackedSampleModel provides a single band model that supports
|
||||
* multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
|
||||
* per data element.
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
*/
|
||||
public class MultiPixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
private int scanlineStride;
|
||||
private int[] bitMasks;
|
||||
private int[] bitOffsets;
|
||||
private int[] sampleSize;
|
||||
private int dataBitOffset;
|
||||
private int elemBits;
|
||||
private int numberOfBits;
|
||||
private int numElems;
|
||||
|
||||
public MultiPixelPackedSampleModel(int dataType, int w, int h,
|
||||
int numberOfBits)
|
||||
{
|
||||
this(dataType, w, h, numberOfBits, 0, 0);
|
||||
}
|
||||
|
||||
public MultiPixelPackedSampleModel(int dataType, int w, int h,
|
||||
int numberOfBits, int scanlineStride,
|
||||
int dataBitOffset)
|
||||
{
|
||||
super(dataType, w, h, 1);
|
||||
|
||||
switch (dataType)
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
elemBits = 8;
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
elemBits = 16;
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
elemBits = 32;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("MultiPixelPackedSampleModel"
|
||||
+ " unsupported dataType");
|
||||
}
|
||||
|
||||
this.dataBitOffset = dataBitOffset;
|
||||
|
||||
this.numberOfBits = numberOfBits;
|
||||
if (numberOfBits > elemBits)
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel pixel size"
|
||||
+ " larger than dataType");
|
||||
switch (numberOfBits)
|
||||
{
|
||||
case 1: case 2: case 4: case 8: case 16: case 32: break;
|
||||
default:
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel pixel"
|
||||
+ " size not 2^n bits");
|
||||
}
|
||||
numElems = elemBits / numberOfBits;
|
||||
|
||||
// Compute scan line large enough for w pixels.
|
||||
if (scanlineStride == 0)
|
||||
scanlineStride = ((dataBitOffset + w * numberOfBits) / elemBits);
|
||||
this.scanlineStride = scanlineStride;
|
||||
|
||||
|
||||
sampleSize = new int[1];
|
||||
sampleSize[0] = numberOfBits;
|
||||
|
||||
bitMasks = new int[numElems];
|
||||
bitOffsets = new int[numElems];
|
||||
for (int i=0; i < numElems; i++)
|
||||
{
|
||||
bitOffsets[numElems - i- 1] = numberOfBits * i;
|
||||
bitMasks[numElems - i - 1] = ((1 << numberOfBits) - 1) <<
|
||||
bitOffsets[numElems - i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
/* FIXME: We can avoid recalculation of bit offsets and sample
|
||||
sizes here by passing these from the current instance to a
|
||||
special private constructor. */
|
||||
return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer for holding pixel data in the format and
|
||||
* layout described by this SampleModel. The returned buffer will
|
||||
* consist of one single bank.
|
||||
*/
|
||||
public DataBuffer createDataBuffer()
|
||||
{
|
||||
int size;
|
||||
|
||||
// FIXME: The comment refers to SinglePixelPackedSampleModel. See if the
|
||||
// same can be done for MultiPixelPackedSampleModel.
|
||||
// We can save (scanlineStride - width) pixels at the very end of
|
||||
// the buffer. The Sun reference implementation (J2SE 1.3.1 and
|
||||
// 1.4.1_01) seems to do this; tested with Mauve test code.
|
||||
size = scanlineStride * height;
|
||||
|
||||
return Buffers.createBuffer(getDataType(), size);
|
||||
}
|
||||
|
||||
|
||||
public int getNumDataElements()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int[] getSampleSize()
|
||||
{
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
public int getSampleSize(int band)
|
||||
{
|
||||
return sampleSize[0];
|
||||
}
|
||||
|
||||
public int getOffset(int x, int y)
|
||||
{
|
||||
return scanlineStride * y + ((dataBitOffset + x*numberOfBits) / elemBits);
|
||||
}
|
||||
|
||||
public int getBitOffset(int x)
|
||||
{
|
||||
return (dataBitOffset + x*numberOfBits) % elemBits;
|
||||
}
|
||||
|
||||
public int getDataBitOffset()
|
||||
{
|
||||
return dataBitOffset;
|
||||
}
|
||||
|
||||
public int getScanlineStride()
|
||||
{
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
public int getPixelBitStride()
|
||||
{
|
||||
return numberOfBits;
|
||||
}
|
||||
|
||||
|
||||
public SampleModel createSubsetSampleModel(int[] bands)
|
||||
{
|
||||
int numBands = bands.length;
|
||||
if (numBands != 1)
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel only"
|
||||
+ " supports one band");
|
||||
|
||||
return new MultiPixelPackedSampleModel(dataType, width, height,
|
||||
numberOfBits, scanlineStride,
|
||||
dataBitOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract one pixel and return in an array of transfer type.
|
||||
*
|
||||
* Extracts the pixel at x, y from data and stores into the 0th index of the
|
||||
* 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 <code>obj</code>.
|
||||
* @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
|
||||
* @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)
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
if (iArray == null) iArray = new int[1];
|
||||
iArray[0] = getSample(x, y, 0, data);
|
||||
|
||||
return iArray;
|
||||
}
|
||||
|
||||
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<h; y++)
|
||||
{
|
||||
int lineOffset = offset;
|
||||
for (x=0; x<w;)
|
||||
{
|
||||
int samples = data.getElem(lineOffset++);
|
||||
for (int b=0; b<numElems && x<w; b++)
|
||||
{
|
||||
iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
|
||||
x++;
|
||||
}
|
||||
}
|
||||
offset += scanlineStride;
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public int getSample(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
int pos =
|
||||
((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
|
||||
int offset = getOffset(x, y);
|
||||
int samples = data.getElem(offset);
|
||||
return (samples & bitMasks[pos]) >>> bitOffsets[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pixel at x, y to the value in the first element of the primitive
|
||||
* array obj.
|
||||
*
|
||||
* @param x The x-coordinate of the data elements in <code>obj</code>.
|
||||
* @param y The y-coordinate of the data elements in <code>obj</code>.
|
||||
* @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");
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
setSample(x, y, 0, iArray[0], data);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, int s, DataBuffer data)
|
||||
{
|
||||
int bitpos =
|
||||
((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
|
||||
int offset = getOffset(x, y);
|
||||
|
||||
s = s << bitOffsets[bitpos];
|
||||
s = s & bitMasks[bitpos];
|
||||
|
||||
int sample = data.getElem(offset);
|
||||
sample |= s;
|
||||
data.setElem(offset, sample);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a String with some information about this SampleModel.
|
||||
* @return A String describing this SampleModel.
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append(getClass().getName());
|
||||
result.append("[");
|
||||
result.append("scanlineStride=").append(scanlineStride);
|
||||
for(int i=0; i < bitMasks.length; i+=1)
|
||||
{
|
||||
result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
|
||||
}
|
||||
|
||||
result.append("]");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.BitMaskExtent;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.color.ColorSpace;
|
||||
|
||||
/**
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public abstract class PackedColorModel extends ColorModel
|
||||
{
|
||||
private int masks[];
|
||||
|
||||
/* Package accessibility, the DirectColorModel needs this array */
|
||||
int shifts[];
|
||||
|
||||
public PackedColorModel(ColorSpace cspace, int pixelBits,
|
||||
int[] colorMaskArray, int alphaMask,
|
||||
boolean isAlphaPremultiplied,
|
||||
int transparency,
|
||||
int transferType)
|
||||
{
|
||||
super(pixelBits, calcBitsPerComponent(colorMaskArray, alphaMask),
|
||||
cspace, (alphaMask != 0), isAlphaPremultiplied, transparency,
|
||||
transferType);
|
||||
initMasks(colorMaskArray, alphaMask);
|
||||
if ((pixelBits<1) || (pixelBits>32)) {
|
||||
throw new IllegalArgumentException("pixels per bits must be " +
|
||||
"in the range [1, 32]");
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] calcBitsPerComponent(int[] colorMaskArray,
|
||||
int alphaMask)
|
||||
{
|
||||
int numComponents = colorMaskArray.length;
|
||||
if (alphaMask != 0) numComponents++;
|
||||
|
||||
int[] bitsPerComponent = new int[numComponents];
|
||||
|
||||
BitMaskExtent extent = new BitMaskExtent();
|
||||
for (int b=0; b<colorMaskArray.length; b++)
|
||||
{
|
||||
extent.setMask(colorMaskArray[b]);
|
||||
bitsPerComponent[b] = extent.bitWidth;
|
||||
}
|
||||
if (alphaMask != 0)
|
||||
{
|
||||
extent.setMask(alphaMask);
|
||||
bitsPerComponent[numComponents-1] = extent.bitWidth;
|
||||
}
|
||||
return bitsPerComponent;
|
||||
}
|
||||
|
||||
/** Initializes the masks.
|
||||
*
|
||||
* @return an array containing the number of bits per color
|
||||
* component.
|
||||
*/
|
||||
private void initMasks(int[] colorMaskArray, int alphaMask)
|
||||
{
|
||||
int numComponents = colorMaskArray.length;
|
||||
if (alphaMask == 0)
|
||||
{
|
||||
masks = colorMaskArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
masks = new int[numComponents+1];
|
||||
System.arraycopy(colorMaskArray, 0,
|
||||
masks, 0,
|
||||
numComponents);
|
||||
masks[numComponents++] = alphaMask;
|
||||
}
|
||||
|
||||
shifts = new int[numComponents];
|
||||
|
||||
// Bit field handling have been moved to a utility class
|
||||
BitMaskExtent extent = new BitMaskExtent();
|
||||
for (int b=0; b<numComponents; b++)
|
||||
{
|
||||
extent.setMask(masks[b]);
|
||||
shifts[b] = extent.leastSignificantBit;
|
||||
}
|
||||
}
|
||||
|
||||
public PackedColorModel(ColorSpace cspace, int pixelBits,
|
||||
int rmask, int gmask, int bmask,
|
||||
int amask, boolean isAlphaPremultiplied,
|
||||
int transparency,
|
||||
int transferType)
|
||||
{
|
||||
this(cspace, pixelBits, makeColorMaskArray(rmask, gmask, bmask),
|
||||
amask, isAlphaPremultiplied, transparency, transferType);
|
||||
}
|
||||
|
||||
/* TODO: If there is a alpha mask, it is inefficient to create a
|
||||
color mask array that will be discarded when the alpha mask is
|
||||
appended. We should probably create a private constructor that
|
||||
takes a complete array of masks (color+alpha) as an
|
||||
argument. */
|
||||
|
||||
private static int[] makeColorMaskArray(int rmask, int gmask, int bmask)
|
||||
{
|
||||
int[] colorMaskArray = { rmask, gmask, bmask };
|
||||
return colorMaskArray;
|
||||
}
|
||||
|
||||
public final int getMask(int index)
|
||||
{
|
||||
return masks[index];
|
||||
}
|
||||
|
||||
public final int[] getMasks()
|
||||
{
|
||||
return masks;
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
return new SinglePixelPackedSampleModel(transferType, w, h, masks);
|
||||
}
|
||||
|
||||
public boolean isCompatibleSampleModel(SampleModel sm)
|
||||
{
|
||||
if (!super.isCompatibleSampleModel(sm)) return false;
|
||||
if (!(sm instanceof SinglePixelPackedSampleModel)) return false;
|
||||
|
||||
SinglePixelPackedSampleModel sppsm =
|
||||
(SinglePixelPackedSampleModel) sm;
|
||||
return java.util.Arrays.equals(sppsm.getBitMasks(), masks);
|
||||
}
|
||||
|
||||
public WritableRaster getAlphaRaster(WritableRaster raster) {
|
||||
if (!hasAlpha()) return null;
|
||||
|
||||
SampleModel sm = raster.getSampleModel();
|
||||
int[] alphaBand = { sm.getNumBands() - 1 };
|
||||
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
|
||||
DataBuffer buffer = raster.getDataBuffer();
|
||||
Point origin = new Point(0, 0);
|
||||
return Raster.createWritableRaster(alphaModel, buffer, origin);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (!super.equals(obj)) return false;
|
||||
if (!(obj instanceof PackedColorModel)) return false;
|
||||
|
||||
PackedColorModel other = (PackedColorModel) obj;
|
||||
|
||||
return java.util.Arrays.equals(masks, other.masks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,618 @@
|
||||
/* PixelGrabber.java -- retrieve a subset of an image's data
|
||||
Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* PixelGrabber is an ImageConsumer that extracts a rectangular region
|
||||
* of pixels from an Image.
|
||||
*/
|
||||
public class PixelGrabber implements ImageConsumer
|
||||
{
|
||||
int x, y, offset;
|
||||
int width = -1;
|
||||
int height = -1;
|
||||
int scansize = -1;
|
||||
boolean forceRGB = true;
|
||||
|
||||
ColorModel model = ColorModel.getRGBdefault();
|
||||
int hints;
|
||||
Hashtable props;
|
||||
|
||||
int int_pixel_buffer[];
|
||||
boolean ints_delivered = false;
|
||||
byte byte_pixel_buffer[];
|
||||
boolean bytes_delivered = false;
|
||||
|
||||
ImageProducer ip;
|
||||
int observerStatus;
|
||||
int consumerStatus;
|
||||
|
||||
private Thread grabberThread;
|
||||
boolean grabbing = false;
|
||||
|
||||
/**
|
||||
* Construct a PixelGrabber that will retrieve RGB data from a given
|
||||
* Image.
|
||||
*
|
||||
* The RGB data will be retrieved from a rectangular region
|
||||
* <code>(x, y, w, h)</code> within the image. The data will be
|
||||
* stored in the provided <code>pix</code> array, which must have
|
||||
* been initialized to a size of at least <code>w * h</code>. The
|
||||
* data for a pixel (m, n) in the grab rectangle will be stored at
|
||||
* <code>pix[(n - y) * scansize + (m - x) + off]</code>.
|
||||
*
|
||||
* @param img the Image from which to grab pixels
|
||||
* @param x the x coordinate, relative to <code>img</code>'s
|
||||
* top-left corner, of the grab rectangle's top-left pixel
|
||||
* @param y the y coordinate, relative to <code>img</code>'s
|
||||
* top-left corner, of the grab rectangle's top-left pixel
|
||||
* @param w the width of the grab rectangle, in pixels
|
||||
* @param h the height of the grab rectangle, in pixels
|
||||
* @param pix the array in which to store grabbed RGB pixel data
|
||||
* @param off the offset into the <code>pix</code> array at which to
|
||||
* start storing RGB data
|
||||
* @param scansize a set of <code>scansize</code> consecutive
|
||||
* elements in the <code>pix</code> array represents one row of
|
||||
* pixels in the grab rectangle
|
||||
*/
|
||||
public PixelGrabber(Image img, int x, int y, int w, int h,
|
||||
int pix[], int off, int scansize)
|
||||
{
|
||||
this (img.getSource(), x, y, w, h, pix, off, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a PixelGrabber that will retrieve RGB data from a given
|
||||
* ImageProducer.
|
||||
*
|
||||
* The RGB data will be retrieved from a rectangular region
|
||||
* <code>(x, y, w, h)</code> within the image produced by
|
||||
* <code>ip</code>. The data will be stored in the provided
|
||||
* <code>pix</code> array, which must have been initialized to a
|
||||
* size of at least <code>w * h</code>. The data for a pixel (m, n)
|
||||
* in the grab rectangle will be stored at
|
||||
* <code>pix[(n - y) * scansize + (m - x) + off]</code>.
|
||||
*
|
||||
* @param ip the ImageProducer from which to grab pixels
|
||||
* @param x the x coordinate of the grab rectangle's top-left pixel,
|
||||
* specified relative to the top-left corner of the image produced
|
||||
* by <code>ip</code>
|
||||
* @param y the y coordinate of the grab rectangle's top-left pixel,
|
||||
* specified relative to the top-left corner of the image produced
|
||||
* by <code>ip</code>
|
||||
* @param w the width of the grab rectangle, in pixels
|
||||
* @param h the height of the grab rectangle, in pixels
|
||||
* @param pix the array in which to store grabbed RGB pixel data
|
||||
* @param off the offset into the <code>pix</code> array at which to
|
||||
* start storing RGB data
|
||||
* @param scansize a set of <code>scansize</code> consecutive
|
||||
* elements in the <code>pix</code> array represents one row of
|
||||
* pixels in the grab rectangle
|
||||
*/
|
||||
public PixelGrabber(ImageProducer ip, int x, int y, int w, int h,
|
||||
int pix[], int off, int scansize)
|
||||
{
|
||||
this.ip = ip;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.offset = off;
|
||||
this.scansize = scansize;
|
||||
|
||||
int_pixel_buffer = pix;
|
||||
// Initialize the byte array in case ip sends us byte-formatted
|
||||
// pixel data.
|
||||
byte_pixel_buffer = new byte[pix.length * 4];
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a PixelGrabber that will retrieve data from a given
|
||||
* Image.
|
||||
*
|
||||
* The RGB data will be retrieved from a rectangular region
|
||||
* <code>(x, y, w, h)</code> within the image. The data will be
|
||||
* stored in an internal array which can be accessed by calling
|
||||
* <code>getPixels</code>. The data for a pixel (m, n) in the grab
|
||||
* rectangle will be stored in the returned array at index
|
||||
* <code>(n - y) * scansize + (m - x) + off</code>.
|
||||
* If forceRGB is false, then the returned data will be not be
|
||||
* converted to RGB from its format in <code>img</code>.
|
||||
*
|
||||
* If <code>w</code> is negative, the width of the grab region will
|
||||
* be from x to the right edge of the image. Likewise, if
|
||||
* <code>h</code> is negative, the height of the grab region will be
|
||||
* from y to the bottom edge of the image.
|
||||
*
|
||||
* @param img the Image from which to grab pixels
|
||||
* @param x the x coordinate, relative to <code>img</code>'s
|
||||
* top-left corner, of the grab rectangle's top-left pixel
|
||||
* @param y the y coordinate, relative to <code>img</code>'s
|
||||
* top-left corner, of the grab rectangle's top-left pixel
|
||||
* @param w the width of the grab rectangle, in pixels
|
||||
* @param h the height of the grab rectangle, in pixels
|
||||
* @param forceRGB true to force conversion of the rectangular
|
||||
* region's pixel data to RGB
|
||||
*/
|
||||
public PixelGrabber(Image img,
|
||||
int x, int y,
|
||||
int w, int h,
|
||||
boolean forceRGB)
|
||||
{
|
||||
this.ip = img.getSource();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
width = w;
|
||||
height = h;
|
||||
// If width or height is negative, postpone pixel buffer
|
||||
// initialization until setDimensions is called back by ip.
|
||||
if (width >= 0 && height >= 0)
|
||||
{
|
||||
int_pixel_buffer = new int[width * height];
|
||||
byte_pixel_buffer = new byte[width * height];
|
||||
}
|
||||
this.forceRGB = forceRGB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start grabbing pixels.
|
||||
*
|
||||
* Spawns an image production thread that calls back to this
|
||||
* PixelGrabber's ImageConsumer methods.
|
||||
*/
|
||||
public synchronized void startGrabbing()
|
||||
{
|
||||
// Make sure we're not already grabbing.
|
||||
if (grabbing == false)
|
||||
{
|
||||
grabbing = true;
|
||||
grabberThread = new Thread ()
|
||||
{
|
||||
public void run ()
|
||||
{
|
||||
ip.startProduction (PixelGrabber.this);
|
||||
}
|
||||
};
|
||||
grabberThread.start ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abort pixel grabbing.
|
||||
*/
|
||||
public synchronized void abortGrabbing()
|
||||
{
|
||||
if (grabbing)
|
||||
{
|
||||
// Interrupt the grabbing thread.
|
||||
Thread moribund = grabberThread;
|
||||
grabberThread = null;
|
||||
moribund.interrupt();
|
||||
|
||||
imageComplete (ImageConsumer.IMAGEABORTED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Have our Image or ImageProducer start sending us pixels via our
|
||||
* ImageConsumer methods and wait for all pixels in the grab
|
||||
* rectangle to be delivered.
|
||||
*
|
||||
* @return true if successful, false on abort or error
|
||||
*
|
||||
* @throws InterruptedException if interrupted by another thread.
|
||||
*/
|
||||
public synchronized boolean grabPixels() throws InterruptedException
|
||||
{
|
||||
return grabPixels(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* grabPixels's behavior depends on the value of <code>ms</code>.
|
||||
*
|
||||
* If ms < 0, return true if all pixels from the source image have
|
||||
* been delivered, false otherwise. Do not wait.
|
||||
*
|
||||
* If ms >= 0 then we request that our Image or ImageProducer start
|
||||
* delivering pixels to us via our ImageConsumer methods.
|
||||
*
|
||||
* If ms > 0, wait at most <code>ms</code> milliseconds for
|
||||
* delivery of all pixels within the grab rectangle.
|
||||
*
|
||||
* If ms == 0, wait until all pixels have been delivered.
|
||||
*
|
||||
* @return true if all pixels from the source image have been
|
||||
* delivered, false otherwise
|
||||
*
|
||||
* @throws InterruptedException if this thread is interrupted while
|
||||
* we are waiting for pixels to be delivered
|
||||
*/
|
||||
public synchronized boolean grabPixels(long ms) throws InterruptedException
|
||||
{
|
||||
if (ms < 0)
|
||||
return ((observerStatus & (ImageObserver.FRAMEBITS
|
||||
| ImageObserver.ALLBITS)) != 0);
|
||||
|
||||
// Spawn a new ImageProducer thread to send us the image data via
|
||||
// our ImageConsumer methods.
|
||||
startGrabbing();
|
||||
|
||||
if (ms > 0)
|
||||
{
|
||||
long stop_time = System.currentTimeMillis() + ms;
|
||||
long time_remaining;
|
||||
while (grabbing)
|
||||
{
|
||||
time_remaining = stop_time - System.currentTimeMillis();
|
||||
if (time_remaining <= 0)
|
||||
break;
|
||||
wait (time_remaining);
|
||||
}
|
||||
abortGrabbing ();
|
||||
}
|
||||
else
|
||||
wait ();
|
||||
|
||||
// If consumerStatus is non-zero then the image is done loading or
|
||||
// an error has occurred.
|
||||
if (consumerStatus != 0)
|
||||
return setObserverStatus ();
|
||||
|
||||
return ((observerStatus & (ImageObserver.FRAMEBITS
|
||||
| ImageObserver.ALLBITS)) != 0);
|
||||
}
|
||||
|
||||
// Set observer status flags based on the current consumer status
|
||||
// flags. Return true if the consumer flags indicate that the
|
||||
// image was loaded successfully, or false otherwise.
|
||||
private synchronized boolean setObserverStatus ()
|
||||
{
|
||||
boolean retval = false;
|
||||
|
||||
if ((consumerStatus & IMAGEERROR) != 0)
|
||||
observerStatus |= ImageObserver.ERROR;
|
||||
|
||||
if ((consumerStatus & IMAGEABORTED) != 0)
|
||||
observerStatus |= ImageObserver.ABORT;
|
||||
|
||||
if ((consumerStatus & STATICIMAGEDONE) != 0)
|
||||
{
|
||||
observerStatus |= ImageObserver.ALLBITS;
|
||||
retval = true;
|
||||
}
|
||||
|
||||
if ((consumerStatus & SINGLEFRAMEDONE) != 0)
|
||||
{
|
||||
observerStatus |= ImageObserver.FRAMEBITS;
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the status of the pixel grabbing thread, represented by a
|
||||
* bitwise OR of ImageObserver flags
|
||||
*/
|
||||
public synchronized int getStatus()
|
||||
{
|
||||
return observerStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the width of the grab rectangle in pixels, or a negative
|
||||
* number if the ImageProducer has not yet called our setDimensions
|
||||
* method
|
||||
*/
|
||||
public synchronized int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the height of the grab rectangle in pixels, or a negative
|
||||
* number if the ImageProducer has not yet called our setDimensions
|
||||
* method
|
||||
*/
|
||||
public synchronized int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a byte array of pixel data if ImageProducer delivered
|
||||
* pixel data using the byte[] variant of setPixels, or an int array
|
||||
* otherwise
|
||||
*/
|
||||
public synchronized Object getPixels()
|
||||
{
|
||||
if (ints_delivered)
|
||||
return int_pixel_buffer;
|
||||
else if (bytes_delivered)
|
||||
return byte_pixel_buffer;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ColorModel currently being used for the majority of
|
||||
* pixel data conversions
|
||||
*/
|
||||
public synchronized ColorModel getColorModel()
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our <code>ImageProducer</code> calls this method to indicate the
|
||||
* size of the image being produced.
|
||||
*
|
||||
* setDimensions is an ImageConsumer method. None of PixelGrabber's
|
||||
* ImageConsumer methods should be called by code that instantiates
|
||||
* a PixelGrabber. They are only made public so they can be called
|
||||
* by the PixelGrabber's ImageProducer.
|
||||
*
|
||||
* @param width the width of the image
|
||||
* @param height the height of the image
|
||||
*/
|
||||
public synchronized void setDimensions(int width, int height)
|
||||
{
|
||||
// Our width wasn't set when we were constructed. Set our width
|
||||
// so that the grab region includes all pixels from x to the right
|
||||
// edge of the source image.
|
||||
if (this.width < 0)
|
||||
this.width = width - x;
|
||||
|
||||
// Our height wasn't set when we were constructed. Set our height
|
||||
// so that the grab region includes all pixels from y to the
|
||||
// bottom edge of the source image.
|
||||
if (this.height < 0)
|
||||
this.height = height - y;
|
||||
|
||||
if (scansize < 0)
|
||||
scansize = this.width;
|
||||
|
||||
if (int_pixel_buffer == null)
|
||||
int_pixel_buffer = new int[this.width * this.height];
|
||||
|
||||
if (byte_pixel_buffer == null)
|
||||
byte_pixel_buffer = new byte[this.width * this.height];
|
||||
}
|
||||
|
||||
/**
|
||||
* Our <code>ImageProducer</code> may call this method to send us a
|
||||
* list of its image's properties.
|
||||
*
|
||||
* setProperties is an ImageConsumer method. None of PixelGrabber's
|
||||
* ImageConsumer methods should be called by code that instantiates
|
||||
* a PixelGrabber. They are only made public so they can be called
|
||||
* by the PixelGrabber's ImageProducer.
|
||||
*
|
||||
* @param props a list of properties associated with the image being
|
||||
* produced
|
||||
*/
|
||||
public synchronized void setProperties(Hashtable props)
|
||||
{
|
||||
this.props = props;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our ImageProducer will call <code>setColorModel</code> to
|
||||
* indicate the model used by the majority of calls to
|
||||
* <code>setPixels</code>. Each call to <code>setPixels</code>
|
||||
* could however indicate a different <code>ColorModel</code>.
|
||||
*
|
||||
* setColorModel is an ImageConsumer method. None of PixelGrabber's
|
||||
* ImageConsumer methods should be called by code that instantiates
|
||||
* a PixelGrabber. They are only made public so they can be called
|
||||
* by the PixelGrabber's ImageProducer.
|
||||
*
|
||||
* @param model the color model to be used most often by setPixels
|
||||
*
|
||||
* @see ColorModel
|
||||
*/
|
||||
public synchronized void setColorModel(ColorModel model)
|
||||
{
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our <code>ImageProducer</code> may call this method with a
|
||||
* bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
|
||||
* <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
|
||||
* <code>SINGLEPASS</code>, <code>SINGLEFRAME</code>.
|
||||
*
|
||||
* setHints is an ImageConsumer method. None of PixelGrabber's
|
||||
* ImageConsumer methods should be called by code that instantiates
|
||||
* a PixelGrabber. They are only made public so they can be called
|
||||
* by the PixelGrabber's ImageProducer.
|
||||
*
|
||||
* @param flags a bit mask of hints
|
||||
*/
|
||||
public synchronized void setHints(int flags)
|
||||
{
|
||||
hints = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our ImageProducer calls setPixels to deliver a subset of its
|
||||
* pixels.
|
||||
*
|
||||
* Each element of the pixels array represents one pixel. The
|
||||
* pixel data is formatted according to the color model model.
|
||||
* The x and y parameters are the coordinates of the rectangular
|
||||
* region of pixels being delivered to this ImageConsumer,
|
||||
* specified relative to the top left corner of the image being
|
||||
* produced. Likewise, w and h are the pixel region's dimensions.
|
||||
*
|
||||
* @param x x coordinate of pixel block
|
||||
* @param y y coordinate of pixel block
|
||||
* @param w width of pixel block
|
||||
* @param h height of pixel block
|
||||
* @param model color model used to interpret pixel data
|
||||
* @param pixels pixel block data
|
||||
* @param offset offset into pixels array
|
||||
* @param scansize width of one row in the pixel block
|
||||
*/
|
||||
public synchronized void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels,
|
||||
int offset, int scansize)
|
||||
{
|
||||
ColorModel currentModel;
|
||||
if (model != null)
|
||||
currentModel = model;
|
||||
else
|
||||
currentModel = this.model;
|
||||
|
||||
for(int yp = y; yp < (y + h); yp++)
|
||||
{
|
||||
for(int xp = x; xp < (x + w); xp++)
|
||||
{
|
||||
// Check if the coordinates (xp, yp) are within the
|
||||
// pixel block that we are grabbing.
|
||||
if(xp >= this.x
|
||||
&& yp >= this.y
|
||||
&& xp < (this.x + this.width)
|
||||
&& yp < (this.y + this.height))
|
||||
{
|
||||
int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
|
||||
int p = (yp - y) * scansize + (xp - x) + offset;
|
||||
if (forceRGB)
|
||||
{
|
||||
ints_delivered = true;
|
||||
|
||||
int_pixel_buffer[i] = currentModel.getRGB (pixels[p] & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_delivered = true;
|
||||
|
||||
byte_pixel_buffer[i] = pixels[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Our ImageProducer calls setPixels to deliver a subset of its
|
||||
* pixels.
|
||||
*
|
||||
* Each element of the pixels array represents one pixel. The
|
||||
* pixel data is formatted according to the color model model.
|
||||
* The x and y parameters are the coordinates of the rectangular
|
||||
* region of pixels being delivered to this ImageConsumer,
|
||||
* specified relative to the top left corner of the image being
|
||||
* produced. Likewise, w and h are the pixel region's dimensions.
|
||||
*
|
||||
* @param x x coordinate of pixel block
|
||||
* @param y y coordinate of pixel block
|
||||
* @param w width of pixel block
|
||||
* @param h height of pixel block
|
||||
* @param model color model used to interpret pixel data
|
||||
* @param pixels pixel block data
|
||||
* @param offset offset into pixels array
|
||||
* @param scansize width of one row in the pixel block
|
||||
*/
|
||||
public synchronized void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels,
|
||||
int offset, int scansize)
|
||||
{
|
||||
ColorModel currentModel;
|
||||
if (model != null)
|
||||
currentModel = model;
|
||||
else
|
||||
currentModel = this.model;
|
||||
|
||||
ints_delivered = true;
|
||||
|
||||
for(int yp = y; yp < (y + h); yp++)
|
||||
{
|
||||
for(int xp = x; xp < (x + w); xp++)
|
||||
{
|
||||
// Check if the coordinates (xp, yp) are within the
|
||||
// pixel block that we are grabbing.
|
||||
if(xp >= this.x
|
||||
&& yp >= this.y
|
||||
&& xp < (this.x + this.width)
|
||||
&& yp < (this.y + this.height))
|
||||
{
|
||||
int i = (yp - this.y) * this.scansize + (xp - this.x) + this.offset;
|
||||
int p = (yp - y) * scansize + (xp - x) + offset;
|
||||
if (forceRGB)
|
||||
int_pixel_buffer[i] = currentModel.getRGB (pixels[p]);
|
||||
else
|
||||
int_pixel_buffer[i] = pixels[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Our <code>ImageProducer</code> calls this method to inform us
|
||||
* that a single frame or the entire image is complete. The method
|
||||
* is also used to inform us of an error in loading or producing the
|
||||
* image.
|
||||
*
|
||||
* @param status the status of image production, represented by a
|
||||
* bitwise OR of ImageConsumer flags
|
||||
*/
|
||||
public synchronized void imageComplete(int status)
|
||||
{
|
||||
consumerStatus = status;
|
||||
setObserverStatus ();
|
||||
grabbing = false;
|
||||
ip.removeConsumer (this);
|
||||
|
||||
notifyAll ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the return value of getStatus
|
||||
*
|
||||
* @specnote The newer getStatus should be used in place of status.
|
||||
*/
|
||||
public synchronized int status()
|
||||
{
|
||||
return getStatus();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/* PixelInterleavedSampleModel.java
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* A <code>SampleModel</code> that uses exactly one element of the
|
||||
* raster’s {@link DataBuffer} per pixel, holds all bands in a
|
||||
* single bank, and stores band data in pixel-interleaved manner.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @author Sascha Brawer (brawer@dandelis.ch)
|
||||
*/
|
||||
public class PixelInterleavedSampleModel
|
||||
extends ComponentSampleModel
|
||||
{
|
||||
public PixelInterleavedSampleModel(int dataType, int width, int height,
|
||||
int pixelStride, int scanlineStride,
|
||||
int[] bandOffsets)
|
||||
{
|
||||
super(dataType, width, height, pixelStride, scanlineStride,
|
||||
bandOffsets);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>SampleModel</code> that is like this one, but
|
||||
* uses the specified width and height.
|
||||
*
|
||||
* @param width the number of pixels in the horizontal direction.
|
||||
*
|
||||
* @param height the number of pixels in the vertical direction.
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int width, int height)
|
||||
{
|
||||
return new PixelInterleavedSampleModel(dataType, width, height,
|
||||
pixelStride, scanlineStride,
|
||||
bandOffsets);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>SampleModel</code> that is like this one, but
|
||||
* uses only a subset of its bands.
|
||||
*
|
||||
* @param bands an array whose elements indicate which bands shall
|
||||
* be part of the subset. For example, <code>[0, 2, 3]</code> would
|
||||
* create a SampleModel containing bands #0, #2 and #3.
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int[] bands)
|
||||
{
|
||||
int[] subOffsets;
|
||||
|
||||
subOffsets = new int[bands.length];
|
||||
for (int i = 0; i < bands.length; i++)
|
||||
subOffsets[i] = bandOffsets[bands[i]];
|
||||
|
||||
return new PixelInterleavedSampleModel(dataType, width, height,
|
||||
pixelStride, scanlineStride,
|
||||
subOffsets);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/* RGBImageFilter.java -- Java class for filtering Pixels by RGB values
|
||||
Copyright (C) 1999, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* A filter designed to filter images in the default RGBColorModel regardless of
|
||||
* the ImageProducer's ColorModel.
|
||||
*
|
||||
* @author Mark Benvenuto (mcb54@columbia.edu)
|
||||
*/
|
||||
public abstract class RGBImageFilter extends ImageFilter
|
||||
{
|
||||
protected ColorModel origmodel;
|
||||
|
||||
protected ColorModel newmodel;
|
||||
|
||||
/**
|
||||
Specifies whether to apply the filter to the index entries of the
|
||||
IndexColorModel. Subclasses should set this to true if the filter
|
||||
does not depend on the pixel's coordinate.
|
||||
*/
|
||||
protected boolean canFilterIndexColorModel = false;
|
||||
|
||||
/**
|
||||
Construct new RGBImageFilter.
|
||||
*/
|
||||
public RGBImageFilter()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ColorModel used to filter with. If the specified ColorModel is IndexColorModel
|
||||
* and canFilterIndexColorModel is true, we subsitute the ColorModel for a filtered one
|
||||
* here and in setPixels whenever the original one appears. Otherwise overrides the default
|
||||
* ColorModel of ImageProducer and specifies the default RGBColorModel
|
||||
*
|
||||
* @param model the color model to be used most often by setPixels
|
||||
* @see ColorModel */
|
||||
public void setColorModel(ColorModel model)
|
||||
{
|
||||
origmodel = model;
|
||||
newmodel = model;
|
||||
|
||||
if( ( model instanceof IndexColorModel) && canFilterIndexColorModel ) {
|
||||
newmodel = filterIndexColorModel( (IndexColorModel) model );
|
||||
consumer.setColorModel(newmodel);
|
||||
}
|
||||
else {
|
||||
consumer.setColorModel(ColorModel.getRGBdefault());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Registers a new ColorModel to subsitute for the old ColorModel when
|
||||
setPixels encounters the a pixel with the old ColorModel. The pixel
|
||||
remains unchanged except for a new ColorModel.
|
||||
|
||||
@param oldcm the old ColorModel
|
||||
@param newcm the new ColorModel
|
||||
*/
|
||||
public void substituteColorModel(ColorModel oldcm,
|
||||
ColorModel newcm)
|
||||
{
|
||||
origmodel = oldcm;
|
||||
newmodel = newcm;
|
||||
}
|
||||
|
||||
/**
|
||||
Filters an IndexColorModel through the filterRGB function. Uses
|
||||
coordinates of -1 to indicate its filtering an index and not a pixel.
|
||||
|
||||
@param icm an IndexColorModel to filter
|
||||
*/
|
||||
public IndexColorModel filterIndexColorModel(IndexColorModel icm)
|
||||
{
|
||||
int len = icm.getMapSize(), rgb;
|
||||
byte reds[] = new byte[len], greens[] = new byte[len], blues[] = new byte[len], alphas[] = new byte[len];
|
||||
|
||||
icm.getAlphas( alphas );
|
||||
icm.getReds( reds );
|
||||
icm.getGreens( greens );
|
||||
icm.getBlues( blues );
|
||||
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
rgb = filterRGB( -1, -1, makeColor ( alphas[i], reds[i], greens[i], blues[i] ) );
|
||||
alphas[i] = (byte)(( 0xff000000 & rgb ) >> 24);
|
||||
reds[i] = (byte)(( 0xff0000 & rgb ) >> 16);
|
||||
greens[i] = (byte)(( 0xff00 & rgb ) >> 8);
|
||||
blues[i] = (byte)(0xff & rgb);
|
||||
}
|
||||
return new IndexColorModel( icm.getPixelSize(), len, reds, greens, blues, alphas );
|
||||
}
|
||||
|
||||
private int makeColor( byte a, byte r, byte g, byte b )
|
||||
{
|
||||
return ( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b );
|
||||
}
|
||||
|
||||
/**
|
||||
This functions filters a set of RGB pixels through filterRGB.
|
||||
|
||||
@param x the x coordinate of the rectangle
|
||||
@param y the y coordinate of the rectangle
|
||||
@param w the width of the rectangle
|
||||
@param h the height of the rectangle
|
||||
@param pixels the array of pixel values
|
||||
@param offset the index of the first pixels in the <code>pixels</code> array
|
||||
@param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void filterRGBPixels(int x, int y, int w, int h, int[] pixels,
|
||||
int offset, int scansize)
|
||||
{
|
||||
for (int yp = 0; yp < h; yp++)
|
||||
{
|
||||
for (int xp = 0; xp < w; xp++)
|
||||
{
|
||||
pixels[offset + xp] = filterRGB(xp + x, yp + y, pixels[offset + xp]);
|
||||
}
|
||||
offset += scansize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the ColorModel is the same ColorModel which as already converted
|
||||
* then it converts it the converted ColorModel. Otherwise it passes the
|
||||
* array of pixels through filterRGBpixels.
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels,
|
||||
int offset, int scansize)
|
||||
{
|
||||
if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
|
||||
{
|
||||
consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
|
||||
}
|
||||
else
|
||||
{
|
||||
int intPixels[] =
|
||||
convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
|
||||
filterRGBPixels( x, y, w, h, intPixels, offset, scansize );
|
||||
consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), intPixels, offset, scansize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as an <code>int</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels,
|
||||
int offset, int scansize)
|
||||
{
|
||||
if(model == origmodel && (model instanceof IndexColorModel) && canFilterIndexColorModel)
|
||||
{
|
||||
consumer.setPixels(x, y, w, h, newmodel, pixels, offset, scansize);
|
||||
}
|
||||
else
|
||||
{
|
||||
//FIXME: Store the filtered pixels in a separate temporary buffer?
|
||||
convertColorModelToDefault( x, y, w, h, model, pixels, offset, scansize );
|
||||
filterRGBPixels( x, y, w, h, pixels, offset, scansize );
|
||||
consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), pixels, offset, scansize);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] convertColorModelToDefault(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[],
|
||||
int offset, int scansize)
|
||||
{
|
||||
int intPixels[] = new int[pixels.length];
|
||||
for (int i = 0; i < pixels.length; i++)
|
||||
intPixels[i] = makeColorbyDefaultCM(model, pixels[i]);
|
||||
return intPixels;
|
||||
}
|
||||
|
||||
private void convertColorModelToDefault(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[],
|
||||
int offset, int scansize)
|
||||
{
|
||||
for (int i = 0; i < pixels.length; i++)
|
||||
pixels[i] = makeColorbyDefaultCM(model, pixels[i]);
|
||||
}
|
||||
|
||||
private int makeColorbyDefaultCM(ColorModel model, byte rgb)
|
||||
{
|
||||
return makeColor( model.getAlpha( rgb ) * 4, model.getRed( rgb ) * 4, model.getGreen( rgb ) * 4, model.getBlue( rgb ) * 4 );
|
||||
}
|
||||
|
||||
private int makeColorbyDefaultCM(ColorModel model, int rgb)
|
||||
{
|
||||
return makeColor( model.getAlpha( rgb ), model.getRed( rgb ), model.getGreen( rgb ), model.getBlue( rgb ) );
|
||||
}
|
||||
|
||||
private int makeColor( int a, int r, int g, int b )
|
||||
{
|
||||
return (int)( 0xff000000 & (a << 24) | 0xff0000 & (r << 16) | 0xff00 & (g << 8) | 0xff & b );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Filters a single pixel from the default ColorModel.
|
||||
|
||||
@param x x-coordinate
|
||||
@param y y-coordinate
|
||||
@param rgb color
|
||||
*/
|
||||
public abstract int filterRGB(int x,
|
||||
int y,
|
||||
int rgb);
|
||||
}
|
||||
@@ -0,0 +1,546 @@
|
||||
/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public class Raster
|
||||
{
|
||||
protected SampleModel sampleModel;
|
||||
protected DataBuffer dataBuffer;
|
||||
protected int minX;
|
||||
protected int minY;
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int sampleModelTranslateX;
|
||||
protected int sampleModelTranslateY;
|
||||
protected int numBands;
|
||||
protected int numDataElements;
|
||||
protected Raster parent;
|
||||
|
||||
protected Raster(SampleModel sampleModel, Point origin)
|
||||
{
|
||||
this(sampleModel, sampleModel.createDataBuffer(), origin);
|
||||
}
|
||||
|
||||
protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
|
||||
Point origin)
|
||||
{
|
||||
this(sampleModel, dataBuffer,
|
||||
new Rectangle(origin.x, origin.y,
|
||||
sampleModel.getWidth(), sampleModel.getHeight()),
|
||||
origin, null);
|
||||
}
|
||||
|
||||
protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
|
||||
Rectangle aRegion,
|
||||
Point sampleModelTranslate, Raster parent)
|
||||
{
|
||||
this.sampleModel = sampleModel;
|
||||
this.dataBuffer = dataBuffer;
|
||||
this.minX = aRegion.x;
|
||||
this.minY = aRegion.y;
|
||||
this.width = aRegion.width;
|
||||
this.height = aRegion.height;
|
||||
|
||||
// If sampleModelTranslate is null, use (0,0). Methods such as
|
||||
// Raster.createRaster are specified to allow for a null argument.
|
||||
if (sampleModelTranslate != null)
|
||||
{
|
||||
this.sampleModelTranslateX = sampleModelTranslate.x;
|
||||
this.sampleModelTranslateY = sampleModelTranslate.y;
|
||||
}
|
||||
|
||||
this.numBands = sampleModel.getNumBands();
|
||||
this.numDataElements = sampleModel.getNumDataElements();
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public static WritableRaster createInterleavedRaster(int dataType,
|
||||
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<bands; b++) bandOffsets[b] = b;
|
||||
|
||||
int scanlineStride = bands*w;
|
||||
return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
|
||||
bandOffsets, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createInterleavedRaster(int dataType,
|
||||
int w, int h,
|
||||
int scanlineStride,
|
||||
int pixelStride,
|
||||
int[] bandOffsets,
|
||||
Point location)
|
||||
{
|
||||
SampleModel sm = new ComponentSampleModel(dataType,
|
||||
w, h,
|
||||
pixelStride,
|
||||
scanlineStride,
|
||||
bandOffsets);
|
||||
return createWritableRaster(sm, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createBandedRaster(int dataType,
|
||||
int w, int h, int bands,
|
||||
Point location)
|
||||
{
|
||||
SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
|
||||
return createWritableRaster(sm, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createBandedRaster(int dataType,
|
||||
int w, int h,
|
||||
int scanlineStride,
|
||||
int[] bankIndices,
|
||||
int[] bandOffsets,
|
||||
Point location)
|
||||
{
|
||||
SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
|
||||
bankIndices, bandOffsets);
|
||||
return createWritableRaster(sm, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createPackedRaster(int dataType,
|
||||
int w, int h,
|
||||
int[] bandMasks,
|
||||
Point location)
|
||||
{
|
||||
SampleModel sm = new SinglePixelPackedSampleModel(dataType,
|
||||
w, h,
|
||||
bandMasks);
|
||||
return createWritableRaster(sm, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createPackedRaster(int dataType,
|
||||
int w, int h,
|
||||
int bands, int bitsPerBand,
|
||||
Point location)
|
||||
{
|
||||
if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
SampleModel sm;
|
||||
|
||||
if (bands == 1)
|
||||
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);
|
||||
}
|
||||
return createWritableRaster(sm, location);
|
||||
}
|
||||
|
||||
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);
|
||||
return createWritableRaster(sm, dataBuffer, location);
|
||||
}
|
||||
|
||||
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);
|
||||
return createWritableRaster(sm, dataBuffer, location);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
return createWritableRaster(sm, dataBuffer, location);
|
||||
}
|
||||
|
||||
public static Raster createRaster(SampleModel sm, DataBuffer db,
|
||||
Point location)
|
||||
{
|
||||
return new Raster(sm, db, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createWritableRaster(SampleModel sm,
|
||||
Point location)
|
||||
{
|
||||
return new WritableRaster(sm, location);
|
||||
}
|
||||
|
||||
public static WritableRaster createWritableRaster(SampleModel sm,
|
||||
DataBuffer db,
|
||||
Point location)
|
||||
{
|
||||
return new WritableRaster(sm, db, location);
|
||||
}
|
||||
|
||||
public Raster getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
public final int getSampleModelTranslateX()
|
||||
{
|
||||
return sampleModelTranslateX;
|
||||
}
|
||||
|
||||
public final int getSampleModelTranslateY()
|
||||
{
|
||||
return sampleModelTranslateY;
|
||||
}
|
||||
|
||||
public WritableRaster createCompatibleWritableRaster()
|
||||
{
|
||||
return new WritableRaster(getSampleModel(), new Point(minX, minY));
|
||||
}
|
||||
|
||||
public WritableRaster createCompatibleWritableRaster(int w, int h)
|
||||
{
|
||||
return createCompatibleWritableRaster(minX, minY, w, h);
|
||||
}
|
||||
|
||||
public WritableRaster createCompatibleWritableRaster(Rectangle rect)
|
||||
{
|
||||
return createCompatibleWritableRaster(rect.x, rect.y,
|
||||
rect.width, rect.height);
|
||||
}
|
||||
|
||||
public WritableRaster createCompatibleWritableRaster(int x, int y,
|
||||
int w, int h)
|
||||
{
|
||||
SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
|
||||
return new WritableRaster(sm, sm.createDataBuffer(),
|
||||
new Point(x, y));
|
||||
}
|
||||
|
||||
public Raster createTranslatedChild(int childMinX, int childMinY) {
|
||||
int tcx = sampleModelTranslateX - minX + childMinX;
|
||||
int tcy = sampleModelTranslateY - minY + childMinY;
|
||||
|
||||
return new Raster(sampleModel, dataBuffer,
|
||||
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)
|
||||
{
|
||||
/* FIXME: Throw RasterFormatException if child bounds extends
|
||||
beyond the bounds of this raster. */
|
||||
|
||||
SampleModel sm = (bandList == null) ?
|
||||
sampleModel :
|
||||
sampleModel.createSubsetSampleModel(bandList);
|
||||
|
||||
/*
|
||||
data origin
|
||||
/
|
||||
+-------------------------
|
||||
|\. __ parent trans
|
||||
| \`.
|
||||
| \ `. parent origin
|
||||
| \ `. /
|
||||
| /\ +-------- - -
|
||||
|trans\ /<\-- deltaTrans
|
||||
|child +-+-\---- - -
|
||||
| /|`| \__ parent [x, y]
|
||||
|child | |`. \
|
||||
|origin| : `.\
|
||||
| | / `\
|
||||
| : / +
|
||||
| child [x, y]
|
||||
|
||||
parent_xy - parent_trans = child_xy - child_trans
|
||||
|
||||
child_trans = parent_trans + child_xy - parent_xy
|
||||
*/
|
||||
|
||||
return new Raster(sm, dataBuffer,
|
||||
new Rectangle(childMinX, childMinY,
|
||||
width, height),
|
||||
new Point(sampleModelTranslateX+childMinX-parentX,
|
||||
sampleModelTranslateY+childMinY-parentY),
|
||||
this);
|
||||
}
|
||||
|
||||
public Rectangle getBounds()
|
||||
{
|
||||
return new Rectangle(minX, minY, width, height);
|
||||
}
|
||||
|
||||
public final int getMinX()
|
||||
{
|
||||
return minX;
|
||||
}
|
||||
|
||||
public final int getMinY()
|
||||
{
|
||||
return minY;
|
||||
}
|
||||
|
||||
public final int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
public final int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public final int getNumBands()
|
||||
{
|
||||
return numBands;
|
||||
}
|
||||
|
||||
public final int getNumDataElements()
|
||||
{
|
||||
return numDataElements;
|
||||
}
|
||||
|
||||
public final int getTransferType()
|
||||
{
|
||||
return sampleModel.getTransferType();
|
||||
}
|
||||
|
||||
public DataBuffer getDataBuffer()
|
||||
{
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
public SampleModel getSampleModel()
|
||||
{
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, Object outData)
|
||||
{
|
||||
return sampleModel.getDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
outData, dataBuffer);
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, int w, int h,
|
||||
Object outData)
|
||||
{
|
||||
return sampleModel.getDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, outData, dataBuffer);
|
||||
}
|
||||
|
||||
public int[] getPixel(int x, int y, int[] iArray)
|
||||
{
|
||||
return sampleModel.getPixel(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
iArray, dataBuffer);
|
||||
}
|
||||
|
||||
public float[] getPixel(int x, int y, float[] fArray)
|
||||
{
|
||||
return sampleModel.getPixel(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
fArray, dataBuffer);
|
||||
}
|
||||
|
||||
public double[] getPixel(int x, int y, double[] dArray)
|
||||
{
|
||||
return sampleModel.getPixel(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
dArray, dataBuffer);
|
||||
}
|
||||
|
||||
public int[] getPixels(int x, int y, int w, int h, int[] iArray)
|
||||
{
|
||||
return sampleModel.getPixels(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, iArray, dataBuffer);
|
||||
}
|
||||
|
||||
public float[] getPixels(int x, int y, int w, int h,
|
||||
float[] fArray)
|
||||
{
|
||||
return sampleModel.getPixels(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, fArray, dataBuffer);
|
||||
}
|
||||
|
||||
public double[] getPixels(int x, int y, int w, int h,
|
||||
double[] dArray)
|
||||
{
|
||||
return sampleModel.getPixels(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, dArray, dataBuffer);
|
||||
}
|
||||
|
||||
public int getSample(int x, int y, int b)
|
||||
{
|
||||
return sampleModel.getSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
b, dataBuffer);
|
||||
}
|
||||
|
||||
public float getSampleFloat(int x, int y, int b)
|
||||
{
|
||||
return sampleModel.getSampleFloat(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
b, dataBuffer);
|
||||
}
|
||||
|
||||
public double getSampleDouble(int x, int y, int b)
|
||||
{
|
||||
return sampleModel.getSampleDouble(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
b, dataBuffer);
|
||||
}
|
||||
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int[] iArray)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a String representing the stat of this Raster.
|
||||
* @return A String representing the stat of this Raster.
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
result.append(getClass().getName());
|
||||
result.append("[(");
|
||||
result.append(minX).append(",").append(minY).append("), ");
|
||||
result.append(width).append(" x ").append(height).append(",");
|
||||
result.append(sampleModel).append(",");
|
||||
result.append(dataBuffer);
|
||||
result.append("]");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
// Map from datatype to bits
|
||||
private static int getTypeBits(int dataType)
|
||||
{
|
||||
switch (dataType)
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
return 8;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
return 16;
|
||||
case DataBuffer.TYPE_INT:
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
return 32;
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
return 64;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/* RasterFormatException.java -- indicates invalid layout in Raster
|
||||
Copyright (C) 2002, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This exception is thrown when there is invalid layout information in
|
||||
* <code>Raster</code>
|
||||
*
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @see Raster
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class RasterFormatException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Compatible with JDK 1.0+.
|
||||
*/
|
||||
private static final long serialVersionUID = 96598996116164315L;
|
||||
|
||||
/**
|
||||
* Create a new instance with a descriptive error message.
|
||||
*
|
||||
* @param message the descriptive error message
|
||||
*/
|
||||
public RasterFormatException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
} // class RasterFormatException
|
||||
@@ -0,0 +1,57 @@
|
||||
/* RasterOp.java --
|
||||
Copyright (C) 2000, 2002, 2004, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
public interface RasterOp
|
||||
{
|
||||
WritableRaster filter(Raster src, WritableRaster dest);
|
||||
|
||||
Rectangle2D getBounds2D(Raster src);
|
||||
|
||||
WritableRaster createCompatibleDestRaster(Raster src);
|
||||
|
||||
Point2D getPoint2D(Point2D srcPoint, Point2D destPoint);
|
||||
|
||||
RenderingHints getRenderingHints();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* RenderedImage.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* NEEDS DOCUMENTATION
|
||||
*/
|
||||
public interface RenderedImage
|
||||
{
|
||||
Vector getSources();
|
||||
Object getProperty(String name);
|
||||
String[] getPropertyNames();
|
||||
ColorModel getColorModel();
|
||||
SampleModel getSampleModel();
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
int getMinX();
|
||||
int getMinY();
|
||||
int getNumXTiles();
|
||||
int getNumYTiles();
|
||||
int getMinTileX();
|
||||
int getMinTileY();
|
||||
int getTileWidth();
|
||||
int getTileHeight();
|
||||
int getTileGridXOffset();
|
||||
int getTileGridYOffset();
|
||||
Raster getTile(int x, int y);
|
||||
Raster getData();
|
||||
Raster getData(Rectangle r);
|
||||
WritableRaster copyData(WritableRaster raster);
|
||||
} // interface RenderedImage
|
||||
@@ -0,0 +1,244 @@
|
||||
/* ReplicateScaleFilter.java -- Java class for filtering images
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This filter should be used for fast scaling of images where the result
|
||||
* does not need to ensure straight lines are still straight, etc. The
|
||||
* exact method is not defined by Sun but some sort of fast Box filter should
|
||||
* probably be correct.
|
||||
* <br>
|
||||
* Currently this filter does nothing and needs to be implemented.
|
||||
*
|
||||
* @author C. Brian Jones (cbj@gnu.org)
|
||||
*/
|
||||
public class ReplicateScaleFilter extends ImageFilter
|
||||
{
|
||||
public ReplicateScaleFilter(int width, int height) {
|
||||
destHeight = height;
|
||||
destWidth = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of the destination image.
|
||||
*/
|
||||
protected int destHeight;
|
||||
|
||||
/**
|
||||
* The width of the destination image.
|
||||
*/
|
||||
protected int destWidth;
|
||||
|
||||
/**
|
||||
* The height of the source image.
|
||||
*/
|
||||
protected int srcHeight;
|
||||
|
||||
/**
|
||||
* The width of the source image.
|
||||
*/
|
||||
protected int srcWidth;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected int srcrows[];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected int srccols[];
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected Object outpixbuf;
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> indicates the size of the image
|
||||
* being produced using this method. A filter can override this
|
||||
* method to intercept these calls from the producer in order to
|
||||
* change either the width or the height before in turn calling
|
||||
* the consumer's <code>setDimensions</code> method.
|
||||
*
|
||||
* @param width the width of the image
|
||||
* @param height the height of the image
|
||||
*/
|
||||
public void setDimensions(int width, int height)
|
||||
{
|
||||
srcWidth = width;
|
||||
srcHeight = height;
|
||||
|
||||
/* If either destHeight or destWidth is < 0, the image should
|
||||
maintain its original aspect ratio. When both are < 0,
|
||||
just maintain the original width and height. */
|
||||
if (destWidth < 0 && destHeight < 0)
|
||||
{
|
||||
destWidth = width;
|
||||
destHeight = height;
|
||||
}
|
||||
else if (destWidth < 0)
|
||||
{
|
||||
destWidth = (int) (width * ((double) destHeight / srcHeight));
|
||||
}
|
||||
else if (destHeight < 0)
|
||||
{
|
||||
destHeight = (int) (height * ((double) destWidth / srcWidth));
|
||||
}
|
||||
|
||||
consumer.setDimensions(destWidth, destHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* An <code>ImageProducer</code> can set a list of properties
|
||||
* associated with this image by using this method.
|
||||
*
|
||||
* @param props the list of properties associated with this image
|
||||
*/
|
||||
public void setProperties(Hashtable props)
|
||||
{
|
||||
props.put("filters", "ReplicateScaleFilter");
|
||||
consumer.setProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as a <code>byte</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte[] pixels, int offset, int scansize)
|
||||
{
|
||||
double rx = ((double) srcWidth) / destWidth;
|
||||
double ry = ((double) srcHeight) / destHeight;
|
||||
|
||||
int destScansize = (int) Math.round(scansize / rx);
|
||||
|
||||
byte[] destPixels = replicatePixels(x, y, w, h,
|
||||
model, pixels, offset, scansize,
|
||||
rx, ry, destScansize);
|
||||
|
||||
consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
|
||||
(int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
|
||||
model, destPixels, 0, destScansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function delivers a rectangle of pixels where any
|
||||
* pixel(m,n) is stored in the array as an <code>int</code> at
|
||||
* index (n * scansize + m + offset).
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
* @param model the <code>ColorModel</code> used to translate the pixels
|
||||
* @param pixels the array of pixel values
|
||||
* @param offset the index of the first pixels in the <code>pixels</code> array
|
||||
* @param scansize the width to use in extracting pixels from the <code>pixels</code> array
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int[] pixels, int offset, int scansize)
|
||||
{
|
||||
double rx = ((double) srcWidth) / destWidth;
|
||||
double ry = ((double) srcHeight) / destHeight;
|
||||
|
||||
int destScansize = (int) Math.round(scansize / rx);
|
||||
|
||||
int[] destPixels = replicatePixels(x, y, w, h,
|
||||
model, pixels, offset, scansize,
|
||||
rx, ry, destScansize);
|
||||
|
||||
consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
|
||||
(int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
|
||||
model, destPixels, 0, destScansize);
|
||||
}
|
||||
|
||||
private byte[] replicatePixels(int srcx, int srcy, int srcw, int srch,
|
||||
ColorModel model, byte[] srcPixels,
|
||||
int srcOffset, int srcScansize,
|
||||
double rx, double ry, int destScansize)
|
||||
{
|
||||
byte[] destPixels =
|
||||
new byte[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)];
|
||||
|
||||
int a, b;
|
||||
for (int i = 0; i < destPixels.length; i++)
|
||||
{
|
||||
a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize;
|
||||
b = (int) ((i % destScansize) * rx);
|
||||
if ((a + b + srcOffset) < srcPixels.length)
|
||||
destPixels[i] = srcPixels[a + b + srcOffset];
|
||||
}
|
||||
|
||||
return destPixels;
|
||||
}
|
||||
|
||||
private int[] replicatePixels(int srcx, int srcy, int srcw, int srch,
|
||||
ColorModel model, int[] srcPixels,
|
||||
int srcOffset, int srcScansize,
|
||||
double rx, double ry, int destScansize)
|
||||
{
|
||||
int[] destPixels =
|
||||
new int[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)];
|
||||
|
||||
int a, b;
|
||||
for (int i = 0; i < destPixels.length; i++)
|
||||
{
|
||||
a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize;
|
||||
b = (int) ((i % destScansize) * rx);
|
||||
if ((a + b + srcOffset) < srcPixels.length)
|
||||
destPixels[i] = srcPixels[a + b + srcOffset];
|
||||
}
|
||||
|
||||
return destPixels;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
*/
|
||||
public class RescaleOp implements BufferedImageOp, RasterOp
|
||||
{
|
||||
private float[] scale;
|
||||
private float[] offsets;
|
||||
private RenderingHints hints = null;
|
||||
|
||||
public RescaleOp(float[] scaleFactors,
|
||||
float[] offsets,
|
||||
RenderingHints hints)
|
||||
{
|
||||
this.scale = scaleFactors;
|
||||
this.offsets = offsets;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
public RescaleOp(float scaleFactor,
|
||||
float offset,
|
||||
RenderingHints hints)
|
||||
{
|
||||
scale = new float[]{ scaleFactor };
|
||||
offsets = new float[]{offset};
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
public final float[] getScaleFactors(float[] scaleFactors)
|
||||
{
|
||||
if (scaleFactors == null)
|
||||
scaleFactors = new float[scale.length];
|
||||
System.arraycopy(scale, 0, scaleFactors, 0, scale.length);
|
||||
return scaleFactors;
|
||||
}
|
||||
|
||||
public final float[] getOffsets(float[] offsets)
|
||||
{
|
||||
if (offsets == null)
|
||||
offsets = new float[this.offsets.length];
|
||||
System.arraycopy(this.offsets, 0, offsets, 0, this.offsets.length);
|
||||
return offsets;
|
||||
}
|
||||
|
||||
public final int getNumFactors()
|
||||
{
|
||||
return scale.length;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#getRenderingHints()
|
||||
*/
|
||||
public RenderingHints getRenderingHints()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage)
|
||||
*/
|
||||
public final BufferedImage filter(BufferedImage src, BufferedImage dst)
|
||||
{
|
||||
// TODO Make sure premultiplied alpha is handled correctly.
|
||||
// TODO See that color conversion is handled.
|
||||
// TODO figure out how to use rendering hints.
|
||||
if (scale.length != offsets.length)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
ColorModel scm = src.getColorModel();
|
||||
if (dst == null) dst = createCompatibleDestImage(src, null);
|
||||
|
||||
WritableRaster wsrc = src.getRaster();
|
||||
WritableRaster wdst = dst.getRaster();
|
||||
|
||||
// Share constant across colors except alpha
|
||||
if (scale.length == 1 || scale.length == scm.getNumColorComponents())
|
||||
{
|
||||
// Construct a raster that doesn't include an alpha band.
|
||||
int[] subbands = new int[scm.getNumColorComponents()];
|
||||
for (int i=0; i < subbands.length; i++) subbands[i] = i;
|
||||
wsrc =
|
||||
wsrc.createWritableChild(wsrc.minX, wsrc.minY, wsrc.width, wsrc.height,
|
||||
wsrc.minX, wsrc.minY, subbands);
|
||||
}
|
||||
// else all color bands
|
||||
|
||||
filter(wsrc, wdst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
|
||||
*/
|
||||
public final WritableRaster filter(Raster src, WritableRaster dest)
|
||||
{
|
||||
if (dest == null) dest = src.createCompatibleWritableRaster();
|
||||
|
||||
// Required sanity checks
|
||||
if (src.numBands != dest.numBands || scale.length != offsets.length)
|
||||
throw new IllegalArgumentException();
|
||||
if (scale.length != 1 && scale.length != src.numBands)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
// Create scaling arrays if needed
|
||||
float[] lscale = scale;
|
||||
float[] loff = offsets;
|
||||
if (scale.length == 1)
|
||||
{
|
||||
lscale = new float[src.numBands];
|
||||
Arrays.fill(lscale, scale[0]);
|
||||
loff = new float[src.numBands];
|
||||
Arrays.fill(loff, offsets[0]);
|
||||
}
|
||||
|
||||
// TODO The efficiency here can be improved for various data storage
|
||||
// patterns, aka SampleModels.
|
||||
float[] pixel = new float[src.numBands];
|
||||
for (int y = src.minY; y < src.height + src.minY; y++)
|
||||
for (int x = src.minX; x < src.width + src.minX; x++)
|
||||
{
|
||||
src.getPixel(x, y, pixel);
|
||||
for (int b = 0; b < src.numBands; b++)
|
||||
pixel[b] = pixel[b] * lscale[b] + loff[b];
|
||||
dest.setPixel(x, y, pixel);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage(BufferedImage src,
|
||||
ColorModel dstCM)
|
||||
{
|
||||
if (dstCM == null) dstCM = src.getColorModel();
|
||||
WritableRaster wr = src.getRaster().createCompatibleWritableRaster();
|
||||
BufferedImage image
|
||||
= new BufferedImage(dstCM, wr, src.isPremultiplied, null);
|
||||
return image;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src)
|
||||
{
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
|
||||
*/
|
||||
public final Rectangle2D getBounds2D(BufferedImage src)
|
||||
{
|
||||
return src.getRaster().getBounds();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
|
||||
*/
|
||||
public final Rectangle2D getBounds2D(Raster src)
|
||||
{
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.awt.image.BufferedImageOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
|
||||
*/
|
||||
public final Point2D getPoint2D(Point2D src, Point2D dst) {
|
||||
if (dst == null) dst = (Point2D) src.clone();
|
||||
else dst.setLocation(src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/* Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public abstract class SampleModel
|
||||
{
|
||||
/** Width of image described. */
|
||||
protected int width;
|
||||
|
||||
/** Height of image described. */
|
||||
protected int height;
|
||||
|
||||
/** Number of bands in the image described. */
|
||||
protected int numBands;
|
||||
|
||||
/**
|
||||
* The DataBuffer type that is used to store the data of the image
|
||||
* described.
|
||||
*/
|
||||
protected int dataType;
|
||||
|
||||
public SampleModel(int dataType, int w, int h, int numBands)
|
||||
{
|
||||
if ((w <= 0) || (h <= 0))
|
||||
throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
|
||||
+(h <= 0 ? " height<=0" : " height is ok"));
|
||||
|
||||
// FIXME: How can an int be greater than Integer.MAX_VALUE?
|
||||
// FIXME: How do we identify an unsupported data type?
|
||||
|
||||
this.dataType = dataType;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.numBands = numBands;
|
||||
}
|
||||
|
||||
public final int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
public final int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public final int getNumBands()
|
||||
{
|
||||
return numBands;
|
||||
}
|
||||
|
||||
public abstract int getNumDataElements();
|
||||
|
||||
public final int getDataType()
|
||||
{
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public int getTransferType()
|
||||
{
|
||||
// FIXME: Is this a reasonable default implementation?
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
if (iArray == null) iArray = new int[numBands];
|
||||
for (int b=0; b<numBands; b++) iArray[b] = getSample(x, y, b, data);
|
||||
return iArray;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This method is provided as a faster alternative to getPixel(),
|
||||
* that can be used when there is no need to decode the pixel into
|
||||
* separate sample values.
|
||||
*
|
||||
* @param obj An array to return the pixel data in. If null, an
|
||||
* array of the right type and size will be created.
|
||||
*
|
||||
* @return A single pixel as an array object of a primitive type,
|
||||
* based on the transfer type. Eg. if transfer type is
|
||||
* DataBuffer.TYPE_USHORT, then a short[] object is returned.
|
||||
*/
|
||||
public abstract Object getDataElements(int x, int y, Object obj,
|
||||
DataBuffer data);
|
||||
|
||||
|
||||
public Object getDataElements(int x, int y, int w, int h, Object obj,
|
||||
DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int numDataElements = getNumDataElements();
|
||||
int dataSize = numDataElements*size;
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
obj = new byte[dataSize];
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
obj = new short[dataSize];
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
obj = new int[dataSize];
|
||||
break;
|
||||
default:
|
||||
// Seems like the only sensible thing to do.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
}
|
||||
Object pixelData = null;
|
||||
int outOffset = 0;
|
||||
for (int yy = y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx = x; xx<(x+w); xx++)
|
||||
{
|
||||
pixelData = getDataElements(xx, yy, pixelData, data);
|
||||
System.arraycopy(pixelData, 0, obj, outOffset,
|
||||
numDataElements);
|
||||
outOffset += numDataElements;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public abstract void setDataElements(int x, int y, Object obj,
|
||||
DataBuffer data);
|
||||
|
||||
public void setDataElements(int x, int y, int w, int h,
|
||||
Object obj, DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int numDataElements = getNumDataElements();
|
||||
int dataSize = numDataElements*size;
|
||||
|
||||
Object pixelData;
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
pixelData = new byte[numDataElements];
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
pixelData = new short[numDataElements];
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
pixelData = new int[numDataElements];
|
||||
break;
|
||||
default:
|
||||
// Seems like the only sensible thing to do.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
int inOffset = 0;
|
||||
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
System.arraycopy(obj, inOffset, pixelData, 0,
|
||||
numDataElements);
|
||||
setDataElements(xx, yy, pixelData, data);
|
||||
inOffset += numDataElements;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
|
||||
{
|
||||
if (fArray == null) fArray = new float[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
fArray[b] = getSampleFloat(x, y, b, data);
|
||||
}
|
||||
return fArray;
|
||||
}
|
||||
|
||||
public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
|
||||
if (dArray == null) dArray = new double[numBands];
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
dArray[b] = getSampleDouble(x, y, b, data);
|
||||
}
|
||||
return dArray;
|
||||
}
|
||||
|
||||
/* FIXME: Should it return a banded or pixel interleaved array of
|
||||
samples? (Assume interleaved.) */
|
||||
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int outOffset = 0;
|
||||
int[] pixel = null;
|
||||
if (iArray == null) iArray = new int[w*h*numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
pixel = getPixel(xx, yy, pixel, data);
|
||||
System.arraycopy(pixel, 0, iArray, outOffset, numBands);
|
||||
outOffset += numBands;
|
||||
}
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
/* FIXME: Should it return a banded or pixel interleaved array of
|
||||
samples? (Assume interleaved.) */
|
||||
public float[] getPixels(int x, int y, int w, int h, float[] fArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int outOffset = 0;
|
||||
float[] pixel = null;
|
||||
if (fArray == null) fArray = new float[w*h*numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
pixel = getPixel(xx, yy, pixel, data);
|
||||
System.arraycopy(pixel, 0, fArray, outOffset, numBands);
|
||||
outOffset += numBands;
|
||||
}
|
||||
}
|
||||
return fArray;
|
||||
}
|
||||
|
||||
/* FIXME: Should it return a banded or pixel interleaved array of
|
||||
samples? (Assume interleaved.) */
|
||||
public double[] getPixels(int x, int y, int w, int h, double[] dArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int outOffset = 0;
|
||||
double[] pixel = null;
|
||||
if (dArray == null) dArray = new double[w*h*numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
pixel = getPixel(xx, yy, pixel, data);
|
||||
System.arraycopy(pixel, 0, dArray, outOffset, numBands);
|
||||
outOffset += numBands;
|
||||
}
|
||||
}
|
||||
return dArray;
|
||||
}
|
||||
|
||||
public abstract int getSample(int x, int y, int b, DataBuffer data);
|
||||
|
||||
public float getSampleFloat(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
return getSample(x, y, b, data);
|
||||
}
|
||||
|
||||
public double getSampleDouble(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
return getSampleFloat(x, y, b, data);
|
||||
}
|
||||
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int[] iArray, DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int outOffset = 0;
|
||||
if (iArray == null) iArray = new int[size];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
iArray[outOffset++] = getSample(xx, yy, b, data);
|
||||
}
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public float[] getSamples(int x, int y, int w, int h, int b,
|
||||
float[] fArray, DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int outOffset = 0;
|
||||
if (fArray == null) fArray = new float[size];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
|
||||
}
|
||||
}
|
||||
return fArray;
|
||||
}
|
||||
|
||||
public double[] getSamples(int x, int y, int w, int h, int b,
|
||||
double[] dArray, DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int outOffset = 0;
|
||||
if (dArray == null) dArray = new double[size];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
|
||||
}
|
||||
}
|
||||
return dArray;
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
for (int b=0; b<numBands; b++) setSample(x, y, b, iArray[b], data);
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, float[] fArray, DataBuffer data)
|
||||
{
|
||||
for (int b=0; b<numBands; b++) setSample(x, y, b, fArray[b], data);
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, double[] dArray, DataBuffer data)
|
||||
{
|
||||
for (int b=0; b<numBands; b++) setSample(x, y, b, dArray[b], data);
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int inOffset = 0;
|
||||
int[] pixel = new int[numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
System.arraycopy(iArray, inOffset, pixel, 0, numBands);
|
||||
setPixel(xx, yy, pixel, data);
|
||||
inOffset += numBands;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, float[] fArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int inOffset = 0;
|
||||
float[] pixel = new float[numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
System.arraycopy(fArray, inOffset, pixel, 0, numBands);
|
||||
setPixel(xx, yy, pixel, data);
|
||||
inOffset += numBands;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, double[] dArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int inOffset = 0;
|
||||
double[] pixel = new double[numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
System.arraycopy(dArray, inOffset, pixel, 0, numBands);
|
||||
setPixel(xx, yy, pixel, data);
|
||||
inOffset += numBands;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data);
|
||||
|
||||
public void setSample(int x, int y, int b, float s,
|
||||
DataBuffer data)
|
||||
{
|
||||
setSample(x, y, b, (int) s, data);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, double s,
|
||||
DataBuffer data)
|
||||
{
|
||||
setSample(x, y, b, (float) s, data);
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int[] iArray, DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int inOffset = 0;
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
setSample(xx, yy, b, iArray[inOffset++], data);
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
float[] fArray, DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int inOffset = 0;
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
setSample(xx, yy, b, fArray[inOffset++], data);
|
||||
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
double[] dArray, DataBuffer data) {
|
||||
int size = w*h;
|
||||
int inOffset = 0;
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
setSample(xx, yy, b, dArray[inOffset++], data);
|
||||
}
|
||||
|
||||
public abstract SampleModel createCompatibleSampleModel(int w, int h);
|
||||
|
||||
/**
|
||||
* Return a SampleModel with a subset of the bands in this model.
|
||||
*
|
||||
* Selects bands.length bands from this sample model. The bands chosen
|
||||
* are specified in the indices of bands[]. This also permits permuting
|
||||
* the bands as well as taking a subset. Thus, giving an array with
|
||||
* 1, 2, 3, ..., numbands, will give an identical sample model.
|
||||
*
|
||||
* @param bands Array with band indices to include.
|
||||
* @return A new sample model
|
||||
*/
|
||||
public abstract SampleModel createSubsetSampleModel(int[] bands);
|
||||
|
||||
public abstract DataBuffer createDataBuffer();
|
||||
|
||||
public abstract int[] getSampleSize();
|
||||
|
||||
public abstract int getSampleSize(int band);
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/* ShortLookupTable.java -- Java class for a pixel translation table.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* ShortLookupTable represents translation arrays for pixel values. It wraps
|
||||
* one or more data arrays for each layer (or component) in an image, such as
|
||||
* Alpha, R, G, and B. When doing translation, the offset is subtracted from
|
||||
* the pixel values to allow a subset of an array to be used.
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ShortLookupTable extends LookupTable
|
||||
{
|
||||
// Array of translation tables.
|
||||
private short data[][];
|
||||
|
||||
/**
|
||||
* Creates a new <code>ShortLookupTable</code> instance.
|
||||
*
|
||||
* Offset is subtracted from pixel values when looking up in the translation
|
||||
* tables. If data.length is one, the same table is applied to all pixel
|
||||
* components.
|
||||
*
|
||||
* @param offset Offset to be subtracted.
|
||||
* @param data Array of lookup tables.
|
||||
* @exception IllegalArgumentException if offset < 0 or data.length < 1.
|
||||
*/
|
||||
public ShortLookupTable(int offset, short[][] data)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
super(offset, data.length);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>ShortLookupTable</code> instance.
|
||||
*
|
||||
* Offset is subtracted from pixel values when looking up in the translation
|
||||
* table. The same table is applied to all pixel components.
|
||||
*
|
||||
* @param offset Offset to be subtracted.
|
||||
* @param data Lookup table for all components.
|
||||
* @exception IllegalArgumentException if offset < 0.
|
||||
*/
|
||||
public ShortLookupTable(int offset, short[] data)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
super(offset, 1);
|
||||
this.data = new short[][] {data};
|
||||
}
|
||||
|
||||
/** Return the lookup tables. */
|
||||
public final short[][] getTable()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return translated values for a pixel.
|
||||
*
|
||||
* For each value in the pixel src, use the value minus offset as an index
|
||||
* in the component array and copy the value there to the output for the
|
||||
* component. If dest is null, the output is a new array, otherwise the
|
||||
* translated values are written to dest. Dest can be the same array as
|
||||
* src.
|
||||
*
|
||||
* For example, if the pixel src is [2, 4, 3], and offset is 1, the output
|
||||
* is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
|
||||
* translation arrays.
|
||||
*
|
||||
* @param src Component values of a pixel.
|
||||
* @param dst Destination array for values, or null.
|
||||
* @return Translated values for the pixel.
|
||||
*/
|
||||
public int[] lookupPixel(int[] src, int[] dst)
|
||||
throws ArrayIndexOutOfBoundsException
|
||||
{
|
||||
if (dst == null)
|
||||
dst = new int[src.length];
|
||||
|
||||
if (data.length == 1)
|
||||
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];
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return translated values for a pixel.
|
||||
*
|
||||
* For each value in the pixel src, use the value minus offset as an index
|
||||
* in the component array and copy the value there to the output for the
|
||||
* component. If dest is null, the output is a new array, otherwise the
|
||||
* translated values are written to dest. Dest can be the same array as
|
||||
* src.
|
||||
*
|
||||
* For example, if the pixel src is [2, 4, 3], and offset is 1, the output
|
||||
* is [comp1[1], comp2[3], comp3[2]], where comp1, comp2, and comp3 are the
|
||||
* translation arrays.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
if (dst == null)
|
||||
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];
|
||||
else
|
||||
for (int i=0; i < src.length; i++)
|
||||
dst[i] = data[i][((int)src[i]) - offset];
|
||||
|
||||
return dst;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import gnu.java.awt.BitMaskExtent;
|
||||
import gnu.java.awt.Buffers;
|
||||
|
||||
/**
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public class SinglePixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
private int scanlineStride;
|
||||
private int[] bitMasks;
|
||||
private int[] bitOffsets;
|
||||
private int[] sampleSize;
|
||||
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int[] bitMasks)
|
||||
{
|
||||
this(dataType, w, h, w, bitMasks);
|
||||
}
|
||||
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int scanlineStride, int[] bitMasks)
|
||||
{
|
||||
super(dataType, w, h, bitMasks.length);
|
||||
|
||||
switch (dataType)
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_INT:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("SinglePixelPackedSampleModel unsupported dataType");
|
||||
}
|
||||
|
||||
this.scanlineStride = scanlineStride;
|
||||
this.bitMasks = bitMasks;
|
||||
|
||||
bitOffsets = new int[numBands];
|
||||
sampleSize = new int[numBands];
|
||||
|
||||
BitMaskExtent extent = new BitMaskExtent();
|
||||
for (int b=0; b<numBands; b++)
|
||||
{
|
||||
extent.setMask(bitMasks[b]);
|
||||
sampleSize[b] = extent.bitWidth;
|
||||
bitOffsets[b] = extent.leastSignificantBit;
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumDataElements()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public SampleModel createCompatibleSampleModel(int w, int h)
|
||||
{
|
||||
/* FIXME: We can avoid recalculation of bit offsets and sample
|
||||
sizes here by passing these from the current instance to a
|
||||
special private constructor. */
|
||||
return new SinglePixelPackedSampleModel(dataType, w, h, bitMasks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer for holding pixel data in the format and
|
||||
* layout described by this SampleModel. The returned buffer will
|
||||
* consist of one single bank.
|
||||
*/
|
||||
public DataBuffer createDataBuffer()
|
||||
{
|
||||
int size;
|
||||
|
||||
// We can save (scanlineStride - width) pixels at the very end of
|
||||
// the buffer. The Sun reference implementation (J2SE 1.3.1 and
|
||||
// 1.4.1_01) seems to do this; tested with Mauve test code.
|
||||
size = scanlineStride * (height - 1) + width;
|
||||
|
||||
return Buffers.createBuffer(getDataType(), size);
|
||||
}
|
||||
|
||||
|
||||
public int[] getSampleSize()
|
||||
{
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
public int getSampleSize(int band)
|
||||
{
|
||||
return sampleSize[band];
|
||||
}
|
||||
|
||||
public int getOffset(int x, int y)
|
||||
{
|
||||
return scanlineStride*y + x;
|
||||
}
|
||||
|
||||
public int[] getBitOffsets()
|
||||
{
|
||||
return bitOffsets;
|
||||
}
|
||||
|
||||
public int[] getBitMasks()
|
||||
{
|
||||
return bitMasks;
|
||||
}
|
||||
|
||||
public int getScanlineStride()
|
||||
{
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
public SampleModel createSubsetSampleModel(int[] bands)
|
||||
{
|
||||
// FIXME: Is this the right way to interpret bands?
|
||||
|
||||
int numBands = bands.length;
|
||||
|
||||
int[] bitMasks = new int[numBands];
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
bitMasks[b] = this.bitMasks[bands[b]];
|
||||
|
||||
return new SinglePixelPackedSampleModel(dataType, width, height,
|
||||
scanlineStride, bitMasks);
|
||||
}
|
||||
|
||||
public Object getDataElements(int x, int y, Object obj,
|
||||
DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x + data.getOffset();
|
||||
|
||||
return Buffers.getData(data, offset, obj,
|
||||
0, // destination offset,
|
||||
1 // length
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a more efficient implementation of the default implementation in the super
|
||||
* class.
|
||||
* @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
|
||||
* @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
|
||||
* @param w The width of the pixel rectangle to store in <code>obj</code>.
|
||||
* @param h The height of the pixel rectangle to store in <code>obj</code>.
|
||||
* @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, int, int, java.lang.Object, java.awt.image.DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, int w, int h, Object obj,
|
||||
DataBuffer data)
|
||||
{
|
||||
int size = w*h;
|
||||
int dataSize = size;
|
||||
Object pixelData = null;
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
pixelData = ((DataBufferByte) data).getData();
|
||||
if (obj == null) obj = new byte[dataSize];
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
pixelData = ((DataBufferUShort) data).getData();
|
||||
if (obj == null) obj = new short[dataSize];
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
pixelData = ((DataBufferInt) data).getData();
|
||||
if (obj == null) obj = new int[dataSize];
|
||||
break;
|
||||
default:
|
||||
// Seems like the only sensible thing to do.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
if(x==0 && scanlineStride == w)
|
||||
{
|
||||
// The full width need to be copied therefore we can copy in one shot.
|
||||
System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj, 0, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since we do not need the full width we need to copy line by line.
|
||||
int outOffset = 0;
|
||||
int dataOffset = scanlineStride*y + x + data.getOffset();
|
||||
for (int yy = y; yy<(y+h); yy++)
|
||||
{
|
||||
System.arraycopy(pixelData, dataOffset, obj, outOffset, w);
|
||||
dataOffset += scanlineStride;
|
||||
outOffset += w;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x;
|
||||
if (iArray == null) iArray = new int[numBands];
|
||||
int samples = data.getElem(offset);
|
||||
|
||||
for (int b=0; b<numBands; b++)
|
||||
iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b];
|
||||
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x;
|
||||
if (iArray == null) iArray = new int[numBands*w*h];
|
||||
int outOffset = 0;
|
||||
for (y=0; y<h; y++)
|
||||
{
|
||||
int lineOffset = offset;
|
||||
for (x=0; x<w; x++)
|
||||
{
|
||||
int samples = data.getElem(lineOffset++);
|
||||
for (int b=0; b<numBands; b++)
|
||||
iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
|
||||
}
|
||||
offset += scanlineStride;
|
||||
}
|
||||
return iArray;
|
||||
}
|
||||
|
||||
public int getSample(int x, int y, int b, DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x;
|
||||
int samples = data.getElem(offset);
|
||||
return (samples & bitMasks[b]) >>> bitOffsets[b];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method implements a more efficient way to set data elements than the default
|
||||
* implementation of the super class. It sets the data elements line by line instead
|
||||
* of pixel by pixel.
|
||||
* @param x The x-coordinate of the data elements in <code>obj</code>.
|
||||
* @param y The y-coordinate of the data elements in <code>obj</code>.
|
||||
* @param w The width of the data elements in <code>obj</code>.
|
||||
* @param h The height of the data elements in <code>obj</code>.
|
||||
* @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, int w, int h,
|
||||
Object obj, DataBuffer data)
|
||||
{
|
||||
|
||||
Object pixelData;
|
||||
switch (getTransferType())
|
||||
{
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
pixelData = ((DataBufferByte) data).getData();
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
pixelData = ((DataBufferUShort) data).getData();
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
pixelData = ((DataBufferInt) data).getData();
|
||||
break;
|
||||
default:
|
||||
// Seems like the only sensible thing to do.
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
int inOffset = 0;
|
||||
int dataOffset = scanlineStride*y + x + data.getOffset();
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
System.arraycopy(obj,inOffset,pixelData,dataOffset,w);
|
||||
dataOffset += scanlineStride;
|
||||
inOffset += w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x + data.getOffset();
|
||||
|
||||
int transferType = getTransferType();
|
||||
if (getTransferType() != data.getDataType())
|
||||
{
|
||||
throw new IllegalArgumentException("transfer type ("+
|
||||
getTransferType()+"), "+
|
||||
"does not match data "+
|
||||
"buffer type (" +
|
||||
data.getDataType() +
|
||||
").");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
// FIXME: Fill in the other possible types.
|
||||
default:
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x;
|
||||
|
||||
int samples = 0;
|
||||
for (int b=0; b<numBands; b++)
|
||||
samples |= (iArray[b] << bitOffsets[b]) & bitMasks[b];
|
||||
|
||||
data.setElem(offset, samples);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method implements a more efficient way to set pixels than the default
|
||||
* implementation of the super class. It copies the pixel components directly
|
||||
* from the input array instead of creating a intermediate buffer.
|
||||
* @param x The x-coordinate of the pixel rectangle in <code>obj</code>.
|
||||
* @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
|
||||
* @param w The width of the pixel rectangle in <code>obj</code>.
|
||||
* @param h The height of the pixel rectangle in <code>obj</code>.
|
||||
* @param iArray The primitive array containing the pixels to set.
|
||||
* @param data The DataBuffer to store the pixels into.
|
||||
* @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[], java.awt.image.DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, int[] iArray,
|
||||
DataBuffer data)
|
||||
{
|
||||
int inOffset = 0;
|
||||
int[] pixel = new int[numBands];
|
||||
for (int yy=y; yy<(y+h); yy++)
|
||||
{
|
||||
int offset = scanlineStride*yy + x;
|
||||
for (int xx=x; xx<(x+w); xx++)
|
||||
{
|
||||
int samples = 0;
|
||||
for (int b=0; b<numBands; b++)
|
||||
samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(0, offset, samples);
|
||||
inOffset += numBands;
|
||||
offset += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setSample(int x, int y, int b, int s, DataBuffer data)
|
||||
{
|
||||
int offset = scanlineStride*y + x;
|
||||
int samples = data.getElem(offset);
|
||||
int bitMask = bitMasks[b];
|
||||
samples &= ~bitMask;
|
||||
samples |= (s << bitOffsets[b]) & bitMask;
|
||||
data.setElem(offset, samples);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a String with some information about this SampleModel.
|
||||
* @return A String describing this SampleModel.
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append(getClass().getName());
|
||||
result.append("[");
|
||||
result.append("scanlineStride=").append(scanlineStride);
|
||||
for(int i=0; i < bitMasks.length; i+=1)
|
||||
{
|
||||
result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
|
||||
}
|
||||
|
||||
result.append("]");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/* TileObserver.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* NEEDS DOCUMENTATION
|
||||
*/
|
||||
public interface TileObserver
|
||||
{
|
||||
void tileUpdate(WritableRenderedImage src, int x, int y, boolean writable);
|
||||
} // interface TileObserver
|
||||
@@ -0,0 +1,253 @@
|
||||
/* VolatileImage.java -- a hardware-accelerated image buffer
|
||||
Copyright (C) 2002, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.ImageCapabilities;
|
||||
|
||||
/**
|
||||
* VolatileImage represents a hardware-accelerated graphics buffer.
|
||||
* The native graphics system may free or damage the resources
|
||||
* occupied by a VolatileImage at any time. As such, one must
|
||||
* frequently check the "validity" of the image buffer's resources.
|
||||
*
|
||||
* A volatile image's "validity" depends on multiple factors. Its
|
||||
* resources may have become unavailble in which case you must
|
||||
* reallocate them. If you move the image from one output device to
|
||||
* another, you may need to recreate the image's resources if the new
|
||||
* output device's capabilities don't match the old one's. Finally,
|
||||
* if the contents of the image's buffer have been damaged you must
|
||||
* re-render the image.
|
||||
*
|
||||
* VolatileImages should always be created using either
|
||||
* Component.createVolatileImage or
|
||||
* GraphicsConfiguration.createCompatibleVolatileImage.
|
||||
*/
|
||||
public abstract class VolatileImage extends Image
|
||||
implements Transparency
|
||||
{
|
||||
/**
|
||||
* One of validate's possible return values. Indicates that the
|
||||
* image buffer matches its graphics configuration's capabilities
|
||||
* and that its resources are initialized and ready to be drawn
|
||||
* into. Also implies that any existing image rendered to the
|
||||
* buffer is intact and need not be re-rendered.
|
||||
*/
|
||||
public static final int IMAGE_OK = 0;
|
||||
|
||||
/**
|
||||
* One of validate's possible return values. Indicates that the
|
||||
* image buffer has been restored, meaning that it is valid and
|
||||
* ready-to-use but that its previous contents have been lost. This
|
||||
* return value implies that the image needs to be re-rendered.
|
||||
*/
|
||||
public static final int IMAGE_RESTORED = 1;
|
||||
|
||||
/**
|
||||
* One of validate's possible return values. Indicates that the
|
||||
* image buffer type is unsupported by the current graphics
|
||||
* configuration. The graphics configuration may have changed, for
|
||||
* example if the image moved from one output device to another.
|
||||
* This return value implies that the image buffer's resources
|
||||
* should be re-acquired.
|
||||
*/
|
||||
public static final int IMAGE_INCOMPATIBLE = 2;
|
||||
|
||||
/**
|
||||
* This image's transparency type. One of Transparency.BITMASK,
|
||||
* Transparency.OPAQUE or Transparency.TRANSLUCENT.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected int transparency;
|
||||
|
||||
/**
|
||||
* Default constructor. VolatileImages should not be created
|
||||
* directly. Rather, you should use Component.createVolatileImage
|
||||
* or GraphicsConfiguration.createCompatibleVolatileImage.
|
||||
*/
|
||||
public VolatileImage()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an image representing the current state of the volatile
|
||||
* image buffer. The returned image is static meaning that it is
|
||||
* not updated after being created. It is a snapshot of the
|
||||
* volatile image buffer at the time getSnapshot is called.
|
||||
*
|
||||
* This method, which reads pixels from the volatile image buffer,
|
||||
* may be less-performant than methods that write pixels since
|
||||
* VolatileImages are typically optimized for writing.
|
||||
*
|
||||
* @return a BufferedImage representing this VolatileImage
|
||||
*/
|
||||
public abstract BufferedImage getSnapshot();
|
||||
|
||||
/**
|
||||
* Returns the width of this image buffer.
|
||||
*
|
||||
* @return the width of this VolatileImage
|
||||
*/
|
||||
public abstract int getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of this image buffer.
|
||||
*
|
||||
* @return the height of this VolatileImage
|
||||
*/
|
||||
public abstract int getHeight();
|
||||
|
||||
/**
|
||||
* Calling this method is equivalent to calling
|
||||
* getSnapshot().getSource(). The ImageProducer produces pixels
|
||||
* from the BufferedImage snapshot and not from the VolatileImage
|
||||
* itself. Thus, changes to the VolatileImage that occur after this
|
||||
* ImageProducer has been retrieved will not be reflected in the
|
||||
* produced pixels.
|
||||
*
|
||||
* This method, which reads pixels from the volatile image buffer,
|
||||
* may be less-performant than methods that write pixels since
|
||||
* VolatileImages are typically optimized for writing.
|
||||
*
|
||||
* @return an ImageProducer for a static BufferedImage snapshot of
|
||||
* this image buffer
|
||||
*/
|
||||
public ImageProducer getSource()
|
||||
{
|
||||
return getSnapshot().getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the system resources taken by this image.
|
||||
*/
|
||||
public void flush()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Graphics2D object that can be used to draw onto this
|
||||
* image. This method is present for backwards-compatibility. It
|
||||
* simply returns the result of createGraphics.
|
||||
*
|
||||
* @return a Graphics2D object that can be used to draw onto this
|
||||
* image
|
||||
*/
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
return createGraphics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Graphics2D object that can be used to draw onto this
|
||||
* image.
|
||||
*
|
||||
* @return a Graphics2D object that can be used to draw onto this
|
||||
* image
|
||||
*/
|
||||
public abstract Graphics2D createGraphics();
|
||||
|
||||
/**
|
||||
* Validates and restores this image. If the image buffer has
|
||||
* become unavailable for further use since the last call to
|
||||
* validate, validate will allocate a new image buffer. The image
|
||||
* is also "validated" against the GraphicsConfiguration parameter.
|
||||
*
|
||||
* "Validating" the image means checking that the capabilities it
|
||||
* requires of the output device are indeed supported by the given
|
||||
* output device. If the image's characteristics, which can be
|
||||
* highly output device-specific, are not supported by the graphics
|
||||
* configuration, then IMAGE_INCOMPATIBLE will be returned. This
|
||||
* can happen, for example, if this image was created on one output
|
||||
* device, then validated against a different output device with
|
||||
* different capabilities. Calling validate with a NULL gc argument
|
||||
* causes validate to skip the validation test.
|
||||
*
|
||||
* @param gc graphics configuration against which to validate or
|
||||
* NULL
|
||||
*
|
||||
* @return a code indicating the result of validation. One of:
|
||||
* <ul>
|
||||
* <li><code>IMAGE_OK</code> if the image did not need to be
|
||||
* validated and didn't need to be restored</li>
|
||||
* <li><code>IMAGE_RESTORED</code> if the image may need to be
|
||||
* re-rendered.</li>
|
||||
* <li><code>IMAGE_INCOMPATIBLE</code> if this image's
|
||||
* requirements are not fulfilled by the graphics configuration
|
||||
* parameter. This implies that you need to create a new
|
||||
* VolatileImage for the different GraphicsConfiguration or
|
||||
* Component. This return value implies nothing about whether the
|
||||
* image is valid or needs to be re-rendered.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public abstract int validate(GraphicsConfiguration gc);
|
||||
|
||||
/**
|
||||
* Returns true if the contents of the image buffer have been
|
||||
* damaged or if the image buffer's resources have been reclaimed by
|
||||
* the graphics system. You should call this method after a series
|
||||
* of rendering operations to or from the image, to see if the image
|
||||
* buffer needs to be revalidated or the image re-rendered.
|
||||
*
|
||||
* @return true if the validate should be called, false otherwise
|
||||
*/
|
||||
public abstract boolean contentsLost();
|
||||
|
||||
/**
|
||||
* Returns the capabilities of this image buffer.
|
||||
*
|
||||
* @return the capabilities of this image buffer
|
||||
*/
|
||||
public abstract ImageCapabilities getCapabilities();
|
||||
|
||||
/**
|
||||
* Returns the transparency type of this image.
|
||||
*
|
||||
* @return Transparency.OPAQUE, Transparency.BITMASK or
|
||||
* Transparency.TRANSLUCENT
|
||||
*/
|
||||
public int getTransparency()
|
||||
{
|
||||
return transparency;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
|
||||
*/
|
||||
public class WritableRaster extends Raster
|
||||
{
|
||||
protected WritableRaster(SampleModel sampleModel, Point origin)
|
||||
{
|
||||
this(sampleModel, sampleModel.createDataBuffer(), origin);
|
||||
}
|
||||
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer, Point origin)
|
||||
{
|
||||
this(sampleModel, dataBuffer,
|
||||
new Rectangle(origin != null ? origin.x : 0,
|
||||
origin != null ? origin.y : 0,
|
||||
sampleModel.getWidth(), sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Rectangle aRegion,
|
||||
Point sampleModelTranslate,
|
||||
WritableRaster parent)
|
||||
{
|
||||
super(sampleModel, dataBuffer, aRegion, sampleModelTranslate,
|
||||
parent);
|
||||
}
|
||||
|
||||
public WritableRaster getWritableParent()
|
||||
{
|
||||
return (WritableRaster) getParent();
|
||||
}
|
||||
|
||||
public WritableRaster createWritableTranslatedChild(int childMinX,
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// FIXME: Throw RasterFormatException if child bounds extends
|
||||
// beyond the bounds of this raster.
|
||||
|
||||
SampleModel sm = (bandList == null) ?
|
||||
sampleModel :
|
||||
sampleModel.createSubsetSampleModel(bandList);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void setDataElements(int x, int y, Raster inRaster)
|
||||
{
|
||||
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)
|
||||
{
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, inData, dataBuffer);
|
||||
}
|
||||
|
||||
public void setRect(Raster srcRaster)
|
||||
{
|
||||
setRect(0, 0, 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 target = getBounds().intersection(targetUnclipped);
|
||||
|
||||
if (target.isEmpty()) return;
|
||||
|
||||
int sx = target.x - dx;
|
||||
int sy = target.y - dy;
|
||||
|
||||
// FIXME: Do tests on rasters and use get/set data instead.
|
||||
|
||||
/* The JDK documentation seems to imply this implementation.
|
||||
(the trucation of higher bits), but an implementation using
|
||||
get/setDataElements would be more efficient. None of the
|
||||
implementations would do anything sensible when the sample
|
||||
models don't match.
|
||||
|
||||
But this is probably not the place to consider such
|
||||
optimizations.*/
|
||||
|
||||
int[] pixels = srcRaster.getPixels(sx, sy,
|
||||
target.width, target.height,
|
||||
(int[]) null);
|
||||
|
||||
setPixels(target.x, target.y, target.width, target.height, pixels);
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, int[] iArray)
|
||||
{
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
iArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, float[] fArray)
|
||||
{
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
fArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, double[] dArray)
|
||||
{
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
dArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, int[] iArray)
|
||||
{
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, iArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, float[] fArray)
|
||||
{
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, fArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, double[] dArray)
|
||||
{
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, dArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, int s)
|
||||
{
|
||||
sampleModel.setSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
b, s, dataBuffer);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, float s)
|
||||
{
|
||||
sampleModel.setSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
b, s, dataBuffer);
|
||||
}
|
||||
|
||||
public void setSample(int x, int y, int b, double s)
|
||||
{
|
||||
sampleModel.setSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
b, s, dataBuffer);
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int[] iArray)
|
||||
{
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, b, iArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
float[] fArray)
|
||||
{
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, b, fArray, dataBuffer);
|
||||
}
|
||||
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
double[] dArray)
|
||||
{
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w, h, b, dArray, dataBuffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* WritableRenderedImage.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* NEEDS DOCUMENTATION
|
||||
*/
|
||||
public interface WritableRenderedImage extends RenderedImage
|
||||
{
|
||||
void addTileObserver(TileObserver to);
|
||||
void removeTileObserver(TileObserver to);
|
||||
WritableRaster getWritableTile(int x, int y);
|
||||
void releaseWritableTile(int x, int y);
|
||||
boolean isTileWritable(int x, int y);
|
||||
Point[] getWritableTileIndices();
|
||||
boolean hasTileWriters();
|
||||
void setData(Raster r);
|
||||
} // interface WritableRenderedImage
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in java.awt.image package.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - java.awt.image</title></head>
|
||||
|
||||
<body>
|
||||
<p>Image consumers, producers and filters.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,56 @@
|
||||
/* ContextualRenderedImageFactory.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* STUBBED
|
||||
*/
|
||||
public interface ContextualRenderedImageFactory extends RenderedImageFactory
|
||||
{
|
||||
RenderContext mapRenderContext(int i, RenderContext context,
|
||||
ParameterBlock block, RenderableImage image);
|
||||
RenderedImage create(RenderContext context, ParameterBlock block);
|
||||
Rectangle2D getBounds2D(ParameterBlock block);
|
||||
Object getProperty(ParameterBlock block, String name);
|
||||
String[] getPropertyNames();
|
||||
boolean isDynamic();
|
||||
} // interface ContextualRenderedImageFactory
|
||||
@@ -0,0 +1,308 @@
|
||||
/* ParameterBlock.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
|
||||
public class ParameterBlock implements Cloneable, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -7577115551785240750L;
|
||||
protected Vector sources;
|
||||
protected Vector parameters;
|
||||
|
||||
public ParameterBlock()
|
||||
{
|
||||
this(new Vector(), new Vector());
|
||||
}
|
||||
|
||||
public ParameterBlock(Vector sources)
|
||||
{
|
||||
this(sources, new Vector());
|
||||
}
|
||||
|
||||
public ParameterBlock(Vector sources, Vector parameters)
|
||||
{
|
||||
this.sources = sources;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public Object shallowClone()
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
throw (Error) new InternalError().initCause(e); // impossible
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
ParameterBlock pb = (ParameterBlock) shallowClone();
|
||||
if (sources != null)
|
||||
pb.sources = (Vector) sources.clone();
|
||||
if (parameters != null)
|
||||
pb.parameters = (Vector) parameters.clone();
|
||||
return pb;
|
||||
}
|
||||
|
||||
public ParameterBlock addSource(Object source)
|
||||
{
|
||||
sources.add(source);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object getSource(int index)
|
||||
{
|
||||
return sources.get(index);
|
||||
}
|
||||
|
||||
public ParameterBlock setSource(Object source, int index)
|
||||
{
|
||||
sources.ensureCapacity(index);
|
||||
sources.set(index, source);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderedImage getRenderedSource(int index)
|
||||
{
|
||||
return (RenderedImage) sources.get(index);
|
||||
}
|
||||
|
||||
public RenderableImage getRenderableSource(int index)
|
||||
{
|
||||
return (RenderableImage) sources.get(index);
|
||||
}
|
||||
|
||||
public int getNumSources()
|
||||
{
|
||||
return sources.size();
|
||||
}
|
||||
|
||||
public Vector getSources()
|
||||
{
|
||||
return sources;
|
||||
}
|
||||
|
||||
public void setSources(Vector sources)
|
||||
{
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
public void removeSources()
|
||||
{
|
||||
if (sources != null)
|
||||
sources.clear();
|
||||
}
|
||||
|
||||
public int getNumParameters()
|
||||
{
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public Vector getParameters()
|
||||
{
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(Vector parameters)
|
||||
{
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public void removeParameters()
|
||||
{
|
||||
if (parameters != null)
|
||||
parameters.clear();
|
||||
}
|
||||
|
||||
public ParameterBlock add(Object o)
|
||||
{
|
||||
parameters.add(o);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParameterBlock add(byte b)
|
||||
{
|
||||
return add(new Byte(b));
|
||||
}
|
||||
|
||||
public ParameterBlock add(char c)
|
||||
{
|
||||
return add(new Character(c));
|
||||
}
|
||||
|
||||
public ParameterBlock add(short s)
|
||||
{
|
||||
return add(new Short(s));
|
||||
}
|
||||
|
||||
public ParameterBlock add(int i)
|
||||
{
|
||||
return add(new Integer(i));
|
||||
}
|
||||
|
||||
public ParameterBlock add(long l)
|
||||
{
|
||||
return add(new Long(l));
|
||||
}
|
||||
|
||||
public ParameterBlock add(float f)
|
||||
{
|
||||
return add(new Float(f));
|
||||
}
|
||||
|
||||
public ParameterBlock add(double d)
|
||||
{
|
||||
return add(new Double(d));
|
||||
}
|
||||
|
||||
public ParameterBlock set(Object o, int index)
|
||||
{
|
||||
parameters.ensureCapacity(index);
|
||||
parameters.set(index, o);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParameterBlock set(byte b, int index)
|
||||
{
|
||||
return set(new Byte(b), index);
|
||||
}
|
||||
|
||||
public ParameterBlock set(char c, int index)
|
||||
{
|
||||
return set(new Character(c), index);
|
||||
}
|
||||
|
||||
public ParameterBlock set(short s, int index)
|
||||
{
|
||||
return set(new Short(s), index);
|
||||
}
|
||||
|
||||
public ParameterBlock set(int i, int index)
|
||||
{
|
||||
return set(new Integer(i), index);
|
||||
}
|
||||
|
||||
public ParameterBlock set(long l, int index)
|
||||
{
|
||||
return set(new Long(l), index);
|
||||
}
|
||||
|
||||
public ParameterBlock set(float f, int index)
|
||||
{
|
||||
return set(new Float(f), index);
|
||||
}
|
||||
|
||||
public ParameterBlock set(double d, int index)
|
||||
{
|
||||
return set(new Double(d), index);
|
||||
}
|
||||
|
||||
public Object getObjectParameter(int index)
|
||||
{
|
||||
return parameters.get(index);
|
||||
}
|
||||
|
||||
public byte getByteParameter(int index)
|
||||
{
|
||||
return ((Byte) parameters.get(index)).byteValue();
|
||||
}
|
||||
|
||||
public char getCharParameter(int index)
|
||||
{
|
||||
return ((Character) parameters.get(index)).charValue();
|
||||
}
|
||||
|
||||
public short getShortParameter(int index)
|
||||
{
|
||||
return ((Short) parameters.get(index)).shortValue();
|
||||
}
|
||||
|
||||
public int getIntParameter(int index)
|
||||
{
|
||||
return ((Integer) parameters.get(index)).intValue();
|
||||
}
|
||||
|
||||
public long getLongParameter(int index)
|
||||
{
|
||||
return ((Long) parameters.get(index)).longValue();
|
||||
}
|
||||
|
||||
public float getFloatParameter(int index)
|
||||
{
|
||||
return ((Float) parameters.get(index)).floatValue();
|
||||
}
|
||||
|
||||
public double getDoubleParameter(int index)
|
||||
{
|
||||
return ((Double) parameters.get(index)).doubleValue();
|
||||
}
|
||||
|
||||
public Class[] getParamClasses()
|
||||
{
|
||||
int i = parameters.size();
|
||||
Class[] result = new Class[i];
|
||||
while (--i >= 0)
|
||||
{
|
||||
Class c = parameters.get(i).getClass();
|
||||
if (c == Byte.class)
|
||||
result[i] = byte.class;
|
||||
else if (c == Character.class)
|
||||
result[i] = char.class;
|
||||
else if (c == Short.class)
|
||||
result[i] = short.class;
|
||||
else if (c == Integer.class)
|
||||
result[i] = int.class;
|
||||
else if (c == Long.class)
|
||||
result[i] = long.class;
|
||||
else if (c == Float.class)
|
||||
result[i] = float.class;
|
||||
else if (c == Double.class)
|
||||
result[i] = double.class;
|
||||
else
|
||||
result[i] = c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // class ParameterBlock
|
||||
@@ -0,0 +1,141 @@
|
||||
/* RenderContext.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
|
||||
public class RenderContext implements Cloneable
|
||||
{
|
||||
private AffineTransform xform;
|
||||
private Shape aoi;
|
||||
private RenderingHints hints;
|
||||
|
||||
public RenderContext(AffineTransform xform, Shape aoi, RenderingHints hints)
|
||||
{
|
||||
this.xform = xform;
|
||||
this.aoi = aoi;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
public RenderContext(AffineTransform xform)
|
||||
{
|
||||
this(xform, null, null);
|
||||
}
|
||||
|
||||
public RenderContext(AffineTransform xform, RenderingHints hints)
|
||||
{
|
||||
this(xform, null, hints);
|
||||
}
|
||||
|
||||
public RenderContext(AffineTransform xform, Shape aoi)
|
||||
{
|
||||
this(xform, aoi, null);
|
||||
}
|
||||
|
||||
public RenderingHints getRenderingHints()
|
||||
{
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setRenderingHints(RenderingHints hints)
|
||||
{
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
public void setTransform(AffineTransform xform)
|
||||
{
|
||||
this.xform = xform;
|
||||
}
|
||||
|
||||
public void preConcatenateTransform(AffineTransform pre)
|
||||
{
|
||||
preConcetenateTransform (pre);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
public void preConcetenateTransform(AffineTransform pre)
|
||||
{
|
||||
xform.preConcatenate (pre);
|
||||
}
|
||||
|
||||
public void concatenateTransform(AffineTransform post)
|
||||
{
|
||||
concetenateTransform (post);
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
public void concetenateTransform(AffineTransform post)
|
||||
{
|
||||
xform.concatenate (post);
|
||||
}
|
||||
|
||||
public AffineTransform getTransform()
|
||||
{
|
||||
return xform;
|
||||
}
|
||||
|
||||
public void setAreaOfInterest(Shape aoi)
|
||||
{
|
||||
this.aoi = aoi;
|
||||
}
|
||||
|
||||
public Shape getAreaOfInterest()
|
||||
{
|
||||
return aoi;
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
RenderContext copy = (RenderContext) super.clone();
|
||||
if (xform != null)
|
||||
copy.xform = (AffineTransform) xform.clone();
|
||||
if (hints != null)
|
||||
copy.hints = (RenderingHints) hints.clone();
|
||||
return copy;
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
throw (Error) new InternalError().initCause(e); // impossible
|
||||
}
|
||||
}
|
||||
} // class RenderContext
|
||||
@@ -0,0 +1,62 @@
|
||||
/* RenderableImage.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.util.Vector;
|
||||
|
||||
public interface RenderableImage
|
||||
{
|
||||
String HINTS_OBSERVED = "HINTS_OBSERVED";
|
||||
|
||||
Vector getSources();
|
||||
Object getProperty(String name);
|
||||
String[] getPropertyNames();
|
||||
boolean isDynamic();
|
||||
float getWidth();
|
||||
float getHeight();
|
||||
float getMinX();
|
||||
float getMinY();
|
||||
RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
|
||||
RenderedImage createDefaultRendering();
|
||||
RenderedImage createRendering(RenderContext context);
|
||||
|
||||
} // interface RenderableImage
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/* RenderableImageOp.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.util.Vector;
|
||||
|
||||
public class RenderableImageOp implements RenderableImage
|
||||
{
|
||||
private final ContextualRenderedImageFactory crif;
|
||||
private ParameterBlock block;
|
||||
|
||||
public RenderableImageOp(ContextualRenderedImageFactory crif,
|
||||
ParameterBlock block)
|
||||
{
|
||||
this.crif = crif;
|
||||
this.block = (ParameterBlock) block.clone();
|
||||
}
|
||||
|
||||
public Vector getSources()
|
||||
{
|
||||
if (block.sources == null)
|
||||
return null;
|
||||
int size = block.sources.size();
|
||||
Vector v = new Vector();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
Object o = block.sources.get(i);
|
||||
if (o instanceof RenderableImage)
|
||||
v.add(o);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public Object getProperty(String name)
|
||||
{
|
||||
return crif.getProperty(block, name);
|
||||
}
|
||||
|
||||
public String[] getPropertyNames()
|
||||
{
|
||||
return crif.getPropertyNames();
|
||||
}
|
||||
|
||||
public boolean isDynamic()
|
||||
{
|
||||
return crif.isDynamic();
|
||||
}
|
||||
|
||||
public float getWidth()
|
||||
{
|
||||
return (float) crif.getBounds2D(block).getWidth();
|
||||
}
|
||||
|
||||
public float getHeight()
|
||||
{
|
||||
return (float) crif.getBounds2D(block).getHeight();
|
||||
}
|
||||
|
||||
public float getMinX()
|
||||
{
|
||||
return (float) crif.getBounds2D(block).getX();
|
||||
}
|
||||
|
||||
public float getMinY()
|
||||
{
|
||||
return (float) crif.getBounds2D(block).getY();
|
||||
}
|
||||
|
||||
public ParameterBlock setParameterBlock(ParameterBlock block)
|
||||
{
|
||||
ParameterBlock result = this.block;
|
||||
this.block = (ParameterBlock) block.clone();
|
||||
return result;
|
||||
}
|
||||
|
||||
public ParameterBlock getParameterBlock()
|
||||
{
|
||||
return block;
|
||||
}
|
||||
|
||||
public RenderedImage createScaledRendering(int w, int h,
|
||||
RenderingHints hints)
|
||||
{
|
||||
if (w == 0)
|
||||
if (h == 0)
|
||||
throw new IllegalArgumentException();
|
||||
else
|
||||
w = Math.round(h * getWidth() / getHeight());
|
||||
if (h == 0)
|
||||
h = Math.round(w * getHeight() / getWidth());
|
||||
AffineTransform xform = AffineTransform.getScaleInstance(w * getWidth(),
|
||||
h * getHeight());
|
||||
return createRendering(new RenderContext(xform, hints));
|
||||
}
|
||||
|
||||
public RenderedImage createDefaultRendering()
|
||||
{
|
||||
return createRendering(new RenderContext(new AffineTransform()));
|
||||
}
|
||||
|
||||
public RenderedImage createRendering(RenderContext context)
|
||||
{
|
||||
ParameterBlock copy = (ParameterBlock) block.clone();
|
||||
int i = block.sources.size();
|
||||
while (--i >= 0)
|
||||
{
|
||||
Object o = block.sources.get(i);
|
||||
if (o instanceof RenderableImage)
|
||||
{
|
||||
RenderableImage ri = (RenderableImage) o;
|
||||
RenderContext rc = crif.mapRenderContext(i, context, block, ri);
|
||||
copy.sources.set(i, ri.createRendering(rc));
|
||||
}
|
||||
}
|
||||
// Now copy.sources should be only RenderedImages.
|
||||
return crif.create(context, copy);
|
||||
}
|
||||
} // class RenderableImageOp
|
||||
@@ -0,0 +1,79 @@
|
||||
/* RenderableImageProducer.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
|
||||
public class RenderableImageProducer implements ImageProducer, Runnable
|
||||
{
|
||||
public RenderableImageProducer(RenderableImage image, RenderContext context)
|
||||
{
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
public void setRenderContext(RenderContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void addConsumer(ImageConsumer consumer)
|
||||
{
|
||||
}
|
||||
|
||||
public boolean isConsumer(ImageConsumer consumer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeConsumer(ImageConsumer consumer)
|
||||
{
|
||||
}
|
||||
|
||||
public void startProduction(ImageConsumer consumer)
|
||||
{
|
||||
}
|
||||
|
||||
public void requestTopDownLeftRightResend(ImageConsumer consumer)
|
||||
{
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
}
|
||||
} // class RenderableImageProducer
|
||||
@@ -0,0 +1,47 @@
|
||||
/* RenderedImageFactory.java --
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt.image.renderable;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
public interface RenderedImageFactory
|
||||
{
|
||||
RenderedImage create(ParameterBlock block, RenderingHints hints);
|
||||
} // interface RenderedImageFactory
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in java.awt.image.renderable package.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - java.awt.image.renderable</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user