feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
561
jdkSrc/jdk8/java/awt/image/AffineTransformOp.java
Normal file
561
jdkSrc/jdk8/java/awt/image/AffineTransformOp.java
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.NoninvertibleTransformException;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Transparency;
|
||||
import java.lang.annotation.Native;
|
||||
import sun.awt.image.ImagingLib;
|
||||
|
||||
/**
|
||||
* This class uses an affine transform to perform a linear mapping from
|
||||
* 2D coordinates in the source image or <CODE>Raster</CODE> to 2D coordinates
|
||||
* in the destination image or <CODE>Raster</CODE>.
|
||||
* The type of interpolation that is used is specified through a constructor,
|
||||
* either by a <CODE>RenderingHints</CODE> object or by one of the integer
|
||||
* interpolation types defined in this class.
|
||||
* <p>
|
||||
* If a <CODE>RenderingHints</CODE> object is specified in the constructor, the
|
||||
* interpolation hint and the rendering quality hint are used to set
|
||||
* the interpolation type for this operation. The color rendering hint
|
||||
* and the dithering hint can be used when color conversion is required.
|
||||
* <p>
|
||||
* Note that the following constraints have to be met:
|
||||
* <ul>
|
||||
* <li>The source and destination must be different.
|
||||
* <li>For <CODE>Raster</CODE> objects, the number of bands in the source must
|
||||
* be equal to the number of bands in the destination.
|
||||
* </ul>
|
||||
* @see AffineTransform
|
||||
* @see BufferedImageFilter
|
||||
* @see java.awt.RenderingHints#KEY_INTERPOLATION
|
||||
* @see java.awt.RenderingHints#KEY_RENDERING
|
||||
* @see java.awt.RenderingHints#KEY_COLOR_RENDERING
|
||||
* @see java.awt.RenderingHints#KEY_DITHERING
|
||||
*/
|
||||
public class AffineTransformOp implements BufferedImageOp, RasterOp {
|
||||
private AffineTransform xform;
|
||||
RenderingHints hints;
|
||||
|
||||
/**
|
||||
* Nearest-neighbor interpolation type.
|
||||
*/
|
||||
@Native public static final int TYPE_NEAREST_NEIGHBOR = 1;
|
||||
|
||||
/**
|
||||
* Bilinear interpolation type.
|
||||
*/
|
||||
@Native public static final int TYPE_BILINEAR = 2;
|
||||
|
||||
/**
|
||||
* Bicubic interpolation type.
|
||||
*/
|
||||
@Native public static final int TYPE_BICUBIC = 3;
|
||||
|
||||
int interpolationType = TYPE_NEAREST_NEIGHBOR;
|
||||
|
||||
/**
|
||||
* Constructs an <CODE>AffineTransformOp</CODE> given an affine transform.
|
||||
* The interpolation type is determined from the
|
||||
* <CODE>RenderingHints</CODE> object. If the interpolation hint is
|
||||
* defined, it will be used. Otherwise, if the rendering quality hint is
|
||||
* defined, the interpolation type is determined from its value. If no
|
||||
* hints are specified (<CODE>hints</CODE> is null),
|
||||
* the interpolation type is {@link #TYPE_NEAREST_NEIGHBOR
|
||||
* TYPE_NEAREST_NEIGHBOR}.
|
||||
*
|
||||
* @param xform The <CODE>AffineTransform</CODE> to use for the
|
||||
* operation.
|
||||
*
|
||||
* @param hints The <CODE>RenderingHints</CODE> object used to specify
|
||||
* the interpolation type for the operation.
|
||||
*
|
||||
* @throws ImagingOpException if the transform is non-invertible.
|
||||
* @see java.awt.RenderingHints#KEY_INTERPOLATION
|
||||
* @see java.awt.RenderingHints#KEY_RENDERING
|
||||
*/
|
||||
public AffineTransformOp(AffineTransform xform, RenderingHints hints){
|
||||
validateTransform(xform);
|
||||
this.xform = (AffineTransform) xform.clone();
|
||||
this.hints = hints;
|
||||
|
||||
if (hints != null) {
|
||||
Object value = hints.get(hints.KEY_INTERPOLATION);
|
||||
if (value == null) {
|
||||
value = hints.get(hints.KEY_RENDERING);
|
||||
if (value == hints.VALUE_RENDER_SPEED) {
|
||||
interpolationType = TYPE_NEAREST_NEIGHBOR;
|
||||
}
|
||||
else if (value == hints.VALUE_RENDER_QUALITY) {
|
||||
interpolationType = TYPE_BILINEAR;
|
||||
}
|
||||
}
|
||||
else if (value == hints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR) {
|
||||
interpolationType = TYPE_NEAREST_NEIGHBOR;
|
||||
}
|
||||
else if (value == hints.VALUE_INTERPOLATION_BILINEAR) {
|
||||
interpolationType = TYPE_BILINEAR;
|
||||
}
|
||||
else if (value == hints.VALUE_INTERPOLATION_BICUBIC) {
|
||||
interpolationType = TYPE_BICUBIC;
|
||||
}
|
||||
}
|
||||
else {
|
||||
interpolationType = TYPE_NEAREST_NEIGHBOR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <CODE>AffineTransformOp</CODE> given an affine transform
|
||||
* and the interpolation type.
|
||||
*
|
||||
* @param xform The <CODE>AffineTransform</CODE> to use for the operation.
|
||||
* @param interpolationType One of the integer
|
||||
* interpolation type constants defined by this class:
|
||||
* {@link #TYPE_NEAREST_NEIGHBOR TYPE_NEAREST_NEIGHBOR},
|
||||
* {@link #TYPE_BILINEAR TYPE_BILINEAR},
|
||||
* {@link #TYPE_BICUBIC TYPE_BICUBIC}.
|
||||
* @throws ImagingOpException if the transform is non-invertible.
|
||||
*/
|
||||
public AffineTransformOp(AffineTransform xform, int interpolationType) {
|
||||
validateTransform(xform);
|
||||
this.xform = (AffineTransform)xform.clone();
|
||||
switch(interpolationType) {
|
||||
case TYPE_NEAREST_NEIGHBOR:
|
||||
case TYPE_BILINEAR:
|
||||
case TYPE_BICUBIC:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown interpolation type: "+
|
||||
interpolationType);
|
||||
}
|
||||
this.interpolationType = interpolationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the interpolation type used by this op.
|
||||
* @return the interpolation type.
|
||||
* @see #TYPE_NEAREST_NEIGHBOR
|
||||
* @see #TYPE_BILINEAR
|
||||
* @see #TYPE_BICUBIC
|
||||
*/
|
||||
public final int getInterpolationType() {
|
||||
return interpolationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the source <CODE>BufferedImage</CODE> and stores the results
|
||||
* in the destination <CODE>BufferedImage</CODE>.
|
||||
* If the color models for the two images do not match, a color
|
||||
* conversion into the destination color model is performed.
|
||||
* If the destination image is null,
|
||||
* a <CODE>BufferedImage</CODE> is created with the source
|
||||
* <CODE>ColorModel</CODE>.
|
||||
* <p>
|
||||
* The coordinates of the rectangle returned by
|
||||
* <code>getBounds2D(BufferedImage)</code>
|
||||
* are not necessarily the same as the coordinates of the
|
||||
* <code>BufferedImage</code> returned by this method. If the
|
||||
* upper-left corner coordinates of the rectangle are
|
||||
* negative then this part of the rectangle is not drawn. If the
|
||||
* upper-left corner coordinates of the rectangle are positive
|
||||
* then the filtered image is drawn at that position in the
|
||||
* destination <code>BufferedImage</code>.
|
||||
* <p>
|
||||
* An <CODE>IllegalArgumentException</CODE> is thrown if the source is
|
||||
* the same as the destination.
|
||||
*
|
||||
* @param src The <CODE>BufferedImage</CODE> to transform.
|
||||
* @param dst The <CODE>BufferedImage</CODE> in which to store the results
|
||||
* of the transformation.
|
||||
*
|
||||
* @return The filtered <CODE>BufferedImage</CODE>.
|
||||
* @throws IllegalArgumentException if <code>src</code> and
|
||||
* <code>dst</code> are the same
|
||||
* @throws ImagingOpException if the image cannot be transformed
|
||||
* because of a data-processing error that might be
|
||||
* caused by an invalid image format, tile format, or
|
||||
* image-processing operation, or any other unsupported
|
||||
* operation.
|
||||
*/
|
||||
public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
|
||||
|
||||
if (src == null) {
|
||||
throw new NullPointerException("src image is null");
|
||||
}
|
||||
if (src == dst) {
|
||||
throw new IllegalArgumentException("src image cannot be the "+
|
||||
"same as the dst image");
|
||||
}
|
||||
|
||||
boolean needToConvert = false;
|
||||
ColorModel srcCM = src.getColorModel();
|
||||
ColorModel dstCM;
|
||||
BufferedImage origDst = dst;
|
||||
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
dstCM = srcCM;
|
||||
origDst = dst;
|
||||
}
|
||||
else {
|
||||
dstCM = dst.getColorModel();
|
||||
if (srcCM.getColorSpace().getType() !=
|
||||
dstCM.getColorSpace().getType())
|
||||
{
|
||||
int type = xform.getType();
|
||||
boolean needTrans = ((type&
|
||||
(xform.TYPE_MASK_ROTATION|
|
||||
xform.TYPE_GENERAL_TRANSFORM))
|
||||
!= 0);
|
||||
if (! needTrans && type != xform.TYPE_TRANSLATION && type != xform.TYPE_IDENTITY)
|
||||
{
|
||||
double[] mtx = new double[4];
|
||||
xform.getMatrix(mtx);
|
||||
// Check out the matrix. A non-integral scale will force ARGB
|
||||
// since the edge conditions can't be guaranteed.
|
||||
needTrans = (mtx[0] != (int)mtx[0] || mtx[3] != (int)mtx[3]);
|
||||
}
|
||||
|
||||
if (needTrans &&
|
||||
srcCM.getTransparency() == Transparency.OPAQUE)
|
||||
{
|
||||
// Need to convert first
|
||||
ColorConvertOp ccop = new ColorConvertOp(hints);
|
||||
BufferedImage tmpSrc = null;
|
||||
int sw = src.getWidth();
|
||||
int sh = src.getHeight();
|
||||
if (dstCM.getTransparency() == Transparency.OPAQUE) {
|
||||
tmpSrc = new BufferedImage(sw, sh,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
else {
|
||||
WritableRaster r =
|
||||
dstCM.createCompatibleWritableRaster(sw, sh);
|
||||
tmpSrc = new BufferedImage(dstCM, r,
|
||||
dstCM.isAlphaPremultiplied(),
|
||||
null);
|
||||
}
|
||||
src = ccop.filter(src, tmpSrc);
|
||||
}
|
||||
else {
|
||||
needToConvert = true;
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (interpolationType != TYPE_NEAREST_NEIGHBOR &&
|
||||
dst.getColorModel() instanceof IndexColorModel) {
|
||||
dst = new BufferedImage(dst.getWidth(), dst.getHeight(),
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
if (ImagingLib.filter(this, src, dst) == null) {
|
||||
throw new ImagingOpException ("Unable to transform src image");
|
||||
}
|
||||
|
||||
if (needToConvert) {
|
||||
ColorConvertOp ccop = new ColorConvertOp(hints);
|
||||
ccop.filter(dst, origDst);
|
||||
}
|
||||
else if (origDst != dst) {
|
||||
java.awt.Graphics2D g = origDst.createGraphics();
|
||||
try {
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.drawImage(dst, 0, 0, null);
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return origDst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the source <CODE>Raster</CODE> and stores the results in
|
||||
* the destination <CODE>Raster</CODE>. This operation performs the
|
||||
* transform band by band.
|
||||
* <p>
|
||||
* If the destination <CODE>Raster</CODE> is null, a new
|
||||
* <CODE>Raster</CODE> is created.
|
||||
* An <CODE>IllegalArgumentException</CODE> may be thrown if the source is
|
||||
* the same as the destination or if the number of bands in
|
||||
* the source is not equal to the number of bands in the
|
||||
* destination.
|
||||
* <p>
|
||||
* The coordinates of the rectangle returned by
|
||||
* <code>getBounds2D(Raster)</code>
|
||||
* are not necessarily the same as the coordinates of the
|
||||
* <code>WritableRaster</code> returned by this method. If the
|
||||
* upper-left corner coordinates of rectangle are negative then
|
||||
* this part of the rectangle is not drawn. If the coordinates
|
||||
* of the rectangle are positive then the filtered image is drawn at
|
||||
* that position in the destination <code>Raster</code>.
|
||||
* <p>
|
||||
* @param src The <CODE>Raster</CODE> to transform.
|
||||
* @param dst The <CODE>Raster</CODE> in which to store the results of the
|
||||
* transformation.
|
||||
*
|
||||
* @return The transformed <CODE>Raster</CODE>.
|
||||
*
|
||||
* @throws ImagingOpException if the raster cannot be transformed
|
||||
* because of a data-processing error that might be
|
||||
* caused by an invalid image format, tile format, or
|
||||
* image-processing operation, or any other unsupported
|
||||
* operation.
|
||||
*/
|
||||
public final WritableRaster filter(Raster src, WritableRaster dst) {
|
||||
if (src == null) {
|
||||
throw new NullPointerException("src image is null");
|
||||
}
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestRaster(src);
|
||||
}
|
||||
if (src == dst) {
|
||||
throw new IllegalArgumentException("src image cannot be the "+
|
||||
"same as the dst image");
|
||||
}
|
||||
if (src.getNumBands() != dst.getNumBands()) {
|
||||
throw new IllegalArgumentException("Number of src bands ("+
|
||||
src.getNumBands()+
|
||||
") does not match number of "+
|
||||
" dst bands ("+
|
||||
dst.getNumBands()+")");
|
||||
}
|
||||
|
||||
if (ImagingLib.filter(this, src, dst) == null) {
|
||||
throw new ImagingOpException ("Unable to transform src image");
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the transformed destination. The
|
||||
* rectangle returned is the actual bounding box of the
|
||||
* transformed points. The coordinates of the upper-left corner
|
||||
* of the returned rectangle might not be (0, 0).
|
||||
*
|
||||
* @param src The <CODE>BufferedImage</CODE> to be transformed.
|
||||
*
|
||||
* @return The <CODE>Rectangle2D</CODE> representing the destination's
|
||||
* bounding box.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (BufferedImage src) {
|
||||
return getBounds2D(src.getRaster());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the transformed destination. The
|
||||
* rectangle returned will be the actual bounding box of the
|
||||
* transformed points. The coordinates of the upper-left corner
|
||||
* of the returned rectangle might not be (0, 0).
|
||||
*
|
||||
* @param src The <CODE>Raster</CODE> to be transformed.
|
||||
*
|
||||
* @return The <CODE>Rectangle2D</CODE> representing the destination's
|
||||
* bounding box.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (Raster src) {
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
|
||||
// Get the bounding box of the src and transform the corners
|
||||
float[] pts = {0, 0, w, 0, w, h, 0, h};
|
||||
xform.transform(pts, 0, pts, 0, 4);
|
||||
|
||||
// Get the min, max of the dst
|
||||
float fmaxX = pts[0];
|
||||
float fmaxY = pts[1];
|
||||
float fminX = pts[0];
|
||||
float fminY = pts[1];
|
||||
for (int i=2; i < 8; i+=2) {
|
||||
if (pts[i] > fmaxX) {
|
||||
fmaxX = pts[i];
|
||||
}
|
||||
else if (pts[i] < fminX) {
|
||||
fminX = pts[i];
|
||||
}
|
||||
if (pts[i+1] > fmaxY) {
|
||||
fmaxY = pts[i+1];
|
||||
}
|
||||
else if (pts[i+1] < fminY) {
|
||||
fminY = pts[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
return new Rectangle2D.Float(fminX, fminY, fmaxX-fminX, fmaxY-fminY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination image with the correct size and number of
|
||||
* bands. A <CODE>RasterFormatException</CODE> may be thrown if the
|
||||
* transformed width or height is equal to 0.
|
||||
* <p>
|
||||
* If <CODE>destCM</CODE> is null,
|
||||
* an appropriate <CODE>ColorModel</CODE> is used; this
|
||||
* <CODE>ColorModel</CODE> may have
|
||||
* an alpha channel even if the source <CODE>ColorModel</CODE> is opaque.
|
||||
*
|
||||
* @param src The <CODE>BufferedImage</CODE> to be transformed.
|
||||
* @param destCM <CODE>ColorModel</CODE> of the destination. If null,
|
||||
* an appropriate <CODE>ColorModel</CODE> is used.
|
||||
*
|
||||
* @return The zeroed destination image.
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage (BufferedImage src,
|
||||
ColorModel destCM) {
|
||||
BufferedImage image;
|
||||
Rectangle r = getBounds2D(src).getBounds();
|
||||
|
||||
// If r.x (or r.y) is < 0, then we want to only create an image
|
||||
// that is in the positive range.
|
||||
// If r.x (or r.y) is > 0, then we need to create an image that
|
||||
// includes the translation.
|
||||
int w = r.x + r.width;
|
||||
int h = r.y + r.height;
|
||||
if (w <= 0) {
|
||||
throw new RasterFormatException("Transformed width ("+w+
|
||||
") is less than or equal to 0.");
|
||||
}
|
||||
if (h <= 0) {
|
||||
throw new RasterFormatException("Transformed height ("+h+
|
||||
") is less than or equal to 0.");
|
||||
}
|
||||
|
||||
if (destCM == null) {
|
||||
ColorModel cm = src.getColorModel();
|
||||
if (interpolationType != TYPE_NEAREST_NEIGHBOR &&
|
||||
(cm instanceof IndexColorModel ||
|
||||
cm.getTransparency() == Transparency.OPAQUE))
|
||||
{
|
||||
image = new BufferedImage(w, h,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
else {
|
||||
image = new BufferedImage(cm,
|
||||
src.getRaster().createCompatibleWritableRaster(w,h),
|
||||
cm.isAlphaPremultiplied(), null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
image = new BufferedImage(destCM,
|
||||
destCM.createCompatibleWritableRaster(w,h),
|
||||
destCM.isAlphaPremultiplied(), null);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination <CODE>Raster</CODE> with the correct size
|
||||
* and number of bands. A <CODE>RasterFormatException</CODE> may be thrown
|
||||
* if the transformed width or height is equal to 0.
|
||||
*
|
||||
* @param src The <CODE>Raster</CODE> to be transformed.
|
||||
*
|
||||
* @return The zeroed destination <CODE>Raster</CODE>.
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster (Raster src) {
|
||||
Rectangle2D r = getBounds2D(src);
|
||||
|
||||
return src.createCompatibleWritableRaster((int)r.getX(),
|
||||
(int)r.getY(),
|
||||
(int)r.getWidth(),
|
||||
(int)r.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the corresponding destination point given a
|
||||
* point in the source. If <CODE>dstPt</CODE> is specified, it
|
||||
* is used to hold the return value.
|
||||
*
|
||||
* @param srcPt The <code>Point2D</code> that represents the source
|
||||
* point.
|
||||
* @param dstPt The <CODE>Point2D</CODE> in which to store the result.
|
||||
*
|
||||
* @return The <CODE>Point2D</CODE> in the destination that corresponds to
|
||||
* the specified point in the source.
|
||||
*/
|
||||
public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
|
||||
return xform.transform (srcPt, dstPt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the affine transform used by this transform operation.
|
||||
*
|
||||
* @return The <CODE>AffineTransform</CODE> associated with this op.
|
||||
*/
|
||||
public final AffineTransform getTransform() {
|
||||
return (AffineTransform) xform.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendering hints used by this transform operation.
|
||||
*
|
||||
* @return The <CODE>RenderingHints</CODE> object associated with this op.
|
||||
*/
|
||||
public final RenderingHints getRenderingHints() {
|
||||
if (hints == null) {
|
||||
Object val;
|
||||
switch(interpolationType) {
|
||||
case TYPE_NEAREST_NEIGHBOR:
|
||||
val = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
|
||||
break;
|
||||
case TYPE_BILINEAR:
|
||||
val = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
|
||||
break;
|
||||
case TYPE_BICUBIC:
|
||||
val = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
|
||||
break;
|
||||
default:
|
||||
// Should never get here
|
||||
throw new InternalError("Unknown interpolation type "+
|
||||
interpolationType);
|
||||
|
||||
}
|
||||
hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, val);
|
||||
}
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
||||
// We need to be able to invert the transform if we want to
|
||||
// transform the image. If the determinant of the matrix is 0,
|
||||
// then we can't invert the transform.
|
||||
void validateTransform(AffineTransform xform) {
|
||||
if (Math.abs(xform.getDeterminant()) <= Double.MIN_VALUE) {
|
||||
throw new ImagingOpException("Unable to invert transform "+xform);
|
||||
}
|
||||
}
|
||||
}
|
||||
281
jdkSrc/jdk8/java/awt/image/AreaAveragingScaleFilter.java
Normal file
281
jdkSrc/jdk8/java/awt/image/AreaAveragingScaleFilter.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.Hashtable;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* An ImageFilter class for scaling images using a simple area averaging
|
||||
* algorithm that produces smoother results than the nearest neighbor
|
||||
* algorithm.
|
||||
* <p>This class extends the basic ImageFilter Class to scale an existing
|
||||
* image and provide a source for a new image containing the resampled
|
||||
* image. The pixels in the source image are blended to produce pixels
|
||||
* for an image of the specified size. The blending process is analogous
|
||||
* to scaling up the source image to a multiple of the destination size
|
||||
* using pixel replication and then scaling it back down to the destination
|
||||
* size by simply averaging all the pixels in the supersized image that
|
||||
* fall within a given pixel of the destination image. If the data from
|
||||
* the source is not delivered in TopDownLeftRight order then the filter
|
||||
* will back off to a simple pixel replication behavior and utilize the
|
||||
* requestTopDownLeftRightResend() method to refilter the pixels in a
|
||||
* better way at the end.
|
||||
* <p>It is meant to be used in conjunction with a FilteredImageSource
|
||||
* object to produce scaled versions of existing images. Due to
|
||||
* implementation dependencies, there may be differences in pixel values
|
||||
* of an image filtered on different platforms.
|
||||
*
|
||||
* @see FilteredImageSource
|
||||
* @see ReplicateScaleFilter
|
||||
* @see ImageFilter
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
|
||||
private static final ColorModel rgbmodel = ColorModel.getRGBdefault();
|
||||
private static final int neededHints = (TOPDOWNLEFTRIGHT
|
||||
| COMPLETESCANLINES);
|
||||
|
||||
private boolean passthrough;
|
||||
private float reds[], greens[], blues[], alphas[];
|
||||
private int savedy;
|
||||
private int savedyrem;
|
||||
|
||||
/**
|
||||
* Constructs an AreaAveragingScaleFilter that scales the pixels from
|
||||
* its source Image as specified by the width and height parameters.
|
||||
* @param width the target width to scale the image
|
||||
* @param height the target height to scale the image
|
||||
*/
|
||||
public AreaAveragingScaleFilter(int width, int height) {
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if the data is being delivered with the necessary hints
|
||||
* to allow the averaging algorithm to do its work.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose
|
||||
* pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#setHints
|
||||
*/
|
||||
public void setHints(int hints) {
|
||||
passthrough = ((hints & neededHints) != neededHints);
|
||||
super.setHints(hints);
|
||||
}
|
||||
|
||||
private void makeAccumBuffers() {
|
||||
reds = new float[destWidth];
|
||||
greens = new float[destWidth];
|
||||
blues = new float[destWidth];
|
||||
alphas = new float[destWidth];
|
||||
}
|
||||
|
||||
private int[] calcRow() {
|
||||
float origmult = ((float) srcWidth) * srcHeight;
|
||||
if (outpixbuf == null || !(outpixbuf instanceof int[])) {
|
||||
outpixbuf = new int[destWidth];
|
||||
}
|
||||
int[] outpix = (int[]) outpixbuf;
|
||||
for (int x = 0; x < destWidth; x++) {
|
||||
float mult = origmult;
|
||||
int a = Math.round(alphas[x] / mult);
|
||||
if (a <= 0) {
|
||||
a = 0;
|
||||
} else if (a >= 255) {
|
||||
a = 255;
|
||||
} else {
|
||||
// un-premultiply the components (by modifying mult here, we
|
||||
// are effectively doing the divide by mult and divide by
|
||||
// alpha in the same step)
|
||||
mult = alphas[x] / 255;
|
||||
}
|
||||
int r = Math.round(reds[x] / mult);
|
||||
int g = Math.round(greens[x] / mult);
|
||||
int b = Math.round(blues[x] / mult);
|
||||
if (r < 0) {r = 0;} else if (r > 255) {r = 255;}
|
||||
if (g < 0) {g = 0;} else if (g > 255) {g = 255;}
|
||||
if (b < 0) {b = 0;} else if (b > 255) {b = 255;}
|
||||
outpix[x] = (a << 24 | r << 16 | g << 8 | b);
|
||||
}
|
||||
return outpix;
|
||||
}
|
||||
|
||||
private void accumPixels(int x, int y, int w, int h,
|
||||
ColorModel model, Object pixels, int off,
|
||||
int scansize) {
|
||||
if (reds == null) {
|
||||
makeAccumBuffers();
|
||||
}
|
||||
int sy = y;
|
||||
int syrem = destHeight;
|
||||
int dy, dyrem;
|
||||
if (sy == 0) {
|
||||
dy = 0;
|
||||
dyrem = 0;
|
||||
} else {
|
||||
dy = savedy;
|
||||
dyrem = savedyrem;
|
||||
}
|
||||
while (sy < y + h) {
|
||||
int amty;
|
||||
if (dyrem == 0) {
|
||||
for (int i = 0; i < destWidth; i++) {
|
||||
alphas[i] = reds[i] = greens[i] = blues[i] = 0f;
|
||||
}
|
||||
dyrem = srcHeight;
|
||||
}
|
||||
if (syrem < dyrem) {
|
||||
amty = syrem;
|
||||
} else {
|
||||
amty = dyrem;
|
||||
}
|
||||
int sx = 0;
|
||||
int dx = 0;
|
||||
int sxrem = 0;
|
||||
int dxrem = srcWidth;
|
||||
float a = 0f, r = 0f, g = 0f, b = 0f;
|
||||
while (sx < w) {
|
||||
if (sxrem == 0) {
|
||||
sxrem = destWidth;
|
||||
int rgb;
|
||||
if (pixels instanceof byte[]) {
|
||||
rgb = ((byte[]) pixels)[off + sx] & 0xff;
|
||||
} else {
|
||||
rgb = ((int[]) pixels)[off + sx];
|
||||
}
|
||||
// getRGB() always returns non-premultiplied components
|
||||
rgb = model.getRGB(rgb);
|
||||
a = rgb >>> 24;
|
||||
r = (rgb >> 16) & 0xff;
|
||||
g = (rgb >> 8) & 0xff;
|
||||
b = rgb & 0xff;
|
||||
// premultiply the components if necessary
|
||||
if (a != 255.0f) {
|
||||
float ascale = a / 255.0f;
|
||||
r *= ascale;
|
||||
g *= ascale;
|
||||
b *= ascale;
|
||||
}
|
||||
}
|
||||
int amtx;
|
||||
if (sxrem < dxrem) {
|
||||
amtx = sxrem;
|
||||
} else {
|
||||
amtx = dxrem;
|
||||
}
|
||||
float mult = ((float) amtx) * amty;
|
||||
alphas[dx] += mult * a;
|
||||
reds[dx] += mult * r;
|
||||
greens[dx] += mult * g;
|
||||
blues[dx] += mult * b;
|
||||
if ((sxrem -= amtx) == 0) {
|
||||
sx++;
|
||||
}
|
||||
if ((dxrem -= amtx) == 0) {
|
||||
dx++;
|
||||
dxrem = srcWidth;
|
||||
}
|
||||
}
|
||||
if ((dyrem -= amty) == 0) {
|
||||
int outpix[] = calcRow();
|
||||
do {
|
||||
consumer.setPixels(0, dy, destWidth, 1,
|
||||
rgbmodel, outpix, 0, destWidth);
|
||||
dy++;
|
||||
} while ((syrem -= amty) >= amty && amty == srcHeight);
|
||||
} else {
|
||||
syrem -= amty;
|
||||
}
|
||||
if (syrem == 0) {
|
||||
syrem = destHeight;
|
||||
sy++;
|
||||
off += scansize;
|
||||
}
|
||||
}
|
||||
savedyrem = dyrem;
|
||||
savedy = dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the components for the delivered byte pixels into the
|
||||
* accumulation arrays and send on any averaged data for rows of
|
||||
* pixels that are complete. If the correct hints were not
|
||||
* specified in the setHints call then relay the work to our
|
||||
* superclass which is capable of scaling pixels regardless of
|
||||
* the delivery hints.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code>
|
||||
* whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ReplicateScaleFilter
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off,
|
||||
int scansize) {
|
||||
if (passthrough) {
|
||||
super.setPixels(x, y, w, h, model, pixels, off, scansize);
|
||||
} else {
|
||||
accumPixels(x, y, w, h, model, pixels, off, scansize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the components for the delivered int pixels into the
|
||||
* accumulation arrays and send on any averaged data for rows of
|
||||
* pixels that are complete. If the correct hints were not
|
||||
* specified in the setHints call then relay the work to our
|
||||
* superclass which is capable of scaling pixels regardless of
|
||||
* the delivery hints.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code>
|
||||
* whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ReplicateScaleFilter
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off,
|
||||
int scansize) {
|
||||
if (passthrough) {
|
||||
super.setPixels(x, y, w, h, model, pixels, off, scansize);
|
||||
} else {
|
||||
accumPixels(x, y, w, h, model, pixels, off, scansize);
|
||||
}
|
||||
}
|
||||
}
|
||||
289
jdkSrc/jdk8/java/awt/image/BandCombineOp.java
Normal file
289
jdkSrc/jdk8/java/awt/image/BandCombineOp.java
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.RenderingHints;
|
||||
import sun.awt.image.ImagingLib;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class performs an arbitrary linear combination of the bands
|
||||
* in a <CODE>Raster</CODE>, using a specified matrix.
|
||||
* <p>
|
||||
* The width of the matrix must be equal to the number of bands in the
|
||||
* source <CODE>Raster</CODE>, optionally plus one. If there is one more
|
||||
* column in the matrix than the number of bands, there is an implied 1 at the
|
||||
* end of the vector of band samples representing a pixel. The height
|
||||
* of the matrix must be equal to the number of bands in the destination.
|
||||
* <p>
|
||||
* For example, a 3-banded <CODE>Raster</CODE> might have the following
|
||||
* transformation applied to each pixel in order to invert the second band of
|
||||
* the <CODE>Raster</CODE>.
|
||||
* <pre>
|
||||
* [ 1.0 0.0 0.0 0.0 ] [ b1 ]
|
||||
* [ 0.0 -1.0 0.0 255.0 ] x [ b2 ]
|
||||
* [ 0.0 0.0 1.0 0.0 ] [ b3 ]
|
||||
* [ 1 ]
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Note that the source and destination can be the same object.
|
||||
*/
|
||||
public class BandCombineOp implements RasterOp {
|
||||
float[][] matrix;
|
||||
int nrows = 0;
|
||||
int ncols = 0;
|
||||
RenderingHints hints;
|
||||
|
||||
/**
|
||||
* Constructs a <CODE>BandCombineOp</CODE> with the specified matrix.
|
||||
* The width of the matrix must be equal to the number of bands in
|
||||
* the source <CODE>Raster</CODE>, optionally plus one. If there is one
|
||||
* more column in the matrix than the number of bands, there is an implied
|
||||
* 1 at the end of the vector of band samples representing a pixel. The
|
||||
* height of the matrix must be equal to the number of bands in the
|
||||
* destination.
|
||||
* <p>
|
||||
* The first subscript is the row index and the second
|
||||
* is the column index. This operation uses none of the currently
|
||||
* defined rendering hints; the <CODE>RenderingHints</CODE> argument can be
|
||||
* null.
|
||||
*
|
||||
* @param matrix The matrix to use for the band combine operation.
|
||||
* @param hints The <CODE>RenderingHints</CODE> object for this operation.
|
||||
* Not currently used so it can be null.
|
||||
*/
|
||||
public BandCombineOp (float[][] matrix, RenderingHints hints) {
|
||||
nrows = matrix.length;
|
||||
ncols = matrix[0].length;
|
||||
this.matrix = new float[nrows][];
|
||||
for (int i=0; i < nrows; i++) {
|
||||
/* Arrays.copyOf is forgiving of the source array being
|
||||
* too short, but it is also faster than other cloning
|
||||
* methods, so we provide our own protection for short
|
||||
* matrix rows.
|
||||
*/
|
||||
if (ncols > matrix[i].length) {
|
||||
throw new IndexOutOfBoundsException("row "+i+" too short");
|
||||
}
|
||||
this.matrix[i] = Arrays.copyOf(matrix[i], ncols);
|
||||
}
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the linear combination matrix.
|
||||
*
|
||||
* @return The matrix associated with this band combine operation.
|
||||
*/
|
||||
public final float[][] getMatrix() {
|
||||
float[][] ret = new float[nrows][];
|
||||
for (int i = 0; i < nrows; i++) {
|
||||
ret[i] = Arrays.copyOf(matrix[i], ncols);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the <CODE>Raster</CODE> using the matrix specified in the
|
||||
* constructor. An <CODE>IllegalArgumentException</CODE> may be thrown if
|
||||
* the number of bands in the source or destination is incompatible with
|
||||
* the matrix. See the class comments for more details.
|
||||
* <p>
|
||||
* If the destination is null, it will be created with a number of bands
|
||||
* equalling the number of rows in the matrix. No exception is thrown
|
||||
* if the operation causes a data overflow.
|
||||
*
|
||||
* @param src The <CODE>Raster</CODE> to be filtered.
|
||||
* @param dst The <CODE>Raster</CODE> in which to store the results
|
||||
* of the filter operation.
|
||||
*
|
||||
* @return The filtered <CODE>Raster</CODE>.
|
||||
*
|
||||
* @throws IllegalArgumentException If the number of bands in the
|
||||
* source or destination is incompatible with the matrix.
|
||||
*/
|
||||
public WritableRaster filter(Raster src, WritableRaster dst) {
|
||||
int nBands = src.getNumBands();
|
||||
if (ncols != nBands && ncols != (nBands+1)) {
|
||||
throw new IllegalArgumentException("Number of columns in the "+
|
||||
"matrix ("+ncols+
|
||||
") must be equal to the number"+
|
||||
" of bands ([+1]) in src ("+
|
||||
nBands+").");
|
||||
}
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestRaster(src);
|
||||
}
|
||||
else if (nrows != dst.getNumBands()) {
|
||||
throw new IllegalArgumentException("Number of rows in the "+
|
||||
"matrix ("+nrows+
|
||||
") must be equal to the number"+
|
||||
" of bands ([+1]) in dst ("+
|
||||
nBands+").");
|
||||
}
|
||||
|
||||
if (ImagingLib.filter(this, src, dst) != null) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
int[] pixel = null;
|
||||
int[] dstPixel = new int[dst.getNumBands()];
|
||||
float accum;
|
||||
int sminX = src.getMinX();
|
||||
int sY = src.getMinY();
|
||||
int dminX = dst.getMinX();
|
||||
int dY = dst.getMinY();
|
||||
int sX;
|
||||
int dX;
|
||||
if (ncols == nBands) {
|
||||
for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
|
||||
dX = dminX;
|
||||
sX = sminX;
|
||||
for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
|
||||
pixel = src.getPixel(sX, sY, pixel);
|
||||
for (int r=0; r < nrows; r++) {
|
||||
accum = 0.f;
|
||||
for (int c=0; c < ncols; c++) {
|
||||
accum += matrix[r][c]*pixel[c];
|
||||
}
|
||||
dstPixel[r] = (int) accum;
|
||||
}
|
||||
dst.setPixel(dX, dY, dstPixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Need to add constant
|
||||
for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
|
||||
dX = dminX;
|
||||
sX = sminX;
|
||||
for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
|
||||
pixel = src.getPixel(sX, sY, pixel);
|
||||
for (int r=0; r < nrows; r++) {
|
||||
accum = 0.f;
|
||||
for (int c=0; c < nBands; c++) {
|
||||
accum += matrix[r][c]*pixel[c];
|
||||
}
|
||||
dstPixel[r] = (int) (accum+matrix[r][nBands]);
|
||||
}
|
||||
dst.setPixel(dX, dY, dstPixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the transformed destination. Since
|
||||
* this is not a geometric operation, the bounding box is the same for
|
||||
* the source and destination.
|
||||
* An <CODE>IllegalArgumentException</CODE> may be thrown if the number of
|
||||
* bands in the source is incompatible with the matrix. See
|
||||
* the class comments for more details.
|
||||
*
|
||||
* @param src The <CODE>Raster</CODE> to be filtered.
|
||||
*
|
||||
* @return The <CODE>Rectangle2D</CODE> representing the destination
|
||||
* image's bounding box.
|
||||
*
|
||||
* @throws IllegalArgumentException If the number of bands in the source
|
||||
* is incompatible with the matrix.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (Raster src) {
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination <CODE>Raster</CODE> with the correct size
|
||||
* and number of bands.
|
||||
* An <CODE>IllegalArgumentException</CODE> may be thrown if the number of
|
||||
* bands in the source is incompatible with the matrix. See
|
||||
* the class comments for more details.
|
||||
*
|
||||
* @param src The <CODE>Raster</CODE> to be filtered.
|
||||
*
|
||||
* @return The zeroed destination <CODE>Raster</CODE>.
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster (Raster src) {
|
||||
int nBands = src.getNumBands();
|
||||
if ((ncols != nBands) && (ncols != (nBands+1))) {
|
||||
throw new IllegalArgumentException("Number of columns in the "+
|
||||
"matrix ("+ncols+
|
||||
") must be equal to the number"+
|
||||
" of bands ([+1]) in src ("+
|
||||
nBands+").");
|
||||
}
|
||||
if (src.getNumBands() == nrows) {
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Don't know how to create a "+
|
||||
" compatible Raster with "+
|
||||
nrows+" bands.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the corresponding destination point given a
|
||||
* point in the source <CODE>Raster</CODE>. If <CODE>dstPt</CODE> is
|
||||
* specified, it is used to hold the return value.
|
||||
* Since this is not a geometric operation, the point returned
|
||||
* is the same as the specified <CODE>srcPt</CODE>.
|
||||
*
|
||||
* @param srcPt The <code>Point2D</code> that represents the point in
|
||||
* the source <code>Raster</code>
|
||||
* @param dstPt The <CODE>Point2D</CODE> in which to store the result.
|
||||
*
|
||||
* @return The <CODE>Point2D</CODE> in the destination image that
|
||||
* corresponds to the specified point in the source image.
|
||||
*/
|
||||
public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
|
||||
if (dstPt == null) {
|
||||
dstPt = new Point2D.Float();
|
||||
}
|
||||
dstPt.setLocation(srcPt.getX(), srcPt.getY());
|
||||
|
||||
return dstPt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendering hints for this operation.
|
||||
*
|
||||
* @return The <CODE>RenderingHints</CODE> object associated with this
|
||||
* operation. Returns null if no hints have been set.
|
||||
*/
|
||||
public final RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
}
|
||||
849
jdkSrc/jdk8/java/awt/image/BandedSampleModel.java
Normal file
849
jdkSrc/jdk8/java/awt/image/BandedSampleModel.java
Normal file
@@ -0,0 +1,849 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This class represents image data which is stored in a band interleaved
|
||||
* fashion and for
|
||||
* which each sample of a pixel occupies one data element of the DataBuffer.
|
||||
* It subclasses ComponentSampleModel but provides a more efficient
|
||||
* implementation for accessing band interleaved image data than is provided
|
||||
* by ComponentSampleModel. This class should typically be used when working
|
||||
* with images which store sample data for each band in a different bank of the
|
||||
* DataBuffer. Accessor methods are provided so that image data can be
|
||||
* manipulated directly. Pixel stride is the number of
|
||||
* data array elements between two samples for the same band on the same
|
||||
* scanline. The pixel stride for a BandedSampleModel is one.
|
||||
* Scanline stride is the number of data array elements between
|
||||
* a given sample and the corresponding sample in the same column of the next
|
||||
* scanline. Band offsets denote the number
|
||||
* of data array elements from the first data array element of the bank
|
||||
* of the DataBuffer holding each band to the first sample of the band.
|
||||
* The bands are numbered from 0 to N-1.
|
||||
* Bank indices denote the correspondence between a bank of the data buffer
|
||||
* and a band of image data. This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT},
|
||||
* {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
|
||||
* {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
|
||||
*/
|
||||
|
||||
|
||||
public final class BandedSampleModel extends ComponentSampleModel
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a BandedSampleModel with the specified parameters.
|
||||
* The pixel stride will be one data element. The scanline stride
|
||||
* will be the same as the width. Each band will be stored in
|
||||
* a separate bank and all band offsets will be zero.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of image
|
||||
* data described.
|
||||
* @param numBands The number of bands for the image data.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public BandedSampleModel(int dataType, int w, int h, int numBands) {
|
||||
super(dataType, w, h, 1, w,
|
||||
BandedSampleModel.createIndicesArray(numBands),
|
||||
BandedSampleModel.createOffsetArray(numBands));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BandedSampleModel with the specified parameters.
|
||||
* The number of bands will be inferred from the lengths of the
|
||||
* bandOffsets bankIndices arrays, which must be equal. The pixel
|
||||
* stride will be one data element.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param scanlineStride The line stride of the of the image data.
|
||||
* @param bankIndices The bank index for each band.
|
||||
* @param bandOffsets The band offset for each band.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public BandedSampleModel(int dataType,
|
||||
int w, int h,
|
||||
int scanlineStride,
|
||||
int bankIndices[],
|
||||
int bandOffsets[]) {
|
||||
|
||||
super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BandedSampleModel with the specified
|
||||
* width and height. The new BandedSampleModel will have the same
|
||||
* number of bands, storage data type, and bank indices
|
||||
* as this BandedSampleModel. The band offsets will be compressed
|
||||
* such that the offset between bands will be w*pixelStride and
|
||||
* the minimum of all of the band offsets is zero.
|
||||
* @param w the width of the resulting <code>BandedSampleModel</code>
|
||||
* @param h the height of the resulting <code>BandedSampleModel</code>
|
||||
* @return a new <code>BandedSampleModel</code> with the specified
|
||||
* width and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> equals either
|
||||
* <code>Integer.MAX_VALUE</code> or
|
||||
* <code>Integer.MIN_VALUE</code>
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int[] bandOffs;
|
||||
|
||||
if (numBanks == 1) {
|
||||
bandOffs = orderBands(bandOffsets, w*h);
|
||||
}
|
||||
else {
|
||||
bandOffs = new int[bandOffsets.length];
|
||||
}
|
||||
|
||||
SampleModel sampleModel =
|
||||
new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BandedSampleModel with a subset of the bands of this
|
||||
* BandedSampleModel. The new BandedSampleModel can be
|
||||
* used with any DataBuffer that the existing BandedSampleModel
|
||||
* can be used with. The new BandedSampleModel/DataBuffer
|
||||
* combination will represent an image with a subset of the bands
|
||||
* of the original BandedSampleModel/DataBuffer combination.
|
||||
* @throws RasterFormatException if the number of bands is greater than
|
||||
* the number of banks in this sample model.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands.length > bankIndices.length)
|
||||
throw new RasterFormatException("There are only " +
|
||||
bankIndices.length +
|
||||
" bands");
|
||||
int newBankIndices[] = new int[bands.length];
|
||||
int newBandOffsets[] = new int[bands.length];
|
||||
|
||||
for (int i=0; i<bands.length; i++) {
|
||||
newBankIndices[i] = bankIndices[bands[i]];
|
||||
newBandOffsets[i] = bandOffsets[bands[i]];
|
||||
}
|
||||
|
||||
return new BandedSampleModel(this.dataType, width, height,
|
||||
this.scanlineStride,
|
||||
newBankIndices, newBandOffsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer that corresponds to this BandedSampleModel,
|
||||
* The DataBuffer's data type, number of banks, and size
|
||||
* will be consistent with this BandedSampleModel.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported types.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = scanlineStride * height;
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
dataBuffer = new DataBufferShort(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
dataBuffer = new DataBufferFloat(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
dataBuffer = new DataBufferDouble(size, numBanks);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("dataType is not one " +
|
||||
"of the supported types.");
|
||||
}
|
||||
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a BandedSampleModel, this will be the same
|
||||
* as the data type, and samples will be returned one per array
|
||||
* element. Generally, obj
|
||||
* should be passed in as null, so that the Object will be created
|
||||
* automatically and will be of the right primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* BandedSampleModel bsm1, bsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
|
||||
* db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If obj is non-null, it should be a primitive array of type TransferType.
|
||||
* Otherwise, a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is non-null and is not large enough to hold
|
||||
* the pixel data.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param obj If non-null, a primitive array in which to return
|
||||
* the pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the data for the specified pixel.
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null) {
|
||||
bdata = new byte[numDataElems];
|
||||
} else {
|
||||
bdata = (byte[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
bdata[i] = (byte)data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null) {
|
||||
sdata = new short[numDataElems];
|
||||
} else {
|
||||
sdata = (short[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
sdata[i] = (short)data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null) {
|
||||
idata = new int[numDataElems];
|
||||
} else {
|
||||
idata = (int[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
idata[i] = data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
|
||||
float[] fdata;
|
||||
|
||||
if (obj == null) {
|
||||
fdata = new float[numDataElems];
|
||||
} else {
|
||||
fdata = (float[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
fdata[i] = data.getElemFloat(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)fdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
|
||||
double[] ddata;
|
||||
|
||||
if (obj == null) {
|
||||
ddata = new double[numDataElems];
|
||||
} else {
|
||||
ddata = (double[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
ddata[i] = data.getElemDouble(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)ddata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified pixel in an int array.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples for the specified pixel.
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int[] pixels;
|
||||
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [numBands];
|
||||
}
|
||||
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
pixels[i] = data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified rectangle of pixels in
|
||||
* an int array, one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples for the pixels within the specified region.
|
||||
* @see #setPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
int x1 = x + w;
|
||||
int y1 = y + h;
|
||||
|
||||
if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
|
||||
y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
|
||||
{
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int[] pixels;
|
||||
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int[w*h*numBands];
|
||||
}
|
||||
|
||||
for (int k = 0; k < numBands; k++) {
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[k];
|
||||
int srcOffset = k;
|
||||
int bank = bankIndices[k];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int pixelOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
pixels[srcOffset] = data.getElem(bank, pixelOffset++);
|
||||
srcOffset += numBands;
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as int the sample in a specified band for the pixel
|
||||
* located at (x,y).
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the sample in the specified band for the specified pixel.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int sample =
|
||||
data.getElem(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample in a specified band
|
||||
* for the pixel located at (x,y) as a float.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return a float value that represents the sample in the specified
|
||||
* band for the specified pixel.
|
||||
*/
|
||||
public float getSampleFloat(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
float sample = data.getElemFloat(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample in a specified band
|
||||
* for a pixel located at (x,y) as a double.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return a double value that represents the sample in the specified
|
||||
* band for the specified pixel.
|
||||
*/
|
||||
public double getSampleDouble(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
double sample = data.getElemDouble(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples in a specified band for the specified rectangle
|
||||
* of pixels in an int array, one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param b The band to return
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples in the specified band for the pixels within
|
||||
* the specified region.
|
||||
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int samples[];
|
||||
if (iArray != null) {
|
||||
samples = iArray;
|
||||
} else {
|
||||
samples = new int [w*h];
|
||||
}
|
||||
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[b];
|
||||
int srcOffset = 0;
|
||||
int bank = bankIndices[b];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int sampleOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
samples[srcOffset++] = data.getElem(bank, sampleOffset++);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified DataBuffer from a
|
||||
* primitive array of type TransferType. For a BandedSampleModel,
|
||||
* this will be the same as the data type, and samples are transferred
|
||||
* one per array element.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* BandedSampleModel bsm1, bsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
|
||||
* db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* obj must be a primitive array of type TransferType. Otherwise,
|
||||
* a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is not large enough to hold the pixel data.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param obj If non-null, returns the primitive array in this
|
||||
* object
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
barray[i] & 0xff);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
sarray[i] & 0xffff);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
iarray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
|
||||
float[] farray = (float[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
farray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
|
||||
double[] darray = (double[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
darray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param iArray The input samples in an int array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
iArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param iArray The input samples in an int array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
int x1 = x + w;
|
||||
int y1 = y + h;
|
||||
|
||||
if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
|
||||
y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
|
||||
{
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
for (int k = 0; k < numBands; k++) {
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[k];
|
||||
int srcOffset = k;
|
||||
int bank = bankIndices[k];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int pixelOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
data.setElem(bank, pixelOffset++, iArray[srcOffset]);
|
||||
srcOffset += numBands;
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as an int
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElem(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a float for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as a float
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b,
|
||||
float s ,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElemFloat(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a double for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as a double
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b,
|
||||
double s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElemDouble(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param b The band to set
|
||||
* @param iArray The input sample array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[b];
|
||||
int srcOffset = 0;
|
||||
int bank = bankIndices[b];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int sampleOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] createOffsetArray(int numBands) {
|
||||
int[] bandOffsets = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bandOffsets[i] = 0;
|
||||
}
|
||||
return bandOffsets;
|
||||
}
|
||||
|
||||
private static int[] createIndicesArray(int numBands) {
|
||||
int[] bankIndices = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bankIndices[i] = i;
|
||||
}
|
||||
return bankIndices;
|
||||
}
|
||||
|
||||
// Differentiate hash code from other ComponentSampleModel subclasses
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ 0x2;
|
||||
}
|
||||
}
|
||||
204
jdkSrc/jdk8/java/awt/image/BufferStrategy.java
Normal file
204
jdkSrc/jdk8/java/awt/image/BufferStrategy.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.BufferCapabilities;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
|
||||
/**
|
||||
* The <code>BufferStrategy</code> class represents the mechanism with which
|
||||
* to organize complex memory on a particular <code>Canvas</code> or
|
||||
* <code>Window</code>. Hardware and software limitations determine whether and
|
||||
* how a particular buffer strategy can be implemented. These limitations
|
||||
* are detectable through the capabilities of the
|
||||
* <code>GraphicsConfiguration</code> used when creating the
|
||||
* <code>Canvas</code> or <code>Window</code>.
|
||||
* <p>
|
||||
* It is worth noting that the terms <i>buffer</i> and <i>surface</i> are meant
|
||||
* to be synonymous: an area of contiguous memory, either in video device
|
||||
* memory or in system memory.
|
||||
* <p>
|
||||
* There are several types of complex buffer strategies, including
|
||||
* sequential ring buffering and blit buffering.
|
||||
* Sequential ring buffering (i.e., double or triple
|
||||
* buffering) is the most common; an application draws to a single <i>back
|
||||
* buffer</i> and then moves the contents to the front (display) in a single
|
||||
* step, either by copying the data or moving the video pointer.
|
||||
* Moving the video pointer exchanges the buffers so that the first buffer
|
||||
* drawn becomes the <i>front buffer</i>, or what is currently displayed on the
|
||||
* device; this is called <i>page flipping</i>.
|
||||
* <p>
|
||||
* Alternatively, the contents of the back buffer can be copied, or
|
||||
* <i>blitted</i> forward in a chain instead of moving the video pointer.
|
||||
* <pre>{@code
|
||||
* Double buffering:
|
||||
*
|
||||
* *********** ***********
|
||||
* * * ------> * *
|
||||
* [To display] <---- * Front B * Show * Back B. * <---- Rendering
|
||||
* * * <------ * *
|
||||
* *********** ***********
|
||||
*
|
||||
* Triple buffering:
|
||||
*
|
||||
* [To *********** *********** ***********
|
||||
* display] * * --------+---------+------> * *
|
||||
* <---- * Front B * Show * Mid. B. * * Back B. * <---- Rendering
|
||||
* * * <------ * * <----- * *
|
||||
* *********** *********** ***********
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Here is an example of how buffer strategies can be created and used:
|
||||
* <pre><code>
|
||||
*
|
||||
* // Check the capabilities of the GraphicsConfiguration
|
||||
* ...
|
||||
*
|
||||
* // Create our component
|
||||
* Window w = new Window(gc);
|
||||
*
|
||||
* // Show our window
|
||||
* w.setVisible(true);
|
||||
*
|
||||
* // Create a general double-buffering strategy
|
||||
* w.createBufferStrategy(2);
|
||||
* BufferStrategy strategy = w.getBufferStrategy();
|
||||
*
|
||||
* // Main loop
|
||||
* while (!done) {
|
||||
* // Prepare for rendering the next frame
|
||||
* // ...
|
||||
*
|
||||
* // Render single frame
|
||||
* do {
|
||||
* // The following loop ensures that the contents of the drawing buffer
|
||||
* // are consistent in case the underlying surface was recreated
|
||||
* do {
|
||||
* // Get a new graphics context every time through the loop
|
||||
* // to make sure the strategy is validated
|
||||
* Graphics graphics = strategy.getDrawGraphics();
|
||||
*
|
||||
* // Render to graphics
|
||||
* // ...
|
||||
*
|
||||
* // Dispose the graphics
|
||||
* graphics.dispose();
|
||||
*
|
||||
* // Repeat the rendering if the drawing buffer contents
|
||||
* // were restored
|
||||
* } while (strategy.contentsRestored());
|
||||
*
|
||||
* // Display the buffer
|
||||
* strategy.show();
|
||||
*
|
||||
* // Repeat the rendering if the drawing buffer was lost
|
||||
* } while (strategy.contentsLost());
|
||||
* }
|
||||
*
|
||||
* // Dispose the window
|
||||
* w.setVisible(false);
|
||||
* w.dispose();
|
||||
* </code></pre>
|
||||
*
|
||||
* @see java.awt.Window
|
||||
* @see java.awt.Canvas
|
||||
* @see java.awt.GraphicsConfiguration
|
||||
* @see VolatileImage
|
||||
* @author Michael Martak
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class BufferStrategy {
|
||||
|
||||
/**
|
||||
* Returns the <code>BufferCapabilities</code> for this
|
||||
* <code>BufferStrategy</code>.
|
||||
*
|
||||
* @return the buffering capabilities of this strategy
|
||||
*/
|
||||
public abstract BufferCapabilities getCapabilities();
|
||||
|
||||
/**
|
||||
* Creates a graphics context for the drawing buffer. This method may not
|
||||
* be synchronized for performance reasons; use of this method by multiple
|
||||
* threads should be handled at the application level. Disposal of the
|
||||
* graphics object obtained must be handled by the application.
|
||||
*
|
||||
* @return a graphics context for the drawing buffer
|
||||
*/
|
||||
public abstract Graphics getDrawGraphics();
|
||||
|
||||
/**
|
||||
* Returns whether the drawing buffer was lost since the last call to
|
||||
* <code>getDrawGraphics</code>. Since the buffers in a buffer strategy
|
||||
* are usually type <code>VolatileImage</code>, they may become lost.
|
||||
* For a discussion on lost buffers, see <code>VolatileImage</code>.
|
||||
*
|
||||
* @return Whether or not the drawing buffer was lost since the last call
|
||||
* to <code>getDrawGraphics</code>.
|
||||
* @see java.awt.image.VolatileImage
|
||||
*/
|
||||
public abstract boolean contentsLost();
|
||||
|
||||
/**
|
||||
* Returns whether the drawing buffer was recently restored from a lost
|
||||
* state and reinitialized to the default background color (white).
|
||||
* Since the buffers in a buffer strategy are usually type
|
||||
* <code>VolatileImage</code>, they may become lost. If a surface has
|
||||
* been recently restored from a lost state since the last call to
|
||||
* <code>getDrawGraphics</code>, it may require repainting.
|
||||
* For a discussion on lost buffers, see <code>VolatileImage</code>.
|
||||
*
|
||||
* @return Whether or not the drawing buffer was restored since the last
|
||||
* call to <code>getDrawGraphics</code>.
|
||||
* @see java.awt.image.VolatileImage
|
||||
*/
|
||||
public abstract boolean contentsRestored();
|
||||
|
||||
/**
|
||||
* Makes the next available buffer visible by either copying the memory
|
||||
* (blitting) or changing the display pointer (flipping).
|
||||
*/
|
||||
public abstract void show();
|
||||
|
||||
/**
|
||||
* Releases system resources currently consumed by this
|
||||
* <code>BufferStrategy</code> and
|
||||
* removes it from the associated Component. After invoking this
|
||||
* method, <code>getBufferStrategy</code> will return null. Trying
|
||||
* to use a <code>BufferStrategy</code> after it has been disposed will
|
||||
* result in undefined behavior.
|
||||
*
|
||||
* @see java.awt.Window#createBufferStrategy
|
||||
* @see java.awt.Canvas#createBufferStrategy
|
||||
* @see java.awt.Window#getBufferStrategy
|
||||
* @see java.awt.Canvas#getBufferStrategy
|
||||
* @since 1.6
|
||||
*/
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
1641
jdkSrc/jdk8/java/awt/image/BufferedImage.java
Normal file
1641
jdkSrc/jdk8/java/awt/image/BufferedImage.java
Normal file
File diff suppressed because it is too large
Load Diff
417
jdkSrc/jdk8/java/awt/image/BufferedImageFilter.java
Normal file
417
jdkSrc/jdk8/java/awt/image/BufferedImageFilter.java
Normal file
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageFilter;
|
||||
|
||||
/**
|
||||
* The <code>BufferedImageFilter</code> class subclasses an
|
||||
* <code>ImageFilter</code> to provide a simple means of
|
||||
* using a single-source/single-destination image operator
|
||||
* ({@link BufferedImageOp}) to filter a <code>BufferedImage</code>
|
||||
* in the Image Producer/Consumer/Observer
|
||||
* paradigm. Examples of these image operators are: {@link ConvolveOp},
|
||||
* {@link AffineTransformOp} and {@link LookupOp}.
|
||||
*
|
||||
* @see ImageFilter
|
||||
* @see BufferedImage
|
||||
* @see BufferedImageOp
|
||||
*/
|
||||
|
||||
public class BufferedImageFilter extends ImageFilter implements Cloneable {
|
||||
BufferedImageOp bufferedImageOp;
|
||||
ColorModel model;
|
||||
int width;
|
||||
int height;
|
||||
byte[] bytePixels;
|
||||
int[] intPixels;
|
||||
|
||||
/**
|
||||
* Constructs a <code>BufferedImageFilter</code> with the
|
||||
* specified single-source/single-destination operator.
|
||||
* @param op the specified <code>BufferedImageOp</code> to
|
||||
* use to filter a <code>BufferedImage</code>
|
||||
* @throws NullPointerException if op is null
|
||||
*/
|
||||
public BufferedImageFilter (BufferedImageOp op) {
|
||||
super();
|
||||
if (op == null) {
|
||||
throw new NullPointerException("Operation cannot be null");
|
||||
}
|
||||
bufferedImageOp = op;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>BufferedImageOp</code>.
|
||||
* @return the operator of this <code>BufferedImageFilter</code>.
|
||||
*/
|
||||
public BufferedImageOp getBufferedImageOp() {
|
||||
return bufferedImageOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the
|
||||
* {@link ImageConsumer#setDimensions(int, int) setDimensions } method
|
||||
* of the {@link ImageConsumer} interface.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* {@link ImageProducer} of the <code>Image</code> whose pixels are
|
||||
* being filtered. Developers using this class to retrieve pixels from
|
||||
* an image should avoid calling this method directly since that
|
||||
* operation could result in problems with retrieving the requested
|
||||
* pixels.
|
||||
* <p>
|
||||
* @param width the width to which to set the width of this
|
||||
* <code>BufferedImageFilter</code>
|
||||
* @param height the height to which to set the height of this
|
||||
* <code>BufferedImageFilter</code>
|
||||
* @see ImageConsumer#setDimensions
|
||||
*/
|
||||
public void setDimensions(int width, int height) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
imageComplete(STATICIMAGEDONE);
|
||||
return;
|
||||
}
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the
|
||||
* {@link ImageConsumer#setColorModel(ColorModel) setColorModel} method
|
||||
* of the <code>ImageConsumer</code> interface.
|
||||
* <p>
|
||||
* If <code>model</code> is <code>null</code>, this
|
||||
* method clears the current <code>ColorModel</code> of this
|
||||
* <code>BufferedImageFilter</code>.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code>
|
||||
* whose pixels are being filtered. Developers using this
|
||||
* class to retrieve pixels from an image
|
||||
* should avoid calling this method directly since that
|
||||
* operation could result in problems with retrieving the
|
||||
* requested pixels.
|
||||
* @param model the {@link ColorModel} to which to set the
|
||||
* <code>ColorModel</code> of this <code>BufferedImageFilter</code>
|
||||
* @see ImageConsumer#setColorModel
|
||||
*/
|
||||
public void setColorModel(ColorModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
private void convertToRGB() {
|
||||
int size = width * height;
|
||||
int newpixels[] = new int[size];
|
||||
if (bytePixels != null) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
newpixels[i] = this.model.getRGB(bytePixels[i] & 0xff);
|
||||
}
|
||||
} else if (intPixels != null) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
newpixels[i] = this.model.getRGB(intPixels[i]);
|
||||
}
|
||||
}
|
||||
bytePixels = null;
|
||||
intPixels = newpixels;
|
||||
this.model = ColorModel.getRGBdefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the <code>setPixels</code>
|
||||
* method of the <code>ImageConsumer</code> interface which takes
|
||||
* an array of bytes.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @throws IllegalArgumentException if width or height are less than
|
||||
* zero.
|
||||
* @see ImageConsumer#setPixels(int, int, int, int, ColorModel, byte[],
|
||||
int, int)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off,
|
||||
int scansize) {
|
||||
// Fix 4184230
|
||||
if (w < 0 || h < 0) {
|
||||
throw new IllegalArgumentException("Width ("+w+
|
||||
") and height ("+h+
|
||||
") must be > 0");
|
||||
}
|
||||
// Nothing to do
|
||||
if (w == 0 || h == 0) {
|
||||
return;
|
||||
}
|
||||
if (y < 0) {
|
||||
int diff = -y;
|
||||
if (diff >= h) {
|
||||
return;
|
||||
}
|
||||
off += scansize * diff;
|
||||
y += diff;
|
||||
h -= diff;
|
||||
}
|
||||
if (y + h > height) {
|
||||
h = height - y;
|
||||
if (h <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (x < 0) {
|
||||
int diff = -x;
|
||||
if (diff >= w) {
|
||||
return;
|
||||
}
|
||||
off += diff;
|
||||
x += diff;
|
||||
w -= diff;
|
||||
}
|
||||
if (x + w > width) {
|
||||
w = width - x;
|
||||
if (w <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int dstPtr = y*width + x;
|
||||
if (intPixels == null) {
|
||||
if (bytePixels == null) {
|
||||
bytePixels = new byte[width*height];
|
||||
this.model = model;
|
||||
} else if (this.model != model) {
|
||||
convertToRGB();
|
||||
}
|
||||
if (bytePixels != null) {
|
||||
for (int sh = h; sh > 0; sh--) {
|
||||
System.arraycopy(pixels, off, bytePixels, dstPtr, w);
|
||||
off += scansize;
|
||||
dstPtr += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (intPixels != null) {
|
||||
int dstRem = width - w;
|
||||
int srcRem = scansize - w;
|
||||
for (int sh = h; sh > 0; sh--) {
|
||||
for (int sw = w; sw > 0; sw--) {
|
||||
intPixels[dstPtr++] = model.getRGB(pixels[off++]&0xff);
|
||||
}
|
||||
off += srcRem;
|
||||
dstPtr += dstRem;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Filters the information provided in the <code>setPixels</code>
|
||||
* method of the <code>ImageConsumer</code> interface which takes
|
||||
* an array of integers.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose
|
||||
* pixels are being filtered. Developers using this class to
|
||||
* retrieve pixels from an image should avoid calling this method
|
||||
* directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @throws IllegalArgumentException if width or height are less than
|
||||
* zero.
|
||||
* @see ImageConsumer#setPixels(int, int, int, int, ColorModel, int[],
|
||||
int, int)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off,
|
||||
int scansize) {
|
||||
// Fix 4184230
|
||||
if (w < 0 || h < 0) {
|
||||
throw new IllegalArgumentException("Width ("+w+
|
||||
") and height ("+h+
|
||||
") must be > 0");
|
||||
}
|
||||
// Nothing to do
|
||||
if (w == 0 || h == 0) {
|
||||
return;
|
||||
}
|
||||
if (y < 0) {
|
||||
int diff = -y;
|
||||
if (diff >= h) {
|
||||
return;
|
||||
}
|
||||
off += scansize * diff;
|
||||
y += diff;
|
||||
h -= diff;
|
||||
}
|
||||
if (y + h > height) {
|
||||
h = height - y;
|
||||
if (h <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (x < 0) {
|
||||
int diff = -x;
|
||||
if (diff >= w) {
|
||||
return;
|
||||
}
|
||||
off += diff;
|
||||
x += diff;
|
||||
w -= diff;
|
||||
}
|
||||
if (x + w > width) {
|
||||
w = width - x;
|
||||
if (w <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (intPixels == null) {
|
||||
if (bytePixels == null) {
|
||||
intPixels = new int[width * height];
|
||||
this.model = model;
|
||||
} else {
|
||||
convertToRGB();
|
||||
}
|
||||
}
|
||||
int dstPtr = y*width + x;
|
||||
if (this.model == model) {
|
||||
for (int sh = h; sh > 0; sh--) {
|
||||
System.arraycopy(pixels, off, intPixels, dstPtr, w);
|
||||
off += scansize;
|
||||
dstPtr += width;
|
||||
}
|
||||
} else {
|
||||
if (this.model != ColorModel.getRGBdefault()) {
|
||||
convertToRGB();
|
||||
}
|
||||
int dstRem = width - w;
|
||||
int srcRem = scansize - w;
|
||||
for (int sh = h; sh > 0; sh--) {
|
||||
for (int sw = w; sw > 0; sw--) {
|
||||
intPixels[dstPtr++] = model.getRGB(pixels[off++]);
|
||||
}
|
||||
off += srcRem;
|
||||
dstPtr += dstRem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the <code>imageComplete</code>
|
||||
* method of the <code>ImageConsumer</code> interface.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param status the status of image loading
|
||||
* @throws ImagingOpException if there was a problem calling the filter
|
||||
* method of the <code>BufferedImageOp</code> associated with this
|
||||
* instance.
|
||||
* @see ImageConsumer#imageComplete
|
||||
*/
|
||||
public void imageComplete(int status) {
|
||||
WritableRaster wr;
|
||||
switch(status) {
|
||||
case IMAGEERROR:
|
||||
case IMAGEABORTED:
|
||||
// reinitialize the params
|
||||
model = null;
|
||||
width = -1;
|
||||
height = -1;
|
||||
intPixels = null;
|
||||
bytePixels = null;
|
||||
break;
|
||||
|
||||
case SINGLEFRAMEDONE:
|
||||
case STATICIMAGEDONE:
|
||||
if (width <= 0 || height <= 0) break;
|
||||
if (model instanceof DirectColorModel) {
|
||||
if (intPixels == null) break;
|
||||
wr = createDCMraster();
|
||||
}
|
||||
else if (model instanceof IndexColorModel) {
|
||||
int[] bandOffsets = {0};
|
||||
if (bytePixels == null) break;
|
||||
DataBufferByte db = new DataBufferByte(bytePixels,
|
||||
width*height);
|
||||
wr = Raster.createInterleavedRaster(db, width, height, width,
|
||||
1, bandOffsets, null);
|
||||
}
|
||||
else {
|
||||
convertToRGB();
|
||||
if (intPixels == null) break;
|
||||
wr = createDCMraster();
|
||||
}
|
||||
BufferedImage bi = new BufferedImage(model, wr,
|
||||
model.isAlphaPremultiplied(),
|
||||
null);
|
||||
bi = bufferedImageOp.filter(bi, null);
|
||||
WritableRaster r = bi.getRaster();
|
||||
ColorModel cm = bi.getColorModel();
|
||||
int w = r.getWidth();
|
||||
int h = r.getHeight();
|
||||
consumer.setDimensions(w, h);
|
||||
consumer.setColorModel(cm);
|
||||
if (cm instanceof DirectColorModel) {
|
||||
DataBufferInt db = (DataBufferInt) r.getDataBuffer();
|
||||
consumer.setPixels(0, 0, w, h,
|
||||
cm, db.getData(), 0, w);
|
||||
}
|
||||
else if (cm instanceof IndexColorModel) {
|
||||
DataBufferByte db = (DataBufferByte) r.getDataBuffer();
|
||||
consumer.setPixels(0, 0, w, h,
|
||||
cm, db.getData(), 0, w);
|
||||
}
|
||||
else {
|
||||
throw new InternalError("Unknown color model "+cm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
consumer.imageComplete(status);
|
||||
}
|
||||
|
||||
private final WritableRaster createDCMraster() {
|
||||
WritableRaster wr;
|
||||
DirectColorModel dcm = (DirectColorModel) model;
|
||||
boolean hasAlpha = model.hasAlpha();
|
||||
int[] bandMasks = new int[3+(hasAlpha ? 1 : 0)];
|
||||
bandMasks[0] = dcm.getRedMask();
|
||||
bandMasks[1] = dcm.getGreenMask();
|
||||
bandMasks[2] = dcm.getBlueMask();
|
||||
if (hasAlpha) {
|
||||
bandMasks[3] = dcm.getAlphaMask();
|
||||
}
|
||||
DataBufferInt db = new DataBufferInt(intPixels, width*height);
|
||||
wr = Raster.createPackedRaster(db, width, height, width,
|
||||
bandMasks, null);
|
||||
return wr;
|
||||
}
|
||||
|
||||
}
|
||||
136
jdkSrc/jdk8/java/awt/image/BufferedImageOp.java
Normal file
136
jdkSrc/jdk8/java/awt/image/BufferedImageOp.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
/**
|
||||
* This interface describes single-input/single-output
|
||||
* operations performed on <CODE>BufferedImage</CODE> objects.
|
||||
* It is implemented by <CODE>AffineTransformOp</CODE>,
|
||||
* <CODE>ConvolveOp</CODE>, <CODE>ColorConvertOp</CODE>, <CODE>RescaleOp</CODE>,
|
||||
* and <CODE>LookupOp</CODE>. These objects can be passed into
|
||||
* a <CODE>BufferedImageFilter</CODE> to operate on a
|
||||
* <CODE>BufferedImage</CODE> in the
|
||||
* ImageProducer-ImageFilter-ImageConsumer paradigm.
|
||||
* <p>
|
||||
* Classes that implement this
|
||||
* interface must specify whether or not they allow in-place filtering--
|
||||
* filter operations where the source object is equal to the destination
|
||||
* object.
|
||||
* <p>
|
||||
* This interface cannot be used to describe more sophisticated operations
|
||||
* such as those that take multiple sources. Note that this restriction also
|
||||
* means that the values of the destination pixels prior to the operation are
|
||||
* not used as input to the filter operation.
|
||||
|
||||
* @see BufferedImage
|
||||
* @see BufferedImageFilter
|
||||
* @see AffineTransformOp
|
||||
* @see BandCombineOp
|
||||
* @see ColorConvertOp
|
||||
* @see ConvolveOp
|
||||
* @see LookupOp
|
||||
* @see RescaleOp
|
||||
*/
|
||||
public interface BufferedImageOp {
|
||||
/**
|
||||
* Performs a single-input/single-output operation on a
|
||||
* <CODE>BufferedImage</CODE>.
|
||||
* If the color models for the two images do not match, a color
|
||||
* conversion into the destination color model is performed.
|
||||
* If the destination image is null,
|
||||
* a <CODE>BufferedImage</CODE> with an appropriate <CODE>ColorModel</CODE>
|
||||
* is created.
|
||||
* <p>
|
||||
* An <CODE>IllegalArgumentException</CODE> may be thrown if the source
|
||||
* and/or destination image is incompatible with the types of images $
|
||||
* allowed by the class implementing this filter.
|
||||
*
|
||||
* @param src The <CODE>BufferedImage</CODE> to be filtered
|
||||
* @param dest The <CODE>BufferedImage</CODE> in which to store the results$
|
||||
*
|
||||
* @return The filtered <CODE>BufferedImage</CODE>.
|
||||
*
|
||||
* @throws IllegalArgumentException If the source and/or destination
|
||||
* image is not compatible with the types of images allowed by the class
|
||||
* implementing this filter.
|
||||
*/
|
||||
public BufferedImage filter(BufferedImage src, BufferedImage dest);
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the filtered destination image.
|
||||
* An <CODE>IllegalArgumentException</CODE> may be thrown if the source
|
||||
* image is incompatible with the types of images allowed
|
||||
* by the class implementing this filter.
|
||||
*
|
||||
* @param src The <CODE>BufferedImage</CODE> to be filtered
|
||||
*
|
||||
* @return The <CODE>Rectangle2D</CODE> representing the destination
|
||||
* image's bounding box.
|
||||
*/
|
||||
public Rectangle2D getBounds2D (BufferedImage src);
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination image with the correct size and number of
|
||||
* bands.
|
||||
* An <CODE>IllegalArgumentException</CODE> may be thrown if the source
|
||||
* image is incompatible with the types of images allowed
|
||||
* by the class implementing this filter.
|
||||
*
|
||||
* @param src The <CODE>BufferedImage</CODE> to be filtered
|
||||
* @param destCM <CODE>ColorModel</CODE> of the destination. If null,
|
||||
* the <CODE>ColorModel</CODE> of the source is used.
|
||||
*
|
||||
* @return The zeroed destination image.
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage (BufferedImage src,
|
||||
ColorModel destCM);
|
||||
|
||||
/**
|
||||
* Returns the location of the corresponding destination point given a
|
||||
* point in the source image. If <CODE>dstPt</CODE> is specified, it
|
||||
* is used to hold the return value.
|
||||
* @param srcPt the <code>Point2D</code> that represents the point in
|
||||
* the source image
|
||||
* @param dstPt The <CODE>Point2D</CODE> in which to store the result
|
||||
*
|
||||
* @return The <CODE>Point2D</CODE> in the destination image that
|
||||
* corresponds to the specified point in the source image.
|
||||
*/
|
||||
public Point2D getPoint2D (Point2D srcPt, Point2D dstPt);
|
||||
|
||||
/**
|
||||
* Returns the rendering hints for this operation.
|
||||
*
|
||||
* @return The <CODE>RenderingHints</CODE> object for this
|
||||
* <CODE>BufferedImageOp</CODE>. Returns
|
||||
* null if no hints have been set.
|
||||
*/
|
||||
public RenderingHints getRenderingHints();
|
||||
}
|
||||
210
jdkSrc/jdk8/java/awt/image/ByteLookupTable.java
Normal file
210
jdkSrc/jdk8/java/awt/image/ByteLookupTable.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* This class defines a lookup table object. The output of a
|
||||
* lookup operation using an object of this class is interpreted
|
||||
* as an unsigned byte quantity. The lookup table contains byte
|
||||
* data arrays for one or more bands (or components) of an image,
|
||||
* and it contains an offset which will be subtracted from the
|
||||
* input values before indexing the arrays. This allows an array
|
||||
* smaller than the native data size to be provided for a
|
||||
* constrained input. If there is only one array in the lookup
|
||||
* table, it will be applied to all bands.
|
||||
*
|
||||
* @see ShortLookupTable
|
||||
* @see LookupOp
|
||||
*/
|
||||
public class ByteLookupTable extends LookupTable {
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
byte data[][];
|
||||
|
||||
/**
|
||||
* Constructs a ByteLookupTable object from an array of byte
|
||||
* arrays representing a lookup table for each
|
||||
* band. The offset will be subtracted from input
|
||||
* values before indexing into the arrays. The number of
|
||||
* bands is the length of the data argument. The
|
||||
* data array for each band is stored as a reference.
|
||||
* @param offset the value subtracted from the input values
|
||||
* before indexing into the arrays
|
||||
* @param data an array of byte arrays representing a lookup
|
||||
* table for each band
|
||||
* @throws IllegalArgumentException if <code>offset</code> is
|
||||
* is less than 0 or if the length of <code>data</code>
|
||||
* is less than 1
|
||||
*/
|
||||
public ByteLookupTable(int offset, byte data[][]) {
|
||||
super(offset,data.length);
|
||||
numComponents = data.length;
|
||||
numEntries = data[0].length;
|
||||
this.data = new byte[numComponents][];
|
||||
// Allocate the array and copy the data reference
|
||||
for (int i=0; i < numComponents; i++) {
|
||||
this.data[i] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ByteLookupTable object from an array
|
||||
* of bytes representing a lookup table to be applied to all
|
||||
* bands. The offset will be subtracted from input
|
||||
* values before indexing into the array.
|
||||
* The data array is stored as a reference.
|
||||
* @param offset the value subtracted from the input values
|
||||
* before indexing into the array
|
||||
* @param data an array of bytes
|
||||
* @throws IllegalArgumentException if <code>offset</code> is
|
||||
* is less than 0 or if the length of <code>data</code>
|
||||
* is less than 1
|
||||
*/
|
||||
public ByteLookupTable(int offset, byte data[]) {
|
||||
super(offset,data.length);
|
||||
numComponents = 1;
|
||||
numEntries = data.length;
|
||||
this.data = new byte[1][];
|
||||
this.data[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lookup table data by reference. If this ByteLookupTable
|
||||
* was constructed using a single byte array, the length of the returned
|
||||
* array is one.
|
||||
* @return the data array of this <code>ByteLookupTable</code>.
|
||||
*/
|
||||
public final byte[][] getTable(){
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of samples of a pixel, translated with the lookup
|
||||
* table. The source and destination array can be the same array.
|
||||
* Array <code>dst</code> is returned.
|
||||
*
|
||||
* @param src the source array.
|
||||
* @param dst the destination array. This array must be at least as
|
||||
* long as <code>src</code>. If <code>dst</code> is
|
||||
* <code>null</code>, a new array will be allocated having the
|
||||
* same length as <code>src</code>.
|
||||
* @return the array <code>dst</code>, an <code>int</code> array of
|
||||
* samples.
|
||||
* @exception ArrayIndexOutOfBoundsException if <code>src</code> is
|
||||
* longer than <code>dst</code> or if for any element
|
||||
* <code>i</code> of <code>src</code>,
|
||||
* <code>src[i]-offset</code> is either less than zero or
|
||||
* greater than or equal to the length of the lookup table
|
||||
* for any band.
|
||||
*/
|
||||
public int[] lookupPixel(int[] src, int[] dst){
|
||||
if (dst == null) {
|
||||
// Need to alloc a new destination array
|
||||
dst = new int[src.length];
|
||||
}
|
||||
|
||||
if (numComponents == 1) {
|
||||
// Apply one LUT to all bands
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = src[i] - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = (int) data[0][s];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = src[i] - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = (int) data[i][s];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of samples of a pixel, translated with the lookup
|
||||
* table. The source and destination array can be the same array.
|
||||
* Array <code>dst</code> is returned.
|
||||
*
|
||||
* @param src the source array.
|
||||
* @param dst the destination array. This array must be at least as
|
||||
* long as <code>src</code>. If <code>dst</code> is
|
||||
* <code>null</code>, a new array will be allocated having the
|
||||
* same length as <code>src</code>.
|
||||
* @return the array <code>dst</code>, an <code>int</code> array of
|
||||
* samples.
|
||||
* @exception ArrayIndexOutOfBoundsException if <code>src</code> is
|
||||
* longer than <code>dst</code> or if for any element
|
||||
* <code>i</code> of <code>src</code>,
|
||||
* {@code (src[i]&0xff)-offset} is either less than
|
||||
* zero or greater than or equal to the length of the
|
||||
* lookup table for any band.
|
||||
*/
|
||||
public byte[] lookupPixel(byte[] src, byte[] dst){
|
||||
if (dst == null) {
|
||||
// Need to alloc a new destination array
|
||||
dst = new byte[src.length];
|
||||
}
|
||||
|
||||
if (numComponents == 1) {
|
||||
// Apply one LUT to all bands
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = (src[i]&0xff) - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = data[0][s];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = (src[i]&0xff) - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = data[i][s];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
}
|
||||
1115
jdkSrc/jdk8/java/awt/image/ColorConvertOp.java
Normal file
1115
jdkSrc/jdk8/java/awt/image/ColorConvertOp.java
Normal file
File diff suppressed because it is too large
Load Diff
1964
jdkSrc/jdk8/java/awt/image/ColorModel.java
Normal file
1964
jdkSrc/jdk8/java/awt/image/ColorModel.java
Normal file
File diff suppressed because it is too large
Load Diff
2948
jdkSrc/jdk8/java/awt/image/ComponentColorModel.java
Normal file
2948
jdkSrc/jdk8/java/awt/image/ComponentColorModel.java
Normal file
File diff suppressed because it is too large
Load Diff
1242
jdkSrc/jdk8/java/awt/image/ComponentSampleModel.java
Normal file
1242
jdkSrc/jdk8/java/awt/image/ComponentSampleModel.java
Normal file
File diff suppressed because it is too large
Load Diff
348
jdkSrc/jdk8/java/awt/image/ConvolveOp.java
Normal file
348
jdkSrc/jdk8/java/awt/image/ConvolveOp.java
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.lang.annotation.Native;
|
||||
import sun.awt.image.ImagingLib;
|
||||
|
||||
/**
|
||||
* This class implements a convolution from the source
|
||||
* to the destination.
|
||||
* Convolution using a convolution kernel is a spatial operation that
|
||||
* computes the output pixel from an input pixel by multiplying the kernel
|
||||
* with the surround of the input pixel.
|
||||
* This allows the output pixel to be affected by the immediate neighborhood
|
||||
* in a way that can be mathematically specified with a kernel.
|
||||
*<p>
|
||||
* This class operates with BufferedImage data in which color components are
|
||||
* premultiplied with the alpha component. If the Source BufferedImage has
|
||||
* an alpha component, and the color components are not premultiplied with
|
||||
* the alpha component, then the data are premultiplied before being
|
||||
* convolved. If the Destination has color components which are not
|
||||
* premultiplied, then alpha is divided out before storing into the
|
||||
* Destination (if alpha is 0, the color components are set to 0). If the
|
||||
* Destination has no alpha component, then the resulting alpha is discarded
|
||||
* after first dividing it out of the color components.
|
||||
* <p>
|
||||
* Rasters are treated as having no alpha channel. If the above treatment
|
||||
* of the alpha channel in BufferedImages is not desired, it may be avoided
|
||||
* by getting the Raster of a source BufferedImage and using the filter method
|
||||
* of this class which works with Rasters.
|
||||
* <p>
|
||||
* If a RenderingHints object is specified in the constructor, the
|
||||
* color rendering hint and the dithering hint may be used when color
|
||||
* conversion is required.
|
||||
*<p>
|
||||
* Note that the Source and the Destination may not be the same object.
|
||||
* @see Kernel
|
||||
* @see java.awt.RenderingHints#KEY_COLOR_RENDERING
|
||||
* @see java.awt.RenderingHints#KEY_DITHERING
|
||||
*/
|
||||
public class ConvolveOp implements BufferedImageOp, RasterOp {
|
||||
Kernel kernel;
|
||||
int edgeHint;
|
||||
RenderingHints hints;
|
||||
/**
|
||||
* Edge condition constants.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pixels at the edge of the destination image are set to zero. This
|
||||
* is the default.
|
||||
*/
|
||||
|
||||
@Native public static final int EDGE_ZERO_FILL = 0;
|
||||
|
||||
/**
|
||||
* Pixels at the edge of the source image are copied to
|
||||
* the corresponding pixels in the destination without modification.
|
||||
*/
|
||||
@Native public static final int EDGE_NO_OP = 1;
|
||||
|
||||
/**
|
||||
* Constructs a ConvolveOp given a Kernel, an edge condition, and a
|
||||
* RenderingHints object (which may be null).
|
||||
* @param kernel the specified <code>Kernel</code>
|
||||
* @param edgeCondition the specified edge condition
|
||||
* @param hints the specified <code>RenderingHints</code> object
|
||||
* @see Kernel
|
||||
* @see #EDGE_NO_OP
|
||||
* @see #EDGE_ZERO_FILL
|
||||
* @see java.awt.RenderingHints
|
||||
*/
|
||||
public ConvolveOp(Kernel kernel, int edgeCondition, RenderingHints hints) {
|
||||
this.kernel = kernel;
|
||||
this.edgeHint = edgeCondition;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ConvolveOp given a Kernel. The edge condition
|
||||
* will be EDGE_ZERO_FILL.
|
||||
* @param kernel the specified <code>Kernel</code>
|
||||
* @see Kernel
|
||||
* @see #EDGE_ZERO_FILL
|
||||
*/
|
||||
public ConvolveOp(Kernel kernel) {
|
||||
this.kernel = kernel;
|
||||
this.edgeHint = EDGE_ZERO_FILL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the edge condition.
|
||||
* @return the edge condition of this <code>ConvolveOp</code>.
|
||||
* @see #EDGE_NO_OP
|
||||
* @see #EDGE_ZERO_FILL
|
||||
*/
|
||||
public int getEdgeCondition() {
|
||||
return edgeHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Kernel.
|
||||
* @return the <code>Kernel</code> of this <code>ConvolveOp</code>.
|
||||
*/
|
||||
public final Kernel getKernel() {
|
||||
return (Kernel) kernel.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a convolution on BufferedImages. Each component of the
|
||||
* source image will be convolved (including the alpha component, if
|
||||
* present).
|
||||
* If the color model in the source image is not the same as that
|
||||
* in the destination image, the pixels will be converted
|
||||
* in the destination. If the destination image is null,
|
||||
* a BufferedImage will be created with the source ColorModel.
|
||||
* The IllegalArgumentException may be thrown if the source is the
|
||||
* same as the destination.
|
||||
* @param src the source <code>BufferedImage</code> to filter
|
||||
* @param dst the destination <code>BufferedImage</code> for the
|
||||
* filtered <code>src</code>
|
||||
* @return the filtered <code>BufferedImage</code>
|
||||
* @throws NullPointerException if <code>src</code> is <code>null</code>
|
||||
* @throws IllegalArgumentException if <code>src</code> equals
|
||||
* <code>dst</code>
|
||||
* @throws ImagingOpException if <code>src</code> cannot be filtered
|
||||
*/
|
||||
public final BufferedImage filter (BufferedImage src, BufferedImage dst) {
|
||||
if (src == null) {
|
||||
throw new NullPointerException("src image is null");
|
||||
}
|
||||
if (src == dst) {
|
||||
throw new IllegalArgumentException("src image cannot be the "+
|
||||
"same as the dst image");
|
||||
}
|
||||
|
||||
boolean needToConvert = false;
|
||||
ColorModel srcCM = src.getColorModel();
|
||||
ColorModel dstCM;
|
||||
BufferedImage origDst = dst;
|
||||
|
||||
// Can't convolve an IndexColorModel. Need to expand it
|
||||
if (srcCM instanceof IndexColorModel) {
|
||||
IndexColorModel icm = (IndexColorModel) srcCM;
|
||||
src = icm.convertToIntDiscrete(src.getRaster(), false);
|
||||
srcCM = src.getColorModel();
|
||||
}
|
||||
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
dstCM = srcCM;
|
||||
origDst = dst;
|
||||
}
|
||||
else {
|
||||
dstCM = dst.getColorModel();
|
||||
if (srcCM.getColorSpace().getType() !=
|
||||
dstCM.getColorSpace().getType())
|
||||
{
|
||||
needToConvert = true;
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
dstCM = dst.getColorModel();
|
||||
}
|
||||
else if (dstCM instanceof IndexColorModel) {
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
dstCM = dst.getColorModel();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImagingLib.filter(this, src, dst) == null) {
|
||||
throw new ImagingOpException ("Unable to convolve src image");
|
||||
}
|
||||
|
||||
if (needToConvert) {
|
||||
ColorConvertOp ccop = new ColorConvertOp(hints);
|
||||
ccop.filter(dst, origDst);
|
||||
}
|
||||
else if (origDst != dst) {
|
||||
java.awt.Graphics2D g = origDst.createGraphics();
|
||||
try {
|
||||
g.drawImage(dst, 0, 0, null);
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return origDst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a convolution on Rasters. Each band of the source Raster
|
||||
* will be convolved.
|
||||
* The source and destination must have the same number of bands.
|
||||
* If the destination Raster is null, a new Raster will be created.
|
||||
* The IllegalArgumentException may be thrown if the source is
|
||||
* the same as the destination.
|
||||
* @param src the source <code>Raster</code> to filter
|
||||
* @param dst the destination <code>WritableRaster</code> for the
|
||||
* filtered <code>src</code>
|
||||
* @return the filtered <code>WritableRaster</code>
|
||||
* @throws NullPointerException if <code>src</code> is <code>null</code>
|
||||
* @throws ImagingOpException if <code>src</code> and <code>dst</code>
|
||||
* do not have the same number of bands
|
||||
* @throws ImagingOpException if <code>src</code> cannot be filtered
|
||||
* @throws IllegalArgumentException if <code>src</code> equals
|
||||
* <code>dst</code>
|
||||
*/
|
||||
public final WritableRaster filter (Raster src, WritableRaster dst) {
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestRaster(src);
|
||||
}
|
||||
else if (src == dst) {
|
||||
throw new IllegalArgumentException("src image cannot be the "+
|
||||
"same as the dst image");
|
||||
}
|
||||
else if (src.getNumBands() != dst.getNumBands()) {
|
||||
throw new ImagingOpException("Different number of bands in src "+
|
||||
" and dst Rasters");
|
||||
}
|
||||
|
||||
if (ImagingLib.filter(this, src, dst) == null) {
|
||||
throw new ImagingOpException ("Unable to convolve src image");
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination image with the correct size and number
|
||||
* of bands. If destCM is null, an appropriate ColorModel will be used.
|
||||
* @param src Source image for the filter operation.
|
||||
* @param destCM ColorModel of the destination. Can be null.
|
||||
* @return a destination <code>BufferedImage</code> with the correct
|
||||
* size and number of bands.
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage(BufferedImage src,
|
||||
ColorModel destCM) {
|
||||
BufferedImage image;
|
||||
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
|
||||
WritableRaster wr = null;
|
||||
|
||||
if (destCM == null) {
|
||||
destCM = src.getColorModel();
|
||||
// Not much support for ICM
|
||||
if (destCM instanceof IndexColorModel) {
|
||||
destCM = ColorModel.getRGBdefault();
|
||||
} else {
|
||||
/* Create destination image as similar to the source
|
||||
* as it possible...
|
||||
*/
|
||||
wr = src.getData().createCompatibleWritableRaster(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
if (wr == null) {
|
||||
/* This is the case when destination color model
|
||||
* was explicitly specified (and it may be not compatible
|
||||
* with source raster structure) or source is indexed image.
|
||||
* We should use destination color model to create compatible
|
||||
* destination raster here.
|
||||
*/
|
||||
wr = destCM.createCompatibleWritableRaster(w, h);
|
||||
}
|
||||
|
||||
image = new BufferedImage (destCM, wr,
|
||||
destCM.isAlphaPremultiplied(), null);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination Raster with the correct size and number
|
||||
* of bands, given this source.
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src) {
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the filtered destination image. Since
|
||||
* this is not a geometric operation, the bounding box does not
|
||||
* change.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D(BufferedImage src) {
|
||||
return getBounds2D(src.getRaster());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the filtered destination Raster. Since
|
||||
* this is not a geometric operation, the bounding box does not
|
||||
* change.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D(Raster src) {
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the destination point given a
|
||||
* point in the source. If dstPt is non-null, it will
|
||||
* be used to hold the return value. Since this is not a geometric
|
||||
* operation, the srcPt will equal the dstPt.
|
||||
*/
|
||||
public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
|
||||
if (dstPt == null) {
|
||||
dstPt = new Point2D.Float();
|
||||
}
|
||||
dstPt.setLocation(srcPt.getX(), srcPt.getY());
|
||||
|
||||
return dstPt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendering hints for this op.
|
||||
*/
|
||||
public final RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
}
|
||||
193
jdkSrc/jdk8/java/awt/image/CropImageFilter.java
Normal file
193
jdkSrc/jdk8/java/awt/image/CropImageFilter.java
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.Hashtable;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* An ImageFilter class for cropping images.
|
||||
* This class extends the basic ImageFilter Class to extract a given
|
||||
* rectangular region of an existing Image and provide a source for a
|
||||
* new image containing just the extracted region. It is meant to
|
||||
* be used in conjunction with a FilteredImageSource object to produce
|
||||
* cropped versions of existing images.
|
||||
*
|
||||
* @see FilteredImageSource
|
||||
* @see ImageFilter
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class CropImageFilter extends ImageFilter {
|
||||
int cropX;
|
||||
int cropY;
|
||||
int cropW;
|
||||
int cropH;
|
||||
|
||||
/**
|
||||
* Constructs a CropImageFilter that extracts the absolute rectangular
|
||||
* region of pixels from its source Image as specified by the x, y,
|
||||
* w, and h parameters.
|
||||
* @param x the x location of the top of the rectangle to be extracted
|
||||
* @param y the y location of the top of the rectangle to be extracted
|
||||
* @param w the width of the rectangle to be extracted
|
||||
* @param h the height of the rectangle to be extracted
|
||||
*/
|
||||
public CropImageFilter(int x, int y, int w, int h) {
|
||||
cropX = x;
|
||||
cropY = y;
|
||||
cropW = w;
|
||||
cropH = h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes along the properties from the source object after adding a
|
||||
* property indicating the cropped region.
|
||||
* This method invokes <code>super.setProperties</code>,
|
||||
* which might result in additional properties being added.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*/
|
||||
public void setProperties(Hashtable<?,?> props) {
|
||||
Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone();
|
||||
p.put("croprect", new Rectangle(cropX, cropY, cropW, cropH));
|
||||
super.setProperties(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the source image's dimensions and pass the dimensions
|
||||
* of the rectangular cropped region to the ImageConsumer.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose
|
||||
* pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public void setDimensions(int w, int h) {
|
||||
consumer.setDimensions(cropW, cropH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the delivered byte pixels intersect the region to
|
||||
* be extracted and passes through only that subset of pixels that
|
||||
* appear in the output region.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose
|
||||
* pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off,
|
||||
int scansize) {
|
||||
int x1 = x;
|
||||
if (x1 < cropX) {
|
||||
x1 = cropX;
|
||||
}
|
||||
int x2 = addWithoutOverflow(x, w);
|
||||
if (x2 > cropX + cropW) {
|
||||
x2 = cropX + cropW;
|
||||
}
|
||||
int y1 = y;
|
||||
if (y1 < cropY) {
|
||||
y1 = cropY;
|
||||
}
|
||||
|
||||
int y2 = addWithoutOverflow(y, h);
|
||||
if (y2 > cropY + cropH) {
|
||||
y2 = cropY + cropH;
|
||||
}
|
||||
if (x1 >= x2 || y1 >= y2) {
|
||||
return;
|
||||
}
|
||||
consumer.setPixels(x1 - cropX, y1 - cropY, (x2 - x1), (y2 - y1),
|
||||
model, pixels,
|
||||
off + (y1 - y) * scansize + (x1 - x), scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the delivered int pixels intersect the region to
|
||||
* be extracted and pass through only that subset of pixels that
|
||||
* appear in the output region.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose
|
||||
* pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off,
|
||||
int scansize) {
|
||||
int x1 = x;
|
||||
if (x1 < cropX) {
|
||||
x1 = cropX;
|
||||
}
|
||||
int x2 = addWithoutOverflow(x, w);
|
||||
if (x2 > cropX + cropW) {
|
||||
x2 = cropX + cropW;
|
||||
}
|
||||
int y1 = y;
|
||||
if (y1 < cropY) {
|
||||
y1 = cropY;
|
||||
}
|
||||
|
||||
int y2 = addWithoutOverflow(y, h);
|
||||
if (y2 > cropY + cropH) {
|
||||
y2 = cropY + cropH;
|
||||
}
|
||||
if (x1 >= x2 || y1 >= y2) {
|
||||
return;
|
||||
}
|
||||
consumer.setPixels(x1 - cropX, y1 - cropY, (x2 - x1), (y2 - y1),
|
||||
model, pixels,
|
||||
off + (y1 - y) * scansize + (x1 - x), scansize);
|
||||
}
|
||||
|
||||
//check for potential overflow (see bug 4801285)
|
||||
private int addWithoutOverflow(int x, int w) {
|
||||
int x2 = x + w;
|
||||
if ( x > 0 && w > 0 && x2 < 0 ) {
|
||||
x2 = Integer.MAX_VALUE;
|
||||
} else if( x < 0 && w < 0 && x2 > 0 ) {
|
||||
x2 = Integer.MIN_VALUE;
|
||||
}
|
||||
return x2;
|
||||
}
|
||||
}
|
||||
543
jdkSrc/jdk8/java/awt/image/DataBuffer.java
Normal file
543
jdkSrc/jdk8/java/awt/image/DataBuffer.java
Normal file
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import sun.java2d.StateTrackable.State;
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
import sun.java2d.StateTrackableDelegate;
|
||||
|
||||
import sun.awt.image.SunWritableRaster;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
|
||||
/**
|
||||
* This class exists to wrap one or more data arrays. Each data array in
|
||||
* the DataBuffer is referred to as a bank. Accessor methods for getting
|
||||
* and setting elements of the DataBuffer's banks exist with and without
|
||||
* a bank specifier. The methods without a bank specifier use the default 0th
|
||||
* bank. The DataBuffer can optionally take an offset per bank, so that
|
||||
* data in an existing array can be used even if the interesting data
|
||||
* doesn't start at array location zero. Getting or setting the 0th
|
||||
* element of a bank, uses the (0+offset)th element of the array. The
|
||||
* size field specifies how much of the data array is available for
|
||||
* use. Size + offset for a given bank should never be greater
|
||||
* than the length of the associated data array. The data type of
|
||||
* a data buffer indicates the type of the data array(s) and may also
|
||||
* indicate additional semantics, e.g. storing unsigned 8-bit data
|
||||
* in elements of a byte array. The data type may be TYPE_UNDEFINED
|
||||
* or one of the types defined below. Other types may be added in
|
||||
* the future. Generally, an object of class DataBuffer will be cast down
|
||||
* to one of its data type specific subclasses to access data type specific
|
||||
* methods for improved performance. Currently, the Java 2D(tm) API
|
||||
* image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
|
||||
* TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
|
||||
* @see java.awt.image.Raster
|
||||
* @see java.awt.image.SampleModel
|
||||
*/
|
||||
public abstract class DataBuffer {
|
||||
|
||||
/** Tag for unsigned byte data. */
|
||||
@Native public static final int TYPE_BYTE = 0;
|
||||
|
||||
/** Tag for unsigned short data. */
|
||||
@Native public static final int TYPE_USHORT = 1;
|
||||
|
||||
/** Tag for signed short data. Placeholder for future use. */
|
||||
@Native public static final int TYPE_SHORT = 2;
|
||||
|
||||
/** Tag for int data. */
|
||||
@Native public static final int TYPE_INT = 3;
|
||||
|
||||
/** Tag for float data. Placeholder for future use. */
|
||||
@Native public static final int TYPE_FLOAT = 4;
|
||||
|
||||
/** Tag for double data. Placeholder for future use. */
|
||||
@Native public static final int TYPE_DOUBLE = 5;
|
||||
|
||||
/** Tag for undefined data. */
|
||||
@Native public static final int TYPE_UNDEFINED = 32;
|
||||
|
||||
/** The data type of this DataBuffer. */
|
||||
protected int dataType;
|
||||
|
||||
/** The number of banks in this DataBuffer. */
|
||||
protected int banks;
|
||||
|
||||
/** Offset into default (first) bank from which to get the first element. */
|
||||
protected int offset;
|
||||
|
||||
/** Usable size of all banks. */
|
||||
protected int size;
|
||||
|
||||
/** Offsets into all banks. */
|
||||
protected int offsets[];
|
||||
|
||||
/* The current StateTrackable state. */
|
||||
StateTrackableDelegate theTrackable;
|
||||
|
||||
/** Size of the data types indexed by DataType tags defined above. */
|
||||
private static final int dataTypeSize[] = {8,16,16,32,32,64};
|
||||
|
||||
/** Returns the size (in bits) of the data type, given a datatype tag.
|
||||
* @param type the value of one of the defined datatype tags
|
||||
* @return the size of the data type
|
||||
* @throws IllegalArgumentException if <code>type</code> is less than
|
||||
* zero or greater than {@link #TYPE_DOUBLE}
|
||||
*/
|
||||
public static int getDataTypeSize(int type) {
|
||||
if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
|
||||
throw new IllegalArgumentException("Unknown data type "+type);
|
||||
}
|
||||
return dataTypeSize[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing one bank of the specified
|
||||
* data type and size.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size) {
|
||||
this(UNTRACKABLE, dataType, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing one bank of the specified
|
||||
* data type and size with the indicated initial {@link State State}.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = 1;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
this.offsets = new int[1]; // init to 0 by new
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing the specified number of
|
||||
* banks. Each bank has the specified size and an offset of 0.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing the specified number of
|
||||
* banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified size and an offset of 0.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
this.offsets = new int[banks]; // init to 0 by new
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer that contains the specified number
|
||||
* of banks. Each bank has the specified datatype, size and offset.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offset the offset for each bank
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer that contains the specified number
|
||||
* of banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified datatype, size and offset.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offset the offset for each bank
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks, int offset)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = offset;
|
||||
this.offsets = new int[numBanks];
|
||||
for (int i = 0; i < numBanks; i++) {
|
||||
this.offsets[i] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer which contains the specified number
|
||||
* of banks. Each bank has the specified datatype and size. The
|
||||
* offset for each bank is specified by its respective entry in
|
||||
* the offsets array.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offsets an array containing an offset for each bank.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
|
||||
* does not equal the length of <code>offsets</code>
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks, offsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer which contains the specified number
|
||||
* of banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified datatype and size. The
|
||||
* offset for each bank is specified by its respective entry in
|
||||
* the offsets array.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offsets an array containing an offset for each bank.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
|
||||
* does not equal the length of <code>offsets</code>
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks, int offsets[])
|
||||
{
|
||||
if (numBanks != offsets.length) {
|
||||
throw new ArrayIndexOutOfBoundsException("Number of banks" +
|
||||
" does not match number of bank offsets");
|
||||
}
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = offsets[0];
|
||||
this.offsets = (int[])offsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the data type of this DataBuffer.
|
||||
* @return the data type of this <code>DataBuffer</code>.
|
||||
*/
|
||||
public int getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/** Returns the size (in array elements) of all banks.
|
||||
* @return the size of all banks.
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/** Returns the offset of the default bank in array elements.
|
||||
* @return the offset of the default bank.
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Returns the offsets (in array elements) of all the banks.
|
||||
* @return the offsets of all banks.
|
||||
*/
|
||||
public int[] getOffsets() {
|
||||
return (int[])offsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the number of banks in this DataBuffer.
|
||||
* @return the number of banks.
|
||||
*/
|
||||
public int getNumBanks() {
|
||||
return banks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as an integer.
|
||||
* @param i the index of the requested data array element
|
||||
* @return the data array element at the specified index.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return getElem(0,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank
|
||||
* as an integer.
|
||||
* @param bank the specified bank
|
||||
* @param i the index of the requested data array element
|
||||
* @return the data array element at the specified index from the
|
||||
* specified bank at the specified index.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public abstract int getElem(int bank, int i);
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given integer.
|
||||
* @param i the specified index into the data array
|
||||
* @param val the data to set the element at the specified index in
|
||||
* the data array
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
setElem(0,i,val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index into the data array
|
||||
* @param val the data to set the element in the specified bank
|
||||
* at the specified index in the data array
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public abstract void setElem(int bank, int i, int val);
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as a float. The implementation in this class is to cast getElem(i)
|
||||
* to a float. Subclasses may override this method if another
|
||||
* implementation is needed.
|
||||
* @param i the index of the requested data array element
|
||||
* @return a float value representing the data array element at the
|
||||
* specified index.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int i) {
|
||||
return (float)getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank
|
||||
* as a float. The implementation in this class is to cast
|
||||
* {@link #getElem(int, int)}
|
||||
* to a float. Subclasses can override this method if another
|
||||
* implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the index of the requested data array element
|
||||
* @return a float value representing the data array element from the
|
||||
* specified bank at the specified index.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return (float)getElem(bank,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given float. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses
|
||||
* can override this method if another implementation is needed.
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element at the specified index in
|
||||
* the data array
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int i, float val) {
|
||||
setElem(i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given float. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element in the specified bank at
|
||||
* the specified index in the data array
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
setElem(bank,i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as a double. The implementation in this class is to cast
|
||||
* {@link #getElem(int)}
|
||||
* to a double. Subclasses can override this method if another
|
||||
* implementation is needed.
|
||||
* @param i the specified index
|
||||
* @return a double value representing the element at the specified
|
||||
* index in the data array.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int i) {
|
||||
return (double)getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank as
|
||||
* a double. The implementation in this class is to cast getElem(bank, i)
|
||||
* to a double. Subclasses may override this method if another
|
||||
* implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @return a double value representing the element from the specified
|
||||
* bank at the specified index in the data array.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return (double)getElem(bank,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given double. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element at the specified index
|
||||
* in the data array
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int i, double val) {
|
||||
setElem(i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given double. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element in the specified bank
|
||||
* at the specified index of the data array
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
setElem(bank,i,(int)val);
|
||||
}
|
||||
|
||||
static int[] toIntArray(Object obj) {
|
||||
if (obj instanceof int[]) {
|
||||
return (int[])obj;
|
||||
} else if (obj == null) {
|
||||
return null;
|
||||
} else if (obj instanceof short[]) {
|
||||
short sdata[] = (short[])obj;
|
||||
int idata[] = new int[sdata.length];
|
||||
for (int i = 0; i < sdata.length; i++) {
|
||||
idata[i] = (int)sdata[i] & 0xffff;
|
||||
}
|
||||
return idata;
|
||||
} else if (obj instanceof byte[]) {
|
||||
byte bdata[] = (byte[])obj;
|
||||
int idata[] = new int[bdata.length];
|
||||
for (int i = 0; i < bdata.length; i++) {
|
||||
idata[i] = 0xff & (int)bdata[i];
|
||||
}
|
||||
return idata;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
|
||||
public byte[] getData(DataBufferByte dbb, int bank) {
|
||||
return dbb.bankdata[bank];
|
||||
}
|
||||
|
||||
public short[] getData(DataBufferUShort dbus, int bank) {
|
||||
return dbus.bankdata[bank];
|
||||
}
|
||||
|
||||
public int[] getData(DataBufferInt dbi, int bank) {
|
||||
return dbi.bankdata[bank];
|
||||
}
|
||||
|
||||
public StateTrackableDelegate getTrackable(DataBuffer db) {
|
||||
return db.theTrackable;
|
||||
}
|
||||
|
||||
public void setTrackable(DataBuffer db,
|
||||
StateTrackableDelegate trackable)
|
||||
{
|
||||
db.theTrackable = trackable;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
286
jdkSrc/jdk8/java/awt/image/DataBufferByte.java
Normal file
286
jdkSrc/jdk8/java/awt/image/DataBufferByte.java
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as bytes.
|
||||
* Values stored in the byte array(s) of this <CODE>DataBuffer</CODE> are treated as
|
||||
* unsigned values.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array, as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferByte extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
byte data[];
|
||||
|
||||
/** All data banks */
|
||||
byte bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(int size) {
|
||||
super(STABLE, TYPE_BYTE, size);
|
||||
data = new byte[size];
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(int size, int numBanks) {
|
||||
super(STABLE, TYPE_BYTE, size, numBanks);
|
||||
bankdata = new byte[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new byte[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size);
|
||||
data = dataArray;
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>. <CODE>dataArray</CODE>
|
||||
* must have at least <CODE>offset</CODE> + <CODE>size</CODE> elements.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[], int size, int offset){
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length);
|
||||
bankdata = (byte[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding <CODE>offset</CODE>.
|
||||
* There must be an entry in the <CODE>offset</CODE> array for each <CODE>dataArray</CODE>
|
||||
* entry. For each bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be used by accessors of this
|
||||
* <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length, offsets);
|
||||
bankdata = (byte[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) byte data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first byte data array.
|
||||
*/
|
||||
public byte[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public byte[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public byte[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (byte[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (byte)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (byte)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
||||
403
jdkSrc/jdk8/java/awt/image/DataBufferDouble.java
Normal file
403
jdkSrc/jdk8/java/awt/image/DataBufferDouble.java
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <code>DataBuffer</code> and stores data internally
|
||||
* in <code>double</code> form.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final class DataBufferDouble extends DataBuffer {
|
||||
|
||||
/** The array of data banks. */
|
||||
double bankdata[][];
|
||||
|
||||
/** A reference to the default data bank. */
|
||||
double data[];
|
||||
|
||||
/**
|
||||
* Constructs a <code>double</code>-based <code>DataBuffer</code>
|
||||
* with a specified size.
|
||||
*
|
||||
* @param size The number of elements in the <code>DataBuffer</code>.
|
||||
*/
|
||||
public DataBufferDouble(int size) {
|
||||
super(STABLE, TYPE_DOUBLE, size);
|
||||
data = new double[size];
|
||||
bankdata = new double[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>double</code>-based <code>DataBuffer</code>
|
||||
* with a specified number of banks, all of which are of a
|
||||
* specified size.
|
||||
*
|
||||
* @param size The number of elements in each bank of the
|
||||
* <code>DataBuffer</code>.
|
||||
* @param numBanks The number of banks in the <code>DataBuffer</code>.
|
||||
*/
|
||||
public DataBufferDouble(int size, int numBanks) {
|
||||
super(STABLE, TYPE_DOUBLE, size, numBanks);
|
||||
bankdata = new double[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new double[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>double</code>-based <code>DataBuffer</code>
|
||||
* with the specified data array. Only the first
|
||||
* <code>size</code> elements are available for use by this
|
||||
* <code>DataBuffer</code>. The array must be large enough to
|
||||
* hold <code>size</code> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of <code>double</code>s to be used as the
|
||||
* first and only bank of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of the array to be used.
|
||||
*/
|
||||
public DataBufferDouble(double dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_DOUBLE, size);
|
||||
data = dataArray;
|
||||
bankdata = new double[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>double</code>-based <code>DataBuffer</code>
|
||||
* with the specified data array. Only the elements between
|
||||
* <code>offset</code> and <code>offset + size - 1</code> are
|
||||
* available for use by this <code>DataBuffer</code>. The array
|
||||
* must be large enough to hold <code>offset + size</code> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of <code>double</code>s to be used as the
|
||||
* first and only bank of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of the array to be used.
|
||||
* @param offset The offset of the first element of the array
|
||||
* that will be used.
|
||||
*/
|
||||
public DataBufferDouble(double dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_DOUBLE, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new double[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>double</code>-based <code>DataBuffer</code>
|
||||
* with the specified data arrays. Only the first
|
||||
* <code>size</code> elements of each array are available for use
|
||||
* by this <code>DataBuffer</code>. The number of banks will be
|
||||
* equal <code>to dataArray.length</code>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of arrays of <code>double</code>s to be
|
||||
* used as the banks of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of each array to be used.
|
||||
*/
|
||||
public DataBufferDouble(double dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_DOUBLE, size, dataArray.length);
|
||||
bankdata = (double[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>double</code>-based <code>DataBuffer</code>
|
||||
* with the specified data arrays, size, and per-bank offsets.
|
||||
* The number of banks is equal to dataArray.length. Each array
|
||||
* must be at least as large as <code>size</code> plus the
|
||||
* corresponding offset. There must be an entry in the
|
||||
* <code>offsets</code> array for each data array.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of arrays of <code>double</code>s to be
|
||||
* used as the banks of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of each array to be used.
|
||||
* @param offsets An array of integer offsets, one for each bank.
|
||||
*/
|
||||
public DataBufferDouble(double dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_DOUBLE, size, dataArray.length, offsets);
|
||||
bankdata = (double[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) <code>double</code> data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return the first double data array.
|
||||
*/
|
||||
public double[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank the data array
|
||||
* @return the data array specified by <code>bank</code>.
|
||||
*/
|
||||
public double[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return all data arrays from this data buffer.
|
||||
*/
|
||||
public double[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (double[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first
|
||||
* (default) bank as an <code>int</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @return The data entry as an <code>int</code>.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified
|
||||
* bank as an <code>int</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as an <code>int</code>.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default)
|
||||
* bank to the given <code>int</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (double)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* to the given <code>int</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (double)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first
|
||||
* (default) bank as a <code>float</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>float</code>.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int i) {
|
||||
return (float)data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified
|
||||
* bank as a <code>float</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>float</code>.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return (float)bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default)
|
||||
* bank to the given <code>float</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int i, float val) {
|
||||
data[i+offset] = (double)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank to
|
||||
* the given <code>float</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
bankdata[bank][i+offsets[bank]] = (double)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first
|
||||
* (default) bank as a <code>double</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>double</code>.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int i) {
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified
|
||||
* bank as a <code>double</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>double</code>.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default)
|
||||
* bank to the given <code>double</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int i, double val) {
|
||||
data[i+offset] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank to
|
||||
* the given <code>double</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
bankdata[bank][i+offsets[bank]] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
||||
406
jdkSrc/jdk8/java/awt/image/DataBufferFloat.java
Normal file
406
jdkSrc/jdk8/java/awt/image/DataBufferFloat.java
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <code>DataBuffer</code> and stores data internally
|
||||
* in <code>float</code> form.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public final class DataBufferFloat extends DataBuffer {
|
||||
|
||||
/** The array of data banks. */
|
||||
float bankdata[][];
|
||||
|
||||
/** A reference to the default data bank. */
|
||||
float data[];
|
||||
|
||||
/**
|
||||
* Constructs a <code>float</code>-based <code>DataBuffer</code>
|
||||
* with a specified size.
|
||||
*
|
||||
* @param size The number of elements in the DataBuffer.
|
||||
*/
|
||||
public DataBufferFloat(int size) {
|
||||
super(STABLE, TYPE_FLOAT, size);
|
||||
data = new float[size];
|
||||
bankdata = new float[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>float</code>-based <code>DataBuffer</code>
|
||||
* with a specified number of banks, all of which are of a
|
||||
* specified size.
|
||||
*
|
||||
* @param size The number of elements in each bank of the
|
||||
* <code>DataBuffer</code>.
|
||||
* @param numBanks The number of banks in the
|
||||
* <code>DataBuffer</code>.
|
||||
*/
|
||||
public DataBufferFloat(int size, int numBanks) {
|
||||
super(STABLE, TYPE_FLOAT, size, numBanks);
|
||||
bankdata = new float[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new float[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>float</code>-based <code>DataBuffer</code>
|
||||
* with the specified data array. Only the first
|
||||
* <code>size</code> elements are available for use by this
|
||||
* <code>DataBuffer</code>. The array must be large enough to
|
||||
* hold <code>size</code> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of <code>float</code>s to be used as the
|
||||
* first and only bank of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of the array to be used.
|
||||
*/
|
||||
public DataBufferFloat(float dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_FLOAT, size);
|
||||
data = dataArray;
|
||||
bankdata = new float[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>float</code>-based <code>DataBuffer</code>
|
||||
* with the specified data array. Only the elements between
|
||||
* <code>offset</code> and <code>offset + size - 1</code> are
|
||||
* available for use by this <code>DataBuffer</code>. The array
|
||||
* must be large enough to hold <code>offset + size</code>
|
||||
* elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of <code>float</code>s to be used as the
|
||||
* first and only bank of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of the array to be used.
|
||||
* @param offset The offset of the first element of the array
|
||||
* that will be used.
|
||||
*/
|
||||
public DataBufferFloat(float dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_FLOAT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new float[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>float</code>-based <code>DataBuffer</code>
|
||||
* with the specified data arrays. Only the first
|
||||
* <code>size</code> elements of each array are available for use
|
||||
* by this <code>DataBuffer</code>. The number of banks will be
|
||||
* equal to <code>dataArray.length</code>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of arrays of <code>float</code>s to be
|
||||
* used as the banks of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of each array to be used.
|
||||
*/
|
||||
public DataBufferFloat(float dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_FLOAT, size, dataArray.length);
|
||||
bankdata = (float[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>float</code>-based <code>DataBuffer</code>
|
||||
* with the specified data arrays, size, and per-bank offsets.
|
||||
* The number of banks is equal to <code>dataArray.length</code>.
|
||||
* Each array must be at least as large as <code>size</code> plus the
|
||||
* corresponding offset. There must be an entry in the offsets
|
||||
* array for each data array.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray An array of arrays of <code>float</code>s to be
|
||||
* used as the banks of this <code>DataBuffer</code>.
|
||||
* @param size The number of elements of each array to be used.
|
||||
* @param offsets An array of integer offsets, one for each bank.
|
||||
*/
|
||||
public DataBufferFloat(float dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_FLOAT, size,dataArray.length, offsets);
|
||||
bankdata = (float[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) <code>float</code> data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return the first float data array.
|
||||
*/
|
||||
public float[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank the data array
|
||||
* @return the data array specified by <code>bank</code>.
|
||||
*/
|
||||
public float[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return all data arrays for this data buffer.
|
||||
*/
|
||||
public float[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (float[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first
|
||||
* (default) bank as an <code>int</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as an <code>int</code>.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified
|
||||
* bank as an <code>int</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as an <code>int</code>.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default)
|
||||
* bank to the given <code>int</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (float)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank to
|
||||
* the given <code>int</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (float)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first
|
||||
* (default) bank as a <code>float</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>float</code>.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int i) {
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified
|
||||
* bank as a <code>float</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>float</code>.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default)
|
||||
* bank to the given <code>float</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int i, float val) {
|
||||
data[i+offset] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank to
|
||||
* the given <code>float</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
bankdata[bank][i+offsets[bank]] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first
|
||||
* (default) bank as a <code>double</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>double</code>.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int i) {
|
||||
return (double)data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified
|
||||
* bank as a <code>double</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
*
|
||||
* @return The data entry as a <code>double</code>.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return (double)bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default)
|
||||
* bank to the given <code>double</code>.
|
||||
*
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int i, double val) {
|
||||
data[i+offset] = (float)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank to
|
||||
* the given <code>double</code>.
|
||||
*
|
||||
* @param bank The bank number.
|
||||
* @param i The desired data array element.
|
||||
* @param val The value to be set.
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
bankdata[bank][i+offsets[bank]] = (float)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
||||
284
jdkSrc/jdk8/java/awt/image/DataBufferInt.java
Normal file
284
jdkSrc/jdk8/java/awt/image/DataBufferInt.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally
|
||||
* as integers.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferInt extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
int data[];
|
||||
|
||||
/** All data banks */
|
||||
int bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank
|
||||
* and the specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int size) {
|
||||
super(STABLE, TYPE_INT, size);
|
||||
data = new int[size];
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks, all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int size, int numBanks) {
|
||||
super(STABLE, TYPE_INT, size, numBanks);
|
||||
bankdata = new int[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new int[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_INT, size);
|
||||
data = dataArray;
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, dataArray.length);
|
||||
bankdata = (int [][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, dataArray.length, offsets);
|
||||
bankdata = (int [][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) int data array in <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first integer data array.
|
||||
*/
|
||||
public int[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public int[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public int[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (int [][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* to the integer value <CODE>i</CODE>.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (int)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
||||
283
jdkSrc/jdk8/java/awt/image/DataBufferShort.java
Normal file
283
jdkSrc/jdk8/java/awt/image/DataBufferShort.java
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as shorts.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferShort extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
short data[];
|
||||
|
||||
/** All data banks */
|
||||
short bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(int size) {
|
||||
super(STABLE, TYPE_SHORT,size);
|
||||
data = new short[size];
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(int size, int numBanks) {
|
||||
super(STABLE, TYPE_SHORT,size,numBanks);
|
||||
bankdata = new short[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new short[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size);
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length);
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length, offsets);
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) byte data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first short data array.
|
||||
*/
|
||||
public short[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public short[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public short[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (short[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (short)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (short)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
||||
318
jdkSrc/jdk8/java/awt/image/DataBufferUShort.java
Normal file
318
jdkSrc/jdk8/java/awt/image/DataBufferUShort.java
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as
|
||||
* shorts. Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
|
||||
* are treated as unsigned values.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferUShort extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
short data[];
|
||||
|
||||
/** All data banks */
|
||||
short bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(int size) {
|
||||
super(STABLE, TYPE_USHORT, size);
|
||||
data = new short[size];
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks, all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(int size, int numBanks) {
|
||||
super(STABLE, TYPE_USHORT, size, numBanks);
|
||||
bankdata = new short[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new short[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
|
||||
* using the specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
|
||||
* using the specified array, size, and offset. <CODE>dataArray</CODE> must have at
|
||||
* least <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements
|
||||
* <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
|
||||
* be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
if ((size+offset) > dataArray.length) {
|
||||
throw new IllegalArgumentException("Length of dataArray is less "+
|
||||
" than size+offset.");
|
||||
}
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
for (int i=0; i < dataArray.length; i++) {
|
||||
if (dataArray[i] == null) {
|
||||
throw new NullPointerException("dataArray["+i+"] is null");
|
||||
}
|
||||
}
|
||||
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
|
||||
* size, and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
for (int i=0; i < dataArray.length; i++) {
|
||||
if (dataArray[i] == null) {
|
||||
throw new NullPointerException("dataArray["+i+"] is null");
|
||||
}
|
||||
if ((size+offsets[i]) > dataArray[i].length) {
|
||||
throw new IllegalArgumentException("Length of dataArray["+i+
|
||||
"] is less than size+"+
|
||||
"offsets["+i+"].");
|
||||
}
|
||||
|
||||
}
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) unsigned-short data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first unsigned-short data array.
|
||||
*/
|
||||
public short[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public short[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public short[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (short[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]&0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (short)(val&0xffff);
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
||||
1416
jdkSrc/jdk8/java/awt/image/DirectColorModel.java
Normal file
1416
jdkSrc/jdk8/java/awt/image/DirectColorModel.java
Normal file
File diff suppressed because it is too large
Load Diff
209
jdkSrc/jdk8/java/awt/image/FilteredImageSource.java
Normal file
209
jdkSrc/jdk8/java/awt/image/FilteredImageSource.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.ImageFilter;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.util.Hashtable;
|
||||
import java.awt.image.ColorModel;
|
||||
|
||||
/**
|
||||
* This class is an implementation of the ImageProducer interface which
|
||||
* takes an existing image and a filter object and uses them to produce
|
||||
* image data for a new filtered version of the original image.
|
||||
* Here is an example which filters an image by swapping the red and
|
||||
* blue compents:
|
||||
* <pre>
|
||||
*
|
||||
* Image src = getImage("doc:///demo/images/duke/T1.gif");
|
||||
* ImageFilter colorfilter = new RedBlueSwapFilter();
|
||||
* Image img = createImage(new FilteredImageSource(src.getSource(),
|
||||
* colorfilter));
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @see ImageProducer
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class FilteredImageSource implements ImageProducer {
|
||||
ImageProducer src;
|
||||
ImageFilter filter;
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object from an existing ImageProducer
|
||||
* and a filter object.
|
||||
* @param orig the specified <code>ImageProducer</code>
|
||||
* @param imgf the specified <code>ImageFilter</code>
|
||||
* @see ImageFilter
|
||||
* @see java.awt.Component#createImage
|
||||
*/
|
||||
public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
|
||||
src = orig;
|
||||
filter = imgf;
|
||||
}
|
||||
|
||||
private Hashtable proxies;
|
||||
|
||||
/**
|
||||
* Adds the specified <code>ImageConsumer</code>
|
||||
* to the list of consumers interested in data for the filtered image.
|
||||
* An instance of the original <code>ImageFilter</code>
|
||||
* is created
|
||||
* (using the filter's <code>getFilterInstance</code> method)
|
||||
* to manipulate the image data
|
||||
* for the specified <code>ImageConsumer</code>.
|
||||
* The newly created filter instance
|
||||
* is then passed to the <code>addConsumer</code> method
|
||||
* of the original <code>ImageProducer</code>.
|
||||
*
|
||||
* <p>
|
||||
* This method is public as a side effect
|
||||
* of this class implementing
|
||||
* the <code>ImageProducer</code> interface.
|
||||
* It should not be called from user code,
|
||||
* and its behavior if called from user code is unspecified.
|
||||
*
|
||||
* @param ic the consumer for the filtered image
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic) {
|
||||
if (proxies == null) {
|
||||
proxies = new Hashtable();
|
||||
}
|
||||
if (!proxies.containsKey(ic)) {
|
||||
ImageFilter imgf = filter.getFilterInstance(ic);
|
||||
proxies.put(ic, imgf);
|
||||
src.addConsumer(imgf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an ImageConsumer is on the list of consumers
|
||||
* currently interested in data for this image.
|
||||
*
|
||||
* <p>
|
||||
* This method is public as a side effect
|
||||
* of this class implementing
|
||||
* the <code>ImageProducer</code> interface.
|
||||
* It should not be called from user code,
|
||||
* and its behavior if called from user code is unspecified.
|
||||
*
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @return true if the ImageConsumer is on the list; false otherwise
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic) {
|
||||
return (proxies != null && proxies.containsKey(ic));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an ImageConsumer from the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* <p>
|
||||
* This method is public as a side effect
|
||||
* of this class implementing
|
||||
* the <code>ImageProducer</code> interface.
|
||||
* It should not be called from user code,
|
||||
* and its behavior if called from user code is unspecified.
|
||||
*
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic) {
|
||||
if (proxies != null) {
|
||||
ImageFilter imgf = (ImageFilter) proxies.get(ic);
|
||||
if (imgf != null) {
|
||||
src.removeConsumer(imgf);
|
||||
proxies.remove(ic);
|
||||
if (proxies.isEmpty()) {
|
||||
proxies = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts production of the filtered image.
|
||||
* If the specified <code>ImageConsumer</code>
|
||||
* isn't already a consumer of the filtered image,
|
||||
* an instance of the original <code>ImageFilter</code>
|
||||
* is created
|
||||
* (using the filter's <code>getFilterInstance</code> method)
|
||||
* to manipulate the image data
|
||||
* for the <code>ImageConsumer</code>.
|
||||
* The filter instance for the <code>ImageConsumer</code>
|
||||
* is then passed to the <code>startProduction</code> method
|
||||
* of the original <code>ImageProducer</code>.
|
||||
*
|
||||
* <p>
|
||||
* This method is public as a side effect
|
||||
* of this class implementing
|
||||
* the <code>ImageProducer</code> interface.
|
||||
* It should not be called from user code,
|
||||
* and its behavior if called from user code is unspecified.
|
||||
*
|
||||
* @param ic the consumer for the filtered image
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized void startProduction(ImageConsumer ic) {
|
||||
if (proxies == null) {
|
||||
proxies = new Hashtable();
|
||||
}
|
||||
ImageFilter imgf = (ImageFilter) proxies.get(ic);
|
||||
if (imgf == null) {
|
||||
imgf = filter.getFilterInstance(ic);
|
||||
proxies.put(ic, imgf);
|
||||
}
|
||||
src.startProduction(imgf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a given ImageConsumer have the image data delivered
|
||||
* one more time in top-down, left-right order. The request is
|
||||
* handed to the ImageFilter for further processing, since the
|
||||
* ability to preserve the pixel ordering depends on the filter.
|
||||
*
|
||||
* <p>
|
||||
* This method is public as a side effect
|
||||
* of this class implementing
|
||||
* the <code>ImageProducer</code> interface.
|
||||
* It should not be called from user code,
|
||||
* and its behavior if called from user code is unspecified.
|
||||
*
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized void requestTopDownLeftRightResend(ImageConsumer ic) {
|
||||
if (proxies != null) {
|
||||
ImageFilter imgf = (ImageFilter) proxies.get(ic);
|
||||
if (imgf != null) {
|
||||
imgf.resendTopDownLeftRight(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
227
jdkSrc/jdk8/java/awt/image/ImageConsumer.java
Normal file
227
jdkSrc/jdk8/java/awt/image/ImageConsumer.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
||||
/**
|
||||
* The interface for objects expressing interest in image data through
|
||||
* the ImageProducer interfaces. When a consumer is added to an image
|
||||
* producer, the producer delivers all of the data about the image
|
||||
* using the method calls defined in this interface.
|
||||
*
|
||||
* @see ImageProducer
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public interface ImageConsumer {
|
||||
/**
|
||||
* The dimensions of the source image are reported using the
|
||||
* setDimensions method call.
|
||||
* @param width the width of the source image
|
||||
* @param height the height of the source image
|
||||
*/
|
||||
void setDimensions(int width, int height);
|
||||
|
||||
/**
|
||||
* Sets the extensible list of properties associated with this image.
|
||||
* @param props the list of properties to be associated with this
|
||||
* image
|
||||
*/
|
||||
void setProperties(Hashtable<?,?> props);
|
||||
|
||||
/**
|
||||
* Sets the ColorModel object used for the majority of
|
||||
* the pixels reported using the setPixels method
|
||||
* calls. Note that each set of pixels delivered using setPixels
|
||||
* contains its own ColorModel object, so no assumption should
|
||||
* be made that this model will be the only one used in delivering
|
||||
* pixel values. A notable case where multiple ColorModel objects
|
||||
* may be seen is a filtered image when for each set of pixels
|
||||
* that it filters, the filter
|
||||
* determines whether the
|
||||
* pixels can be sent on untouched, using the original ColorModel,
|
||||
* or whether the pixels should be modified (filtered) and passed
|
||||
* on using a ColorModel more convenient for the filtering process.
|
||||
* @param model the specified <code>ColorModel</code>
|
||||
* @see ColorModel
|
||||
*/
|
||||
void setColorModel(ColorModel model);
|
||||
|
||||
/**
|
||||
* Sets the hints that the ImageConsumer uses to process the
|
||||
* pixels delivered by the ImageProducer.
|
||||
* The ImageProducer can deliver the pixels in any order, but
|
||||
* the ImageConsumer may be able to scale or convert the pixels
|
||||
* to the destination ColorModel more efficiently or with higher
|
||||
* quality if it knows some information about how the pixels will
|
||||
* be delivered up front. The setHints method should be called
|
||||
* before any calls to any of the setPixels methods with a bit mask
|
||||
* of hints about the manner in which the pixels will be delivered.
|
||||
* If the ImageProducer does not follow the guidelines for the
|
||||
* indicated hint, the results are undefined.
|
||||
* @param hintflags a set of hints that the ImageConsumer uses to
|
||||
* process the pixels
|
||||
*/
|
||||
void setHints(int hintflags);
|
||||
|
||||
/**
|
||||
* The pixels will be delivered in a random order. This tells the
|
||||
* ImageConsumer not to use any optimizations that depend on the
|
||||
* order of pixel delivery, which should be the default assumption
|
||||
* in the absence of any call to the setHints method.
|
||||
* @see #setHints
|
||||
*/
|
||||
int RANDOMPIXELORDER = 1;
|
||||
|
||||
/**
|
||||
* The pixels will be delivered in top-down, left-to-right order.
|
||||
* @see #setHints
|
||||
*/
|
||||
int TOPDOWNLEFTRIGHT = 2;
|
||||
|
||||
/**
|
||||
* The pixels will be delivered in (multiples of) complete scanlines
|
||||
* at a time.
|
||||
* @see #setHints
|
||||
*/
|
||||
int COMPLETESCANLINES = 4;
|
||||
|
||||
/**
|
||||
* The pixels will be delivered in a single pass. Each pixel will
|
||||
* appear in only one call to any of the setPixels methods. An
|
||||
* example of an image format which does not meet this criterion
|
||||
* is a progressive JPEG image which defines pixels in multiple
|
||||
* passes, each more refined than the previous.
|
||||
* @see #setHints
|
||||
*/
|
||||
int SINGLEPASS = 8;
|
||||
|
||||
/**
|
||||
* The image contain a single static image. The pixels will be defined
|
||||
* in calls to the setPixels methods and then the imageComplete method
|
||||
* will be called with the STATICIMAGEDONE flag after which no more
|
||||
* image data will be delivered. An example of an image type which
|
||||
* would not meet these criteria would be the output of a video feed,
|
||||
* or the representation of a 3D rendering being manipulated
|
||||
* by the user. The end of each frame in those types of images will
|
||||
* be indicated by calling imageComplete with the SINGLEFRAMEDONE flag.
|
||||
* @see #setHints
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int SINGLEFRAME = 16;
|
||||
|
||||
/**
|
||||
* Delivers the pixels of the image with one or more calls
|
||||
* to this method. Each call specifies the location and
|
||||
* size of the rectangle of source pixels that are contained in
|
||||
* the array of pixels. The specified ColorModel object should
|
||||
* be used to convert the pixels into their corresponding color
|
||||
* and alpha components. Pixel (m,n) is stored in the pixels array
|
||||
* at index (n * scansize + m + off). The pixels delivered using
|
||||
* this method are all stored as bytes.
|
||||
* @param x the X coordinate of the upper-left corner of the
|
||||
* area of pixels to be set
|
||||
* @param y the Y coordinate of the upper-left corner of the
|
||||
* area of pixels to be set
|
||||
* @param w the width of the area of pixels
|
||||
* @param h the height of the area of pixels
|
||||
* @param model the specified <code>ColorModel</code>
|
||||
* @param pixels the array of pixels
|
||||
* @param off the offset into the <code>pixels</code> array
|
||||
* @param scansize the distance from one row of pixels to the next in
|
||||
* the <code>pixels</code> array
|
||||
* @see ColorModel
|
||||
*/
|
||||
void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off, int scansize);
|
||||
|
||||
/**
|
||||
* The pixels of the image are delivered using one or more calls
|
||||
* to the setPixels method. Each call specifies the location and
|
||||
* size of the rectangle of source pixels that are contained in
|
||||
* the array of pixels. The specified ColorModel object should
|
||||
* be used to convert the pixels into their corresponding color
|
||||
* and alpha components. Pixel (m,n) is stored in the pixels array
|
||||
* at index (n * scansize + m + off). The pixels delivered using
|
||||
* this method are all stored as ints.
|
||||
* this method are all stored as ints.
|
||||
* @param x the X coordinate of the upper-left corner of the
|
||||
* area of pixels to be set
|
||||
* @param y the Y coordinate of the upper-left corner of the
|
||||
* area of pixels to be set
|
||||
* @param w the width of the area of pixels
|
||||
* @param h the height of the area of pixels
|
||||
* @param model the specified <code>ColorModel</code>
|
||||
* @param pixels the array of pixels
|
||||
* @param off the offset into the <code>pixels</code> array
|
||||
* @param scansize the distance from one row of pixels to the next in
|
||||
* the <code>pixels</code> array
|
||||
* @see ColorModel
|
||||
*/
|
||||
void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off, int scansize);
|
||||
|
||||
/**
|
||||
* The imageComplete method is called when the ImageProducer is
|
||||
* finished delivering all of the pixels that the source image
|
||||
* contains, or when a single frame of a multi-frame animation has
|
||||
* been completed, or when an error in loading or producing the
|
||||
* image has occurred. The ImageConsumer should remove itself from the
|
||||
* list of consumers registered with the ImageProducer at this time,
|
||||
* unless it is interested in successive frames.
|
||||
* @param status the status of image loading
|
||||
* @see ImageProducer#removeConsumer
|
||||
*/
|
||||
void imageComplete(int status);
|
||||
|
||||
/**
|
||||
* An error was encountered while producing the image.
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int IMAGEERROR = 1;
|
||||
|
||||
/**
|
||||
* One frame of the image is complete but there are more frames
|
||||
* to be delivered.
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int SINGLEFRAMEDONE = 2;
|
||||
|
||||
/**
|
||||
* The image is complete and there are no more pixels or frames
|
||||
* to be delivered.
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int STATICIMAGEDONE = 3;
|
||||
|
||||
/**
|
||||
* The image creation process was deliberately aborted.
|
||||
* @see #imageComplete
|
||||
*/
|
||||
int IMAGEABORTED = 4;
|
||||
}
|
||||
258
jdkSrc/jdk8/java/awt/image/ImageFilter.java
Normal file
258
jdkSrc/jdk8/java/awt/image/ImageFilter.java
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This class implements a filter for the set of interface methods that
|
||||
* are used to deliver data from an ImageProducer to an ImageConsumer.
|
||||
* It is meant to be used in conjunction with a FilteredImageSource
|
||||
* object to produce filtered versions of existing images. It is a
|
||||
* base class that provides the calls needed to implement a "Null filter"
|
||||
* which has no effect on the data being passed through. Filters should
|
||||
* subclass this class and override the methods which deal with the
|
||||
* data that needs to be filtered and modify it as necessary.
|
||||
*
|
||||
* @see FilteredImageSource
|
||||
* @see ImageConsumer
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class ImageFilter implements ImageConsumer, Cloneable {
|
||||
/**
|
||||
* The consumer of the particular image data stream for which this
|
||||
* instance of the ImageFilter is filtering data. It is not
|
||||
* initialized during the constructor, but rather during the
|
||||
* getFilterInstance() method call when the FilteredImageSource
|
||||
* is creating a unique instance of this object for a particular
|
||||
* image data stream.
|
||||
* @see #getFilterInstance
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
protected ImageConsumer consumer;
|
||||
|
||||
/**
|
||||
* Returns a unique instance of an ImageFilter object which will
|
||||
* actually perform the filtering for the specified ImageConsumer.
|
||||
* The default implementation just clones this object.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @return an <code>ImageFilter</code> used to perform the
|
||||
* filtering for the specified <code>ImageConsumer</code>.
|
||||
*/
|
||||
public ImageFilter getFilterInstance(ImageConsumer ic) {
|
||||
ImageFilter instance = (ImageFilter) clone();
|
||||
instance.consumer = ic;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the setDimensions method
|
||||
* of the ImageConsumer interface.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#setDimensions
|
||||
*/
|
||||
public void setDimensions(int width, int height) {
|
||||
consumer.setDimensions(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the properties from the source object along after adding a
|
||||
* property indicating the stream of filters it has been run through.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*
|
||||
* @param props the properties from the source object
|
||||
* @exception NullPointerException if <code>props</code> is null
|
||||
*/
|
||||
public void setProperties(Hashtable<?,?> props) {
|
||||
Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone();
|
||||
Object o = p.get("filters");
|
||||
if (o == null) {
|
||||
p.put("filters", toString());
|
||||
} else if (o instanceof String) {
|
||||
p.put("filters", ((String) o)+toString());
|
||||
}
|
||||
consumer.setProperties(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the information provided in the setColorModel method
|
||||
* of the ImageConsumer interface.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#setColorModel
|
||||
*/
|
||||
public void setColorModel(ColorModel model) {
|
||||
consumer.setColorModel(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the setHints method
|
||||
* of the ImageConsumer interface.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#setHints
|
||||
*/
|
||||
public void setHints(int hints) {
|
||||
consumer.setHints(hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the setPixels method of the
|
||||
* ImageConsumer interface which takes an array of bytes.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#setPixels
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off,
|
||||
int scansize) {
|
||||
consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the setPixels method of the
|
||||
* ImageConsumer interface which takes an array of integers.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#setPixels
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off,
|
||||
int scansize) {
|
||||
consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the information provided in the imageComplete method of
|
||||
* the ImageConsumer interface.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer#imageComplete
|
||||
*/
|
||||
public void imageComplete(int status) {
|
||||
consumer.imageComplete(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to a request for a TopDownLeftRight (TDLR) ordered resend
|
||||
* of the pixel data from an <code>ImageConsumer</code>.
|
||||
* When an <code>ImageConsumer</code> being fed
|
||||
* by an instance of this <code>ImageFilter</code>
|
||||
* requests a resend of the data in TDLR order,
|
||||
* the <code>FilteredImageSource</code>
|
||||
* invokes this method of the <code>ImageFilter</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* An <code>ImageFilter</code> subclass might override this method or not,
|
||||
* depending on if and how it can send data in TDLR order.
|
||||
* Three possibilities exist:
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
* Do not override this method.
|
||||
* This makes the subclass use the default implementation,
|
||||
* which is to
|
||||
* forward the request
|
||||
* to the indicated <code>ImageProducer</code>
|
||||
* using this filter as the requesting <code>ImageConsumer</code>.
|
||||
* This behavior
|
||||
* is appropriate if the filter can determine
|
||||
* that it will forward the pixels
|
||||
* in TDLR order if its upstream producer object
|
||||
* sends them in TDLR order.
|
||||
*
|
||||
* <li>
|
||||
* Override the method to simply send the data.
|
||||
* This is appropriate if the filter can handle the request itself —
|
||||
* for example,
|
||||
* if the generated pixels have been saved in some sort of buffer.
|
||||
*
|
||||
* <li>
|
||||
* Override the method to do nothing.
|
||||
* This is appropriate
|
||||
* if the filter cannot produce filtered data in TDLR order.
|
||||
* </ul>
|
||||
*
|
||||
* @see ImageProducer#requestTopDownLeftRightResend
|
||||
* @param ip the ImageProducer that is feeding this instance of
|
||||
* the filter - also the ImageProducer that the request should be
|
||||
* forwarded to if necessary
|
||||
* @exception NullPointerException if <code>ip</code> is null
|
||||
*/
|
||||
public void resendTopDownLeftRight(ImageProducer ip) {
|
||||
ip.requestTopDownLeftRightResend(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones this object.
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
171
jdkSrc/jdk8/java/awt/image/ImageObserver.java
Normal file
171
jdkSrc/jdk8/java/awt/image/ImageObserver.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Image;
|
||||
|
||||
|
||||
/**
|
||||
* An asynchronous update interface for receiving notifications about
|
||||
* Image information as the Image is constructed.
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public interface ImageObserver {
|
||||
/**
|
||||
* This method is called when information about an image which was
|
||||
* previously requested using an asynchronous interface becomes
|
||||
* available. Asynchronous interfaces are method calls such as
|
||||
* getWidth(ImageObserver) and drawImage(img, x, y, ImageObserver)
|
||||
* which take an ImageObserver object as an argument. Those methods
|
||||
* register the caller as interested either in information about
|
||||
* the overall image itself (in the case of getWidth(ImageObserver))
|
||||
* or about an output version of an image (in the case of the
|
||||
* drawImage(img, x, y, [w, h,] ImageObserver) call).
|
||||
*
|
||||
* <p>This method
|
||||
* should return true if further updates are needed or false if the
|
||||
* required information has been acquired. The image which was being
|
||||
* tracked is passed in using the img argument. Various constants
|
||||
* are combined to form the infoflags argument which indicates what
|
||||
* information about the image is now available. The interpretation
|
||||
* of the x, y, width, and height arguments depends on the contents
|
||||
* of the infoflags argument.
|
||||
* <p>
|
||||
* The <code>infoflags</code> argument should be the bitwise inclusive
|
||||
* <b>OR</b> of the following flags: <code>WIDTH</code>,
|
||||
* <code>HEIGHT</code>, <code>PROPERTIES</code>, <code>SOMEBITS</code>,
|
||||
* <code>FRAMEBITS</code>, <code>ALLBITS</code>, <code>ERROR</code>,
|
||||
* <code>ABORT</code>.
|
||||
*
|
||||
* @param img the image being observed.
|
||||
* @param infoflags the bitwise inclusive OR of the following
|
||||
* flags: <code>WIDTH</code>, <code>HEIGHT</code>,
|
||||
* <code>PROPERTIES</code>, <code>SOMEBITS</code>,
|
||||
* <code>FRAMEBITS</code>, <code>ALLBITS</code>,
|
||||
* <code>ERROR</code>, <code>ABORT</code>.
|
||||
* @param x the <i>x</i> coordinate.
|
||||
* @param y the <i>y</i> coordinate.
|
||||
* @param width the width.
|
||||
* @param height the height.
|
||||
* @return <code>false</code> if the infoflags indicate that the
|
||||
* image is completely loaded; <code>true</code> otherwise.
|
||||
*
|
||||
* @see #WIDTH
|
||||
* @see #HEIGHT
|
||||
* @see #PROPERTIES
|
||||
* @see #SOMEBITS
|
||||
* @see #FRAMEBITS
|
||||
* @see #ALLBITS
|
||||
* @see #ERROR
|
||||
* @see #ABORT
|
||||
* @see Image#getWidth
|
||||
* @see Image#getHeight
|
||||
* @see java.awt.Graphics#drawImage
|
||||
*/
|
||||
public boolean imageUpdate(Image img, int infoflags,
|
||||
int x, int y, int width, int height);
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* the width of the base image is now available and can be taken
|
||||
* from the width argument to the imageUpdate callback method.
|
||||
* @see Image#getWidth
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int WIDTH = 1;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* the height of the base image is now available and can be taken
|
||||
* from the height argument to the imageUpdate callback method.
|
||||
* @see Image#getHeight
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int HEIGHT = 2;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* the properties of the image are now available.
|
||||
* @see Image#getProperty
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int PROPERTIES = 4;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* more pixels needed for drawing a scaled variation of the image
|
||||
* are available. The bounding box of the new pixels can be taken
|
||||
* from the x, y, width, and height arguments to the imageUpdate
|
||||
* callback method.
|
||||
* @see java.awt.Graphics#drawImage
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int SOMEBITS = 8;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* another complete frame of a multi-frame image which was previously
|
||||
* drawn is now available to be drawn again. The x, y, width, and height
|
||||
* arguments to the imageUpdate callback method should be ignored.
|
||||
* @see java.awt.Graphics#drawImage
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int FRAMEBITS = 16;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* a static image which was previously drawn is now complete and can
|
||||
* be drawn again in its final form. The x, y, width, and height
|
||||
* arguments to the imageUpdate callback method should be ignored.
|
||||
* @see java.awt.Graphics#drawImage
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int ALLBITS = 32;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* an image which was being tracked asynchronously has encountered
|
||||
* an error. No further information will become available and
|
||||
* drawing the image will fail.
|
||||
* As a convenience, the ABORT flag will be indicated at the same
|
||||
* time to indicate that the image production was aborted.
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int ERROR = 64;
|
||||
|
||||
/**
|
||||
* This flag in the infoflags argument to imageUpdate indicates that
|
||||
* an image which was being tracked asynchronously was aborted before
|
||||
* production was complete. No more information will become available
|
||||
* without further action to trigger another image production sequence.
|
||||
* If the ERROR flag was not also set in this image update, then
|
||||
* accessing any of the data in the image will restart the production
|
||||
* again, probably from the beginning.
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
public static final int ABORT = 128;
|
||||
}
|
||||
112
jdkSrc/jdk8/java/awt/image/ImageProducer.java
Normal file
112
jdkSrc/jdk8/java/awt/image/ImageProducer.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* The interface for objects which can produce the image data for Images.
|
||||
* Each image contains an ImageProducer which is used to reconstruct
|
||||
* the image whenever it is needed, for example, when a new size of the
|
||||
* Image is scaled, or when the width or height of the Image is being
|
||||
* requested.
|
||||
*
|
||||
* @see ImageConsumer
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public interface ImageProducer {
|
||||
/**
|
||||
* Registers an <code>ImageConsumer</code> with the
|
||||
* <code>ImageProducer</code> for access to the image data
|
||||
* during a later reconstruction of the <code>Image</code>.
|
||||
* The <code>ImageProducer</code> may, at its discretion,
|
||||
* start delivering the image data to the consumer
|
||||
* using the <code>ImageConsumer</code> interface immediately,
|
||||
* or when the next available image reconstruction is triggered
|
||||
* by a call to the <code>startProduction</code> method.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @see #startProduction
|
||||
*/
|
||||
public void addConsumer(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Determines if a specified <code>ImageConsumer</code>
|
||||
* object is currently registered with this
|
||||
* <code>ImageProducer</code> as one of its consumers.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @return <code>true</code> if the specified
|
||||
* <code>ImageConsumer</code> is registered with
|
||||
* this <code>ImageProducer</code>;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isConsumer(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Removes the specified <code>ImageConsumer</code> object
|
||||
* from the list of consumers currently registered to
|
||||
* receive image data. It is not considered an error
|
||||
* to remove a consumer that is not currently registered.
|
||||
* The <code>ImageProducer</code> should stop sending data
|
||||
* to this consumer as soon as is feasible.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
*/
|
||||
public void removeConsumer(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Registers the specified <code>ImageConsumer</code> object
|
||||
* as a consumer and starts an immediate reconstruction of
|
||||
* the image data which will then be delivered to this
|
||||
* consumer and any other consumer which might have already
|
||||
* been registered with the producer. This method differs
|
||||
* from the addConsumer method in that a reproduction of
|
||||
* the image data should be triggered as soon as possible.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @see #addConsumer
|
||||
*/
|
||||
public void startProduction(ImageConsumer ic);
|
||||
|
||||
/**
|
||||
* Requests, on behalf of the <code>ImageConsumer</code>,
|
||||
* that the <code>ImageProducer</code> attempt to resend
|
||||
* the image data one more time in TOPDOWNLEFTRIGHT order
|
||||
* so that higher quality conversion algorithms which
|
||||
* depend on receiving pixels in order can be used to
|
||||
* produce a better output version of the image. The
|
||||
* <code>ImageProducer</code> is free to
|
||||
* ignore this call if it cannot resend the data in that
|
||||
* order. If the data can be resent, the
|
||||
* <code>ImageProducer</code> should respond by executing
|
||||
* the following minimum set of <code>ImageConsumer</code>
|
||||
* method calls:
|
||||
* <pre>{@code
|
||||
* ic.setHints(TOPDOWNLEFTRIGHT | < otherhints >);
|
||||
* ic.setPixels(...); // As many times as needed
|
||||
* ic.imageComplete();
|
||||
* }</pre>
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @see ImageConsumer#setHints
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic);
|
||||
}
|
||||
45
jdkSrc/jdk8/java/awt/image/ImagingOpException.java
Normal file
45
jdkSrc/jdk8/java/awt/image/ImagingOpException.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* The <code>ImagingOpException</code> is thrown if one of the
|
||||
* {@link BufferedImageOp} or {@link RasterOp} filter methods cannot
|
||||
* process the image.
|
||||
*/
|
||||
public class ImagingOpException extends java.lang.RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImagingOpException</code> object with the
|
||||
* specified message.
|
||||
* @param s the message to generate when a
|
||||
* <code>ImagingOpException</code> is thrown
|
||||
*/
|
||||
public ImagingOpException(String s) {
|
||||
super (s);
|
||||
}
|
||||
}
|
||||
1535
jdkSrc/jdk8/java/awt/image/IndexColorModel.java
Normal file
1535
jdkSrc/jdk8/java/awt/image/IndexColorModel.java
Normal file
File diff suppressed because it is too large
Load Diff
153
jdkSrc/jdk8/java/awt/image/Kernel.java
Normal file
153
jdkSrc/jdk8/java/awt/image/Kernel.java
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* The <code>Kernel</code> class defines a matrix that describes how a
|
||||
* specified pixel and its surrounding pixels affect the value
|
||||
* computed for the pixel's position in the output image of a filtering
|
||||
* operation. The X origin and Y origin indicate the kernel matrix element
|
||||
* that corresponds to the pixel position for which an output value is
|
||||
* being computed.
|
||||
*
|
||||
* @see ConvolveOp
|
||||
*/
|
||||
public class Kernel implements Cloneable {
|
||||
private int width;
|
||||
private int height;
|
||||
private int xOrigin;
|
||||
private int yOrigin;
|
||||
private float data[];
|
||||
|
||||
private static native void initIDs();
|
||||
static {
|
||||
ColorModel.loadLibraries();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>Kernel</code> object from an array of floats.
|
||||
* The first <code>width</code>*<code>height</code> elements of
|
||||
* the <code>data</code> array are copied.
|
||||
* If the length of the <code>data</code> array is less
|
||||
* than width*height, an <code>IllegalArgumentException</code> is thrown.
|
||||
* The X origin is (width-1)/2 and the Y origin is (height-1)/2.
|
||||
* @param width width of the kernel
|
||||
* @param height height of the kernel
|
||||
* @param data kernel data in row major order
|
||||
* @throws IllegalArgumentException if the length of <code>data</code>
|
||||
* is less than the product of <code>width</code> and
|
||||
* <code>height</code>
|
||||
*/
|
||||
public Kernel(int width, int height, float data[]) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.xOrigin = (width-1)>>1;
|
||||
this.yOrigin = (height-1)>>1;
|
||||
int len = width*height;
|
||||
if (data.length < len) {
|
||||
throw new IllegalArgumentException("Data array too small "+
|
||||
"(is "+data.length+
|
||||
" and should be "+len);
|
||||
}
|
||||
this.data = new float[len];
|
||||
System.arraycopy(data, 0, this.data, 0, len);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the X origin of this <code>Kernel</code>.
|
||||
* @return the X origin.
|
||||
*/
|
||||
final public int getXOrigin(){
|
||||
return xOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Y origin of this <code>Kernel</code>.
|
||||
* @return the Y origin.
|
||||
*/
|
||||
final public int getYOrigin() {
|
||||
return yOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of this <code>Kernel</code>.
|
||||
* @return the width of this <code>Kernel</code>.
|
||||
*/
|
||||
final public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of this <code>Kernel</code>.
|
||||
* @return the height of this <code>Kernel</code>.
|
||||
*/
|
||||
final public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kernel data in row major order.
|
||||
* The <code>data</code> array is returned. If <code>data</code>
|
||||
* is <code>null</code>, a new array is allocated.
|
||||
* @param data if non-null, contains the returned kernel data
|
||||
* @return the <code>data</code> array containing the kernel data
|
||||
* in row major order or, if <code>data</code> is
|
||||
* <code>null</code>, a newly allocated array containing
|
||||
* the kernel data in row major order
|
||||
* @throws IllegalArgumentException if <code>data</code> is less
|
||||
* than the size of this <code>Kernel</code>
|
||||
*/
|
||||
final public float[] getKernelData(float[] data) {
|
||||
if (data == null) {
|
||||
data = new float[this.data.length];
|
||||
}
|
||||
else if (data.length < this.data.length) {
|
||||
throw new IllegalArgumentException("Data array too small "+
|
||||
"(should be "+this.data.length+
|
||||
" but is "+
|
||||
data.length+" )");
|
||||
}
|
||||
System.arraycopy(this.data, 0, data, 0, this.data.length);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones this object.
|
||||
* @return a clone of this object.
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
567
jdkSrc/jdk8/java/awt/image/LookupOp.java
Normal file
567
jdkSrc/jdk8/java/awt/image/LookupOp.java
Normal file
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Point2D;
|
||||
import sun.awt.image.ImagingLib;
|
||||
|
||||
/**
|
||||
* This class implements a lookup operation from the source
|
||||
* to the destination. The LookupTable object may contain a single array
|
||||
* or multiple arrays, subject to the restrictions below.
|
||||
* <p>
|
||||
* For Rasters, the lookup operates on bands. The number of
|
||||
* lookup arrays may be one, in which case the same array is
|
||||
* applied to all bands, or it must equal the number of Source
|
||||
* Raster bands.
|
||||
* <p>
|
||||
* For BufferedImages, the lookup operates on color and alpha components.
|
||||
* The number of lookup arrays may be one, in which case the
|
||||
* same array is applied to all color (but not alpha) components.
|
||||
* Otherwise, the number of lookup arrays may
|
||||
* equal the number of Source color components, in which case no
|
||||
* lookup of the alpha component (if present) is performed.
|
||||
* If neither of these cases apply, the number of lookup arrays
|
||||
* must equal the number of Source color components plus alpha components,
|
||||
* in which case lookup is performed for all color and alpha components.
|
||||
* This allows non-uniform rescaling of multi-band BufferedImages.
|
||||
* <p>
|
||||
* BufferedImage sources with premultiplied alpha data are treated in the same
|
||||
* manner as non-premultiplied images for purposes of the lookup. That is,
|
||||
* the lookup is done per band on the raw data of the BufferedImage source
|
||||
* without regard to whether the data is premultiplied. If a color conversion
|
||||
* is required to the destination ColorModel, the premultiplied state of
|
||||
* both source and destination will be taken into account for this step.
|
||||
* <p>
|
||||
* Images with an IndexColorModel cannot be used.
|
||||
* <p>
|
||||
* If a RenderingHints object is specified in the constructor, the
|
||||
* color rendering hint and the dithering hint may be used when color
|
||||
* conversion is required.
|
||||
* <p>
|
||||
* This class allows the Source to be the same as the Destination.
|
||||
*
|
||||
* @see LookupTable
|
||||
* @see java.awt.RenderingHints#KEY_COLOR_RENDERING
|
||||
* @see java.awt.RenderingHints#KEY_DITHERING
|
||||
*/
|
||||
|
||||
public class LookupOp implements BufferedImageOp, RasterOp {
|
||||
private LookupTable ltable;
|
||||
private int numComponents;
|
||||
RenderingHints hints;
|
||||
|
||||
/**
|
||||
* Constructs a <code>LookupOp</code> object given the lookup
|
||||
* table and a <code>RenderingHints</code> object, which might
|
||||
* be <code>null</code>.
|
||||
* @param lookup the specified <code>LookupTable</code>
|
||||
* @param hints the specified <code>RenderingHints</code>,
|
||||
* or <code>null</code>
|
||||
*/
|
||||
public LookupOp(LookupTable lookup, RenderingHints hints) {
|
||||
this.ltable = lookup;
|
||||
this.hints = hints;
|
||||
numComponents = ltable.getNumComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>LookupTable</code>.
|
||||
* @return the <code>LookupTable</code> of this
|
||||
* <code>LookupOp</code>.
|
||||
*/
|
||||
public final LookupTable getTable() {
|
||||
return ltable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a lookup operation on a <code>BufferedImage</code>.
|
||||
* If the color model in the source image is not the same as that
|
||||
* in the destination image, the pixels will be converted
|
||||
* in the destination. If the destination image is <code>null</code>,
|
||||
* a <code>BufferedImage</code> will be created with an appropriate
|
||||
* <code>ColorModel</code>. An <code>IllegalArgumentException</code>
|
||||
* might be thrown if the number of arrays in the
|
||||
* <code>LookupTable</code> does not meet the restrictions
|
||||
* stated in the class comment above, or if the source image
|
||||
* has an <code>IndexColorModel</code>.
|
||||
* @param src the <code>BufferedImage</code> to be filtered
|
||||
* @param dst the <code>BufferedImage</code> in which to
|
||||
* store the results of the filter operation
|
||||
* @return the filtered <code>BufferedImage</code>.
|
||||
* @throws IllegalArgumentException if the number of arrays in the
|
||||
* <code>LookupTable</code> does not meet the restrictions
|
||||
* described in the class comments, or if the source image
|
||||
* has an <code>IndexColorModel</code>.
|
||||
*/
|
||||
public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
|
||||
ColorModel srcCM = src.getColorModel();
|
||||
int numBands = srcCM.getNumColorComponents();
|
||||
ColorModel dstCM;
|
||||
if (srcCM instanceof IndexColorModel) {
|
||||
throw new
|
||||
IllegalArgumentException("LookupOp cannot be "+
|
||||
"performed on an indexed image");
|
||||
}
|
||||
int numComponents = ltable.getNumComponents();
|
||||
if (numComponents != 1 &&
|
||||
numComponents != srcCM.getNumComponents() &&
|
||||
numComponents != srcCM.getNumColorComponents())
|
||||
{
|
||||
throw new IllegalArgumentException("Number of arrays in the "+
|
||||
" lookup table ("+
|
||||
numComponents+
|
||||
" is not compatible with the "+
|
||||
" src image: "+src);
|
||||
}
|
||||
|
||||
|
||||
boolean needToConvert = false;
|
||||
|
||||
int width = src.getWidth();
|
||||
int height = src.getHeight();
|
||||
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
dstCM = srcCM;
|
||||
}
|
||||
else {
|
||||
if (width != dst.getWidth()) {
|
||||
throw new
|
||||
IllegalArgumentException("Src width ("+width+
|
||||
") not equal to dst width ("+
|
||||
dst.getWidth()+")");
|
||||
}
|
||||
if (height != dst.getHeight()) {
|
||||
throw new
|
||||
IllegalArgumentException("Src height ("+height+
|
||||
") not equal to dst height ("+
|
||||
dst.getHeight()+")");
|
||||
}
|
||||
|
||||
dstCM = dst.getColorModel();
|
||||
if (srcCM.getColorSpace().getType() !=
|
||||
dstCM.getColorSpace().getType())
|
||||
{
|
||||
needToConvert = true;
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BufferedImage origDst = dst;
|
||||
|
||||
if (ImagingLib.filter(this, src, dst) == null) {
|
||||
// Do it the slow way
|
||||
WritableRaster srcRaster = src.getRaster();
|
||||
WritableRaster dstRaster = dst.getRaster();
|
||||
|
||||
if (srcCM.hasAlpha()) {
|
||||
if (numBands-1 == numComponents || numComponents == 1) {
|
||||
int minx = srcRaster.getMinX();
|
||||
int miny = srcRaster.getMinY();
|
||||
int[] bands = new int[numBands-1];
|
||||
for (int i=0; i < numBands-1; i++) {
|
||||
bands[i] = i;
|
||||
}
|
||||
srcRaster =
|
||||
srcRaster.createWritableChild(minx, miny,
|
||||
srcRaster.getWidth(),
|
||||
srcRaster.getHeight(),
|
||||
minx, miny,
|
||||
bands);
|
||||
}
|
||||
}
|
||||
if (dstCM.hasAlpha()) {
|
||||
int dstNumBands = dstRaster.getNumBands();
|
||||
if (dstNumBands-1 == numComponents || numComponents == 1) {
|
||||
int minx = dstRaster.getMinX();
|
||||
int miny = dstRaster.getMinY();
|
||||
int[] bands = new int[numBands-1];
|
||||
for (int i=0; i < numBands-1; i++) {
|
||||
bands[i] = i;
|
||||
}
|
||||
dstRaster =
|
||||
dstRaster.createWritableChild(minx, miny,
|
||||
dstRaster.getWidth(),
|
||||
dstRaster.getHeight(),
|
||||
minx, miny,
|
||||
bands);
|
||||
}
|
||||
}
|
||||
|
||||
filter(srcRaster, dstRaster);
|
||||
}
|
||||
|
||||
if (needToConvert) {
|
||||
// ColorModels are not the same
|
||||
ColorConvertOp ccop = new ColorConvertOp(hints);
|
||||
ccop.filter(dst, origDst);
|
||||
}
|
||||
|
||||
return origDst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a lookup operation on a <code>Raster</code>.
|
||||
* If the destination <code>Raster</code> is <code>null</code>,
|
||||
* a new <code>Raster</code> will be created.
|
||||
* The <code>IllegalArgumentException</code> might be thrown
|
||||
* if the source <code>Raster</code> and the destination
|
||||
* <code>Raster</code> do not have the same
|
||||
* number of bands or if the number of arrays in the
|
||||
* <code>LookupTable</code> does not meet the
|
||||
* restrictions stated in the class comment above.
|
||||
* @param src the source <code>Raster</code> to filter
|
||||
* @param dst the destination <code>WritableRaster</code> for the
|
||||
* filtered <code>src</code>
|
||||
* @return the filtered <code>WritableRaster</code>.
|
||||
* @throws IllegalArgumentException if the source and destinations
|
||||
* rasters do not have the same number of bands, or the
|
||||
* number of arrays in the <code>LookupTable</code> does
|
||||
* not meet the restrictions described in the class comments.
|
||||
*
|
||||
*/
|
||||
public final WritableRaster filter (Raster src, WritableRaster dst) {
|
||||
int numBands = src.getNumBands();
|
||||
int dstLength = dst.getNumBands();
|
||||
int height = src.getHeight();
|
||||
int width = src.getWidth();
|
||||
int srcPix[] = new int[numBands];
|
||||
|
||||
// Create a new destination Raster, if needed
|
||||
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestRaster(src);
|
||||
}
|
||||
else if (height != dst.getHeight() || width != dst.getWidth()) {
|
||||
throw new
|
||||
IllegalArgumentException ("Width or height of Rasters do not "+
|
||||
"match");
|
||||
}
|
||||
dstLength = dst.getNumBands();
|
||||
|
||||
if (numBands != dstLength) {
|
||||
throw new
|
||||
IllegalArgumentException ("Number of channels in the src ("
|
||||
+ numBands +
|
||||
") does not match number of channels"
|
||||
+ " in the destination ("
|
||||
+ dstLength + ")");
|
||||
}
|
||||
int numComponents = ltable.getNumComponents();
|
||||
if (numComponents != 1 && numComponents != src.getNumBands()) {
|
||||
throw new IllegalArgumentException("Number of arrays in the "+
|
||||
" lookup table ("+
|
||||
numComponents+
|
||||
" is not compatible with the "+
|
||||
" src Raster: "+src);
|
||||
}
|
||||
|
||||
|
||||
if (ImagingLib.filter(this, src, dst) != null) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
// Optimize for cases we know about
|
||||
if (ltable instanceof ByteLookupTable) {
|
||||
byteFilter ((ByteLookupTable) ltable, src, dst,
|
||||
width, height, numBands);
|
||||
}
|
||||
else if (ltable instanceof ShortLookupTable) {
|
||||
shortFilter ((ShortLookupTable) ltable, src, dst, width,
|
||||
height, numBands);
|
||||
}
|
||||
else {
|
||||
// Not one we recognize so do it slowly
|
||||
int sminX = src.getMinX();
|
||||
int sY = src.getMinY();
|
||||
int dminX = dst.getMinX();
|
||||
int dY = dst.getMinY();
|
||||
for (int y=0; y < height; y++, sY++, dY++) {
|
||||
int sX = sminX;
|
||||
int dX = dminX;
|
||||
for (int x=0; x < width; x++, sX++, dX++) {
|
||||
// Find data for all bands at this x,y position
|
||||
src.getPixel(sX, sY, srcPix);
|
||||
|
||||
// Lookup the data for all bands at this x,y position
|
||||
ltable.lookupPixel(srcPix, srcPix);
|
||||
|
||||
// Put it back for all bands
|
||||
dst.setPixel(dX, dY, srcPix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the filtered destination image. Since
|
||||
* this is not a geometric operation, the bounding box does not
|
||||
* change.
|
||||
* @param src the <code>BufferedImage</code> to be filtered
|
||||
* @return the bounds of the filtered definition image.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (BufferedImage src) {
|
||||
return getBounds2D(src.getRaster());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the filtered destination Raster. Since
|
||||
* this is not a geometric operation, the bounding box does not
|
||||
* change.
|
||||
* @param src the <code>Raster</code> to be filtered
|
||||
* @return the bounds of the filtered definition <code>Raster</code>.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (Raster src) {
|
||||
return src.getBounds();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination image with the correct size and number of
|
||||
* bands. If destCM is <code>null</code>, an appropriate
|
||||
* <code>ColorModel</code> will be used.
|
||||
* @param src Source image for the filter operation.
|
||||
* @param destCM the destination's <code>ColorModel</code>, which
|
||||
* can be <code>null</code>.
|
||||
* @return a filtered destination <code>BufferedImage</code>.
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage (BufferedImage src,
|
||||
ColorModel destCM) {
|
||||
BufferedImage image;
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
int transferType = DataBuffer.TYPE_BYTE;
|
||||
if (destCM == null) {
|
||||
ColorModel cm = src.getColorModel();
|
||||
Raster raster = src.getRaster();
|
||||
if (cm instanceof ComponentColorModel) {
|
||||
DataBuffer db = raster.getDataBuffer();
|
||||
boolean hasAlpha = cm.hasAlpha();
|
||||
boolean isPre = cm.isAlphaPremultiplied();
|
||||
int trans = cm.getTransparency();
|
||||
int[] nbits = null;
|
||||
if (ltable instanceof ByteLookupTable) {
|
||||
if (db.getDataType() == db.TYPE_USHORT) {
|
||||
// Dst raster should be of type byte
|
||||
if (hasAlpha) {
|
||||
nbits = new int[2];
|
||||
if (trans == cm.BITMASK) {
|
||||
nbits[1] = 1;
|
||||
}
|
||||
else {
|
||||
nbits[1] = 8;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nbits = new int[1];
|
||||
}
|
||||
nbits[0] = 8;
|
||||
}
|
||||
// For byte, no need to change the cm
|
||||
}
|
||||
else if (ltable instanceof ShortLookupTable) {
|
||||
transferType = DataBuffer.TYPE_USHORT;
|
||||
if (db.getDataType() == db.TYPE_BYTE) {
|
||||
if (hasAlpha) {
|
||||
nbits = new int[2];
|
||||
if (trans == cm.BITMASK) {
|
||||
nbits[1] = 1;
|
||||
}
|
||||
else {
|
||||
nbits[1] = 16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nbits = new int[1];
|
||||
}
|
||||
nbits[0] = 16;
|
||||
}
|
||||
}
|
||||
if (nbits != null) {
|
||||
cm = new ComponentColorModel(cm.getColorSpace(),
|
||||
nbits, hasAlpha, isPre,
|
||||
trans, transferType);
|
||||
}
|
||||
}
|
||||
image = new BufferedImage(cm,
|
||||
cm.createCompatibleWritableRaster(w, h),
|
||||
cm.isAlphaPremultiplied(),
|
||||
null);
|
||||
}
|
||||
else {
|
||||
image = new BufferedImage(destCM,
|
||||
destCM.createCompatibleWritableRaster(w,
|
||||
h),
|
||||
destCM.isAlphaPremultiplied(),
|
||||
null);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed-destination <code>Raster</code> with the
|
||||
* correct size and number of bands, given this source.
|
||||
* @param src the <code>Raster</code> to be transformed
|
||||
* @return the zeroed-destination <code>Raster</code>.
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster (Raster src) {
|
||||
return src.createCompatibleWritableRaster();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the destination point given a
|
||||
* point in the source. If <code>dstPt</code> is not
|
||||
* <code>null</code>, it will be used to hold the return value.
|
||||
* Since this is not a geometric operation, the <code>srcPt</code>
|
||||
* will equal the <code>dstPt</code>.
|
||||
* @param srcPt a <code>Point2D</code> that represents a point
|
||||
* in the source image
|
||||
* @param dstPt a <code>Point2D</code>that represents the location
|
||||
* in the destination
|
||||
* @return the <code>Point2D</code> in the destination that
|
||||
* corresponds to the specified point in the source.
|
||||
*/
|
||||
public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
|
||||
if (dstPt == null) {
|
||||
dstPt = new Point2D.Float();
|
||||
}
|
||||
dstPt.setLocation(srcPt.getX(), srcPt.getY());
|
||||
|
||||
return dstPt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendering hints for this op.
|
||||
* @return the <code>RenderingHints</code> object associated
|
||||
* with this op.
|
||||
*/
|
||||
public final RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
private final void byteFilter(ByteLookupTable lookup, Raster src,
|
||||
WritableRaster dst,
|
||||
int width, int height, int numBands) {
|
||||
int[] srcPix = null;
|
||||
|
||||
// Find the ref to the table and the offset
|
||||
byte[][] table = lookup.getTable();
|
||||
int offset = lookup.getOffset();
|
||||
int tidx;
|
||||
int step=1;
|
||||
|
||||
// Check if it is one lookup applied to all bands
|
||||
if (table.length == 1) {
|
||||
step=0;
|
||||
}
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int band;
|
||||
int len = table[0].length;
|
||||
|
||||
// Loop through the data
|
||||
for ( y=0; y < height; y++) {
|
||||
tidx = 0;
|
||||
for ( band=0; band < numBands; band++, tidx+=step) {
|
||||
// Find data for this band, scanline
|
||||
srcPix = src.getSamples(0, y, width, 1, band, srcPix);
|
||||
|
||||
for ( x=0; x < width; x++) {
|
||||
int index = srcPix[x]-offset;
|
||||
if (index < 0 || index > len) {
|
||||
throw new
|
||||
IllegalArgumentException("index ("+index+
|
||||
"(out of range: "+
|
||||
" srcPix["+x+
|
||||
"]="+ srcPix[x]+
|
||||
" offset="+ offset);
|
||||
}
|
||||
// Do the lookup
|
||||
srcPix[x] = table[tidx][index];
|
||||
}
|
||||
// Put it back
|
||||
dst.setSamples(0, y, width, 1, band, srcPix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void shortFilter(ShortLookupTable lookup, Raster src,
|
||||
WritableRaster dst,
|
||||
int width, int height, int numBands) {
|
||||
int band;
|
||||
int[] srcPix = null;
|
||||
|
||||
// Find the ref to the table and the offset
|
||||
short[][] table = lookup.getTable();
|
||||
int offset = lookup.getOffset();
|
||||
int tidx;
|
||||
int step=1;
|
||||
|
||||
// Check if it is one lookup applied to all bands
|
||||
if (table.length == 1) {
|
||||
step=0;
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int index;
|
||||
int maxShort = (1<<16)-1;
|
||||
// Loop through the data
|
||||
for (y=0; y < height; y++) {
|
||||
tidx = 0;
|
||||
for ( band=0; band < numBands; band++, tidx+=step) {
|
||||
// Find data for this band, scanline
|
||||
srcPix = src.getSamples(0, y, width, 1, band, srcPix);
|
||||
|
||||
for ( x=0; x < width; x++) {
|
||||
index = srcPix[x]-offset;
|
||||
if (index < 0 || index > maxShort) {
|
||||
throw new
|
||||
IllegalArgumentException("index out of range "+
|
||||
index+" x is "+x+
|
||||
"srcPix[x]="+srcPix[x]
|
||||
+" offset="+ offset);
|
||||
}
|
||||
// Do the lookup
|
||||
srcPix[x] = table[tidx][index];
|
||||
}
|
||||
// Put it back
|
||||
dst.setSamples(0, y, width, 1, band, srcPix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
109
jdkSrc/jdk8/java/awt/image/LookupTable.java
Normal file
109
jdkSrc/jdk8/java/awt/image/LookupTable.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* This abstract class defines a lookup table object. ByteLookupTable
|
||||
* and ShortLookupTable are subclasses, which
|
||||
* contain byte and short data, respectively. A lookup table
|
||||
* contains data arrays for one or more bands (or components) of an image
|
||||
* (for example, separate arrays for R, G, and B),
|
||||
* and it contains an offset which will be subtracted from the
|
||||
* input values before indexing into the arrays. This allows an array
|
||||
* smaller than the native data size to be provided for a
|
||||
* constrained input. If there is only one array in the lookup
|
||||
* table, it will be applied to all bands. All arrays must be the
|
||||
* same size.
|
||||
*
|
||||
* @see ByteLookupTable
|
||||
* @see ShortLookupTable
|
||||
* @see LookupOp
|
||||
*/
|
||||
public abstract class LookupTable extends Object{
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
int numComponents;
|
||||
int offset;
|
||||
int numEntries;
|
||||
|
||||
/**
|
||||
* Constructs a new LookupTable from the number of components and an offset
|
||||
* into the lookup table.
|
||||
* @param offset the offset to subtract from input values before indexing
|
||||
* into the data arrays for this <code>LookupTable</code>
|
||||
* @param numComponents the number of data arrays in this
|
||||
* <code>LookupTable</code>
|
||||
* @throws IllegalArgumentException if <code>offset</code> is less than 0
|
||||
* or if <code>numComponents</code> is less than 1
|
||||
*/
|
||||
protected LookupTable(int offset, int numComponents) {
|
||||
if (offset < 0) {
|
||||
throw new
|
||||
IllegalArgumentException("Offset must be greater than 0");
|
||||
}
|
||||
if (numComponents < 1) {
|
||||
throw new IllegalArgumentException("Number of components must "+
|
||||
" be at least 1");
|
||||
}
|
||||
this.numComponents = numComponents;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of components in the lookup table.
|
||||
* @return the number of components in this <code>LookupTable</code>.
|
||||
*/
|
||||
public int getNumComponents() {
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset.
|
||||
* @return the offset of this <code>LookupTable</code>.
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>int</code> array of components for
|
||||
* one pixel. The <code>dest</code> array contains the
|
||||
* result of the lookup and is returned. If dest is
|
||||
* <code>null</code>, a new array is allocated. The
|
||||
* source and destination can be equal.
|
||||
* @param src the source array of components of one pixel
|
||||
* @param dest the destination array of components for one pixel,
|
||||
* translated with this <code>LookupTable</code>
|
||||
* @return an <code>int</code> array of components for one
|
||||
* pixel.
|
||||
*/
|
||||
public abstract int[] lookupPixel(int[] src, int[] dest);
|
||||
|
||||
}
|
||||
571
jdkSrc/jdk8/java/awt/image/MemoryImageSource.java
Normal file
571
jdkSrc/jdk8/java/awt/image/MemoryImageSource.java
Normal file
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* This class is an implementation of the ImageProducer interface which
|
||||
* uses an array to produce pixel values for an Image. Here is an example
|
||||
* which calculates a 100x100 image representing a fade from black to blue
|
||||
* along the X axis and a fade from black to red along the Y axis:
|
||||
* <pre>{@code
|
||||
*
|
||||
* int w = 100;
|
||||
* int h = 100;
|
||||
* int pix[] = new int[w * h];
|
||||
* int index = 0;
|
||||
* for (int y = 0; y < h; y++) {
|
||||
* int red = (y * 255) / (h - 1);
|
||||
* for (int x = 0; x < w; x++) {
|
||||
* int blue = (x * 255) / (w - 1);
|
||||
* pix[index++] = (255 << 24) | (red << 16) | blue;
|
||||
* }
|
||||
* }
|
||||
* Image img = createImage(new MemoryImageSource(w, h, pix, 0, w));
|
||||
*
|
||||
* }</pre>
|
||||
* The MemoryImageSource is also capable of managing a memory image which
|
||||
* varies over time to allow animation or custom rendering. Here is an
|
||||
* example showing how to set up the animation source and signal changes
|
||||
* in the data (adapted from the MemoryAnimationSourceDemo by Garth Dickie):
|
||||
* <pre>{@code
|
||||
*
|
||||
* int pixels[];
|
||||
* MemoryImageSource source;
|
||||
*
|
||||
* public void init() {
|
||||
* int width = 50;
|
||||
* int height = 50;
|
||||
* int size = width * height;
|
||||
* pixels = new int[size];
|
||||
*
|
||||
* int value = getBackground().getRGB();
|
||||
* for (int i = 0; i < size; i++) {
|
||||
* pixels[i] = value;
|
||||
* }
|
||||
*
|
||||
* source = new MemoryImageSource(width, height, pixels, 0, width);
|
||||
* source.setAnimated(true);
|
||||
* image = createImage(source);
|
||||
* }
|
||||
*
|
||||
* public void run() {
|
||||
* Thread me = Thread.currentThread( );
|
||||
* me.setPriority(Thread.MIN_PRIORITY);
|
||||
*
|
||||
* while (true) {
|
||||
* try {
|
||||
* Thread.sleep(10);
|
||||
* } catch( InterruptedException e ) {
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* // Modify the values in the pixels array at (x, y, w, h)
|
||||
*
|
||||
* // Send the new data to the interested ImageConsumers
|
||||
* source.newPixels(x, y, w, h);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ImageProducer
|
||||
*
|
||||
* @author Jim Graham
|
||||
* @author Animation capabilities inspired by the
|
||||
* MemoryAnimationSource class written by Garth Dickie
|
||||
*/
|
||||
public class MemoryImageSource implements ImageProducer {
|
||||
int width;
|
||||
int height;
|
||||
ColorModel model;
|
||||
Object pixels;
|
||||
int pixeloffset;
|
||||
int pixelscan;
|
||||
Hashtable properties;
|
||||
Vector theConsumers = new Vector();
|
||||
boolean animating;
|
||||
boolean fullbuffers;
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object which uses an array of bytes
|
||||
* to produce data for an Image object.
|
||||
* @param w the width of the rectangle of pixels
|
||||
* @param h the height of the rectangle of pixels
|
||||
* @param cm the specified <code>ColorModel</code>
|
||||
* @param pix an array of pixels
|
||||
* @param off the offset into the array of where to store the
|
||||
* first pixel
|
||||
* @param scan the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @see java.awt.Component#createImage
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm,
|
||||
byte[] pix, int off, int scan) {
|
||||
initialize(w, h, cm, (Object) pix, off, scan, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object which uses an array of bytes
|
||||
* to produce data for an Image object.
|
||||
* @param w the width of the rectangle of pixels
|
||||
* @param h the height of the rectangle of pixels
|
||||
* @param cm the specified <code>ColorModel</code>
|
||||
* @param pix an array of pixels
|
||||
* @param off the offset into the array of where to store the
|
||||
* first pixel
|
||||
* @param scan the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @param props a list of properties that the <code>ImageProducer</code>
|
||||
* uses to process an image
|
||||
* @see java.awt.Component#createImage
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm,
|
||||
byte[] pix, int off, int scan,
|
||||
Hashtable<?,?> props)
|
||||
{
|
||||
initialize(w, h, cm, (Object) pix, off, scan, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object which uses an array of integers
|
||||
* to produce data for an Image object.
|
||||
* @param w the width of the rectangle of pixels
|
||||
* @param h the height of the rectangle of pixels
|
||||
* @param cm the specified <code>ColorModel</code>
|
||||
* @param pix an array of pixels
|
||||
* @param off the offset into the array of where to store the
|
||||
* first pixel
|
||||
* @param scan the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @see java.awt.Component#createImage
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm,
|
||||
int[] pix, int off, int scan) {
|
||||
initialize(w, h, cm, (Object) pix, off, scan, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object which uses an array of integers
|
||||
* to produce data for an Image object.
|
||||
* @param w the width of the rectangle of pixels
|
||||
* @param h the height of the rectangle of pixels
|
||||
* @param cm the specified <code>ColorModel</code>
|
||||
* @param pix an array of pixels
|
||||
* @param off the offset into the array of where to store the
|
||||
* first pixel
|
||||
* @param scan the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @param props a list of properties that the <code>ImageProducer</code>
|
||||
* uses to process an image
|
||||
* @see java.awt.Component#createImage
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, ColorModel cm,
|
||||
int[] pix, int off, int scan,
|
||||
Hashtable<?,?> props)
|
||||
{
|
||||
initialize(w, h, cm, (Object) pix, off, scan, props);
|
||||
}
|
||||
|
||||
private void initialize(int w, int h, ColorModel cm,
|
||||
Object pix, int off, int scan, Hashtable props) {
|
||||
width = w;
|
||||
height = h;
|
||||
model = cm;
|
||||
pixels = pix;
|
||||
pixeloffset = off;
|
||||
pixelscan = scan;
|
||||
if (props == null) {
|
||||
props = new Hashtable();
|
||||
}
|
||||
properties = props;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object which uses an array of integers
|
||||
* in the default RGB ColorModel to produce data for an Image object.
|
||||
* @param w the width of the rectangle of pixels
|
||||
* @param h the height of the rectangle of pixels
|
||||
* @param pix an array of pixels
|
||||
* @param off the offset into the array of where to store the
|
||||
* first pixel
|
||||
* @param scan the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @see java.awt.Component#createImage
|
||||
* @see ColorModel#getRGBdefault
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
|
||||
initialize(w, h, ColorModel.getRGBdefault(),
|
||||
(Object) pix, off, scan, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ImageProducer object which uses an array of integers
|
||||
* in the default RGB ColorModel to produce data for an Image object.
|
||||
* @param w the width of the rectangle of pixels
|
||||
* @param h the height of the rectangle of pixels
|
||||
* @param pix an array of pixels
|
||||
* @param off the offset into the array of where to store the
|
||||
* first pixel
|
||||
* @param scan the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @param props a list of properties that the <code>ImageProducer</code>
|
||||
* uses to process an image
|
||||
* @see java.awt.Component#createImage
|
||||
* @see ColorModel#getRGBdefault
|
||||
*/
|
||||
public MemoryImageSource(int w, int h, int pix[], int off, int scan,
|
||||
Hashtable<?,?> props)
|
||||
{
|
||||
initialize(w, h, ColorModel.getRGBdefault(),
|
||||
(Object) pix, off, scan, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @throws NullPointerException if the specified
|
||||
* <code>ImageConsumer</code> is null
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic) {
|
||||
if (theConsumers.contains(ic)) {
|
||||
return;
|
||||
}
|
||||
theConsumers.addElement(ic);
|
||||
try {
|
||||
initConsumer(ic);
|
||||
sendPixels(ic, 0, 0, width, height);
|
||||
if (isConsumer(ic)) {
|
||||
ic.imageComplete(animating
|
||||
? ImageConsumer.SINGLEFRAMEDONE
|
||||
: ImageConsumer.STATICIMAGEDONE);
|
||||
if (!animating && isConsumer(ic)) {
|
||||
ic.imageComplete(ImageConsumer.IMAGEERROR);
|
||||
removeConsumer(ic);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (isConsumer(ic)) {
|
||||
ic.imageComplete(ImageConsumer.IMAGEERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an ImageConsumer is on the list of consumers currently
|
||||
* interested in data for this image.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @return <code>true</code> if the <code>ImageConsumer</code>
|
||||
* is on the list; <code>false</code> otherwise.
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic) {
|
||||
return theConsumers.contains(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an ImageConsumer from the list of consumers interested in
|
||||
* data for this image.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic) {
|
||||
theConsumers.removeElement(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image and immediately starts delivery of the
|
||||
* image data through the ImageConsumer interface.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* image data through the ImageConsumer interface.
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public void startProduction(ImageConsumer ic) {
|
||||
addConsumer(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a given ImageConsumer have the image data delivered
|
||||
* one more time in top-down, left-right order.
|
||||
* @param ic the specified <code>ImageConsumer</code>
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic) {
|
||||
// Ignored. The data is either single frame and already in TDLR
|
||||
// format or it is multi-frame and TDLR resends aren't critical.
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes this memory image into a multi-frame animation or a
|
||||
* single-frame static image depending on the animated parameter.
|
||||
* <p>This method should be called immediately after the
|
||||
* MemoryImageSource is constructed and before an image is
|
||||
* created with it to ensure that all ImageConsumers will
|
||||
* receive the correct multi-frame data. If an ImageConsumer
|
||||
* is added to this ImageProducer before this flag is set then
|
||||
* that ImageConsumer will see only a snapshot of the pixel
|
||||
* data that was available when it connected.
|
||||
* @param animated <code>true</code> if the image is a
|
||||
* multi-frame animation
|
||||
*/
|
||||
public synchronized void setAnimated(boolean animated) {
|
||||
this.animating = animated;
|
||||
if (!animating) {
|
||||
Enumeration enum_ = theConsumers.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
ImageConsumer ic = (ImageConsumer) enum_.nextElement();
|
||||
ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
if (isConsumer(ic)) {
|
||||
ic.imageComplete(ImageConsumer.IMAGEERROR);
|
||||
}
|
||||
}
|
||||
theConsumers.removeAllElements();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether this animated memory image should always be
|
||||
* updated by sending the complete buffer of pixels whenever
|
||||
* there is a change.
|
||||
* This flag is ignored if the animation flag is not turned on
|
||||
* through the setAnimated() method.
|
||||
* <p>This method should be called immediately after the
|
||||
* MemoryImageSource is constructed and before an image is
|
||||
* created with it to ensure that all ImageConsumers will
|
||||
* receive the correct pixel delivery hints.
|
||||
* @param fullbuffers <code>true</code> if the complete pixel
|
||||
* buffer should always
|
||||
* be sent
|
||||
* @see #setAnimated
|
||||
*/
|
||||
public synchronized void setFullBufferUpdates(boolean fullbuffers) {
|
||||
if (this.fullbuffers == fullbuffers) {
|
||||
return;
|
||||
}
|
||||
this.fullbuffers = fullbuffers;
|
||||
if (animating) {
|
||||
Enumeration enum_ = theConsumers.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
ImageConsumer ic = (ImageConsumer) enum_.nextElement();
|
||||
ic.setHints(fullbuffers
|
||||
? (ImageConsumer.TOPDOWNLEFTRIGHT |
|
||||
ImageConsumer.COMPLETESCANLINES)
|
||||
: ImageConsumer.RANDOMPIXELORDER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a whole new buffer of pixels to any ImageConsumers that
|
||||
* are currently interested in the data for this image and notify
|
||||
* them that an animation frame is complete.
|
||||
* This method only has effect if the animation flag has been
|
||||
* turned on through the setAnimated() method.
|
||||
* @see #newPixels(int, int, int, int, boolean)
|
||||
* @see ImageConsumer
|
||||
* @see #setAnimated
|
||||
*/
|
||||
public void newPixels() {
|
||||
newPixels(0, 0, width, height, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a rectangular region of the buffer of pixels to any
|
||||
* ImageConsumers that are currently interested in the data for
|
||||
* this image and notify them that an animation frame is complete.
|
||||
* This method only has effect if the animation flag has been
|
||||
* turned on through the setAnimated() method.
|
||||
* If the full buffer update flag was turned on with the
|
||||
* setFullBufferUpdates() method then the rectangle parameters
|
||||
* will be ignored and the entire buffer will always be sent.
|
||||
* @param x the x coordinate of the upper left corner of the rectangle
|
||||
* of pixels to be sent
|
||||
* @param y the y coordinate of the upper left corner of the rectangle
|
||||
* of pixels to be sent
|
||||
* @param w the width of the rectangle of pixels to be sent
|
||||
* @param h the height of the rectangle of pixels to be sent
|
||||
* @see #newPixels(int, int, int, int, boolean)
|
||||
* @see ImageConsumer
|
||||
* @see #setAnimated
|
||||
* @see #setFullBufferUpdates
|
||||
*/
|
||||
public synchronized void newPixels(int x, int y, int w, int h) {
|
||||
newPixels(x, y, w, h, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a rectangular region of the buffer of pixels to any
|
||||
* ImageConsumers that are currently interested in the data for
|
||||
* this image.
|
||||
* If the framenotify parameter is true then the consumers are
|
||||
* also notified that an animation frame is complete.
|
||||
* This method only has effect if the animation flag has been
|
||||
* turned on through the setAnimated() method.
|
||||
* If the full buffer update flag was turned on with the
|
||||
* setFullBufferUpdates() method then the rectangle parameters
|
||||
* will be ignored and the entire buffer will always be sent.
|
||||
* @param x the x coordinate of the upper left corner of the rectangle
|
||||
* of pixels to be sent
|
||||
* @param y the y coordinate of the upper left corner of the rectangle
|
||||
* of pixels to be sent
|
||||
* @param w the width of the rectangle of pixels to be sent
|
||||
* @param h the height of the rectangle of pixels to be sent
|
||||
* @param framenotify <code>true</code> if the consumers should be sent a
|
||||
* {@link ImageConsumer#SINGLEFRAMEDONE SINGLEFRAMEDONE} notification
|
||||
* @see ImageConsumer
|
||||
* @see #setAnimated
|
||||
* @see #setFullBufferUpdates
|
||||
*/
|
||||
public synchronized void newPixels(int x, int y, int w, int h,
|
||||
boolean framenotify) {
|
||||
if (animating) {
|
||||
if (fullbuffers) {
|
||||
x = y = 0;
|
||||
w = width;
|
||||
h = height;
|
||||
} else {
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (x + w > width) {
|
||||
w = width - x;
|
||||
}
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (y + h > height) {
|
||||
h = height - y;
|
||||
}
|
||||
}
|
||||
if ((w <= 0 || h <= 0) && !framenotify) {
|
||||
return;
|
||||
}
|
||||
Enumeration enum_ = theConsumers.elements();
|
||||
while (enum_.hasMoreElements()) {
|
||||
ImageConsumer ic = (ImageConsumer) enum_.nextElement();
|
||||
if (w > 0 && h > 0) {
|
||||
sendPixels(ic, x, y, w, h);
|
||||
}
|
||||
if (framenotify && isConsumer(ic)) {
|
||||
ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes to a new byte array to hold the pixels for this image.
|
||||
* If the animation flag has been turned on through the setAnimated()
|
||||
* method, then the new pixels will be immediately delivered to any
|
||||
* ImageConsumers that are currently interested in the data for
|
||||
* this image.
|
||||
* @param newpix the new pixel array
|
||||
* @param newmodel the specified <code>ColorModel</code>
|
||||
* @param offset the offset into the array
|
||||
* @param scansize the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @see #newPixels(int, int, int, int, boolean)
|
||||
* @see #setAnimated
|
||||
*/
|
||||
public synchronized void newPixels(byte[] newpix, ColorModel newmodel,
|
||||
int offset, int scansize) {
|
||||
this.pixels = newpix;
|
||||
this.model = newmodel;
|
||||
this.pixeloffset = offset;
|
||||
this.pixelscan = scansize;
|
||||
newPixels();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes to a new int array to hold the pixels for this image.
|
||||
* If the animation flag has been turned on through the setAnimated()
|
||||
* method, then the new pixels will be immediately delivered to any
|
||||
* ImageConsumers that are currently interested in the data for
|
||||
* this image.
|
||||
* @param newpix the new pixel array
|
||||
* @param newmodel the specified <code>ColorModel</code>
|
||||
* @param offset the offset into the array
|
||||
* @param scansize the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @see #newPixels(int, int, int, int, boolean)
|
||||
* @see #setAnimated
|
||||
*/
|
||||
public synchronized void newPixels(int[] newpix, ColorModel newmodel,
|
||||
int offset, int scansize) {
|
||||
this.pixels = newpix;
|
||||
this.model = newmodel;
|
||||
this.pixeloffset = offset;
|
||||
this.pixelscan = scansize;
|
||||
newPixels();
|
||||
}
|
||||
|
||||
private void initConsumer(ImageConsumer ic) {
|
||||
if (isConsumer(ic)) {
|
||||
ic.setDimensions(width, height);
|
||||
}
|
||||
if (isConsumer(ic)) {
|
||||
ic.setProperties(properties);
|
||||
}
|
||||
if (isConsumer(ic)) {
|
||||
ic.setColorModel(model);
|
||||
}
|
||||
if (isConsumer(ic)) {
|
||||
ic.setHints(animating
|
||||
? (fullbuffers
|
||||
? (ImageConsumer.TOPDOWNLEFTRIGHT |
|
||||
ImageConsumer.COMPLETESCANLINES)
|
||||
: ImageConsumer.RANDOMPIXELORDER)
|
||||
: (ImageConsumer.TOPDOWNLEFTRIGHT |
|
||||
ImageConsumer.COMPLETESCANLINES |
|
||||
ImageConsumer.SINGLEPASS |
|
||||
ImageConsumer.SINGLEFRAME));
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPixels(ImageConsumer ic, int x, int y, int w, int h) {
|
||||
int off = pixeloffset + pixelscan * y + x;
|
||||
if (isConsumer(ic)) {
|
||||
if (pixels instanceof byte[]) {
|
||||
ic.setPixels(x, y, w, h, model,
|
||||
((byte[]) pixels), off, pixelscan);
|
||||
} else {
|
||||
ic.setPixels(x, y, w, h, model,
|
||||
((int[]) pixels), off, pixelscan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
699
jdkSrc/jdk8/java/awt/image/MultiPixelPackedSampleModel.java
Normal file
699
jdkSrc/jdk8/java/awt/image/MultiPixelPackedSampleModel.java
Normal file
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* The <code>MultiPixelPackedSampleModel</code> class represents
|
||||
* one-banded images and can pack multiple one-sample
|
||||
* pixels into one data element. Pixels are not allowed to span data elements.
|
||||
* The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
|
||||
* or DataBuffer.TYPE_INT. Each pixel must be a power of 2 number of bits
|
||||
* and a power of 2 number of pixels must fit exactly in one data element.
|
||||
* Pixel bit stride is equal to the number of bits per pixel. Scanline
|
||||
* stride is in data elements and the last several data elements might be
|
||||
* padded with unused pixels. Data bit offset is the offset in bits from
|
||||
* the beginning of the {@link DataBuffer} to the first pixel and must be
|
||||
* a multiple of pixel bit stride.
|
||||
* <p>
|
||||
* The following code illustrates extracting the bits for pixel
|
||||
* <code>x, y</code> from <code>DataBuffer</code> <code>data</code>
|
||||
* and storing the pixel data in data elements of type
|
||||
* <code>dataType</code>:
|
||||
* <pre>{@code
|
||||
* int dataElementSize = DataBuffer.getDataTypeSize(dataType);
|
||||
* int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
* int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
* int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
* - pixelBitStride;
|
||||
* int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
|
||||
* }</pre>
|
||||
*/
|
||||
|
||||
public class MultiPixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
/** The number of bits from one pixel to the next. */
|
||||
int pixelBitStride;
|
||||
|
||||
/** Bitmask that extracts the rightmost pixel of a data element. */
|
||||
int bitMask;
|
||||
|
||||
/**
|
||||
* The number of pixels that fit in a data element. Also used
|
||||
* as the number of bits per pixel.
|
||||
*/
|
||||
int pixelsPerDataElement;
|
||||
|
||||
/** The size of a data element in bits. */
|
||||
int dataElementSize;
|
||||
|
||||
/** The bit offset into the data array where the first pixel begins.
|
||||
*/
|
||||
int dataBitOffset;
|
||||
|
||||
/** ScanlineStride of the data buffer described in data array elements. */
|
||||
int scanlineStride;
|
||||
|
||||
/**
|
||||
* Constructs a <code>MultiPixelPackedSampleModel</code> with the
|
||||
* specified data type, width, height and number of bits per pixel.
|
||||
* @param dataType the data type for storing samples
|
||||
* @param w the width, in pixels, of the region of
|
||||
* image data described
|
||||
* @param h the height, in pixels, of the region of
|
||||
* image data described
|
||||
* @param numberOfBits the number of bits per pixel
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public MultiPixelPackedSampleModel(int dataType,
|
||||
int w,
|
||||
int h,
|
||||
int numberOfBits) {
|
||||
this(dataType,w,h,
|
||||
numberOfBits,
|
||||
(w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
|
||||
DataBuffer.getDataTypeSize(dataType),
|
||||
0);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>MultiPixelPackedSampleModel</code> with
|
||||
* specified data type, width, height, number of bits per pixel,
|
||||
* scanline stride and data bit offset.
|
||||
* @param dataType the data type for storing samples
|
||||
* @param w the width, in pixels, of the region of
|
||||
* image data described
|
||||
* @param h the height, in pixels, of the region of
|
||||
* image data described
|
||||
* @param numberOfBits the number of bits per pixel
|
||||
* @param scanlineStride the line stride of the image data
|
||||
* @param dataBitOffset the data bit offset for the region of image
|
||||
* data described
|
||||
* @exception RasterFormatException if the number of bits per pixel
|
||||
* is not a power of 2 or if a power of 2 number of
|
||||
* pixels do not fit in one data element.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public MultiPixelPackedSampleModel(int dataType, int w, int h,
|
||||
int numberOfBits,
|
||||
int scanlineStride,
|
||||
int dataBitOffset) {
|
||||
super(dataType, w, h, 1);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
this.pixelBitStride = numberOfBits;
|
||||
this.scanlineStride = scanlineStride;
|
||||
this.dataBitOffset = dataBitOffset;
|
||||
this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
|
||||
this.pixelsPerDataElement = dataElementSize/numberOfBits;
|
||||
if (pixelsPerDataElement*numberOfBits != dataElementSize) {
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel " +
|
||||
"does not allow pixels to " +
|
||||
"span data element boundaries");
|
||||
}
|
||||
this.bitMask = (1 << numberOfBits) - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>MultiPixelPackedSampleModel</code> with the
|
||||
* specified width and height. The new
|
||||
* <code>MultiPixelPackedSampleModel</code> has the
|
||||
* same storage data type and number of bits per pixel as this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
* @param w the specified width
|
||||
* @param h the specified height
|
||||
* @return a {@link SampleModel} with the specified width and height
|
||||
* and with the same storage data type and number of bits per pixel
|
||||
* as this <code>MultiPixelPackedSampleModel</code>.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
SampleModel sampleModel =
|
||||
new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>DataBuffer</code> that corresponds to this
|
||||
* <code>MultiPixelPackedSampleModel</code>. The
|
||||
* <code>DataBuffer</code> object's data type and size
|
||||
* is consistent with this <code>MultiPixelPackedSampleModel</code>.
|
||||
* The <code>DataBuffer</code> has a single bank.
|
||||
* @return a <code>DataBuffer</code> with the same data type and
|
||||
* size as this <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = (int)scanlineStride*height;
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
|
||||
break;
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data elements needed to transfer one pixel
|
||||
* via the {@link #getDataElements} and {@link #setDataElements}
|
||||
* methods. For a <code>MultiPixelPackedSampleModel</code>, this is
|
||||
* one.
|
||||
* @return the number of data elements.
|
||||
*/
|
||||
public int getNumDataElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits per sample for all bands.
|
||||
* @return the number of bits per sample.
|
||||
*/
|
||||
public int[] getSampleSize() {
|
||||
int sampleSize[] = {pixelBitStride};
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits per sample for the specified band.
|
||||
* @param band the specified band
|
||||
* @return the number of bits per sample for the specified band.
|
||||
*/
|
||||
public int getSampleSize(int band) {
|
||||
return pixelBitStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of pixel (x, y) in data array elements.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @return the offset of the specified pixel.
|
||||
*/
|
||||
public int getOffset(int x, int y) {
|
||||
int offset = y * scanlineStride;
|
||||
offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset, in bits, into the data element in which it is
|
||||
* stored for the <code>x</code>th pixel of a scanline.
|
||||
* This offset is the same for all scanlines.
|
||||
* @param x the specified pixel
|
||||
* @return the bit offset of the specified pixel.
|
||||
*/
|
||||
public int getBitOffset(int x){
|
||||
return (x*pixelBitStride+dataBitOffset)%dataElementSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanline stride.
|
||||
* @return the scanline stride of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getScanlineStride() {
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pixel bit stride in bits. This value is the same as
|
||||
* the number of bits per pixel.
|
||||
* @return the <code>pixelBitStride</code> of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getPixelBitStride() {
|
||||
return pixelBitStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data bit offset in bits.
|
||||
* @return the <code>dataBitOffset</code> of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getDataBitOffset() {
|
||||
return dataBitOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TransferType used to transfer pixels by way of the
|
||||
* <code>getDataElements</code> and <code>setDataElements</code>
|
||||
* methods. The TransferType might or might not be the same as the
|
||||
* storage DataType. The TransferType is one of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
|
||||
* or DataBuffer.TYPE_INT.
|
||||
* @return the transfertype.
|
||||
*/
|
||||
public int getTransferType() {
|
||||
if (pixelBitStride > 16)
|
||||
return DataBuffer.TYPE_INT;
|
||||
else if (pixelBitStride > 8)
|
||||
return DataBuffer.TYPE_USHORT;
|
||||
else
|
||||
return DataBuffer.TYPE_BYTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>MultiPixelPackedSampleModel</code> with a
|
||||
* subset of the bands of this
|
||||
* <code>MultiPixelPackedSampleModel</code>. Since a
|
||||
* <code>MultiPixelPackedSampleModel</code> only has one band, the
|
||||
* bands argument must have a length of one and indicate the zeroth
|
||||
* band.
|
||||
* @param bands the specified bands
|
||||
* @return a new <code>SampleModel</code> with a subset of bands of
|
||||
* this <code>MultiPixelPackedSampleModel</code>.
|
||||
* @exception RasterFormatException if the number of bands requested
|
||||
* is not one.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands != null) {
|
||||
if (bands.length != 1)
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel has "
|
||||
+ "only one band.");
|
||||
}
|
||||
SampleModel sm = createCompatibleSampleModel(width, height);
|
||||
return sm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as <code>int</code> the sample in a specified band for the
|
||||
* pixel located at (x, y). An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param b the band to return, which is assumed to be 0
|
||||
* @param data the <code>DataBuffer</code> containing the image
|
||||
* data
|
||||
* @return the specified band containing the sample of the specified
|
||||
* pixel.
|
||||
* @exception ArrayIndexOutOfBoundsException if the specified
|
||||
* coordinates are not in bounds.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// 'b' must be 0
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
|
||||
(b != 0)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
return (element >> shift) & bitMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at
|
||||
* (x, y) in the <code>DataBuffer</code> using an
|
||||
* <code>int</code> for input.
|
||||
* An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param b the band to return, which is assumed to be 0
|
||||
* @param s the input sample as an <code>int</code>
|
||||
* @param data the <code>DataBuffer</code> where image data is stored
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates are
|
||||
* not in bounds.
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// 'b' must be 0
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
|
||||
(b != 0)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
element |= (s & bitMask) << shift;
|
||||
data.setElem(index,element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
|
||||
* the array has one element, and the type is the smallest of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
|
||||
* that can hold a single pixel. Generally, <code>obj</code>
|
||||
* should be passed in as <code>null</code>, so that the
|
||||
* <code>Object</code> is created automatically and is the
|
||||
* correct primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
|
||||
* described by <code>MultiPixelPackedSampleModel</code>
|
||||
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
|
||||
* The transfer is generally more efficient than using
|
||||
* <code>getPixel</code> or <code>setPixel</code>.
|
||||
* <pre>
|
||||
* MultiPixelPackedSampleModel mppsm1, mppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using <code>getDataElements</code> or <code>setDataElements</code>
|
||||
* to transfer between two <code>DataBuffer/SampleModel</code> pairs
|
||||
* is legitimate if the <code>SampleModels</code> have the same number
|
||||
* of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If <code>obj</code> is not <code>null</code>, it should be a
|
||||
* primitive array of type TransferType. Otherwise, a
|
||||
* <code>ClassCastException</code> is thrown. An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds, or if <code>obj</code> is not
|
||||
* <code>null</code> and is not large enough to hold the pixel data.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param obj a primitive array in which to return the pixel data or
|
||||
* <code>null</code>.
|
||||
* @param data the <code>DataBuffer</code> containing the image data.
|
||||
* @return an <code>Object</code> containing data for the specified
|
||||
* pixel.
|
||||
* @exception ClassCastException if <code>obj</code> is not a
|
||||
* primitive array of type TransferType or is not <code>null</code>
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates are
|
||||
* not in bounds, or if <code>obj</code> is not <code>null</code> or
|
||||
* not large enough to hold the pixel data
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = 0;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null)
|
||||
bdata = new byte[1];
|
||||
else
|
||||
bdata = (byte[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
bdata[0] = (byte)((element >> shift) & bitMask);
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null)
|
||||
sdata = new short[1];
|
||||
else
|
||||
sdata = (short[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
sdata[0] = (short)((element >> shift) & bitMask);
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null)
|
||||
idata = new int[1];
|
||||
else
|
||||
idata = (int[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
idata[0] = (element >> shift) & bitMask;
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified single band pixel in the first element
|
||||
* of an <code>int</code> array.
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param iArray the array containing the pixel to be returned or
|
||||
* <code>null</code>
|
||||
* @param data the <code>DataBuffer</code> where image data is stored
|
||||
* @return an array containing the specified pixel.
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates
|
||||
* are not in bounds
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [numBands];
|
||||
}
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
pixels[0] = (element >> shift) & bitMask;
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified
|
||||
* <code>DataBuffer</code> from a primitive array of type
|
||||
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
|
||||
* only the first element of the array holds valid data,
|
||||
* and the type must be the smallest of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
|
||||
* that can hold a single pixel.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
|
||||
* described by <code>MultiPixelPackedSampleModel</code>
|
||||
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
|
||||
* The transfer is generally more efficient than using
|
||||
* <code>getPixel</code> or <code>setPixel</code>.
|
||||
* <pre>
|
||||
* MultiPixelPackedSampleModel mppsm1, mppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using <code>getDataElements</code> or <code>setDataElements</code> to
|
||||
* transfer between two <code>DataBuffer/SampleModel</code> pairs is
|
||||
* legitimate if the <code>SampleModel</code> objects have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* <code>obj</code> must be a primitive array of type TransferType.
|
||||
* Otherwise, a <code>ClassCastException</code> is thrown. An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds, or if <code>obj</code> is not large
|
||||
* enough to hold the pixel data.
|
||||
* @param x the X coordinate of the pixel location
|
||||
* @param y the Y coordinate of the pixel location
|
||||
* @param obj a primitive array containing pixel data
|
||||
* @param data the <code>DataBuffer</code> containing the image data
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
element |= (iarray[0] & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the <code>DataBuffer</code> using an
|
||||
* <code>int</code> array for input.
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if
|
||||
* the coordinates are not in bounds.
|
||||
* @param x the X coordinate of the pixel location
|
||||
* @param y the Y coordinate of the pixel location
|
||||
* @param iArray the input pixel in an <code>int</code> array
|
||||
* @param data the <code>DataBuffer</code> containing the image data
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
element |= (iArray[0] & bitMask) << shift;
|
||||
data.setElem(index,element);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
|
||||
return this.width == that.width &&
|
||||
this.height == that.height &&
|
||||
this.numBands == that.numBands &&
|
||||
this.dataType == that.dataType &&
|
||||
this.pixelBitStride == that.pixelBitStride &&
|
||||
this.bitMask == that.bitMask &&
|
||||
this.pixelsPerDataElement == that.pixelsPerDataElement &&
|
||||
this.dataElementSize == that.dataElementSize &&
|
||||
this.dataBitOffset == that.dataBitOffset &&
|
||||
this.scanlineStride == that.scanlineStride;
|
||||
}
|
||||
|
||||
// If we implement equals() we must also implement hashCode
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
hash = width;
|
||||
hash <<= 8;
|
||||
hash ^= height;
|
||||
hash <<= 8;
|
||||
hash ^= numBands;
|
||||
hash <<= 8;
|
||||
hash ^= dataType;
|
||||
hash <<= 8;
|
||||
hash ^= pixelBitStride;
|
||||
hash <<= 8;
|
||||
hash ^= bitMask;
|
||||
hash <<= 8;
|
||||
hash ^= pixelsPerDataElement;
|
||||
hash <<= 8;
|
||||
hash ^= dataElementSize;
|
||||
hash <<= 8;
|
||||
hash ^= dataBitOffset;
|
||||
hash <<= 8;
|
||||
hash ^= scanlineStride;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
486
jdkSrc/jdk8/java/awt/image/PackedColorModel.java
Normal file
486
jdkSrc/jdk8/java/awt/image/PackedColorModel.java
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
|
||||
/**
|
||||
* The <code>PackedColorModel</code> class is an abstract
|
||||
* {@link ColorModel} class that works with pixel values which represent
|
||||
* color and alpha information as separate samples and which pack all
|
||||
* samples for a single pixel into a single int, short, or byte quantity.
|
||||
* This class can be used with an arbitrary {@link ColorSpace}. The number of
|
||||
* color samples in the pixel values must be the same as the number of color
|
||||
* components in the <code>ColorSpace</code>. There can be a single alpha
|
||||
* sample. The array length is always 1 for those methods that use a
|
||||
* primitive array pixel representation of type <code>transferType</code>.
|
||||
* The transfer types supported are DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, and DataBuffer.TYPE_INT.
|
||||
* Color and alpha samples are stored in the single element of the array
|
||||
* in bits indicated by bit masks. Each bit mask must be contiguous and
|
||||
* masks must not overlap. The same masks apply to the single int
|
||||
* pixel representation used by other methods. The correspondence of
|
||||
* masks and color/alpha samples is as follows:
|
||||
* <ul>
|
||||
* <li> Masks are identified by indices running from 0 through
|
||||
* {@link ColorModel#getNumComponents() getNumComponents} - 1.
|
||||
* <li> The first
|
||||
* {@link ColorModel#getNumColorComponents() getNumColorComponents}
|
||||
* indices refer to color samples.
|
||||
* <li> If an alpha sample is present, it corresponds the last index.
|
||||
* <li> The order of the color indices is specified
|
||||
* by the <code>ColorSpace</code>. Typically, this reflects the name of
|
||||
* the color space type (for example, TYPE_RGB), index 0
|
||||
* corresponds to red, index 1 to green, and index 2 to blue.
|
||||
* </ul>
|
||||
* <p>
|
||||
* The translation from pixel values to color/alpha components for
|
||||
* display or processing purposes is a one-to-one correspondence of
|
||||
* samples to components.
|
||||
* A <code>PackedColorModel</code> is typically used with image data
|
||||
* that uses masks to define packed samples. For example, a
|
||||
* <code>PackedColorModel</code> can be used in conjunction with a
|
||||
* {@link SinglePixelPackedSampleModel} to construct a
|
||||
* {@link BufferedImage}. Normally the masks used by the
|
||||
* {@link SampleModel} and the <code>ColorModel</code> would be the same.
|
||||
* However, if they are different, the color interpretation of pixel data is
|
||||
* done according to the masks of the <code>ColorModel</code>.
|
||||
* <p>
|
||||
* A single <code>int</code> pixel representation is valid for all objects
|
||||
* of this class since it is always possible to represent pixel values
|
||||
* used with this class in a single <code>int</code>. Therefore, methods
|
||||
* that use this representation do not throw an
|
||||
* <code>IllegalArgumentException</code> due to an invalid pixel value.
|
||||
* <p>
|
||||
* A subclass of <code>PackedColorModel</code> is {@link DirectColorModel},
|
||||
* which is similar to an X11 TrueColor visual.
|
||||
*
|
||||
* @see DirectColorModel
|
||||
* @see SinglePixelPackedSampleModel
|
||||
* @see BufferedImage
|
||||
*/
|
||||
|
||||
public abstract class PackedColorModel extends ColorModel {
|
||||
int[] maskArray;
|
||||
int[] maskOffsets;
|
||||
float[] scaleFactors;
|
||||
|
||||
/**
|
||||
* Constructs a <code>PackedColorModel</code> from a color mask array,
|
||||
* which specifies which bits in an <code>int</code> pixel representation
|
||||
* contain each of the color samples, and an alpha mask. Color
|
||||
* components are in the specified <code>ColorSpace</code>. The length of
|
||||
* <code>colorMaskArray</code> should be the number of components in
|
||||
* the <code>ColorSpace</code>. All of the bits in each mask
|
||||
* must be contiguous and fit in the specified number of least significant
|
||||
* bits of an <code>int</code> pixel representation. If the
|
||||
* <code>alphaMask</code> is 0, there is no alpha. If there is alpha,
|
||||
* the <code>boolean</code> <code>isAlphaPremultiplied</code> specifies
|
||||
* how to interpret color and alpha samples in pixel values. If the
|
||||
* <code>boolean</code> is <code>true</code>, color samples are assumed
|
||||
* to have been multiplied by the alpha sample. The transparency,
|
||||
* <code>trans</code>, specifies what alpha values can be represented
|
||||
* by this color model. The transfer type is the type of primitive
|
||||
* array used to represent pixel values.
|
||||
* @param space the specified <code>ColorSpace</code>
|
||||
* @param bits the number of bits in the pixel values
|
||||
* @param colorMaskArray array that specifies the masks representing
|
||||
* the bits of the pixel values that represent the color
|
||||
* components
|
||||
* @param alphaMask specifies the mask representing
|
||||
* the bits of the pixel values that represent the alpha
|
||||
* component
|
||||
* @param isAlphaPremultiplied <code>true</code> if color samples are
|
||||
* premultiplied by the alpha sample; <code>false</code> otherwise
|
||||
* @param trans specifies the alpha value that can be represented by
|
||||
* this color model
|
||||
* @param transferType the type of array used to represent pixel values
|
||||
* @throws IllegalArgumentException if <code>bits</code> is less than
|
||||
* 1 or greater than 32
|
||||
*/
|
||||
public PackedColorModel (ColorSpace space, int bits,
|
||||
int[] colorMaskArray, int alphaMask,
|
||||
boolean isAlphaPremultiplied,
|
||||
int trans, int transferType) {
|
||||
super(bits, PackedColorModel.createBitsArray(colorMaskArray,
|
||||
alphaMask),
|
||||
space, (alphaMask == 0 ? false : true),
|
||||
isAlphaPremultiplied, trans, transferType);
|
||||
if (bits < 1 || bits > 32) {
|
||||
throw new IllegalArgumentException("Number of bits must be between"
|
||||
+" 1 and 32.");
|
||||
}
|
||||
maskArray = new int[numComponents];
|
||||
maskOffsets = new int[numComponents];
|
||||
scaleFactors = new float[numComponents];
|
||||
|
||||
for (int i=0; i < numColorComponents; i++) {
|
||||
// Get the mask offset and #bits
|
||||
DecomposeMask(colorMaskArray[i], i, space.getName(i));
|
||||
}
|
||||
if (alphaMask != 0) {
|
||||
DecomposeMask(alphaMask, numColorComponents, "alpha");
|
||||
if (nBits[numComponents-1] == 1) {
|
||||
transparency = Transparency.BITMASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>PackedColorModel</code> from the specified
|
||||
* masks which indicate which bits in an <code>int</code> pixel
|
||||
* representation contain the alpha, red, green and blue color samples.
|
||||
* Color components are in the specified <code>ColorSpace</code>, which
|
||||
* must be of type ColorSpace.TYPE_RGB. All of the bits in each
|
||||
* mask must be contiguous and fit in the specified number of
|
||||
* least significant bits of an <code>int</code> pixel representation. If
|
||||
* <code>amask</code> is 0, there is no alpha. If there is alpha,
|
||||
* the <code>boolean</code> <code>isAlphaPremultiplied</code>
|
||||
* specifies how to interpret color and alpha samples
|
||||
* in pixel values. If the <code>boolean</code> is <code>true</code>,
|
||||
* color samples are assumed to have been multiplied by the alpha sample.
|
||||
* The transparency, <code>trans</code>, specifies what alpha values
|
||||
* can be represented by this color model.
|
||||
* The transfer type is the type of primitive array used to represent
|
||||
* pixel values.
|
||||
* @param space the specified <code>ColorSpace</code>
|
||||
* @param bits the number of bits in the pixel values
|
||||
* @param rmask specifies the mask representing
|
||||
* the bits of the pixel values that represent the red
|
||||
* color component
|
||||
* @param gmask specifies the mask representing
|
||||
* the bits of the pixel values that represent the green
|
||||
* color component
|
||||
* @param bmask specifies the mask representing
|
||||
* the bits of the pixel values that represent
|
||||
* the blue color component
|
||||
* @param amask specifies the mask representing
|
||||
* the bits of the pixel values that represent
|
||||
* the alpha component
|
||||
* @param isAlphaPremultiplied <code>true</code> if color samples are
|
||||
* premultiplied by the alpha sample; <code>false</code> otherwise
|
||||
* @param trans specifies the alpha value that can be represented by
|
||||
* this color model
|
||||
* @param transferType the type of array used to represent pixel values
|
||||
* @throws IllegalArgumentException if <code>space</code> is not a
|
||||
* TYPE_RGB space
|
||||
* @see ColorSpace
|
||||
*/
|
||||
public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask,
|
||||
int bmask, int amask,
|
||||
boolean isAlphaPremultiplied,
|
||||
int trans, int transferType) {
|
||||
super (bits, PackedColorModel.createBitsArray(rmask, gmask, bmask,
|
||||
amask),
|
||||
space, (amask == 0 ? false : true),
|
||||
isAlphaPremultiplied, trans, transferType);
|
||||
|
||||
if (space.getType() != ColorSpace.TYPE_RGB) {
|
||||
throw new IllegalArgumentException("ColorSpace must be TYPE_RGB.");
|
||||
}
|
||||
maskArray = new int[numComponents];
|
||||
maskOffsets = new int[numComponents];
|
||||
scaleFactors = new float[numComponents];
|
||||
|
||||
DecomposeMask(rmask, 0, "red");
|
||||
|
||||
DecomposeMask(gmask, 1, "green");
|
||||
|
||||
DecomposeMask(bmask, 2, "blue");
|
||||
|
||||
if (amask != 0) {
|
||||
DecomposeMask(amask, 3, "alpha");
|
||||
if (nBits[3] == 1) {
|
||||
transparency = Transparency.BITMASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mask indicating which bits in a pixel
|
||||
* contain the specified color/alpha sample. For color
|
||||
* samples, <code>index</code> corresponds to the placement of color
|
||||
* sample names in the color space. Thus, an <code>index</code>
|
||||
* equal to 0 for a CMYK ColorSpace would correspond to
|
||||
* Cyan and an <code>index</code> equal to 1 would correspond to
|
||||
* Magenta. If there is alpha, the alpha <code>index</code> would be:
|
||||
* <pre>
|
||||
* alphaIndex = numComponents() - 1;
|
||||
* </pre>
|
||||
* @param index the specified color or alpha sample
|
||||
* @return the mask, which indicates which bits of the <code>int</code>
|
||||
* pixel representation contain the color or alpha sample specified
|
||||
* by <code>index</code>.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code> is
|
||||
* greater than the number of components minus 1 in this
|
||||
* <code>PackedColorModel</code> or if <code>index</code> is
|
||||
* less than zero
|
||||
*/
|
||||
final public int getMask(int index) {
|
||||
return maskArray[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mask array indicating which bits in a pixel
|
||||
* contain the color and alpha samples.
|
||||
* @return the mask array , which indicates which bits of the
|
||||
* <code>int</code> pixel
|
||||
* representation contain the color or alpha samples.
|
||||
*/
|
||||
final public int[] getMasks() {
|
||||
return (int[]) maskArray.clone();
|
||||
}
|
||||
|
||||
/*
|
||||
* A utility function to compute the mask offset and scalefactor,
|
||||
* store these and the mask in instance arrays, and verify that
|
||||
* the mask fits in the specified pixel size.
|
||||
*/
|
||||
private void DecomposeMask(int mask, int idx, String componentName) {
|
||||
int off = 0;
|
||||
int count = nBits[idx];
|
||||
|
||||
// Store the mask
|
||||
maskArray[idx] = mask;
|
||||
|
||||
// Now find the shift
|
||||
if (mask != 0) {
|
||||
while ((mask & 1) == 0) {
|
||||
mask >>>= 1;
|
||||
off++;
|
||||
}
|
||||
}
|
||||
|
||||
if (off + count > pixel_bits) {
|
||||
throw new IllegalArgumentException(componentName + " mask "+
|
||||
Integer.toHexString(maskArray[idx])+
|
||||
" overflows pixel (expecting "+
|
||||
pixel_bits+" bits");
|
||||
}
|
||||
|
||||
maskOffsets[idx] = off;
|
||||
if (count == 0) {
|
||||
// High enough to scale any 0-ff value down to 0.0, but not
|
||||
// high enough to get Infinity when scaling back to pixel bits
|
||||
scaleFactors[idx] = 256.0f;
|
||||
} else {
|
||||
scaleFactors[idx] = 255.0f / ((1 << count) - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>SampleModel</code> with the specified width and
|
||||
* height that has a data layout compatible with this
|
||||
* <code>ColorModel</code>.
|
||||
* @param w the width (in pixels) of the region of the image data
|
||||
* described
|
||||
* @param h the height (in pixels) of the region of the image data
|
||||
* described
|
||||
* @return the newly created <code>SampleModel</code>.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @see SampleModel
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
return new SinglePixelPackedSampleModel(transferType, w, h,
|
||||
maskArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified <code>SampleModel</code> is compatible
|
||||
* with this <code>ColorModel</code>. If <code>sm</code> is
|
||||
* <code>null</code>, this method returns <code>false</code>.
|
||||
* @param sm the specified <code>SampleModel</code>,
|
||||
* or <code>null</code>
|
||||
* @return <code>true</code> if the specified <code>SampleModel</code>
|
||||
* is compatible with this <code>ColorModel</code>;
|
||||
* <code>false</code> otherwise.
|
||||
* @see SampleModel
|
||||
*/
|
||||
public boolean isCompatibleSampleModel(SampleModel sm) {
|
||||
if (! (sm instanceof SinglePixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must have the same number of components
|
||||
if (numComponents != sm.getNumBands()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transfer type must be the same
|
||||
if (sm.getTransferType() != transferType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
|
||||
// Now compare the specific masks
|
||||
int[] bitMasks = sppsm.getBitMasks();
|
||||
if (bitMasks.length != maskArray.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* compare 'effective' masks only, i.e. only part of the mask
|
||||
* which fits the capacity of the transfer type.
|
||||
*/
|
||||
int maxMask = (int)((1L << DataBuffer.getDataTypeSize(transferType)) - 1);
|
||||
for (int i=0; i < bitMasks.length; i++) {
|
||||
if ((maxMask & bitMasks[i]) != (maxMask & maskArray[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link WritableRaster} representing the alpha channel of
|
||||
* an image, extracted from the input <code>WritableRaster</code>.
|
||||
* This method assumes that <code>WritableRaster</code> objects
|
||||
* associated with this <code>ColorModel</code> store the alpha band,
|
||||
* if present, as the last band of image data. Returns <code>null</code>
|
||||
* if there is no separate spatial alpha channel associated with this
|
||||
* <code>ColorModel</code>. This method creates a new
|
||||
* <code>WritableRaster</code>, but shares the data array.
|
||||
* @param raster a <code>WritableRaster</code> containing an image
|
||||
* @return a <code>WritableRaster</code> that represents the alpha
|
||||
* channel of the image contained in <code>raster</code>.
|
||||
*/
|
||||
public WritableRaster getAlphaRaster(WritableRaster raster) {
|
||||
if (hasAlpha() == false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int x = raster.getMinX();
|
||||
int y = raster.getMinY();
|
||||
int[] band = new int[1];
|
||||
band[0] = raster.getNumBands() - 1;
|
||||
return raster.createWritableChild(x, y, raster.getWidth(),
|
||||
raster.getHeight(), x, y,
|
||||
band);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the specified <code>Object</code> is an instance
|
||||
* of <code>PackedColorModel</code> and equals this
|
||||
* <code>PackedColorModel</code>.
|
||||
* @param obj the <code>Object</code> to test for equality
|
||||
* @return <code>true</code> if the specified <code>Object</code>
|
||||
* is an instance of <code>PackedColorModel</code> and equals this
|
||||
* <code>PackedColorModel</code>; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof PackedColorModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PackedColorModel cm = (PackedColorModel) obj;
|
||||
int numC = cm.getNumComponents();
|
||||
if (numC != numComponents) {
|
||||
return false;
|
||||
}
|
||||
for(int i=0; i < numC; i++) {
|
||||
if (maskArray[i] != cm.getMask(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private final static int[] createBitsArray(int[]colorMaskArray,
|
||||
int alphaMask) {
|
||||
int numColors = colorMaskArray.length;
|
||||
int numAlpha = (alphaMask == 0 ? 0 : 1);
|
||||
int[] arr = new int[numColors+numAlpha];
|
||||
for (int i=0; i < numColors; i++) {
|
||||
arr[i] = countBits(colorMaskArray[i]);
|
||||
if (arr[i] < 0) {
|
||||
throw new IllegalArgumentException("Noncontiguous color mask ("
|
||||
+ Integer.toHexString(colorMaskArray[i])+
|
||||
"at index "+i);
|
||||
}
|
||||
}
|
||||
if (alphaMask != 0) {
|
||||
arr[numColors] = countBits(alphaMask);
|
||||
if (arr[numColors] < 0) {
|
||||
throw new IllegalArgumentException("Noncontiguous alpha mask ("
|
||||
+ Integer.toHexString(alphaMask));
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private final static int[] createBitsArray(int rmask, int gmask, int bmask,
|
||||
int amask) {
|
||||
int[] arr = new int[3 + (amask == 0 ? 0 : 1)];
|
||||
arr[0] = countBits(rmask);
|
||||
arr[1] = countBits(gmask);
|
||||
arr[2] = countBits(bmask);
|
||||
if (arr[0] < 0) {
|
||||
throw new IllegalArgumentException("Noncontiguous red mask ("
|
||||
+ Integer.toHexString(rmask));
|
||||
}
|
||||
else if (arr[1] < 0) {
|
||||
throw new IllegalArgumentException("Noncontiguous green mask ("
|
||||
+ Integer.toHexString(gmask));
|
||||
}
|
||||
else if (arr[2] < 0) {
|
||||
throw new IllegalArgumentException("Noncontiguous blue mask ("
|
||||
+ Integer.toHexString(bmask));
|
||||
}
|
||||
if (amask != 0) {
|
||||
arr[3] = countBits(amask);
|
||||
if (arr[3] < 0) {
|
||||
throw new IllegalArgumentException("Noncontiguous alpha mask ("
|
||||
+ Integer.toHexString(amask));
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private final static int countBits(int mask) {
|
||||
int count = 0;
|
||||
if (mask != 0) {
|
||||
while ((mask & 1) == 0) {
|
||||
mask >>>= 1;
|
||||
}
|
||||
while ((mask & 1) == 1) {
|
||||
mask >>>= 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (mask != 0) {
|
||||
return -1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
672
jdkSrc/jdk8/java/awt/image/PixelGrabber.java
Normal file
672
jdkSrc/jdk8/java/awt/image/PixelGrabber.java
Normal file
@@ -0,0 +1,672 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.Image;
|
||||
|
||||
/**
|
||||
* The PixelGrabber class implements an ImageConsumer which can be attached
|
||||
* to an Image or ImageProducer object to retrieve a subset of the pixels
|
||||
* in that image. Here is an example:
|
||||
* <pre>{@code
|
||||
*
|
||||
* public void handlesinglepixel(int x, int y, int pixel) {
|
||||
* int alpha = (pixel >> 24) & 0xff;
|
||||
* int red = (pixel >> 16) & 0xff;
|
||||
* int green = (pixel >> 8) & 0xff;
|
||||
* int blue = (pixel ) & 0xff;
|
||||
* // Deal with the pixel as necessary...
|
||||
* }
|
||||
*
|
||||
* public void handlepixels(Image img, int x, int y, int w, int h) {
|
||||
* int[] pixels = new int[w * h];
|
||||
* PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w);
|
||||
* try {
|
||||
* pg.grabPixels();
|
||||
* } catch (InterruptedException e) {
|
||||
* System.err.println("interrupted waiting for pixels!");
|
||||
* return;
|
||||
* }
|
||||
* if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
|
||||
* System.err.println("image fetch aborted or errored");
|
||||
* return;
|
||||
* }
|
||||
* for (int j = 0; j < h; j++) {
|
||||
* for (int i = 0; i < w; i++) {
|
||||
* handlesinglepixel(x+i, y+j, pixels[j * w + i]);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see ColorModel#getRGBdefault
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class PixelGrabber implements ImageConsumer {
|
||||
ImageProducer producer;
|
||||
|
||||
int dstX;
|
||||
int dstY;
|
||||
int dstW;
|
||||
int dstH;
|
||||
|
||||
ColorModel imageModel;
|
||||
byte[] bytePixels;
|
||||
int[] intPixels;
|
||||
int dstOff;
|
||||
int dstScan;
|
||||
|
||||
private boolean grabbing;
|
||||
private int flags;
|
||||
|
||||
private static final int GRABBEDBITS = (ImageObserver.FRAMEBITS
|
||||
| ImageObserver.ALLBITS);
|
||||
private static final int DONEBITS = (GRABBEDBITS
|
||||
| ImageObserver.ERROR);
|
||||
|
||||
/**
|
||||
* Create a PixelGrabber object to grab the (x, y, w, h) rectangular
|
||||
* section of pixels from the specified image into the given array.
|
||||
* The pixels are stored into the array in the default RGB ColorModel.
|
||||
* The RGB data for pixel (i, j) where (i, j) is inside the rectangle
|
||||
* (x, y, w, h) is stored in the array at
|
||||
* <tt>pix[(j - y) * scansize + (i - x) + off]</tt>.
|
||||
* @see ColorModel#getRGBdefault
|
||||
* @param img the image to retrieve pixels from
|
||||
* @param x the x coordinate of the upper left corner of the rectangle
|
||||
* of pixels to retrieve from the image, relative to the default
|
||||
* (unscaled) size of the image
|
||||
* @param y the y coordinate of the upper left corner of the rectangle
|
||||
* of pixels to retrieve from the image
|
||||
* @param w the width of the rectangle of pixels to retrieve
|
||||
* @param h the height of the rectangle of pixels to retrieve
|
||||
* @param pix the array of integers which are to be used to hold the
|
||||
* RGB pixels retrieved from the image
|
||||
* @param off the offset into the array of where to store the first pixel
|
||||
* @param scansize the distance from one row of pixels to the next in
|
||||
* the array
|
||||
*/
|
||||
public PixelGrabber(Image img, int x, int y, int w, int h,
|
||||
int[] pix, int off, int scansize) {
|
||||
this(img.getSource(), x, y, w, h, pix, off, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PixelGrabber object to grab the (x, y, w, h) rectangular
|
||||
* section of pixels from the image produced by the specified
|
||||
* ImageProducer into the given array.
|
||||
* The pixels are stored into the array in the default RGB ColorModel.
|
||||
* The RGB data for pixel (i, j) where (i, j) is inside the rectangle
|
||||
* (x, y, w, h) is stored in the array at
|
||||
* <tt>pix[(j - y) * scansize + (i - x) + off]</tt>.
|
||||
* @param ip the <code>ImageProducer</code> that produces the
|
||||
* image from which to retrieve pixels
|
||||
* @param x the x coordinate of the upper left corner of the rectangle
|
||||
* of pixels to retrieve from the image, relative to the default
|
||||
* (unscaled) size of the image
|
||||
* @param y the y coordinate of the upper left corner of the rectangle
|
||||
* of pixels to retrieve from the image
|
||||
* @param w the width of the rectangle of pixels to retrieve
|
||||
* @param h the height of the rectangle of pixels to retrieve
|
||||
* @param pix the array of integers which are to be used to hold the
|
||||
* RGB pixels retrieved from the image
|
||||
* @param off the offset into the array of where to store the first pixel
|
||||
* @param scansize the distance from one row of pixels to the next in
|
||||
* the array
|
||||
* @see ColorModel#getRGBdefault
|
||||
*/
|
||||
public PixelGrabber(ImageProducer ip, int x, int y, int w, int h,
|
||||
int[] pix, int off, int scansize) {
|
||||
producer = ip;
|
||||
dstX = x;
|
||||
dstY = y;
|
||||
dstW = w;
|
||||
dstH = h;
|
||||
dstOff = off;
|
||||
dstScan = scansize;
|
||||
intPixels = pix;
|
||||
imageModel = ColorModel.getRGBdefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PixelGrabber object to grab the (x, y, w, h) rectangular
|
||||
* section of pixels from the specified image. The pixels are
|
||||
* accumulated in the original ColorModel if the same ColorModel
|
||||
* is used for every call to setPixels, otherwise the pixels are
|
||||
* accumulated in the default RGB ColorModel. If the forceRGB
|
||||
* parameter is true, then the pixels will be accumulated in the
|
||||
* default RGB ColorModel anyway. A buffer is allocated by the
|
||||
* PixelGrabber to hold the pixels in either case. If {@code (w < 0)} or
|
||||
* {@code (h < 0)}, then they will default to the remaining width and
|
||||
* height of the source data when that information is delivered.
|
||||
* @param img the image to retrieve the image data from
|
||||
* @param x the x coordinate of the upper left corner of the rectangle
|
||||
* of pixels to retrieve from the image, relative to the default
|
||||
* (unscaled) size of the image
|
||||
* @param y the y coordinate of the upper left corner of the rectangle
|
||||
* of pixels to retrieve from the image
|
||||
* @param w the width of the rectangle of pixels to retrieve
|
||||
* @param h the height of the rectangle of pixels to retrieve
|
||||
* @param forceRGB true if the pixels should always be converted to
|
||||
* the default RGB ColorModel
|
||||
*/
|
||||
public PixelGrabber(Image img, int x, int y, int w, int h,
|
||||
boolean forceRGB)
|
||||
{
|
||||
producer = img.getSource();
|
||||
dstX = x;
|
||||
dstY = y;
|
||||
dstW = w;
|
||||
dstH = h;
|
||||
if (forceRGB) {
|
||||
imageModel = ColorModel.getRGBdefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the PixelGrabber to start fetching the pixels.
|
||||
*/
|
||||
public synchronized void startGrabbing() {
|
||||
if ((flags & DONEBITS) != 0) {
|
||||
return;
|
||||
}
|
||||
if (!grabbing) {
|
||||
grabbing = true;
|
||||
flags &= ~(ImageObserver.ABORT);
|
||||
producer.startProduction(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the PixelGrabber to abort the image fetch.
|
||||
*/
|
||||
public synchronized void abortGrabbing() {
|
||||
imageComplete(IMAGEABORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the Image or ImageProducer to start delivering pixels and
|
||||
* wait for all of the pixels in the rectangle of interest to be
|
||||
* delivered.
|
||||
* @return true if the pixels were successfully grabbed, false on
|
||||
* abort, error or timeout
|
||||
* @exception InterruptedException
|
||||
* Another thread has interrupted this thread.
|
||||
*/
|
||||
public boolean grabPixels() throws InterruptedException {
|
||||
return grabPixels(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the Image or ImageProducer to start delivering pixels and
|
||||
* wait for all of the pixels in the rectangle of interest to be
|
||||
* delivered or until the specified timeout has elapsed. This method
|
||||
* behaves in the following ways, depending on the value of
|
||||
* <code>ms</code>:
|
||||
* <ul>
|
||||
* <li> If {@code ms == 0}, waits until all pixels are delivered
|
||||
* <li> If {@code ms > 0}, waits until all pixels are delivered
|
||||
* as timeout expires.
|
||||
* <li> If {@code ms < 0}, returns <code>true</code> if all pixels
|
||||
* are grabbed, <code>false</code> otherwise and does not wait.
|
||||
* </ul>
|
||||
* @param ms the number of milliseconds to wait for the image pixels
|
||||
* to arrive before timing out
|
||||
* @return true if the pixels were successfully grabbed, false on
|
||||
* abort, error or timeout
|
||||
* @exception InterruptedException
|
||||
* Another thread has interrupted this thread.
|
||||
*/
|
||||
public synchronized boolean grabPixels(long ms)
|
||||
throws InterruptedException
|
||||
{
|
||||
if ((flags & DONEBITS) != 0) {
|
||||
return (flags & GRABBEDBITS) != 0;
|
||||
}
|
||||
long end = ms + System.currentTimeMillis();
|
||||
if (!grabbing) {
|
||||
grabbing = true;
|
||||
flags &= ~(ImageObserver.ABORT);
|
||||
producer.startProduction(this);
|
||||
}
|
||||
while (grabbing) {
|
||||
long timeout;
|
||||
if (ms == 0) {
|
||||
timeout = 0;
|
||||
} else {
|
||||
timeout = end - System.currentTimeMillis();
|
||||
if (timeout <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
wait(timeout);
|
||||
}
|
||||
return (flags & GRABBEDBITS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the status of the pixels. The ImageObserver flags
|
||||
* representing the available pixel information are returned.
|
||||
* @return the bitwise OR of all relevant ImageObserver flags
|
||||
* @see ImageObserver
|
||||
*/
|
||||
public synchronized int getStatus() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the pixel buffer (after adjusting for image width).
|
||||
* If no width was specified for the rectangle of pixels to grab then
|
||||
* then this information will only be available after the image has
|
||||
* delivered the dimensions.
|
||||
* @return the final width used for the pixel buffer or -1 if the width
|
||||
* is not yet known
|
||||
* @see #getStatus
|
||||
*/
|
||||
public synchronized int getWidth() {
|
||||
return (dstW < 0) ? -1 : dstW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the pixel buffer (after adjusting for image height).
|
||||
* If no width was specified for the rectangle of pixels to grab then
|
||||
* then this information will only be available after the image has
|
||||
* delivered the dimensions.
|
||||
* @return the final height used for the pixel buffer or -1 if the height
|
||||
* is not yet known
|
||||
* @see #getStatus
|
||||
*/
|
||||
public synchronized int getHeight() {
|
||||
return (dstH < 0) ? -1 : dstH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pixel buffer. If the PixelGrabber was not constructed
|
||||
* with an explicit pixel buffer to hold the pixels then this method
|
||||
* will return null until the size and format of the image data is
|
||||
* known.
|
||||
* Since the PixelGrabber may fall back on accumulating the data
|
||||
* in the default RGB ColorModel at any time if the source image
|
||||
* uses more than one ColorModel to deliver the data, the array
|
||||
* object returned by this method may change over time until the
|
||||
* image grab is complete.
|
||||
* @return either a byte array or an int array
|
||||
* @see #getStatus
|
||||
* @see #setPixels(int, int, int, int, ColorModel, byte[], int, int)
|
||||
* @see #setPixels(int, int, int, int, ColorModel, int[], int, int)
|
||||
*/
|
||||
public synchronized Object getPixels() {
|
||||
return (bytePixels == null)
|
||||
? ((Object) intPixels)
|
||||
: ((Object) bytePixels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ColorModel for the pixels stored in the array. If the
|
||||
* PixelGrabber was constructed with an explicit pixel buffer then
|
||||
* this method will always return the default RGB ColorModel,
|
||||
* otherwise it may return null until the ColorModel used by the
|
||||
* ImageProducer is known.
|
||||
* Since the PixelGrabber may fall back on accumulating the data
|
||||
* in the default RGB ColorModel at any time if the source image
|
||||
* uses more than one ColorModel to deliver the data, the ColorModel
|
||||
* object returned by this method may change over time until the
|
||||
* image grab is complete and may not reflect any of the ColorModel
|
||||
* objects that was used by the ImageProducer to deliver the pixels.
|
||||
* @return the ColorModel object used for storing the pixels
|
||||
* @see #getStatus
|
||||
* @see ColorModel#getRGBdefault
|
||||
* @see #setColorModel(ColorModel)
|
||||
*/
|
||||
public synchronized ColorModel getColorModel() {
|
||||
return imageModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* The setDimensions method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param width the width of the dimension
|
||||
* @param height the height of the dimension
|
||||
*/
|
||||
public void setDimensions(int width, int height) {
|
||||
if (dstW < 0) {
|
||||
dstW = width - dstX;
|
||||
}
|
||||
if (dstH < 0) {
|
||||
dstH = height - dstY;
|
||||
}
|
||||
if (dstW <= 0 || dstH <= 0) {
|
||||
imageComplete(STATICIMAGEDONE);
|
||||
} else if (intPixels == null &&
|
||||
imageModel == ColorModel.getRGBdefault()) {
|
||||
intPixels = new int[dstW * dstH];
|
||||
dstScan = dstW;
|
||||
dstOff = 0;
|
||||
}
|
||||
flags |= (ImageObserver.WIDTH | ImageObserver.HEIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* The setHints method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param hints a set of hints used to process the pixels
|
||||
*/
|
||||
public void setHints(int hints) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The setProperties method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param props the list of properties
|
||||
*/
|
||||
public void setProperties(Hashtable<?,?> props) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The setColorModel method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param model the specified <code>ColorModel</code>
|
||||
* @see #getColorModel
|
||||
*/
|
||||
public void setColorModel(ColorModel model) {
|
||||
return;
|
||||
}
|
||||
|
||||
private void convertToRGB() {
|
||||
int size = dstW * dstH;
|
||||
int newpixels[] = new int[size];
|
||||
if (bytePixels != null) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
newpixels[i] = imageModel.getRGB(bytePixels[i] & 0xff);
|
||||
}
|
||||
} else if (intPixels != null) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
newpixels[i] = imageModel.getRGB(intPixels[i]);
|
||||
}
|
||||
}
|
||||
bytePixels = null;
|
||||
intPixels = newpixels;
|
||||
dstScan = dstW;
|
||||
dstOff = 0;
|
||||
imageModel = ColorModel.getRGBdefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* The setPixels method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param srcX the X coordinate of the upper-left corner
|
||||
* of the area of pixels to be set
|
||||
* @param srcY the Y coordinate of the upper-left corner
|
||||
* of the area of pixels to be set
|
||||
* @param srcW the width of the area of pixels
|
||||
* @param srcH the height of the area of pixels
|
||||
* @param model the specified <code>ColorModel</code>
|
||||
* @param pixels the array of pixels
|
||||
* @param srcOff the offset into the pixels array
|
||||
* @param srcScan the distance from one row of pixels to the next
|
||||
* in the pixels array
|
||||
* @see #getPixels
|
||||
*/
|
||||
public void setPixels(int srcX, int srcY, int srcW, int srcH,
|
||||
ColorModel model,
|
||||
byte pixels[], int srcOff, int srcScan) {
|
||||
if (srcY < dstY) {
|
||||
int diff = dstY - srcY;
|
||||
if (diff >= srcH) {
|
||||
return;
|
||||
}
|
||||
srcOff += srcScan * diff;
|
||||
srcY += diff;
|
||||
srcH -= diff;
|
||||
}
|
||||
if (srcY + srcH > dstY + dstH) {
|
||||
srcH = (dstY + dstH) - srcY;
|
||||
if (srcH <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (srcX < dstX) {
|
||||
int diff = dstX - srcX;
|
||||
if (diff >= srcW) {
|
||||
return;
|
||||
}
|
||||
srcOff += diff;
|
||||
srcX += diff;
|
||||
srcW -= diff;
|
||||
}
|
||||
if (srcX + srcW > dstX + dstW) {
|
||||
srcW = (dstX + dstW) - srcX;
|
||||
if (srcW <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int dstPtr = dstOff + (srcY - dstY) * dstScan + (srcX - dstX);
|
||||
if (intPixels == null) {
|
||||
if (bytePixels == null) {
|
||||
bytePixels = new byte[dstW * dstH];
|
||||
dstScan = dstW;
|
||||
dstOff = 0;
|
||||
imageModel = model;
|
||||
} else if (imageModel != model) {
|
||||
convertToRGB();
|
||||
}
|
||||
if (bytePixels != null) {
|
||||
for (int h = srcH; h > 0; h--) {
|
||||
System.arraycopy(pixels, srcOff, bytePixels, dstPtr, srcW);
|
||||
srcOff += srcScan;
|
||||
dstPtr += dstScan;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (intPixels != null) {
|
||||
int dstRem = dstScan - srcW;
|
||||
int srcRem = srcScan - srcW;
|
||||
for (int h = srcH; h > 0; h--) {
|
||||
for (int w = srcW; w > 0; w--) {
|
||||
intPixels[dstPtr++] = model.getRGB(pixels[srcOff++]&0xff);
|
||||
}
|
||||
srcOff += srcRem;
|
||||
dstPtr += dstRem;
|
||||
}
|
||||
}
|
||||
flags |= ImageObserver.SOMEBITS;
|
||||
}
|
||||
|
||||
/**
|
||||
* The setPixels method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param srcX the X coordinate of the upper-left corner
|
||||
* of the area of pixels to be set
|
||||
* @param srcY the Y coordinate of the upper-left corner
|
||||
* of the area of pixels to be set
|
||||
* @param srcW the width of the area of pixels
|
||||
* @param srcH the height of the area of pixels
|
||||
* @param model the specified <code>ColorModel</code>
|
||||
* @param pixels the array of pixels
|
||||
* @param srcOff the offset into the pixels array
|
||||
* @param srcScan the distance from one row of pixels to the next
|
||||
* in the pixels array
|
||||
* @see #getPixels
|
||||
*/
|
||||
public void setPixels(int srcX, int srcY, int srcW, int srcH,
|
||||
ColorModel model,
|
||||
int pixels[], int srcOff, int srcScan) {
|
||||
if (srcY < dstY) {
|
||||
int diff = dstY - srcY;
|
||||
if (diff >= srcH) {
|
||||
return;
|
||||
}
|
||||
srcOff += srcScan * diff;
|
||||
srcY += diff;
|
||||
srcH -= diff;
|
||||
}
|
||||
if (srcY + srcH > dstY + dstH) {
|
||||
srcH = (dstY + dstH) - srcY;
|
||||
if (srcH <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (srcX < dstX) {
|
||||
int diff = dstX - srcX;
|
||||
if (diff >= srcW) {
|
||||
return;
|
||||
}
|
||||
srcOff += diff;
|
||||
srcX += diff;
|
||||
srcW -= diff;
|
||||
}
|
||||
if (srcX + srcW > dstX + dstW) {
|
||||
srcW = (dstX + dstW) - srcX;
|
||||
if (srcW <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (intPixels == null) {
|
||||
if (bytePixels == null) {
|
||||
intPixels = new int[dstW * dstH];
|
||||
dstScan = dstW;
|
||||
dstOff = 0;
|
||||
imageModel = model;
|
||||
} else {
|
||||
convertToRGB();
|
||||
}
|
||||
}
|
||||
int dstPtr = dstOff + (srcY - dstY) * dstScan + (srcX - dstX);
|
||||
if (imageModel == model) {
|
||||
for (int h = srcH; h > 0; h--) {
|
||||
System.arraycopy(pixels, srcOff, intPixels, dstPtr, srcW);
|
||||
srcOff += srcScan;
|
||||
dstPtr += dstScan;
|
||||
}
|
||||
} else {
|
||||
if (imageModel != ColorModel.getRGBdefault()) {
|
||||
convertToRGB();
|
||||
}
|
||||
int dstRem = dstScan - srcW;
|
||||
int srcRem = srcScan - srcW;
|
||||
for (int h = srcH; h > 0; h--) {
|
||||
for (int w = srcW; w > 0; w--) {
|
||||
intPixels[dstPtr++] = model.getRGB(pixels[srcOff++]);
|
||||
}
|
||||
srcOff += srcRem;
|
||||
dstPtr += dstRem;
|
||||
}
|
||||
}
|
||||
flags |= ImageObserver.SOMEBITS;
|
||||
}
|
||||
|
||||
/**
|
||||
* The imageComplete method is part of the ImageConsumer API which
|
||||
* this class must implement to retrieve the pixels.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the ImageProducer
|
||||
* of the Image whose pixels are being grabbed. Developers using
|
||||
* this class to retrieve pixels from an image should avoid calling
|
||||
* this method directly since that operation could result in problems
|
||||
* with retrieving the requested pixels.
|
||||
* @param status the status of image loading
|
||||
*/
|
||||
public synchronized void imageComplete(int status) {
|
||||
grabbing = false;
|
||||
switch (status) {
|
||||
default:
|
||||
case IMAGEERROR:
|
||||
flags |= ImageObserver.ERROR | ImageObserver.ABORT;
|
||||
break;
|
||||
case IMAGEABORTED:
|
||||
flags |= ImageObserver.ABORT;
|
||||
break;
|
||||
case STATICIMAGEDONE:
|
||||
flags |= ImageObserver.ALLBITS;
|
||||
break;
|
||||
case SINGLEFRAMEDONE:
|
||||
flags |= ImageObserver.FRAMEBITS;
|
||||
break;
|
||||
}
|
||||
producer.removeConsumer(this);
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status of the pixels. The ImageObserver flags
|
||||
* representing the available pixel information are returned.
|
||||
* This method and {@link #getStatus() getStatus} have the
|
||||
* same implementation, but <code>getStatus</code> is the
|
||||
* preferred method because it conforms to the convention of
|
||||
* naming information-retrieval methods with the form
|
||||
* "getXXX".
|
||||
* @return the bitwise OR of all relevant ImageObserver flags
|
||||
* @see ImageObserver
|
||||
* @see #getStatus()
|
||||
*/
|
||||
public synchronized int status() {
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
171
jdkSrc/jdk8/java/awt/image/PixelInterleavedSampleModel.java
Normal file
171
jdkSrc/jdk8/java/awt/image/PixelInterleavedSampleModel.java
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This class represents image data which is stored in a pixel interleaved
|
||||
* fashion and for
|
||||
* which each sample of a pixel occupies one data element of the DataBuffer.
|
||||
* It subclasses ComponentSampleModel but provides a more efficient
|
||||
* implementation for accessing pixel interleaved image data than is provided
|
||||
* by ComponentSampleModel. This class
|
||||
* stores sample data for all bands in a single bank of the
|
||||
* DataBuffer. Accessor methods are provided so that image data can be
|
||||
* manipulated directly. Pixel stride is the number of
|
||||
* data array elements between two samples for the same band on the same
|
||||
* scanline. Scanline stride is the number of data array elements between
|
||||
* a given sample and the corresponding sample in the same column of the next
|
||||
* scanline. Band offsets denote the number
|
||||
* of data array elements from the first data array element of the bank
|
||||
* of the DataBuffer holding each band to the first sample of the band.
|
||||
* The bands are numbered from 0 to N-1.
|
||||
* Bank indices denote the correspondence between a bank of the data buffer
|
||||
* and a band of image data.
|
||||
* This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT},
|
||||
* {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT} and
|
||||
* {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes.
|
||||
*/
|
||||
|
||||
public class PixelInterleavedSampleModel extends ComponentSampleModel
|
||||
{
|
||||
/**
|
||||
* Constructs a PixelInterleavedSampleModel with the specified parameters.
|
||||
* The number of bands will be given by the length of the bandOffsets
|
||||
* array.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param pixelStride The pixel stride of the image data.
|
||||
* @param scanlineStride The line stride of the image data.
|
||||
* @param bandOffsets The offsets of all bands.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if any offset between bands is
|
||||
* greater than the scanline stride
|
||||
* @throws IllegalArgumentException if the product of
|
||||
* <code>pixelStride</code> and <code>w</code> is greater
|
||||
* than <code>scanlineStride</code>
|
||||
* @throws IllegalArgumentException if <code>pixelStride</code> is
|
||||
* less than any offset between bands
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public PixelInterleavedSampleModel(int dataType,
|
||||
int w, int h,
|
||||
int pixelStride,
|
||||
int scanlineStride,
|
||||
int bandOffsets[]) {
|
||||
super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
|
||||
int minBandOff=this.bandOffsets[0];
|
||||
int maxBandOff=this.bandOffsets[0];
|
||||
for (int i=1; i<this.bandOffsets.length; i++) {
|
||||
minBandOff = Math.min(minBandOff,this.bandOffsets[i]);
|
||||
maxBandOff = Math.max(maxBandOff,this.bandOffsets[i]);
|
||||
}
|
||||
maxBandOff -= minBandOff;
|
||||
if (maxBandOff > scanlineStride) {
|
||||
throw new IllegalArgumentException("Offsets between bands must be"+
|
||||
" less than the scanline "+
|
||||
" stride");
|
||||
}
|
||||
if (pixelStride*w > scanlineStride) {
|
||||
throw new IllegalArgumentException("Pixel stride times width "+
|
||||
"must be less than or "+
|
||||
"equal to the scanline "+
|
||||
"stride");
|
||||
}
|
||||
if (pixelStride < maxBandOff) {
|
||||
throw new IllegalArgumentException("Pixel stride must be greater"+
|
||||
" than or equal to the offsets"+
|
||||
" between bands");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PixelInterleavedSampleModel with the specified
|
||||
* width and height. The new PixelInterleavedSampleModel will have the
|
||||
* same number of bands, storage data type, and pixel stride
|
||||
* as this PixelInterleavedSampleModel. The band offsets may be
|
||||
* compressed such that the minimum of all of the band offsets is zero.
|
||||
* @param w the width of the resulting <code>SampleModel</code>
|
||||
* @param h the height of the resulting <code>SampleModel</code>
|
||||
* @return a new <code>SampleModel</code> with the specified width
|
||||
* and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int minBandoff=bandOffsets[0];
|
||||
int numBands = bandOffsets.length;
|
||||
for (int i=1; i < numBands; i++) {
|
||||
if (bandOffsets[i] < minBandoff) {
|
||||
minBandoff = bandOffsets[i];
|
||||
}
|
||||
}
|
||||
int[] bandOff;
|
||||
if (minBandoff > 0) {
|
||||
bandOff = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bandOff[i] = bandOffsets[i] - minBandoff;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bandOff = bandOffsets;
|
||||
}
|
||||
return new PixelInterleavedSampleModel(dataType, w, h, pixelStride,
|
||||
pixelStride*w, bandOff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PixelInterleavedSampleModel with a subset of the
|
||||
* bands of this PixelInterleavedSampleModel. The new
|
||||
* PixelInterleavedSampleModel can be used with any DataBuffer that the
|
||||
* existing PixelInterleavedSampleModel can be used with. The new
|
||||
* PixelInterleavedSampleModel/DataBuffer combination will represent
|
||||
* an image with a subset of the bands of the original
|
||||
* PixelInterleavedSampleModel/DataBuffer combination.
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
int newBandOffsets[] = new int[bands.length];
|
||||
for (int i=0; i<bands.length; i++) {
|
||||
newBandOffsets[i] = bandOffsets[bands[i]];
|
||||
}
|
||||
return new PixelInterleavedSampleModel(this.dataType, width, height,
|
||||
this.pixelStride,
|
||||
scanlineStride, newBandOffsets);
|
||||
}
|
||||
|
||||
// Differentiate hash code from other ComponentSampleModel subclasses
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ 0x1;
|
||||
}
|
||||
}
|
||||
292
jdkSrc/jdk8/java/awt/image/RGBImageFilter.java
Normal file
292
jdkSrc/jdk8/java/awt/image/RGBImageFilter.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ColorModel;
|
||||
|
||||
/**
|
||||
* This class provides an easy way to create an ImageFilter which modifies
|
||||
* the pixels of an image in the default RGB ColorModel. It is meant to
|
||||
* be used in conjunction with a FilteredImageSource object to produce
|
||||
* filtered versions of existing images. It is an abstract class that
|
||||
* provides the calls needed to channel all of the pixel data through a
|
||||
* single method which converts pixels one at a time in the default RGB
|
||||
* ColorModel regardless of the ColorModel being used by the ImageProducer.
|
||||
* The only method which needs to be defined to create a useable image
|
||||
* filter is the filterRGB method. Here is an example of a definition
|
||||
* of a filter which swaps the red and blue components of an image:
|
||||
* <pre>{@code
|
||||
*
|
||||
* class RedBlueSwapFilter extends RGBImageFilter {
|
||||
* public RedBlueSwapFilter() {
|
||||
* // The filter's operation does not depend on the
|
||||
* // pixel's location, so IndexColorModels can be
|
||||
* // filtered directly.
|
||||
* canFilterIndexColorModel = true;
|
||||
* }
|
||||
*
|
||||
* public int filterRGB(int x, int y, int rgb) {
|
||||
* return ((rgb & 0xff00ff00)
|
||||
* | ((rgb & 0xff0000) >> 16)
|
||||
* | ((rgb & 0xff) << 16));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see FilteredImageSource
|
||||
* @see ImageFilter
|
||||
* @see ColorModel#getRGBdefault
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public abstract class RGBImageFilter extends ImageFilter {
|
||||
|
||||
/**
|
||||
* The <code>ColorModel</code> to be replaced by
|
||||
* <code>newmodel</code> when the user calls
|
||||
* {@link #substituteColorModel(ColorModel, ColorModel) substituteColorModel}.
|
||||
*/
|
||||
protected ColorModel origmodel;
|
||||
|
||||
/**
|
||||
* The <code>ColorModel</code> with which to
|
||||
* replace <code>origmodel</code> when the user calls
|
||||
* <code>substituteColorModel</code>.
|
||||
*/
|
||||
protected ColorModel newmodel;
|
||||
|
||||
/**
|
||||
* This boolean indicates whether or not it is acceptable to apply
|
||||
* the color filtering of the filterRGB method to the color table
|
||||
* entries of an IndexColorModel object in lieu of pixel by pixel
|
||||
* filtering. Subclasses should set this variable to true in their
|
||||
* constructor if their filterRGB method does not depend on the
|
||||
* coordinate of the pixel being filtered.
|
||||
* @see #substituteColorModel
|
||||
* @see #filterRGB
|
||||
* @see IndexColorModel
|
||||
*/
|
||||
protected boolean canFilterIndexColorModel;
|
||||
|
||||
/**
|
||||
* If the ColorModel is an IndexColorModel and the subclass has
|
||||
* set the canFilterIndexColorModel flag to true, we substitute
|
||||
* a filtered version of the color model here and wherever
|
||||
* that original ColorModel object appears in the setPixels methods.
|
||||
* If the ColorModel is not an IndexColorModel or is null, this method
|
||||
* overrides the default ColorModel used by the ImageProducer and
|
||||
* specifies the default RGB ColorModel instead.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer
|
||||
* @see ColorModel#getRGBdefault
|
||||
*/
|
||||
public void setColorModel(ColorModel model) {
|
||||
if (canFilterIndexColorModel && (model instanceof IndexColorModel)) {
|
||||
ColorModel newcm = filterIndexColorModel((IndexColorModel)model);
|
||||
substituteColorModel(model, newcm);
|
||||
consumer.setColorModel(newcm);
|
||||
} else {
|
||||
consumer.setColorModel(ColorModel.getRGBdefault());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers two ColorModel objects for substitution. If the oldcm
|
||||
* is encountered during any of the setPixels methods, the newcm
|
||||
* is substituted and the pixels passed through
|
||||
* untouched (but with the new ColorModel object).
|
||||
* @param oldcm the ColorModel object to be replaced on the fly
|
||||
* @param newcm the ColorModel object to replace oldcm on the fly
|
||||
*/
|
||||
public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
|
||||
origmodel = oldcm;
|
||||
newmodel = newcm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an IndexColorModel object by running each entry in its
|
||||
* color tables through the filterRGB function that RGBImageFilter
|
||||
* subclasses must provide. Uses coordinates of -1 to indicate that
|
||||
* a color table entry is being filtered rather than an actual
|
||||
* pixel value.
|
||||
* @param icm the IndexColorModel object to be filtered
|
||||
* @exception NullPointerException if <code>icm</code> is null
|
||||
* @return a new IndexColorModel representing the filtered colors
|
||||
*/
|
||||
public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
|
||||
int mapsize = icm.getMapSize();
|
||||
byte r[] = new byte[mapsize];
|
||||
byte g[] = new byte[mapsize];
|
||||
byte b[] = new byte[mapsize];
|
||||
byte a[] = new byte[mapsize];
|
||||
icm.getReds(r);
|
||||
icm.getGreens(g);
|
||||
icm.getBlues(b);
|
||||
icm.getAlphas(a);
|
||||
int trans = icm.getTransparentPixel();
|
||||
boolean needalpha = false;
|
||||
for (int i = 0; i < mapsize; i++) {
|
||||
int rgb = filterRGB(-1, -1, icm.getRGB(i));
|
||||
a[i] = (byte) (rgb >> 24);
|
||||
if (a[i] != ((byte)0xff) && i != trans) {
|
||||
needalpha = true;
|
||||
}
|
||||
r[i] = (byte) (rgb >> 16);
|
||||
g[i] = (byte) (rgb >> 8);
|
||||
b[i] = (byte) (rgb >> 0);
|
||||
}
|
||||
if (needalpha) {
|
||||
return new IndexColorModel(icm.getPixelSize(), mapsize,
|
||||
r, g, b, a);
|
||||
} else {
|
||||
return new IndexColorModel(icm.getPixelSize(), mapsize,
|
||||
r, g, b, trans);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a buffer of pixels in the default RGB ColorModel by passing
|
||||
* them one by one through the filterRGB method.
|
||||
* @param x the X coordinate of the upper-left corner of the region
|
||||
* of pixels
|
||||
* @param y the Y coordinate of the upper-left corner of the region
|
||||
* of pixels
|
||||
* @param w the width of the region of pixels
|
||||
* @param h the height of the region of pixels
|
||||
* @param pixels the array of pixels
|
||||
* @param off the offset into the <code>pixels</code> array
|
||||
* @param scansize the distance from one row of pixels to the next
|
||||
* in the array
|
||||
* @see ColorModel#getRGBdefault
|
||||
* @see #filterRGB
|
||||
*/
|
||||
public void filterRGBPixels(int x, int y, int w, int h,
|
||||
int pixels[], int off, int scansize) {
|
||||
int index = off;
|
||||
for (int cy = 0; cy < h; cy++) {
|
||||
for (int cx = 0; cx < w; cx++) {
|
||||
pixels[index] = filterRGB(x + cx, y + cy, pixels[index]);
|
||||
index++;
|
||||
}
|
||||
index += scansize - w;
|
||||
}
|
||||
consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(),
|
||||
pixels, off, scansize);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the ColorModel object is the same one that has already
|
||||
* been converted, then simply passes the pixels through with the
|
||||
* converted ColorModel. Otherwise converts the buffer of byte
|
||||
* pixels to the default RGB ColorModel and passes the converted
|
||||
* buffer to the filterRGBPixels method to be converted one by one.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ColorModel#getRGBdefault
|
||||
* @see #filterRGBPixels
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off,
|
||||
int scansize) {
|
||||
if (model == origmodel) {
|
||||
consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
|
||||
} else {
|
||||
int filteredpixels[] = new int[w];
|
||||
int index = off;
|
||||
for (int cy = 0; cy < h; cy++) {
|
||||
for (int cx = 0; cx < w; cx++) {
|
||||
filteredpixels[cx] = model.getRGB((pixels[index] & 0xff));
|
||||
index++;
|
||||
}
|
||||
index += scansize - w;
|
||||
filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the ColorModel object is the same one that has already
|
||||
* been converted, then simply passes the pixels through with the
|
||||
* converted ColorModel, otherwise converts the buffer of integer
|
||||
* pixels to the default RGB ColorModel and passes the converted
|
||||
* buffer to the filterRGBPixels method to be converted one by one.
|
||||
* Converts a buffer of integer pixels to the default RGB ColorModel
|
||||
* and passes the converted buffer to the filterRGBPixels method.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ColorModel#getRGBdefault
|
||||
* @see #filterRGBPixels
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off,
|
||||
int scansize) {
|
||||
if (model == origmodel) {
|
||||
consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
|
||||
} else {
|
||||
int filteredpixels[] = new int[w];
|
||||
int index = off;
|
||||
for (int cy = 0; cy < h; cy++) {
|
||||
for (int cx = 0; cx < w; cx++) {
|
||||
filteredpixels[cx] = model.getRGB(pixels[index]);
|
||||
index++;
|
||||
}
|
||||
index += scansize - w;
|
||||
filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must specify a method to convert a single input pixel
|
||||
* in the default RGB ColorModel to a single output pixel.
|
||||
* @param x the X coordinate of the pixel
|
||||
* @param y the Y coordinate of the pixel
|
||||
* @param rgb the integer pixel representation in the default RGB
|
||||
* color model
|
||||
* @return a filtered pixel in the default RGB color model.
|
||||
* @see ColorModel#getRGBdefault
|
||||
* @see #filterRGBPixels
|
||||
*/
|
||||
public abstract int filterRGB(int x, int y, int rgb);
|
||||
}
|
||||
1774
jdkSrc/jdk8/java/awt/image/Raster.java
Normal file
1774
jdkSrc/jdk8/java/awt/image/Raster.java
Normal file
File diff suppressed because it is too large
Load Diff
44
jdkSrc/jdk8/java/awt/image/RasterFormatException.java
Normal file
44
jdkSrc/jdk8/java/awt/image/RasterFormatException.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* The <code>RasterFormatException</code> is thrown if there is
|
||||
* invalid layout information in the {@link Raster}.
|
||||
*/
|
||||
public class RasterFormatException extends java.lang.RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a new <code>RasterFormatException</code> with the
|
||||
* specified message.
|
||||
* @param s the message to generate when a
|
||||
* <code>RasterFormatException</code> is thrown
|
||||
*/
|
||||
public RasterFormatException(String s) {
|
||||
super (s);
|
||||
}
|
||||
}
|
||||
107
jdkSrc/jdk8/java/awt/image/RasterOp.java
Normal file
107
jdkSrc/jdk8/java/awt/image/RasterOp.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
/**
|
||||
* This interface describes single-input/single-output
|
||||
* operations performed on Raster objects. It is implemented by such
|
||||
* classes as AffineTransformOp, ConvolveOp, and LookupOp. The Source
|
||||
* and Destination objects must contain the appropriate number
|
||||
* of bands for the particular classes implementing this interface.
|
||||
* Otherwise, an exception is thrown. This interface cannot be used to
|
||||
* describe more sophisticated Ops such as ones that take multiple sources.
|
||||
* Each class implementing this interface will specify whether or not it
|
||||
* will allow an in-place filtering operation (i.e. source object equal
|
||||
* to the destination object). Note that the restriction to single-input
|
||||
* operations means that the values of destination pixels prior to the
|
||||
* operation are not used as input to the filter operation.
|
||||
* @see AffineTransformOp
|
||||
* @see BandCombineOp
|
||||
* @see ColorConvertOp
|
||||
* @see ConvolveOp
|
||||
* @see LookupOp
|
||||
* @see RescaleOp
|
||||
*/
|
||||
public interface RasterOp {
|
||||
/**
|
||||
* Performs a single-input/single-output operation from a source Raster
|
||||
* to a destination Raster. If the destination Raster is null, a
|
||||
* new Raster will be created. The IllegalArgumentException may be thrown
|
||||
* if the source and/or destination Raster is incompatible with the types
|
||||
* of Rasters allowed by the class implementing this filter.
|
||||
* @param src the source <code>Raster</code>
|
||||
* @param dest the destination <code>WritableRaster</code>
|
||||
* @return a <code>WritableRaster</code> that represents the result of
|
||||
* the filtering operation.
|
||||
*/
|
||||
public WritableRaster filter(Raster src, WritableRaster dest);
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the filtered destination Raster.
|
||||
* The IllegalArgumentException may be thrown if the source Raster
|
||||
* is incompatible with the types of Rasters allowed
|
||||
* by the class implementing this filter.
|
||||
* @param src the source <code>Raster</code>
|
||||
* @return a <code>Rectangle2D</code> that is the bounding box of
|
||||
* the <code>Raster</code> resulting from the filtering
|
||||
* operation.
|
||||
*/
|
||||
public Rectangle2D getBounds2D(Raster src);
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination Raster with the correct size and number of
|
||||
* bands.
|
||||
* The IllegalArgumentException may be thrown if the source Raster
|
||||
* is incompatible with the types of Rasters allowed
|
||||
* by the class implementing this filter.
|
||||
* @param src the source <code>Raster</code>
|
||||
* @return a <code>WritableRaster</code> that is compatible with
|
||||
* <code>src</code>
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster(Raster src);
|
||||
|
||||
/**
|
||||
* Returns the location of the destination point given a
|
||||
* point in the source Raster. If dstPt is non-null, it
|
||||
* will be used to hold the return value.
|
||||
* @param srcPt the source <code>Point2D</code>
|
||||
* @param dstPt the destination <code>Point2D</code>
|
||||
* @return the location of the destination point.
|
||||
*/
|
||||
public Point2D getPoint2D(Point2D srcPt, Point2D dstPt);
|
||||
|
||||
/**
|
||||
* Returns the rendering hints for this RasterOp. Returns
|
||||
* null if no hints have been set.
|
||||
* @return the <code>RenderingHints</code> object of this
|
||||
* <code>RasterOp</code>.
|
||||
*/
|
||||
public RenderingHints getRenderingHints();
|
||||
}
|
||||
217
jdkSrc/jdk8/java/awt/image/RenderedImage.java
Normal file
217
jdkSrc/jdk8/java/awt/image/RenderedImage.java
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* RenderedImage is a common interface for objects which contain
|
||||
* or can produce image data in the form of Rasters. The image
|
||||
* data may be stored/produced as a single tile or a regular array
|
||||
* of tiles.
|
||||
*/
|
||||
|
||||
public interface RenderedImage {
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderedImages that are the immediate sources of
|
||||
* image data for this RenderedImage. This method returns null if
|
||||
* the RenderedImage object has no information about its immediate
|
||||
* sources. It returns an empty Vector if the RenderedImage object has
|
||||
* no immediate sources.
|
||||
* @return a Vector of <code>RenderedImage</code> objects.
|
||||
*/
|
||||
Vector<RenderedImage> getSources();
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image. The set of
|
||||
* properties and whether it is immutable is determined by the
|
||||
* implementing class. This method returns
|
||||
* java.awt.Image.UndefinedProperty if the specified property is
|
||||
* not defined for this RenderedImage.
|
||||
* @param name the name of the property
|
||||
* @return the property indicated by the specified name.
|
||||
* @see java.awt.Image#UndefinedProperty
|
||||
*/
|
||||
Object getProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns an array of names recognized by
|
||||
* {@link #getProperty(String) getProperty(String)}
|
||||
* or <code>null</code>, if no property names are recognized.
|
||||
* @return a <code>String</code> array containing all of the
|
||||
* property names that <code>getProperty(String)</code> recognizes;
|
||||
* or <code>null</code> if no property names are recognized.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns the ColorModel associated with this image. All Rasters
|
||||
* returned from this image will have this as their ColorModel. This
|
||||
* can return null.
|
||||
* @return the <code>ColorModel</code> of this image.
|
||||
*/
|
||||
ColorModel getColorModel();
|
||||
|
||||
/**
|
||||
* Returns the SampleModel associated with this image. All Rasters
|
||||
* returned from this image will have this as their SampleModel.
|
||||
* @return the <code>SampleModel</code> of this image.
|
||||
*/
|
||||
SampleModel getSampleModel();
|
||||
|
||||
/**
|
||||
* Returns the width of the RenderedImage.
|
||||
* @return the width of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of the RenderedImage.
|
||||
* @return the height of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getHeight();
|
||||
|
||||
/**
|
||||
* Returns the minimum X coordinate (inclusive) of the RenderedImage.
|
||||
* @return the X coordinate of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getMinX();
|
||||
|
||||
/**
|
||||
* Returns the minimum Y coordinate (inclusive) of the RenderedImage.
|
||||
* @return the Y coordinate of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getMinY();
|
||||
|
||||
/**
|
||||
* Returns the number of tiles in the X direction.
|
||||
* @return the number of tiles in the X direction.
|
||||
*/
|
||||
int getNumXTiles();
|
||||
|
||||
/**
|
||||
* Returns the number of tiles in the Y direction.
|
||||
* @return the number of tiles in the Y direction.
|
||||
*/
|
||||
int getNumYTiles();
|
||||
|
||||
/**
|
||||
* Returns the minimum tile index in the X direction.
|
||||
* @return the minimum tile index in the X direction.
|
||||
*/
|
||||
int getMinTileX();
|
||||
|
||||
/**
|
||||
* Returns the minimum tile index in the Y direction.
|
||||
* @return the minimum tile index in the X direction.
|
||||
*/
|
||||
int getMinTileY();
|
||||
|
||||
/**
|
||||
* Returns the tile width in pixels. All tiles must have the same
|
||||
* width.
|
||||
* @return the tile width in pixels.
|
||||
*/
|
||||
int getTileWidth();
|
||||
|
||||
/**
|
||||
* Returns the tile height in pixels. All tiles must have the same
|
||||
* height.
|
||||
* @return the tile height in pixels.
|
||||
*/
|
||||
int getTileHeight();
|
||||
|
||||
/**
|
||||
* Returns the X offset of the tile grid relative to the origin,
|
||||
* i.e., the X coordinate of the upper-left pixel of tile (0, 0).
|
||||
* (Note that tile (0, 0) may not actually exist.)
|
||||
* @return the X offset of the tile grid relative to the origin.
|
||||
*/
|
||||
int getTileGridXOffset();
|
||||
|
||||
/**
|
||||
* Returns the Y offset of the tile grid relative to the origin,
|
||||
* i.e., the Y coordinate of the upper-left pixel of tile (0, 0).
|
||||
* (Note that tile (0, 0) may not actually exist.)
|
||||
* @return the Y offset of the tile grid relative to the origin.
|
||||
*/
|
||||
int getTileGridYOffset();
|
||||
|
||||
/**
|
||||
* Returns tile (tileX, tileY). Note that tileX and tileY are indices
|
||||
* into the tile array, not pixel locations. The Raster that is returned
|
||||
* is live and will be updated if the image is changed.
|
||||
* @param tileX the X index of the requested tile in the tile array
|
||||
* @param tileY the Y index of the requested tile in the tile array
|
||||
* @return the tile given the specified indices.
|
||||
*/
|
||||
Raster getTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns the image as one large tile (for tile based
|
||||
* images this will require fetching the whole image
|
||||
* and copying the image data over). The Raster returned is
|
||||
* a copy of the image data and will not be updated if the image
|
||||
* is changed.
|
||||
* @return the image as one large tile.
|
||||
*/
|
||||
Raster getData();
|
||||
|
||||
/**
|
||||
* Computes and returns an arbitrary region of the RenderedImage.
|
||||
* The Raster returned is a copy of the image data and will not
|
||||
* be updated if the image is changed.
|
||||
* @param rect the region of the RenderedImage to be returned.
|
||||
* @return the region of the <code>RenderedImage</code>
|
||||
* indicated by the specified <code>Rectangle</code>.
|
||||
*/
|
||||
Raster getData(Rectangle rect);
|
||||
|
||||
/**
|
||||
* Computes an arbitrary rectangular region of the RenderedImage
|
||||
* and copies it into a caller-supplied WritableRaster. The region
|
||||
* to be computed is determined from the bounds of the supplied
|
||||
* WritableRaster. The supplied WritableRaster must have a
|
||||
* SampleModel that is compatible with this image. If raster is null,
|
||||
* an appropriate WritableRaster is created.
|
||||
* @param raster a WritableRaster to hold the returned portion of the
|
||||
* image, or null.
|
||||
* @return a reference to the supplied or created WritableRaster.
|
||||
*/
|
||||
WritableRaster copyData(WritableRaster raster);
|
||||
}
|
||||
255
jdkSrc/jdk8/java/awt/image/ReplicateScaleFilter.java
Normal file
255
jdkSrc/jdk8/java/awt/image/ReplicateScaleFilter.java
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.Hashtable;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* An ImageFilter class for scaling images using the simplest algorithm.
|
||||
* This class extends the basic ImageFilter Class to scale an existing
|
||||
* image and provide a source for a new image containing the resampled
|
||||
* image. The pixels in the source image are sampled to produce pixels
|
||||
* for an image of the specified size by replicating rows and columns of
|
||||
* pixels to scale up or omitting rows and columns of pixels to scale
|
||||
* down.
|
||||
* <p>It is meant to be used in conjunction with a FilteredImageSource
|
||||
* object to produce scaled versions of existing images. Due to
|
||||
* implementation dependencies, there may be differences in pixel values
|
||||
* of an image filtered on different platforms.
|
||||
*
|
||||
* @see FilteredImageSource
|
||||
* @see ImageFilter
|
||||
*
|
||||
* @author Jim Graham
|
||||
*/
|
||||
public class ReplicateScaleFilter extends ImageFilter {
|
||||
|
||||
/**
|
||||
* The width of the source image.
|
||||
*/
|
||||
protected int srcWidth;
|
||||
|
||||
/**
|
||||
* The height of the source image.
|
||||
*/
|
||||
protected int srcHeight;
|
||||
|
||||
/**
|
||||
* The target width to scale the image.
|
||||
*/
|
||||
protected int destWidth;
|
||||
|
||||
/**
|
||||
* The target height to scale the image.
|
||||
*/
|
||||
protected int destHeight;
|
||||
|
||||
/**
|
||||
* An <code>int</code> array containing information about a
|
||||
* row of pixels.
|
||||
*/
|
||||
protected int srcrows[];
|
||||
|
||||
/**
|
||||
* An <code>int</code> array containing information about a
|
||||
* column of pixels.
|
||||
*/
|
||||
protected int srccols[];
|
||||
|
||||
/**
|
||||
* A <code>byte</code> array initialized with a size of
|
||||
* {@link #destWidth} and used to deliver a row of pixel
|
||||
* data to the {@link ImageConsumer}.
|
||||
*/
|
||||
protected Object outpixbuf;
|
||||
|
||||
/**
|
||||
* Constructs a ReplicateScaleFilter that scales the pixels from
|
||||
* its source Image as specified by the width and height parameters.
|
||||
* @param width the target width to scale the image
|
||||
* @param height the target height to scale the image
|
||||
* @throws IllegalArgumentException if <code>width</code> equals
|
||||
* zero or <code>height</code> equals zero
|
||||
*/
|
||||
public ReplicateScaleFilter(int width, int height) {
|
||||
if (width == 0 || height == 0) {
|
||||
throw new IllegalArgumentException("Width ("+width+
|
||||
") and height ("+height+
|
||||
") must be non-zero");
|
||||
}
|
||||
destWidth = width;
|
||||
destHeight = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes along the properties from the source object after adding a
|
||||
* property indicating the scale applied.
|
||||
* This method invokes <code>super.setProperties</code>,
|
||||
* which might result in additional properties being added.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*/
|
||||
public void setProperties(Hashtable<?,?> props) {
|
||||
Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone();
|
||||
String key = "rescale";
|
||||
String val = destWidth + "x" + destHeight;
|
||||
Object o = p.get(key);
|
||||
if (o != null && o instanceof String) {
|
||||
val = ((String) o) + ", " + val;
|
||||
}
|
||||
p.put(key, val);
|
||||
super.setProperties(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the dimensions of the source image and pass the dimensions
|
||||
* of the new scaled size to the ImageConsumer.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
* @see ImageConsumer
|
||||
*/
|
||||
public void setDimensions(int w, int h) {
|
||||
srcWidth = w;
|
||||
srcHeight = h;
|
||||
if (destWidth < 0) {
|
||||
if (destHeight < 0) {
|
||||
destWidth = srcWidth;
|
||||
destHeight = srcHeight;
|
||||
} else {
|
||||
destWidth = srcWidth * destHeight / srcHeight;
|
||||
}
|
||||
} else if (destHeight < 0) {
|
||||
destHeight = srcHeight * destWidth / srcWidth;
|
||||
}
|
||||
consumer.setDimensions(destWidth, destHeight);
|
||||
}
|
||||
|
||||
private void calculateMaps() {
|
||||
srcrows = new int[destHeight + 1];
|
||||
for (int y = 0; y <= destHeight; y++) {
|
||||
srcrows[y] = (2 * y * srcHeight + srcHeight) / (2 * destHeight);
|
||||
}
|
||||
srccols = new int[destWidth + 1];
|
||||
for (int x = 0; x <= destWidth; x++) {
|
||||
srccols[x] = (2 * x * srcWidth + srcWidth) / (2 * destWidth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose which rows and columns of the delivered byte pixels are
|
||||
* needed for the destination scaled image and pass through just
|
||||
* those rows and columns that are needed, replicated as necessary.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, byte pixels[], int off,
|
||||
int scansize) {
|
||||
if (srcrows == null || srccols == null) {
|
||||
calculateMaps();
|
||||
}
|
||||
int sx, sy;
|
||||
int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * srcWidth);
|
||||
int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * srcHeight);
|
||||
byte outpix[];
|
||||
if (outpixbuf != null && outpixbuf instanceof byte[]) {
|
||||
outpix = (byte[]) outpixbuf;
|
||||
} else {
|
||||
outpix = new byte[destWidth];
|
||||
outpixbuf = outpix;
|
||||
}
|
||||
for (int dy = dy1; (sy = srcrows[dy]) < y + h; dy++) {
|
||||
int srcoff = off + scansize * (sy - y);
|
||||
int dx;
|
||||
for (dx = dx1; (sx = srccols[dx]) < x + w; dx++) {
|
||||
outpix[dx] = pixels[srcoff + sx - x];
|
||||
}
|
||||
if (dx > dx1) {
|
||||
consumer.setPixels(dx1, dy, dx - dx1, 1,
|
||||
model, outpix, dx1, destWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose which rows and columns of the delivered int pixels are
|
||||
* needed for the destination scaled image and pass through just
|
||||
* those rows and columns that are needed, replicated as necessary.
|
||||
* <p>
|
||||
* Note: This method is intended to be called by the
|
||||
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
|
||||
* are being filtered. Developers using
|
||||
* this class to filter pixels from an image should avoid calling
|
||||
* this method directly since that operation could interfere
|
||||
* with the filtering operation.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
ColorModel model, int pixels[], int off,
|
||||
int scansize) {
|
||||
if (srcrows == null || srccols == null) {
|
||||
calculateMaps();
|
||||
}
|
||||
int sx, sy;
|
||||
int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * srcWidth);
|
||||
int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * srcHeight);
|
||||
int outpix[];
|
||||
if (outpixbuf != null && outpixbuf instanceof int[]) {
|
||||
outpix = (int[]) outpixbuf;
|
||||
} else {
|
||||
outpix = new int[destWidth];
|
||||
outpixbuf = outpix;
|
||||
}
|
||||
for (int dy = dy1; (sy = srcrows[dy]) < y + h; dy++) {
|
||||
int srcoff = off + scansize * (sy - y);
|
||||
int dx;
|
||||
for (dx = dx1; (sx = srccols[dx]) < x + w; dx++) {
|
||||
outpix[dx] = pixels[srcoff + sx - x];
|
||||
}
|
||||
if (dx > dx1) {
|
||||
consumer.setPixels(dx1, dy, dx - dx1, 1,
|
||||
model, outpix, dx1, destWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
692
jdkSrc/jdk8/java/awt/image/RescaleOp.java
Normal file
692
jdkSrc/jdk8/java/awt/image/RescaleOp.java
Normal file
@@ -0,0 +1,692 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.RenderingHints;
|
||||
import sun.awt.image.ImagingLib;
|
||||
|
||||
/**
|
||||
* This class performs a pixel-by-pixel rescaling of the data in the
|
||||
* source image by multiplying the sample values for each pixel by a scale
|
||||
* factor and then adding an offset. The scaled sample values are clipped
|
||||
* to the minimum/maximum representable in the destination image.
|
||||
* <p>
|
||||
* The pseudo code for the rescaling operation is as follows:
|
||||
* <pre>
|
||||
*for each pixel from Source object {
|
||||
* for each band/component of the pixel {
|
||||
* dstElement = (srcElement*scaleFactor) + offset
|
||||
* }
|
||||
*}
|
||||
* </pre>
|
||||
* <p>
|
||||
* For Rasters, rescaling operates on bands. The number of
|
||||
* sets of scaling constants may be one, in which case the same constants
|
||||
* are applied to all bands, or it must equal the number of Source
|
||||
* Raster bands.
|
||||
* <p>
|
||||
* For BufferedImages, rescaling operates on color and alpha components.
|
||||
* The number of sets of scaling constants may be one, in which case the
|
||||
* same constants are applied to all color (but not alpha) components.
|
||||
* Otherwise, the number of sets of scaling constants may
|
||||
* equal the number of Source color components, in which case no
|
||||
* rescaling of the alpha component (if present) is performed.
|
||||
* If neither of these cases apply, the number of sets of scaling constants
|
||||
* must equal the number of Source color components plus alpha components,
|
||||
* in which case all color and alpha components are rescaled.
|
||||
* <p>
|
||||
* BufferedImage sources with premultiplied alpha data are treated in the same
|
||||
* manner as non-premultiplied images for purposes of rescaling. That is,
|
||||
* the rescaling is done per band on the raw data of the BufferedImage source
|
||||
* without regard to whether the data is premultiplied. If a color conversion
|
||||
* is required to the destination ColorModel, the premultiplied state of
|
||||
* both source and destination will be taken into account for this step.
|
||||
* <p>
|
||||
* Images with an IndexColorModel cannot be rescaled.
|
||||
* <p>
|
||||
* If a RenderingHints object is specified in the constructor, the
|
||||
* color rendering hint and the dithering hint may be used when color
|
||||
* conversion is required.
|
||||
* <p>
|
||||
* Note that in-place operation is allowed (i.e. the source and destination can
|
||||
* be the same object).
|
||||
* @see java.awt.RenderingHints#KEY_COLOR_RENDERING
|
||||
* @see java.awt.RenderingHints#KEY_DITHERING
|
||||
*/
|
||||
public class RescaleOp implements BufferedImageOp, RasterOp {
|
||||
float[] scaleFactors;
|
||||
float[] offsets;
|
||||
int length = 0;
|
||||
RenderingHints hints;
|
||||
|
||||
private int srcNbits;
|
||||
private int dstNbits;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new RescaleOp with the desired scale factors
|
||||
* and offsets. The length of the scaleFactor and offset arrays
|
||||
* must meet the restrictions stated in the class comments above.
|
||||
* The RenderingHints argument may be null.
|
||||
* @param scaleFactors the specified scale factors
|
||||
* @param offsets the specified offsets
|
||||
* @param hints the specified <code>RenderingHints</code>, or
|
||||
* <code>null</code>
|
||||
*/
|
||||
public RescaleOp (float[] scaleFactors, float[] offsets,
|
||||
RenderingHints hints) {
|
||||
length = scaleFactors.length;
|
||||
if (length > offsets.length) length = offsets.length;
|
||||
|
||||
this.scaleFactors = new float[length];
|
||||
this.offsets = new float[length];
|
||||
for (int i=0; i < length; i++) {
|
||||
this.scaleFactors[i] = scaleFactors[i];
|
||||
this.offsets[i] = offsets[i];
|
||||
}
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new RescaleOp with the desired scale factor
|
||||
* and offset. The scaleFactor and offset will be applied to
|
||||
* all bands in a source Raster and to all color (but not alpha)
|
||||
* components in a BufferedImage.
|
||||
* The RenderingHints argument may be null.
|
||||
* @param scaleFactor the specified scale factor
|
||||
* @param offset the specified offset
|
||||
* @param hints the specified <code>RenderingHints</code>, or
|
||||
* <code>null</code>
|
||||
*/
|
||||
public RescaleOp (float scaleFactor, float offset, RenderingHints hints) {
|
||||
length = 1;
|
||||
this.scaleFactors = new float[1];
|
||||
this.offsets = new float[1];
|
||||
this.scaleFactors[0] = scaleFactor;
|
||||
this.offsets[0] = offset;
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scale factors in the given array. The array is also
|
||||
* returned for convenience. If scaleFactors is null, a new array
|
||||
* will be allocated.
|
||||
* @param scaleFactors the array to contain the scale factors of
|
||||
* this <code>RescaleOp</code>
|
||||
* @return the scale factors of this <code>RescaleOp</code>.
|
||||
*/
|
||||
final public float[] getScaleFactors (float scaleFactors[]) {
|
||||
if (scaleFactors == null) {
|
||||
return (float[]) this.scaleFactors.clone();
|
||||
}
|
||||
System.arraycopy (this.scaleFactors, 0, scaleFactors, 0,
|
||||
Math.min(this.scaleFactors.length,
|
||||
scaleFactors.length));
|
||||
return scaleFactors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offsets in the given array. The array is also returned
|
||||
* for convenience. If offsets is null, a new array
|
||||
* will be allocated.
|
||||
* @param offsets the array to contain the offsets of
|
||||
* this <code>RescaleOp</code>
|
||||
* @return the offsets of this <code>RescaleOp</code>.
|
||||
*/
|
||||
final public float[] getOffsets(float offsets[]) {
|
||||
if (offsets == null) {
|
||||
return (float[]) this.offsets.clone();
|
||||
}
|
||||
|
||||
System.arraycopy (this.offsets, 0, offsets, 0,
|
||||
Math.min(this.offsets.length, offsets.length));
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of scaling factors and offsets used in this
|
||||
* RescaleOp.
|
||||
* @return the number of scaling factors and offsets of this
|
||||
* <code>RescaleOp</code>.
|
||||
*/
|
||||
final public int getNumFactors() {
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a ByteLookupTable to implement the rescale.
|
||||
* The table may have either a SHORT or BYTE input.
|
||||
* @param nElems Number of elements the table is to have.
|
||||
* This will generally be 256 for byte and
|
||||
* 65536 for short.
|
||||
*/
|
||||
private ByteLookupTable createByteLut(float scale[],
|
||||
float off[],
|
||||
int nBands,
|
||||
int nElems) {
|
||||
|
||||
byte[][] lutData = new byte[nBands][nElems];
|
||||
int band;
|
||||
|
||||
for (band=0; band<scale.length; band++) {
|
||||
float bandScale = scale[band];
|
||||
float bandOff = off[band];
|
||||
byte[] bandLutData = lutData[band];
|
||||
for (int i=0; i<nElems; i++) {
|
||||
int val = (int)(i*bandScale + bandOff);
|
||||
if ((val & 0xffffff00) != 0) {
|
||||
if (val < 0) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = 255;
|
||||
}
|
||||
}
|
||||
bandLutData[i] = (byte)val;
|
||||
}
|
||||
|
||||
}
|
||||
int maxToCopy = (nBands == 4 && scale.length == 4) ? 4 : 3;
|
||||
while (band < lutData.length && band < maxToCopy) {
|
||||
System.arraycopy(lutData[band-1], 0, lutData[band], 0, nElems);
|
||||
band++;
|
||||
}
|
||||
if (nBands == 4 && band < nBands) {
|
||||
byte[] bandLutData = lutData[band];
|
||||
for (int i=0; i<nElems; i++) {
|
||||
bandLutData[i] = (byte)i;
|
||||
}
|
||||
}
|
||||
|
||||
return new ByteLookupTable(0, lutData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ShortLookupTable to implement the rescale.
|
||||
* The table may have either a SHORT or BYTE input.
|
||||
* @param nElems Number of elements the table is to have.
|
||||
* This will generally be 256 for byte and
|
||||
* 65536 for short.
|
||||
*/
|
||||
private ShortLookupTable createShortLut(float scale[],
|
||||
float off[],
|
||||
int nBands,
|
||||
int nElems) {
|
||||
|
||||
short[][] lutData = new short[nBands][nElems];
|
||||
int band = 0;
|
||||
|
||||
for (band=0; band<scale.length; band++) {
|
||||
float bandScale = scale[band];
|
||||
float bandOff = off[band];
|
||||
short[] bandLutData = lutData[band];
|
||||
for (int i=0; i<nElems; i++) {
|
||||
int val = (int)(i*bandScale + bandOff);
|
||||
if ((val & 0xffff0000) != 0) {
|
||||
if (val < 0) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = 65535;
|
||||
}
|
||||
}
|
||||
bandLutData[i] = (short)val;
|
||||
}
|
||||
}
|
||||
int maxToCopy = (nBands == 4 && scale.length == 4) ? 4 : 3;
|
||||
while (band < lutData.length && band < maxToCopy) {
|
||||
System.arraycopy(lutData[band-1], 0, lutData[band], 0, nElems);
|
||||
band++;
|
||||
}
|
||||
if (nBands == 4 && band < nBands) {
|
||||
short[] bandLutData = lutData[band];
|
||||
for (int i=0; i<nElems; i++) {
|
||||
bandLutData[i] = (short)i;
|
||||
}
|
||||
}
|
||||
|
||||
return new ShortLookupTable(0, lutData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the rescale can be performed as a lookup.
|
||||
* The dst must be a byte or short type.
|
||||
* The src must be less than 16 bits.
|
||||
* All source band sizes must be the same and all dst band sizes
|
||||
* must be the same.
|
||||
*/
|
||||
private boolean canUseLookup(Raster src, Raster dst) {
|
||||
|
||||
//
|
||||
// Check that the src datatype is either a BYTE or SHORT
|
||||
//
|
||||
int datatype = src.getDataBuffer().getDataType();
|
||||
if(datatype != DataBuffer.TYPE_BYTE &&
|
||||
datatype != DataBuffer.TYPE_USHORT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Check dst sample sizes. All must be 8 or 16 bits.
|
||||
//
|
||||
SampleModel dstSM = dst.getSampleModel();
|
||||
dstNbits = dstSM.getSampleSize(0);
|
||||
|
||||
if (!(dstNbits == 8 || dstNbits == 16)) {
|
||||
return false;
|
||||
}
|
||||
for (int i=1; i<src.getNumBands(); i++) {
|
||||
int bandSize = dstSM.getSampleSize(i);
|
||||
if (bandSize != dstNbits) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check src sample sizes. All must be the same size
|
||||
//
|
||||
SampleModel srcSM = src.getSampleModel();
|
||||
srcNbits = srcSM.getSampleSize(0);
|
||||
if (srcNbits > 16) {
|
||||
return false;
|
||||
}
|
||||
for (int i=1; i<src.getNumBands(); i++) {
|
||||
int bandSize = srcSM.getSampleSize(i);
|
||||
if (bandSize != srcNbits) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dstSM instanceof ComponentSampleModel) {
|
||||
ComponentSampleModel dsm = (ComponentSampleModel)dstSM;
|
||||
if (dsm.getPixelStride() != dst.getNumBands()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (srcSM instanceof ComponentSampleModel) {
|
||||
ComponentSampleModel csm = (ComponentSampleModel)srcSM;
|
||||
if (csm.getPixelStride() != src.getNumBands()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescales the source BufferedImage.
|
||||
* If the color model in the source image is not the same as that
|
||||
* in the destination image, the pixels will be converted
|
||||
* in the destination. If the destination image is null,
|
||||
* a BufferedImage will be created with the source ColorModel.
|
||||
* An IllegalArgumentException may be thrown if the number of
|
||||
* scaling factors/offsets in this object does not meet the
|
||||
* restrictions stated in the class comments above, or if the
|
||||
* source image has an IndexColorModel.
|
||||
* @param src the <code>BufferedImage</code> to be filtered
|
||||
* @param dst the destination for the filtering operation
|
||||
* or <code>null</code>
|
||||
* @return the filtered <code>BufferedImage</code>.
|
||||
* @throws IllegalArgumentException if the <code>ColorModel</code>
|
||||
* of <code>src</code> is an <code>IndexColorModel</code>,
|
||||
* or if the number of scaling factors and offsets in this
|
||||
* <code>RescaleOp</code> do not meet the requirements
|
||||
* stated in the class comments.
|
||||
*/
|
||||
public final BufferedImage filter (BufferedImage src, BufferedImage dst) {
|
||||
ColorModel srcCM = src.getColorModel();
|
||||
ColorModel dstCM;
|
||||
int numSrcColorComp = srcCM.getNumColorComponents();
|
||||
int scaleConst = length;
|
||||
|
||||
if (srcCM instanceof IndexColorModel) {
|
||||
throw new
|
||||
IllegalArgumentException("Rescaling cannot be "+
|
||||
"performed on an indexed image");
|
||||
}
|
||||
if (scaleConst != 1 && scaleConst != numSrcColorComp &&
|
||||
scaleConst != srcCM.getNumComponents())
|
||||
{
|
||||
throw new IllegalArgumentException("Number of scaling constants "+
|
||||
"does not equal the number of"+
|
||||
" of color or color/alpha "+
|
||||
" components");
|
||||
}
|
||||
|
||||
boolean needToConvert = false;
|
||||
boolean needToDraw = false;
|
||||
|
||||
// Include alpha
|
||||
if (scaleConst > numSrcColorComp && srcCM.hasAlpha()) {
|
||||
scaleConst = numSrcColorComp+1;
|
||||
}
|
||||
|
||||
int width = src.getWidth();
|
||||
int height = src.getHeight();
|
||||
|
||||
BufferedImage origDst = dst;
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
dstCM = srcCM;
|
||||
}
|
||||
else {
|
||||
if (width != dst.getWidth()) {
|
||||
throw new
|
||||
IllegalArgumentException("Src width ("+width+
|
||||
") not equal to dst width ("+
|
||||
dst.getWidth()+")");
|
||||
}
|
||||
if (height != dst.getHeight()) {
|
||||
throw new
|
||||
IllegalArgumentException("Src height ("+height+
|
||||
") not equal to dst height ("+
|
||||
dst.getHeight()+")");
|
||||
}
|
||||
|
||||
dstCM = dst.getColorModel();
|
||||
if(srcCM.getColorSpace().getType() !=
|
||||
dstCM.getColorSpace().getType()) {
|
||||
needToConvert = true;
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Try to use a native BI rescale operation first
|
||||
//
|
||||
if (ImagingLib.filter(this, src, dst) == null) {
|
||||
if (src.getRaster().getNumBands() !=
|
||||
dst.getRaster().getNumBands()) {
|
||||
needToDraw = true;
|
||||
dst = createCompatibleDestImage(src, null);
|
||||
}
|
||||
|
||||
//
|
||||
// Native BI rescale failed - convert to rasters
|
||||
//
|
||||
WritableRaster srcRaster = src.getRaster();
|
||||
WritableRaster dstRaster = dst.getRaster();
|
||||
|
||||
//
|
||||
// Call the raster filter method
|
||||
//
|
||||
filterRasterImpl(srcRaster, dstRaster, scaleConst, false);
|
||||
}
|
||||
|
||||
if (needToDraw) {
|
||||
Graphics2D g = origDst.createGraphics();
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.drawImage(dst, 0, 0, width, height, null);
|
||||
g.dispose();
|
||||
}
|
||||
if (needToConvert) {
|
||||
// ColorModels are not the same
|
||||
ColorConvertOp ccop = new ColorConvertOp(hints);
|
||||
dst = ccop.filter(dst, origDst);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescales the pixel data in the source Raster.
|
||||
* If the destination Raster is null, a new Raster will be created.
|
||||
* The source and destination must have the same number of bands.
|
||||
* Otherwise, an IllegalArgumentException is thrown.
|
||||
* Note that the number of scaling factors/offsets in this object must
|
||||
* meet the restrictions stated in the class comments above.
|
||||
* Otherwise, an IllegalArgumentException is thrown.
|
||||
* @param src the <code>Raster</code> to be filtered
|
||||
* @param dst the destination for the filtering operation
|
||||
* or <code>null</code>
|
||||
* @return the filtered <code>WritableRaster</code>.
|
||||
* @throws IllegalArgumentException if <code>src</code> and
|
||||
* <code>dst</code> do not have the same number of bands,
|
||||
* or if the number of scaling factors and offsets in this
|
||||
* <code>RescaleOp</code> do not meet the requirements
|
||||
* stated in the class comments.
|
||||
*/
|
||||
public final WritableRaster filter (Raster src, WritableRaster dst) {
|
||||
return filterRasterImpl(src, dst, length, true);
|
||||
}
|
||||
|
||||
private WritableRaster filterRasterImpl(Raster src, WritableRaster dst,
|
||||
int scaleConst, boolean sCheck) {
|
||||
int numBands = src.getNumBands();
|
||||
int width = src.getWidth();
|
||||
int height = src.getHeight();
|
||||
int[] srcPix = null;
|
||||
int step = 0;
|
||||
int tidx = 0;
|
||||
|
||||
// Create a new destination Raster, if needed
|
||||
if (dst == null) {
|
||||
dst = createCompatibleDestRaster(src);
|
||||
}
|
||||
else if (height != dst.getHeight() || width != dst.getWidth()) {
|
||||
throw new
|
||||
IllegalArgumentException("Width or height of Rasters do not "+
|
||||
"match");
|
||||
}
|
||||
else if (numBands != dst.getNumBands()) {
|
||||
// Make sure that the number of bands are equal
|
||||
throw new IllegalArgumentException("Number of bands in src "
|
||||
+ numBands
|
||||
+ " does not equal number of bands in dest "
|
||||
+ dst.getNumBands());
|
||||
}
|
||||
|
||||
// Make sure that the arrays match
|
||||
// Make sure that the low/high/constant arrays match
|
||||
if (sCheck && scaleConst != 1 && scaleConst != src.getNumBands()) {
|
||||
throw new IllegalArgumentException("Number of scaling constants "+
|
||||
"does not equal the number of"+
|
||||
" of bands in the src raster");
|
||||
}
|
||||
|
||||
//
|
||||
// Try for a native raster rescale first
|
||||
//
|
||||
if (ImagingLib.filter(this, src, dst) != null) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
//
|
||||
// Native raster rescale failed.
|
||||
// Try to see if a lookup operation can be used
|
||||
//
|
||||
if (canUseLookup(src, dst)) {
|
||||
int srcNgray = (1 << srcNbits);
|
||||
int dstNgray = (1 << dstNbits);
|
||||
|
||||
if (dstNgray == 256) {
|
||||
ByteLookupTable lut = createByteLut(scaleFactors, offsets,
|
||||
numBands, srcNgray);
|
||||
LookupOp op = new LookupOp(lut, hints);
|
||||
op.filter(src, dst);
|
||||
} else {
|
||||
ShortLookupTable lut = createShortLut(scaleFactors, offsets,
|
||||
numBands, srcNgray);
|
||||
LookupOp op = new LookupOp(lut, hints);
|
||||
op.filter(src, dst);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Fall back to the slow code
|
||||
//
|
||||
if (scaleConst > 1) {
|
||||
step = 1;
|
||||
}
|
||||
|
||||
int sminX = src.getMinX();
|
||||
int sY = src.getMinY();
|
||||
int dminX = dst.getMinX();
|
||||
int dY = dst.getMinY();
|
||||
int sX;
|
||||
int dX;
|
||||
|
||||
//
|
||||
// Determine bits per band to determine maxval for clamps.
|
||||
// The min is assumed to be zero.
|
||||
// REMIND: This must change if we ever support signed data types.
|
||||
//
|
||||
int nbits;
|
||||
int dstMax[] = new int[numBands];
|
||||
int dstMask[] = new int[numBands];
|
||||
SampleModel dstSM = dst.getSampleModel();
|
||||
for (int z=0; z<numBands; z++) {
|
||||
nbits = dstSM.getSampleSize(z);
|
||||
dstMax[z] = (1 << nbits) - 1;
|
||||
dstMask[z] = ~(dstMax[z]);
|
||||
}
|
||||
|
||||
int val;
|
||||
for (int y=0; y < height; y++, sY++, dY++) {
|
||||
dX = dminX;
|
||||
sX = sminX;
|
||||
for (int x = 0; x < width; x++, sX++, dX++) {
|
||||
// Get data for all bands at this x,y position
|
||||
srcPix = src.getPixel(sX, sY, srcPix);
|
||||
tidx = 0;
|
||||
for (int z=0; z<numBands; z++, tidx += step) {
|
||||
if ((scaleConst == 1 || scaleConst == 3) &&
|
||||
(z == 3) && (numBands == 4)) {
|
||||
val = srcPix[z];
|
||||
} else {
|
||||
val = (int)(srcPix[z]*scaleFactors[tidx]
|
||||
+ offsets[tidx]);
|
||||
|
||||
}
|
||||
// Clamp
|
||||
if ((val & dstMask[z]) != 0) {
|
||||
if (val < 0) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = dstMax[z];
|
||||
}
|
||||
}
|
||||
srcPix[z] = val;
|
||||
|
||||
}
|
||||
|
||||
// Put it back for all bands
|
||||
dst.setPixel(dX, dY, srcPix);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the rescaled destination image. Since
|
||||
* this is not a geometric operation, the bounding box does not
|
||||
* change.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (BufferedImage src) {
|
||||
return getBounds2D(src.getRaster());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounding box of the rescaled destination Raster. Since
|
||||
* this is not a geometric operation, the bounding box does not
|
||||
* change.
|
||||
* @param src the rescaled destination <code>Raster</code>
|
||||
* @return the bounds of the specified <code>Raster</code>.
|
||||
*/
|
||||
public final Rectangle2D getBounds2D (Raster src) {
|
||||
return src.getBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed destination image with the correct size and number of
|
||||
* bands.
|
||||
* @param src Source image for the filter operation.
|
||||
* @param destCM ColorModel of the destination. If null, the
|
||||
* ColorModel of the source will be used.
|
||||
* @return the zeroed-destination image.
|
||||
*/
|
||||
public BufferedImage createCompatibleDestImage (BufferedImage src,
|
||||
ColorModel destCM) {
|
||||
BufferedImage image;
|
||||
if (destCM == null) {
|
||||
ColorModel cm = src.getColorModel();
|
||||
image = new BufferedImage(cm,
|
||||
src.getRaster().createCompatibleWritableRaster(),
|
||||
cm.isAlphaPremultiplied(),
|
||||
null);
|
||||
}
|
||||
else {
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
image = new BufferedImage (destCM,
|
||||
destCM.createCompatibleWritableRaster(w, h),
|
||||
destCM.isAlphaPremultiplied(), null);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zeroed-destination <code>Raster</code> with the correct
|
||||
* size and number of bands, given this source.
|
||||
* @param src the source <code>Raster</code>
|
||||
* @return the zeroed-destination <code>Raster</code>.
|
||||
*/
|
||||
public WritableRaster createCompatibleDestRaster (Raster src) {
|
||||
return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the destination point given a
|
||||
* point in the source. If dstPt is non-null, it will
|
||||
* be used to hold the return value. Since this is not a geometric
|
||||
* operation, the srcPt will equal the dstPt.
|
||||
* @param srcPt a point in the source image
|
||||
* @param dstPt the destination point or <code>null</code>
|
||||
* @return the location of the destination point.
|
||||
*/
|
||||
public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
|
||||
if (dstPt == null) {
|
||||
dstPt = new Point2D.Float();
|
||||
}
|
||||
dstPt.setLocation(srcPt.getX(), srcPt.getY());
|
||||
return dstPt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendering hints for this op.
|
||||
* @return the rendering hints of this <code>RescaleOp</code>.
|
||||
*/
|
||||
public final RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
}
|
||||
1507
jdkSrc/jdk8/java/awt/image/SampleModel.java
Normal file
1507
jdkSrc/jdk8/java/awt/image/SampleModel.java
Normal file
File diff suppressed because it is too large
Load Diff
204
jdkSrc/jdk8/java/awt/image/ShortLookupTable.java
Normal file
204
jdkSrc/jdk8/java/awt/image/ShortLookupTable.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
|
||||
/**
|
||||
* This class defines a lookup table object. The output of a
|
||||
* lookup operation using an object of this class is interpreted
|
||||
* as an unsigned short quantity. The lookup table contains short
|
||||
* data arrays for one or more bands (or components) of an image,
|
||||
* and it contains an offset which will be subtracted from the
|
||||
* input values before indexing the arrays. This allows an array
|
||||
* smaller than the native data size to be provided for a
|
||||
* constrained input. If there is only one array in the lookup
|
||||
* table, it will be applied to all bands.
|
||||
*
|
||||
* @see ByteLookupTable
|
||||
* @see LookupOp
|
||||
*/
|
||||
public class ShortLookupTable extends LookupTable {
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
short data[][];
|
||||
|
||||
/**
|
||||
* Constructs a ShortLookupTable object from an array of short
|
||||
* arrays representing a lookup table for each
|
||||
* band. The offset will be subtracted from the input
|
||||
* values before indexing into the arrays. The number of
|
||||
* bands is the length of the data argument. The
|
||||
* data array for each band is stored as a reference.
|
||||
* @param offset the value subtracted from the input values
|
||||
* before indexing into the arrays
|
||||
* @param data an array of short arrays representing a lookup
|
||||
* table for each band
|
||||
*/
|
||||
public ShortLookupTable(int offset, short data[][]) {
|
||||
super(offset,data.length);
|
||||
numComponents = data.length;
|
||||
numEntries = data[0].length;
|
||||
this.data = new short[numComponents][];
|
||||
// Allocate the array and copy the data reference
|
||||
for (int i=0; i < numComponents; i++) {
|
||||
this.data[i] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ShortLookupTable object from an array
|
||||
* of shorts representing a lookup table for each
|
||||
* band. The offset will be subtracted from the input
|
||||
* values before indexing into the array. The
|
||||
* data array is stored as a reference.
|
||||
* @param offset the value subtracted from the input values
|
||||
* before indexing into the arrays
|
||||
* @param data an array of shorts
|
||||
*/
|
||||
public ShortLookupTable(int offset, short data[]) {
|
||||
super(offset,data.length);
|
||||
numComponents = 1;
|
||||
numEntries = data.length;
|
||||
this.data = new short[1][];
|
||||
this.data[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lookup table data by reference. If this ShortLookupTable
|
||||
* was constructed using a single short array, the length of the returned
|
||||
* array is one.
|
||||
* @return ShortLookupTable data array.
|
||||
*/
|
||||
public final short[][] getTable(){
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of samples of a pixel, translated with the lookup
|
||||
* table. The source and destination array can be the same array.
|
||||
* Array <code>dst</code> is returned.
|
||||
*
|
||||
* @param src the source array.
|
||||
* @param dst the destination array. This array must be at least as
|
||||
* long as <code>src</code>. If <code>dst</code> is
|
||||
* <code>null</code>, a new array will be allocated having the
|
||||
* same length as <code>src</code>.
|
||||
* @return the array <code>dst</code>, an <code>int</code> array of
|
||||
* samples.
|
||||
* @exception ArrayIndexOutOfBoundsException if <code>src</code> is
|
||||
* longer than <code>dst</code> or if for any element
|
||||
* <code>i</code> of <code>src</code>,
|
||||
* {@code (src[i]&0xffff)-offset} is either less than
|
||||
* zero or greater than or equal to the length of the
|
||||
* lookup table for any band.
|
||||
*/
|
||||
public int[] lookupPixel(int[] src, int[] dst){
|
||||
if (dst == null) {
|
||||
// Need to alloc a new destination array
|
||||
dst = new int[src.length];
|
||||
}
|
||||
|
||||
if (numComponents == 1) {
|
||||
// Apply one LUT to all channels
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = (src[i]&0xffff) - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = (int) data[0][s];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = (src[i]&0xffff) - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = (int) data[i][s];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of samples of a pixel, translated with the lookup
|
||||
* table. The source and destination array can be the same array.
|
||||
* Array <code>dst</code> is returned.
|
||||
*
|
||||
* @param src the source array.
|
||||
* @param dst the destination array. This array must be at least as
|
||||
* long as <code>src</code>. If <code>dst</code> is
|
||||
* <code>null</code>, a new array will be allocated having the
|
||||
* same length as <code>src</code>.
|
||||
* @return the array <code>dst</code>, an <code>int</code> array of
|
||||
* samples.
|
||||
* @exception ArrayIndexOutOfBoundsException if <code>src</code> is
|
||||
* longer than <code>dst</code> or if for any element
|
||||
* <code>i</code> of <code>src</code>,
|
||||
* {@code (src[i]&0xffff)-offset} is either less than
|
||||
* zero or greater than or equal to the length of the
|
||||
* lookup table for any band.
|
||||
*/
|
||||
public short[] lookupPixel(short[] src, short[] dst){
|
||||
if (dst == null) {
|
||||
// Need to alloc a new destination array
|
||||
dst = new short[src.length];
|
||||
}
|
||||
|
||||
if (numComponents == 1) {
|
||||
// Apply one LUT to all channels
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = (src[i]&0xffff) - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = data[0][s];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=0; i < src.length; i++) {
|
||||
int s = (src[i]&0xffff) - offset;
|
||||
if (s < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("src["+i+
|
||||
"]-offset is "+
|
||||
"less than zero");
|
||||
}
|
||||
dst[i] = data[i][s];
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
}
|
||||
801
jdkSrc/jdk8/java/awt/image/SinglePixelPackedSampleModel.java
Normal file
801
jdkSrc/jdk8/java/awt/image/SinglePixelPackedSampleModel.java
Normal file
@@ -0,0 +1,801 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class represents pixel data packed such that the N samples which make
|
||||
* up a single pixel are stored in a single data array element, and each data
|
||||
* data array element holds samples for only one pixel.
|
||||
* This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT} data types.
|
||||
* All data array elements reside
|
||||
* in the first bank of a DataBuffer. Accessor methods are provided so
|
||||
* that the image data can be manipulated directly. Scanline stride is the
|
||||
* number of data array elements between a given sample and the corresponding
|
||||
* sample in the same column of the next scanline. Bit masks are the masks
|
||||
* required to extract the samples representing the bands of the pixel.
|
||||
* Bit offsets are the offsets in bits into the data array
|
||||
* element of the samples representing the bands of the pixel.
|
||||
* <p>
|
||||
* The following code illustrates extracting the bits of the sample
|
||||
* representing band <code>b</code> for pixel <code>x,y</code>
|
||||
* from DataBuffer <code>data</code>:
|
||||
* <pre>{@code
|
||||
* int sample = data.getElem(y * scanlineStride + x);
|
||||
* sample = (sample & bitMasks[b]) >>> bitOffsets[b];
|
||||
* }</pre>
|
||||
*/
|
||||
|
||||
public class SinglePixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
/** Bit masks for all bands of the image data. */
|
||||
private int bitMasks[];
|
||||
|
||||
/** Bit Offsets for all bands of the image data. */
|
||||
private int bitOffsets[];
|
||||
|
||||
/** Bit sizes for all the bands of the image data. */
|
||||
private int bitSizes[];
|
||||
|
||||
/** Maximum bit size. */
|
||||
private int maxBitSize;
|
||||
|
||||
/** Line stride of the region of image data described by this
|
||||
* SinglePixelPackedSampleModel.
|
||||
*/
|
||||
private int scanlineStride;
|
||||
|
||||
private static native void initIDs();
|
||||
static {
|
||||
ColorModel.loadLibraries();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
|
||||
* Each sample is stored in a data array element in the position of
|
||||
* its corresponding bit mask. Each bit mask must be contiguous and
|
||||
* masks must not overlap. Bit masks exceeding data type capacity are
|
||||
* truncated.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of the
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of the
|
||||
* image data described.
|
||||
* @param bitMasks The bit masks for all bands.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int bitMasks[]) {
|
||||
this(dataType, w, h, w, bitMasks);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
|
||||
* and a scanline stride equal to scanlineStride data array elements.
|
||||
* Each sample is stored in a data array element in the position of
|
||||
* its corresponding bit mask. Each bit mask must be contiguous and
|
||||
* masks must not overlap. Bit masks exceeding data type capacity are
|
||||
* truncated.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param scanlineStride The line stride of the image data.
|
||||
* @param bitMasks The bit masks for all bands.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if any mask in
|
||||
* <code>bitMask</code> is not contiguous
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int scanlineStride, int bitMasks[]) {
|
||||
super(dataType, w, h, bitMasks.length);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
this.bitMasks = (int[]) bitMasks.clone();
|
||||
this.scanlineStride = scanlineStride;
|
||||
|
||||
this.bitOffsets = new int[numBands];
|
||||
this.bitSizes = new int[numBands];
|
||||
|
||||
int maxMask = (int)((1L << DataBuffer.getDataTypeSize(dataType)) - 1);
|
||||
|
||||
this.maxBitSize = 0;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
int bitOffset = 0, bitSize = 0, mask;
|
||||
this.bitMasks[i] &= maxMask;
|
||||
mask = this.bitMasks[i];
|
||||
if (mask != 0) {
|
||||
while ((mask & 1) == 0) {
|
||||
mask = mask >>> 1;
|
||||
bitOffset++;
|
||||
}
|
||||
while ((mask & 1) == 1) {
|
||||
mask = mask >>> 1;
|
||||
bitSize++;
|
||||
}
|
||||
if (mask != 0) {
|
||||
throw new IllegalArgumentException("Mask "+bitMasks[i]+
|
||||
" must be contiguous");
|
||||
}
|
||||
}
|
||||
bitOffsets[i] = bitOffset;
|
||||
bitSizes[i] = bitSize;
|
||||
if (bitSize > maxBitSize) {
|
||||
maxBitSize = bitSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data elements needed to transfer one pixel
|
||||
* via the getDataElements and setDataElements methods.
|
||||
* For a SinglePixelPackedSampleModel, this is one.
|
||||
*/
|
||||
public int getNumDataElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the buffer (in data array elements)
|
||||
* needed for a data buffer that matches this
|
||||
* SinglePixelPackedSampleModel.
|
||||
*/
|
||||
private long getBufferSize() {
|
||||
long size = scanlineStride * (height-1) + width;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SinglePixelPackedSampleModel with the specified
|
||||
* width and height. The new SinglePixelPackedSampleModel will have the
|
||||
* same storage data type and bit masks as this
|
||||
* SinglePixelPackedSampleModel.
|
||||
* @param w the width of the resulting <code>SampleModel</code>
|
||||
* @param h the height of the resulting <code>SampleModel</code>
|
||||
* @return a <code>SinglePixelPackedSampleModel</code> with the
|
||||
* specified width and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
SampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
|
||||
bitMasks);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer that corresponds to this
|
||||
* SinglePixelPackedSampleModel. The DataBuffer's data type and size
|
||||
* will be consistent with this SinglePixelPackedSampleModel. The
|
||||
* DataBuffer will have a single bank.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = (int)getBufferSize();
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size);
|
||||
break;
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
/** Returns the number of bits per sample for all bands. */
|
||||
public int[] getSampleSize() {
|
||||
return bitSizes.clone();
|
||||
}
|
||||
|
||||
/** Returns the number of bits per sample for the specified band. */
|
||||
public int getSampleSize(int band) {
|
||||
return bitSizes[band];
|
||||
}
|
||||
|
||||
/** Returns the offset (in data array elements) of pixel (x,y).
|
||||
* The data element containing pixel <code>x,y</code>
|
||||
* can be retrieved from a DataBuffer <code>data</code> with a
|
||||
* SinglePixelPackedSampleModel <code>sppsm</code> as:
|
||||
* <pre>
|
||||
* data.getElem(sppsm.getOffset(x, y));
|
||||
* </pre>
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @return the offset of the specified pixel.
|
||||
*/
|
||||
public int getOffset(int x, int y) {
|
||||
int offset = y * scanlineStride + x;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Returns the bit offsets into the data array element representing
|
||||
* a pixel for all bands.
|
||||
* @return the bit offsets representing a pixel for all bands.
|
||||
*/
|
||||
public int [] getBitOffsets() {
|
||||
return (int[])bitOffsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the bit masks for all bands.
|
||||
* @return the bit masks for all bands.
|
||||
*/
|
||||
public int [] getBitMasks() {
|
||||
return (int[])bitMasks.clone();
|
||||
}
|
||||
|
||||
/** Returns the scanline stride of this SinglePixelPackedSampleModel.
|
||||
* @return the scanline stride of this
|
||||
* <code>SinglePixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getScanlineStride() {
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates a new SinglePixelPackedSampleModel with a subset of the
|
||||
* bands of this SinglePixelPackedSampleModel. The new
|
||||
* SinglePixelPackedSampleModel can be used with any DataBuffer that the
|
||||
* existing SinglePixelPackedSampleModel can be used with. The new
|
||||
* SinglePixelPackedSampleModel/DataBuffer combination will represent
|
||||
* an image with a subset of the bands of the original
|
||||
* SinglePixelPackedSampleModel/DataBuffer combination.
|
||||
* @exception RasterFormatException if the length of the bands argument is
|
||||
* greater than the number of bands in
|
||||
* the sample model.
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands.length > numBands)
|
||||
throw new RasterFormatException("There are only " +
|
||||
numBands +
|
||||
" bands");
|
||||
int newBitMasks[] = new int[bands.length];
|
||||
for (int i=0; i<bands.length; i++)
|
||||
newBitMasks[i] = bitMasks[bands[i]];
|
||||
|
||||
return new SinglePixelPackedSampleModel(this.dataType, width, height,
|
||||
this.scanlineStride, newBitMasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a SinglePixelPackedSampleModel, the array will
|
||||
* have one element, and the type will be the same as the storage
|
||||
* data type. Generally, obj
|
||||
* should be passed in as null, so that the Object will be created
|
||||
* automatically and will be of the right primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm1</code>, to
|
||||
* DataBuffer <code>db2</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* SinglePixelPackedSampleModel sppsm1, sppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If obj is non-null, it should be a primitive array of type TransferType.
|
||||
* Otherwise, a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is non-null and is not large enough to hold
|
||||
* the pixel data.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param obj If non-null, a primitive array in which to return
|
||||
* the pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the data for the specified pixel.
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null)
|
||||
bdata = new byte[1];
|
||||
else
|
||||
bdata = (byte[])obj;
|
||||
|
||||
bdata[0] = (byte)data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null)
|
||||
sdata = new short[1];
|
||||
else
|
||||
sdata = (short[])obj;
|
||||
|
||||
sdata[0] = (short)data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null)
|
||||
idata = new int[1];
|
||||
else
|
||||
idata = (int[])obj;
|
||||
|
||||
idata[0] = data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples in for the specified pixel in an int array.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return all samples for the specified pixel.
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int [] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray == null) {
|
||||
pixels = new int [numBands];
|
||||
} else {
|
||||
pixels = iArray;
|
||||
}
|
||||
|
||||
int value = data.getElem(y * scanlineStride + x);
|
||||
for (int i=0; i<numBands; i++) {
|
||||
pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified rectangle of pixels in
|
||||
* an int array, one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param iArray If non-null, returns the samples in this array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return all samples for the specified region of pixels.
|
||||
* @see #setPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
int x1 = x + w;
|
||||
int y1 = y + h;
|
||||
|
||||
if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
|
||||
y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
|
||||
{
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [w*h*numBands];
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int dstOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
for (int k=0; k < numBands; k++) {
|
||||
pixels[dstOffset++] =
|
||||
((value & bitMasks[k]) >>> bitOffsets[k]);
|
||||
}
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as int the sample in a specified band for the pixel
|
||||
* located at (x,y).
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to return.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the sample in a specified band for the specified
|
||||
* pixel.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int sample = data.getElem(y * scanlineStride + x);
|
||||
return ((sample & bitMasks[b]) >>> bitOffsets[b]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples for a specified band for the specified rectangle
|
||||
* of pixels in an int array, one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param b The band to return.
|
||||
* @param iArray If non-null, returns the samples in this array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the samples for the specified band for the specified
|
||||
* region of pixels.
|
||||
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int samples[];
|
||||
if (iArray != null) {
|
||||
samples = iArray;
|
||||
} else {
|
||||
samples = new int [w*h];
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int dstOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
samples[dstOffset++] =
|
||||
((value & bitMasks[b]) >>> bitOffsets[b]);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified DataBuffer from a
|
||||
* primitive array of type TransferType. For a
|
||||
* SinglePixelPackedSampleModel, only the first element of the array
|
||||
* will hold valid data, and the type of the array must be the same as
|
||||
* the storage data type of the SinglePixelPackedSampleModel.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm1</code>,
|
||||
* to DataBuffer <code>db2</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* SinglePixelPackedSampleModel sppsm1, sppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* obj must be a primitive array of type TransferType. Otherwise,
|
||||
* a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is not large enough to hold the pixel data.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param obj A primitive array containing pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
data.setElem(y*scanlineStride+x, iarray[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y,
|
||||
int iArray[],
|
||||
DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y * scanlineStride + x;
|
||||
int value = data.getElem(lineOffset);
|
||||
for (int i=0; i < numBands; i++) {
|
||||
value &= ~bitMasks[i];
|
||||
value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
|
||||
}
|
||||
data.setElem(lineOffset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
int x1 = x + w;
|
||||
int y1 = y + h;
|
||||
|
||||
if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
|
||||
y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
|
||||
{
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
for (int k=0; k < numBands; k++) {
|
||||
value &= ~bitMasks[k];
|
||||
int srcValue = iArray[srcOffset++];
|
||||
value |= ((srcValue << bitOffsets[k])
|
||||
& bitMasks[k]);
|
||||
}
|
||||
data.setElem(lineOffset+j, value);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as an int.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int value = data.getElem(y*scanlineStride + x);
|
||||
value &= ~bitMasks[b];
|
||||
value |= (s << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(y*scanlineStride + x,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
value &= ~bitMasks[b];
|
||||
int sample = iArray[srcOffset++];
|
||||
value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(lineOffset+j,value);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel)o;
|
||||
return this.width == that.width &&
|
||||
this.height == that.height &&
|
||||
this.numBands == that.numBands &&
|
||||
this.dataType == that.dataType &&
|
||||
Arrays.equals(this.bitMasks, that.bitMasks) &&
|
||||
Arrays.equals(this.bitOffsets, that.bitOffsets) &&
|
||||
Arrays.equals(this.bitSizes, that.bitSizes) &&
|
||||
this.maxBitSize == that.maxBitSize &&
|
||||
this.scanlineStride == that.scanlineStride;
|
||||
}
|
||||
|
||||
// If we implement equals() we must also implement hashCode
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
hash = width;
|
||||
hash <<= 8;
|
||||
hash ^= height;
|
||||
hash <<= 8;
|
||||
hash ^= numBands;
|
||||
hash <<= 8;
|
||||
hash ^= dataType;
|
||||
hash <<= 8;
|
||||
for (int i = 0; i < bitMasks.length; i++) {
|
||||
hash ^= bitMasks[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
for (int i = 0; i < bitOffsets.length; i++) {
|
||||
hash ^= bitOffsets[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
for (int i = 0; i < bitSizes.length; i++) {
|
||||
hash ^= bitSizes[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
hash ^= maxBitSize;
|
||||
hash <<= 8;
|
||||
hash ^= scanlineStride;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
55
jdkSrc/jdk8/java/awt/image/TileObserver.java
Normal file
55
jdkSrc/jdk8/java/awt/image/TileObserver.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* An interface for objects that wish to be informed when tiles
|
||||
* of a WritableRenderedImage become modifiable by some writer via
|
||||
* a call to getWritableTile, and when they become unmodifiable via
|
||||
* the last call to releaseWritableTile.
|
||||
*
|
||||
* @see WritableRenderedImage
|
||||
*
|
||||
* @author Thomas DeWeese
|
||||
* @author Daniel Rice
|
||||
*/
|
||||
public interface TileObserver {
|
||||
|
||||
/**
|
||||
* A tile is about to be updated (it is either about to be grabbed
|
||||
* for writing, or it is being released from writing).
|
||||
*
|
||||
* @param source the image that owns the tile.
|
||||
* @param tileX the X index of the tile that is being updated.
|
||||
* @param tileY the Y index of the tile that is being updated.
|
||||
* @param willBeWritable If true, the tile will be grabbed for writing;
|
||||
* otherwise it is being released.
|
||||
*/
|
||||
public void tileUpdate(WritableRenderedImage source,
|
||||
int tileX, int tileY,
|
||||
boolean willBeWritable);
|
||||
|
||||
}
|
||||
342
jdkSrc/jdk8/java/awt/image/VolatileImage.java
Normal file
342
jdkSrc/jdk8/java/awt/image/VolatileImage.java
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Image;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Transparency;
|
||||
|
||||
/**
|
||||
* VolatileImage is an image which can lose its
|
||||
* contents at any time due to circumstances beyond the control of the
|
||||
* application (e.g., situations caused by the operating system or by
|
||||
* other applications). Because of the potential for hardware acceleration,
|
||||
* a VolatileImage object can have significant performance benefits on
|
||||
* some platforms.
|
||||
* <p>
|
||||
* The drawing surface of an image (the memory where the image contents
|
||||
* actually reside) can be lost or invalidated, causing the contents of that
|
||||
* memory to go away. The drawing surface thus needs to be restored
|
||||
* or recreated and the contents of that surface need to be
|
||||
* re-rendered. VolatileImage provides an interface for
|
||||
* allowing the user to detect these problems and fix them
|
||||
* when they occur.
|
||||
* <p>
|
||||
* When a VolatileImage object is created, limited system resources
|
||||
* such as video memory (VRAM) may be allocated in order to support
|
||||
* the image.
|
||||
* When a VolatileImage object is no longer used, it may be
|
||||
* garbage-collected and those system resources will be returned,
|
||||
* but this process does not happen at guaranteed times.
|
||||
* Applications that create many VolatileImage objects (for example,
|
||||
* a resizing window may force recreation of its back buffer as the
|
||||
* size changes) may run out of optimal system resources for new
|
||||
* VolatileImage objects simply because the old objects have not
|
||||
* yet been removed from the system.
|
||||
* (New VolatileImage objects may still be created, but they
|
||||
* may not perform as well as those created in accelerated
|
||||
* memory).
|
||||
* The flush method may be called at any time to proactively release
|
||||
* the resources used by a VolatileImage so that it does not prevent
|
||||
* subsequent VolatileImage objects from being accelerated.
|
||||
* In this way, applications can have more control over the state
|
||||
* of the resources taken up by obsolete VolatileImage objects.
|
||||
* <p>
|
||||
* This image should not be subclassed directly but should be created
|
||||
* by using the {@link java.awt.Component#createVolatileImage(int, int)
|
||||
* Component.createVolatileImage} or
|
||||
* {@link java.awt.GraphicsConfiguration#createCompatibleVolatileImage(int, int)
|
||||
* GraphicsConfiguration.createCompatibleVolatileImage(int, int)} methods.
|
||||
* <P>
|
||||
* An example of using a VolatileImage object follows:
|
||||
* <pre>
|
||||
* // image creation
|
||||
* VolatileImage vImg = createVolatileImage(w, h);
|
||||
*
|
||||
*
|
||||
* // rendering to the image
|
||||
* void renderOffscreen() {
|
||||
* do {
|
||||
* if (vImg.validate(getGraphicsConfiguration()) ==
|
||||
* VolatileImage.IMAGE_INCOMPATIBLE)
|
||||
* {
|
||||
* // old vImg doesn't work with new GraphicsConfig; re-create it
|
||||
* vImg = createVolatileImage(w, h);
|
||||
* }
|
||||
* Graphics2D g = vImg.createGraphics();
|
||||
* //
|
||||
* // miscellaneous rendering commands...
|
||||
* //
|
||||
* g.dispose();
|
||||
* } while (vImg.contentsLost());
|
||||
* }
|
||||
*
|
||||
*
|
||||
* // copying from the image (here, gScreen is the Graphics
|
||||
* // object for the onscreen window)
|
||||
* do {
|
||||
* int returnCode = vImg.validate(getGraphicsConfiguration());
|
||||
* if (returnCode == VolatileImage.IMAGE_RESTORED) {
|
||||
* // Contents need to be restored
|
||||
* renderOffscreen(); // restore contents
|
||||
* } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
|
||||
* // old vImg doesn't work with new GraphicsConfig; re-create it
|
||||
* vImg = createVolatileImage(w, h);
|
||||
* renderOffscreen();
|
||||
* }
|
||||
* gScreen.drawImage(vImg, 0, 0, this);
|
||||
* } while (vImg.contentsLost());
|
||||
* </pre>
|
||||
* <P>
|
||||
* Note that this class subclasses from the {@link Image} class, which
|
||||
* includes methods that take an {@link ImageObserver} parameter for
|
||||
* asynchronous notifications as information is received from
|
||||
* a potential {@link ImageProducer}. Since this <code>VolatileImage</code>
|
||||
* is not loaded from an asynchronous source, the various methods that take
|
||||
* an <code>ImageObserver</code> parameter will behave as if the data has
|
||||
* already been obtained from the <code>ImageProducer</code>.
|
||||
* Specifically, this means that the return values from such methods
|
||||
* will never indicate that the information is not yet available and
|
||||
* the <code>ImageObserver</code> used in such methods will never
|
||||
* need to be recorded for an asynchronous callback notification.
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class VolatileImage extends Image implements Transparency
|
||||
{
|
||||
|
||||
// Return codes for validate() method
|
||||
|
||||
/**
|
||||
* Validated image is ready to use as-is.
|
||||
*/
|
||||
public static final int IMAGE_OK = 0;
|
||||
|
||||
/**
|
||||
* Validated image has been restored and is now ready to use.
|
||||
* Note that restoration causes contents of the image to be lost.
|
||||
*/
|
||||
public static final int IMAGE_RESTORED = 1;
|
||||
|
||||
/**
|
||||
* Validated image is incompatible with supplied
|
||||
* <code>GraphicsConfiguration</code> object and should be
|
||||
* re-created as appropriate. Usage of the image as-is
|
||||
* after receiving this return code from <code>validate</code>
|
||||
* is undefined.
|
||||
*/
|
||||
public static final int IMAGE_INCOMPATIBLE = 2;
|
||||
|
||||
/**
|
||||
* Returns a static snapshot image of this object. The
|
||||
* <code>BufferedImage</code> returned is only current with
|
||||
* the <code>VolatileImage</code> at the time of the request
|
||||
* and will not be updated with any future changes to the
|
||||
* <code>VolatileImage</code>.
|
||||
* @return a {@link BufferedImage} representation of this
|
||||
* <code>VolatileImage</code>
|
||||
* @see BufferedImage
|
||||
*/
|
||||
public abstract BufferedImage getSnapshot();
|
||||
|
||||
/**
|
||||
* Returns the width of the <code>VolatileImage</code>.
|
||||
* @return the width of this <code>VolatileImage</code>.
|
||||
*/
|
||||
public abstract int getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of the <code>VolatileImage</code>.
|
||||
* @return the height of this <code>VolatileImage</code>.
|
||||
*/
|
||||
public abstract int getHeight();
|
||||
|
||||
// Image overrides
|
||||
|
||||
/**
|
||||
* This returns an ImageProducer for this VolatileImage.
|
||||
* Note that the VolatileImage object is optimized for
|
||||
* rendering operations and blitting to the screen or other
|
||||
* VolatileImage objects, as opposed to reading back the
|
||||
* pixels of the image. Therefore, operations such as
|
||||
* <code>getSource</code> may not perform as fast as
|
||||
* operations that do not rely on reading the pixels.
|
||||
* Note also that the pixel values read from the image are current
|
||||
* with those in the image only at the time that they are
|
||||
* retrieved. This method takes a snapshot
|
||||
* of the image at the time the request is made and the
|
||||
* ImageProducer object returned works with
|
||||
* that static snapshot image, not the original VolatileImage.
|
||||
* Calling getSource()
|
||||
* is equivalent to calling getSnapshot().getSource().
|
||||
* @return an {@link ImageProducer} that can be used to produce the
|
||||
* pixels for a <code>BufferedImage</code> representation of
|
||||
* this Image.
|
||||
* @see ImageProducer
|
||||
* @see #getSnapshot()
|
||||
*/
|
||||
public ImageProducer getSource() {
|
||||
// REMIND: Make sure this functionality is in line with the
|
||||
// spec. In particular, we are returning the Source for a
|
||||
// static image (the snapshot), not a changing image (the
|
||||
// VolatileImage). So if the user expects the Source to be
|
||||
// up-to-date with the current contents of the VolatileImage,
|
||||
// they will be disappointed...
|
||||
// REMIND: This assumes that getSnapshot() returns something
|
||||
// valid and not the default null object returned by this class
|
||||
// (so it assumes that the actual VolatileImage object is
|
||||
// subclassed off something that does the right thing
|
||||
// (e.g., SunVolatileImage).
|
||||
return getSnapshot().getSource();
|
||||
}
|
||||
|
||||
// REMIND: if we want any decent performance for getScaledInstance(),
|
||||
// we should override the Image implementation of it...
|
||||
|
||||
/**
|
||||
* This method returns a {@link Graphics2D}, but is here
|
||||
* for backwards compatibility. {@link #createGraphics() createGraphics} is more
|
||||
* convenient, since it is declared to return a
|
||||
* <code>Graphics2D</code>.
|
||||
* @return a <code>Graphics2D</code>, which can be used to draw into
|
||||
* this image.
|
||||
*/
|
||||
public Graphics getGraphics() {
|
||||
return createGraphics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Graphics2D</code>, which can be used to draw into
|
||||
* this <code>VolatileImage</code>.
|
||||
* @return a <code>Graphics2D</code>, used for drawing into this
|
||||
* image.
|
||||
*/
|
||||
public abstract Graphics2D createGraphics();
|
||||
|
||||
|
||||
// Volatile management methods
|
||||
|
||||
/**
|
||||
* Attempts to restore the drawing surface of the image if the surface
|
||||
* had been lost since the last <code>validate</code> call. Also
|
||||
* validates this image against the given GraphicsConfiguration
|
||||
* parameter to see whether operations from this image to the
|
||||
* GraphicsConfiguration are compatible. An example of an
|
||||
* incompatible combination might be a situation where a VolatileImage
|
||||
* object was created on one graphics device and then was used
|
||||
* to render to a different graphics device. Since VolatileImage
|
||||
* objects tend to be very device-specific, this operation might
|
||||
* not work as intended, so the return code from this validate
|
||||
* call would note that incompatibility. A null or incorrect
|
||||
* value for gc may cause incorrect values to be returned from
|
||||
* <code>validate</code> and may cause later problems with rendering.
|
||||
*
|
||||
* @param gc a <code>GraphicsConfiguration</code> object for this
|
||||
* image to be validated against. A null gc implies that the
|
||||
* validate method should skip the compatibility test.
|
||||
* @return <code>IMAGE_OK</code> if the image did not need validation<BR>
|
||||
* <code>IMAGE_RESTORED</code> if the image needed restoration.
|
||||
* Restoration implies that the contents of the image may have
|
||||
* been affected and the image may need to be re-rendered.<BR>
|
||||
* <code>IMAGE_INCOMPATIBLE</code> if the image is incompatible
|
||||
* with the <code>GraphicsConfiguration</code> object passed
|
||||
* into the <code>validate</code> method. Incompatibility
|
||||
* implies that the image may need to be recreated with a
|
||||
* new <code>Component</code> or
|
||||
* <code>GraphicsConfiguration</code> in order to get an image
|
||||
* that can be used successfully with this
|
||||
* <code>GraphicsConfiguration</code>.
|
||||
* An incompatible image is not checked for whether restoration
|
||||
* was necessary, so the state of the image is unchanged
|
||||
* after a return value of <code>IMAGE_INCOMPATIBLE</code>
|
||||
* and this return value implies nothing about whether the
|
||||
* image needs to be restored.
|
||||
* @see java.awt.GraphicsConfiguration
|
||||
* @see java.awt.Component
|
||||
* @see #IMAGE_OK
|
||||
* @see #IMAGE_RESTORED
|
||||
* @see #IMAGE_INCOMPATIBLE
|
||||
*/
|
||||
public abstract int validate(GraphicsConfiguration gc);
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if rendering data was lost since last
|
||||
* <code>validate</code> call. This method should be called by the
|
||||
* application at the end of any series of rendering operations to
|
||||
* or from the image to see whether
|
||||
* the image needs to be validated and the rendering redone.
|
||||
* @return <code>true</code> if the drawing surface needs to be restored;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public abstract boolean contentsLost();
|
||||
|
||||
/**
|
||||
* Returns an ImageCapabilities object which can be
|
||||
* inquired as to the specific capabilities of this
|
||||
* VolatileImage. This would allow programmers to find
|
||||
* out more runtime information on the specific VolatileImage
|
||||
* object that they have created. For example, the user
|
||||
* might create a VolatileImage but the system may have
|
||||
* no video memory left for creating an image of that
|
||||
* size, so although the object is a VolatileImage, it is
|
||||
* not as accelerated as other VolatileImage objects on
|
||||
* this platform might be. The user might want that
|
||||
* information to find other solutions to their problem.
|
||||
* @return an <code>ImageCapabilities</code> object that contains
|
||||
* the capabilities of this <code>VolatileImage</code>.
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract ImageCapabilities getCapabilities();
|
||||
|
||||
/**
|
||||
* The transparency value with which this image was created.
|
||||
* @see java.awt.GraphicsConfiguration#createCompatibleVolatileImage(int,
|
||||
* int,int)
|
||||
* @see java.awt.GraphicsConfiguration#createCompatibleVolatileImage(int,
|
||||
* int,ImageCapabilities,int)
|
||||
* @see Transparency
|
||||
* @since 1.5
|
||||
*/
|
||||
protected int transparency = TRANSLUCENT;
|
||||
|
||||
/**
|
||||
* Returns the transparency. Returns either OPAQUE, BITMASK,
|
||||
* or TRANSLUCENT.
|
||||
* @return the transparency of this <code>VolatileImage</code>.
|
||||
* @see Transparency#OPAQUE
|
||||
* @see Transparency#BITMASK
|
||||
* @see Transparency#TRANSLUCENT
|
||||
* @since 1.5
|
||||
*/
|
||||
public int getTransparency() {
|
||||
return transparency;
|
||||
}
|
||||
}
|
||||
741
jdkSrc/jdk8/java/awt/image/WritableRaster.java
Normal file
741
jdkSrc/jdk8/java/awt/image/WritableRaster.java
Normal file
@@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* This class extends Raster to provide pixel writing capabilities.
|
||||
* Refer to the class comment for Raster for descriptions of how
|
||||
* a Raster stores pixels.
|
||||
*
|
||||
* <p> The constructors of this class are protected. To instantiate
|
||||
* a WritableRaster, use one of the createWritableRaster factory methods
|
||||
* in the Raster class.
|
||||
*/
|
||||
public class WritableRaster extends Raster {
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel. The
|
||||
* WritableRaster's upper left corner is origin and it is the
|
||||
* same size as the SampleModel. A DataBuffer large enough to
|
||||
* describe the WritableRaster is automatically created.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param origin The Point that specifies the origin.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>origin.x + sampleModel.getWidth()</code> or
|
||||
* <code>origin.y + sampleModel.getHeight()</code> results
|
||||
* in integer overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
Point origin) {
|
||||
this(sampleModel,
|
||||
sampleModel.createDataBuffer(),
|
||||
new Rectangle(origin.x,
|
||||
origin.y,
|
||||
sampleModel.getWidth(),
|
||||
sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel and DataBuffer.
|
||||
* The WritableRaster's upper left corner is origin and it is the same
|
||||
* size as the SampleModel. The DataBuffer is not initialized and must
|
||||
* be compatible with SampleModel.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param dataBuffer The DataBuffer that contains the image data.
|
||||
* @param origin The Point that specifies the origin.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>origin.x + sampleModel.getWidth()</code> or
|
||||
* <code>origin.y + sampleModel.getHeight()</code> results
|
||||
* in integer overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Point origin) {
|
||||
this(sampleModel,
|
||||
dataBuffer,
|
||||
new Rectangle(origin.x,
|
||||
origin.y,
|
||||
sampleModel.getWidth(),
|
||||
sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel, DataBuffer,
|
||||
* and parent. aRegion specifies the bounding rectangle of the new
|
||||
* Raster. When translated into the base Raster's coordinate
|
||||
* system, aRegion must be contained by the base Raster.
|
||||
* (The base Raster is the Raster's ancestor which has no parent.)
|
||||
* sampleModelTranslate specifies the sampleModelTranslateX and
|
||||
* sampleModelTranslateY values of the new Raster.
|
||||
*
|
||||
* Note that this constructor should generally be called by other
|
||||
* constructors or create methods, it should not be used directly.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param dataBuffer The DataBuffer that contains the image data.
|
||||
* @param aRegion The Rectangle that specifies the image area.
|
||||
* @param sampleModelTranslate The Point that specifies the translation
|
||||
* from SampleModel to Raster coordinates.
|
||||
* @param parent The parent (if any) of this raster.
|
||||
* @throws RasterFormatException if <code>aRegion</code> has width
|
||||
* or height less than or equal to zero, or computing either
|
||||
* <code>aRegion.x + aRegion.width</code> or
|
||||
* <code>aRegion.y + aRegion.height</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Rectangle aRegion,
|
||||
Point sampleModelTranslate,
|
||||
WritableRaster parent){
|
||||
super(sampleModel,dataBuffer,aRegion,sampleModelTranslate,parent);
|
||||
}
|
||||
|
||||
/** Returns the parent WritableRaster (if any) of this WritableRaster,
|
||||
* or else null.
|
||||
* @return the parent of this <code>WritableRaster</code>, or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public WritableRaster getWritableParent() {
|
||||
return (WritableRaster)parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WritableRaster with the same size, SampleModel and DataBuffer
|
||||
* as this one, but with a different location. The new WritableRaster
|
||||
* will possess a reference to the current WritableRaster, accessible
|
||||
* through its getParent() and getWritableParent() methods.
|
||||
*
|
||||
* @param childMinX X coord of the upper left corner of the new Raster.
|
||||
* @param childMinY Y coord of the upper left corner of the new Raster.
|
||||
* @return a <code>WritableRaster</code> the same as this one except
|
||||
* for the specified location.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>childMinX + this.getWidth()</code> or
|
||||
* <code>childMinY + this.getHeight()</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
public WritableRaster createWritableTranslatedChild(int childMinX,
|
||||
int childMinY) {
|
||||
return createWritableChild(minX,minY,width,height,
|
||||
childMinX,childMinY,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new WritableRaster which shares all or part of this
|
||||
* WritableRaster's DataBuffer. The new WritableRaster will
|
||||
* possess a reference to the current WritableRaster, accessible
|
||||
* through its getParent() and getWritableParent() methods.
|
||||
*
|
||||
* <p> The parentX, parentY, width and height parameters form a
|
||||
* Rectangle in this WritableRaster's coordinate space, indicating
|
||||
* the area of pixels to be shared. An error will be thrown if
|
||||
* this Rectangle is not contained with the bounds of the current
|
||||
* WritableRaster.
|
||||
*
|
||||
* <p> The new WritableRaster may additionally be translated to a
|
||||
* different coordinate system for the plane than that used by the current
|
||||
* WritableRaster. The childMinX and childMinY parameters give
|
||||
* the new (x, y) coordinate of the upper-left pixel of the
|
||||
* returned WritableRaster; the coordinate (childMinX, childMinY)
|
||||
* in the new WritableRaster will map to the same pixel as the
|
||||
* coordinate (parentX, parentY) in the current WritableRaster.
|
||||
*
|
||||
* <p> The new WritableRaster may be defined to contain only a
|
||||
* subset of the bands of the current WritableRaster, possibly
|
||||
* reordered, by means of the bandList parameter. If bandList is
|
||||
* null, it is taken to include all of the bands of the current
|
||||
* WritableRaster in their current order.
|
||||
*
|
||||
* <p> To create a new WritableRaster that contains a subregion of
|
||||
* the current WritableRaster, but shares its coordinate system
|
||||
* and bands, this method should be called with childMinX equal to
|
||||
* parentX, childMinY equal to parentY, and bandList equal to
|
||||
* null.
|
||||
*
|
||||
* @param parentX X coordinate of the upper left corner in this
|
||||
* WritableRaster's coordinates.
|
||||
* @param parentY Y coordinate of the upper left corner in this
|
||||
* WritableRaster's coordinates.
|
||||
* @param w Width of the region starting at (parentX, parentY).
|
||||
* @param h Height of the region starting at (parentX, parentY).
|
||||
* @param childMinX X coordinate of the upper left corner of
|
||||
* the returned WritableRaster.
|
||||
* @param childMinY Y coordinate of the upper left corner of
|
||||
* the returned WritableRaster.
|
||||
* @param bandList Array of band indices, or null to use all bands.
|
||||
* @return a <code>WritableRaster</code> sharing all or part of the
|
||||
* <code>DataBuffer</code> of this <code>WritableRaster</code>.
|
||||
* @exception RasterFormatException if the subregion is outside of the
|
||||
* raster bounds.
|
||||
* @throws RasterFormatException if <code>w</code> or
|
||||
* <code>h</code>
|
||||
* is less than or equal to zero, or computing any of
|
||||
* <code>parentX + w</code>, <code>parentY + h</code>,
|
||||
* <code>childMinX + w</code>, or
|
||||
* <code>childMinY + h</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
public WritableRaster createWritableChild(int parentX, int parentY,
|
||||
int w, int h,
|
||||
int childMinX, int childMinY,
|
||||
int bandList[]) {
|
||||
if (parentX < this.minX) {
|
||||
throw new RasterFormatException("parentX lies outside raster");
|
||||
}
|
||||
if (parentY < this.minY) {
|
||||
throw new RasterFormatException("parentY lies outside raster");
|
||||
}
|
||||
if ((parentX+w < parentX) || (parentX+w > this.width + this.minX)) {
|
||||
throw new RasterFormatException("(parentX + width) is outside raster");
|
||||
}
|
||||
if ((parentY+h < parentY) || (parentY+h > this.height + this.minY)) {
|
||||
throw new RasterFormatException("(parentY + height) is outside raster");
|
||||
}
|
||||
|
||||
SampleModel sm;
|
||||
// Note: the SampleModel for the child Raster should have the same
|
||||
// width and height as that for the parent, since it represents
|
||||
// the physical layout of the pixel data. The child Raster's width
|
||||
// and height represent a "virtual" view of the pixel data, so
|
||||
// they may be different than those of the SampleModel.
|
||||
if (bandList != null) {
|
||||
sm = sampleModel.createSubsetSampleModel(bandList);
|
||||
}
|
||||
else {
|
||||
sm = sampleModel;
|
||||
}
|
||||
|
||||
int deltaX = childMinX - parentX;
|
||||
int deltaY = childMinY - parentY;
|
||||
|
||||
return new WritableRaster(sm,
|
||||
getDataBuffer(),
|
||||
new Rectangle(childMinX,childMinY,
|
||||
w, h),
|
||||
new Point(sampleModelTranslateX+deltaX,
|
||||
sampleModelTranslateY+deltaY),
|
||||
this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel from a
|
||||
* primitive array of type TransferType. For image data supported by
|
||||
* the Java 2D(tm) API, this will be one of DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
|
||||
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
|
||||
* may be in a packed format, thus increasing efficiency for data
|
||||
* transfers.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if inData is not large enough to hold the pixel data.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* A ClassCastException will be thrown if the input object is not null
|
||||
* and references anything other than an array of TransferType.
|
||||
* @see java.awt.image.SampleModel#setDataElements(int, int, Object, DataBuffer)
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param inData An object reference to an array of type defined by
|
||||
* getTransferType() and length getNumDataElements()
|
||||
* containing the pixel data to place at x,y.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if inData is too small to hold the input.
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object inData) {
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
inData, dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a rectangle of pixels from an input Raster.
|
||||
* The input Raster must be compatible with this WritableRaster
|
||||
* in that they must have the same number of bands, corresponding bands
|
||||
* must have the same number of bits per sample, the TransferTypes
|
||||
* and NumDataElements must be the same, and the packing used by
|
||||
* the getDataElements/setDataElements must be identical.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param inRaster Raster containing data to place at x,y.
|
||||
*
|
||||
* @throws NullPointerException if inRaster is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds.
|
||||
*/
|
||||
public void setDataElements(int x, int y, Raster inRaster) {
|
||||
int dstOffX = x+inRaster.getMinX();
|
||||
int dstOffY = y+inRaster.getMinY();
|
||||
int width = inRaster.getWidth();
|
||||
int height = inRaster.getHeight();
|
||||
if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
|
||||
(dstOffX + width > this.minX + this.width) ||
|
||||
(dstOffY + height > this.minY + this.height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int srcOffX = inRaster.getMinX();
|
||||
int srcOffY = inRaster.getMinY();
|
||||
Object tdata = null;
|
||||
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
|
||||
width, 1, tdata);
|
||||
setDataElements(dstOffX, dstOffY+startY,
|
||||
width, 1, tdata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a rectangle of pixels from a
|
||||
* primitive array of type TransferType. For image data supported by
|
||||
* the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
|
||||
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
|
||||
* may be in a packed format, thus increasing efficiency for data
|
||||
* transfers.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if inData is not large enough to hold the pixel data.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* A ClassCastException will be thrown if the input object is not null
|
||||
* and references anything other than an array of TransferType.
|
||||
* @see java.awt.image.SampleModel#setDataElements(int, int, int, int, Object, DataBuffer)
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param inData An object reference to an array of type defined by
|
||||
* getTransferType() and length w*h*getNumDataElements()
|
||||
* containing the pixel data to place between x,y and
|
||||
* x+w-1, y+h-1.
|
||||
*
|
||||
* @throws NullPointerException if inData is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if inData is too small to hold the input.
|
||||
*/
|
||||
public void setDataElements(int x, int y, int w, int h, Object inData) {
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w,h,inData,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies pixels from Raster srcRaster to this WritableRaster. Each pixel
|
||||
* in srcRaster is copied to the same x,y address in this raster, unless
|
||||
* the address falls outside the bounds of this raster. srcRaster
|
||||
* must have the same number of bands as this WritableRaster. The
|
||||
* copy is a simple copy of source samples to the corresponding destination
|
||||
* samples.
|
||||
* <p>
|
||||
* If all samples of both source and destination Rasters are of
|
||||
* integral type and less than or equal to 32 bits in size, then calling
|
||||
* this method is equivalent to executing the following code for all
|
||||
* <code>x,y</code> addresses valid in both Rasters.
|
||||
* <pre>{@code
|
||||
* Raster srcRaster;
|
||||
* WritableRaster dstRaster;
|
||||
* for (int b = 0; b < srcRaster.getNumBands(); b++) {
|
||||
* dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
|
||||
* }
|
||||
* }</pre>
|
||||
* Thus, when copying an integral type source to an integral type
|
||||
* destination, if the source sample size is greater than the destination
|
||||
* sample size for a particular band, the high order bits of the source
|
||||
* sample are truncated. If the source sample size is less than the
|
||||
* destination size for a particular band, the high order bits of the
|
||||
* destination are zero-extended or sign-extended depending on whether
|
||||
* srcRaster's SampleModel treats the sample as a signed or unsigned
|
||||
* quantity.
|
||||
* <p>
|
||||
* When copying a float or double source to an integral type destination,
|
||||
* each source sample is cast to the destination type. When copying an
|
||||
* integral type source to a float or double destination, the source
|
||||
* is first converted to a 32-bit int (if necessary), using the above
|
||||
* rules for integral types, and then the int is cast to float or
|
||||
* double.
|
||||
* <p>
|
||||
* @param srcRaster The Raster from which to copy pixels.
|
||||
*
|
||||
* @throws NullPointerException if srcRaster is null.
|
||||
*/
|
||||
public void setRect(Raster srcRaster) {
|
||||
setRect(0,0,srcRaster);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies pixels from Raster srcRaster to this WritableRaster.
|
||||
* For each (x, y) address in srcRaster, the corresponding pixel
|
||||
* is copied to address (x+dx, y+dy) in this WritableRaster,
|
||||
* unless (x+dx, y+dy) falls outside the bounds of this raster.
|
||||
* srcRaster must have the same number of bands as this WritableRaster.
|
||||
* The copy is a simple copy of source samples to the corresponding
|
||||
* destination samples. For details, see
|
||||
* {@link WritableRaster#setRect(Raster)}.
|
||||
*
|
||||
* @param dx The X translation factor from src space to dst space
|
||||
* of the copy.
|
||||
* @param dy The Y translation factor from src space to dst space
|
||||
* of the copy.
|
||||
* @param srcRaster The Raster from which to copy pixels.
|
||||
*
|
||||
* @throws NullPointerException if srcRaster is null.
|
||||
*/
|
||||
public void setRect(int dx, int dy, Raster srcRaster) {
|
||||
int width = srcRaster.getWidth();
|
||||
int height = srcRaster.getHeight();
|
||||
int srcOffX = srcRaster.getMinX();
|
||||
int srcOffY = srcRaster.getMinY();
|
||||
int dstOffX = dx+srcOffX;
|
||||
int dstOffY = dy+srcOffY;
|
||||
|
||||
// Clip to this raster
|
||||
if (dstOffX < this.minX) {
|
||||
int skipX = this.minX - dstOffX;
|
||||
width -= skipX;
|
||||
srcOffX += skipX;
|
||||
dstOffX = this.minX;
|
||||
}
|
||||
if (dstOffY < this.minY) {
|
||||
int skipY = this.minY - dstOffY;
|
||||
height -= skipY;
|
||||
srcOffY += skipY;
|
||||
dstOffY = this.minY;
|
||||
}
|
||||
if (dstOffX+width > this.minX+this.width) {
|
||||
width = this.minX + this.width - dstOffX;
|
||||
}
|
||||
if (dstOffY+height > this.minY+this.height) {
|
||||
height = this.minY + this.height - dstOffY;
|
||||
}
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (srcRaster.getSampleModel().getDataType()) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_INT:
|
||||
int[] iData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
// Grab one scanline at a time
|
||||
iData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
iData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, iData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
float[] fData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
fData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
fData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, fData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
double[] dData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
// Grab one scanline at a time
|
||||
dData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
dData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, dData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray The input samples in a int array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if iArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, int iArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using a float array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param fArray The input samples in a float array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if fArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, float fArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using a double array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param dArray The input samples in a double array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if dArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, double dArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
dArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param iArray The input int pixel array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if iArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, int iArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from a float array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param fArray The input float pixel array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if fArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, float fArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from a double array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param dArray The input double pixel array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if dArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, double dArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,dArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s) {
|
||||
sampleModel.setSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY, b, s,
|
||||
dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a float for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as a float.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, float s){
|
||||
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
b,s,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a double for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as a double.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, double s){
|
||||
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
b,s,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param iArray The input int sample array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if iArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from a float array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param fArray The input float sample array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if fArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from a double array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w Width of the pixel rectangle.
|
||||
* @param h Height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param dArray The input double sample array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if dArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
151
jdkSrc/jdk8/java/awt/image/WritableRenderedImage.java
Normal file
151
jdkSrc/jdk8/java/awt/image/WritableRenderedImage.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* WriteableRenderedImage is a common interface for objects which
|
||||
* contain or can produce image data in the form of Rasters and
|
||||
* which can be modified and/or written over. The image
|
||||
* data may be stored/produced as a single tile or a regular array
|
||||
* of tiles.
|
||||
* <p>
|
||||
* WritableRenderedImage provides notification to other interested
|
||||
* objects when a tile is checked out for writing (via the
|
||||
* getWritableTile method) and when the last writer of a particular
|
||||
* tile relinquishes its access (via a call to releaseWritableTile).
|
||||
* Additionally, it allows any caller to determine whether any tiles
|
||||
* are currently checked out (via hasTileWriters), and to obtain a
|
||||
* list of such tiles (via getWritableTileIndices, in the form of a Vector
|
||||
* of Point objects).
|
||||
* <p>
|
||||
* Objects wishing to be notified of changes in tile writability must
|
||||
* implement the TileObserver interface, and are added by a
|
||||
* call to addTileObserver. Multiple calls to
|
||||
* addTileObserver for the same object will result in multiple
|
||||
* notifications. An existing observer may reduce its notifications
|
||||
* by calling removeTileObserver; if the observer had no
|
||||
* notifications the operation is a no-op.
|
||||
* <p>
|
||||
* It is necessary for a WritableRenderedImage to ensure that
|
||||
* notifications occur only when the first writer acquires a tile and
|
||||
* the last writer releases it.
|
||||
*
|
||||
*/
|
||||
|
||||
public interface WritableRenderedImage extends RenderedImage
|
||||
{
|
||||
|
||||
/**
|
||||
* Adds an observer. If the observer is already present,
|
||||
* it will receive multiple notifications.
|
||||
* @param to the specified <code>TileObserver</code>
|
||||
*/
|
||||
public void addTileObserver(TileObserver to);
|
||||
|
||||
/**
|
||||
* Removes an observer. If the observer was not registered,
|
||||
* nothing happens. If the observer was registered for multiple
|
||||
* notifications, it will now be registered for one fewer.
|
||||
* @param to the specified <code>TileObserver</code>
|
||||
*/
|
||||
public void removeTileObserver(TileObserver to);
|
||||
|
||||
/**
|
||||
* Checks out a tile for writing.
|
||||
*
|
||||
* The WritableRenderedImage is responsible for notifying all
|
||||
* of its TileObservers when a tile goes from having
|
||||
* no writers to having one writer.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
* @return a writable tile.
|
||||
*/
|
||||
public WritableRaster getWritableTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Relinquishes the right to write to a tile. If the caller
|
||||
* continues to write to the tile, the results are undefined.
|
||||
* Calls to this method should only appear in matching pairs
|
||||
* with calls to getWritableTile; any other use will lead
|
||||
* to undefined results.
|
||||
*
|
||||
* The WritableRenderedImage is responsible for notifying all of
|
||||
* its TileObservers when a tile goes from having one writer
|
||||
* to having no writers.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
*/
|
||||
public void releaseWritableTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns whether a tile is currently checked out for writing.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
* @return <code>true</code> if specified tile is checked out
|
||||
* for writing; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isTileWritable(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns an array of Point objects indicating which tiles
|
||||
* are checked out for writing. Returns null if none are
|
||||
* checked out.
|
||||
* @return an array containing the locations of tiles that are
|
||||
* checked out for writing.
|
||||
*/
|
||||
public Point[] getWritableTileIndices();
|
||||
|
||||
/**
|
||||
* Returns whether any tile is checked out for writing.
|
||||
* Semantically equivalent to (getWritableTileIndices() != null).
|
||||
* @return <code>true</code> if any tiles are checked out for
|
||||
* writing; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasTileWriters();
|
||||
|
||||
/**
|
||||
* Sets a rect of the image to the contents of the Raster r, which is
|
||||
* assumed to be in the same coordinate space as the WritableRenderedImage.
|
||||
* The operation is clipped to the bounds of the WritableRenderedImage.
|
||||
* @param r the specified <code>Raster</code>
|
||||
*/
|
||||
public void setData(Raster r);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* ContextualRenderedImageFactory provides an interface for the
|
||||
* functionality that may differ between instances of
|
||||
* RenderableImageOp. Thus different operations on RenderableImages
|
||||
* may be performed by a single class such as RenderedImageOp through
|
||||
* the use of multiple instances of ContextualRenderedImageFactory.
|
||||
* The name ContextualRenderedImageFactory is commonly shortened to
|
||||
* "CRIF."
|
||||
*
|
||||
* <p> All operations that are to be used in a rendering-independent
|
||||
* chain must implement ContextualRenderedImageFactory.
|
||||
*
|
||||
* <p> Classes that implement this interface must provide a
|
||||
* constructor with no arguments.
|
||||
*/
|
||||
public interface ContextualRenderedImageFactory extends RenderedImageFactory {
|
||||
|
||||
/**
|
||||
* Maps the operation's output RenderContext into a RenderContext
|
||||
* for each of the operation's sources. This is useful for
|
||||
* operations that can be expressed in whole or in part simply as
|
||||
* alterations in the RenderContext, such as an affine mapping, or
|
||||
* operations that wish to obtain lower quality renderings of
|
||||
* their sources in order to save processing effort or
|
||||
* transmission bandwith. Some operations, such as blur, can also
|
||||
* use this mechanism to avoid obtaining sources of higher quality
|
||||
* than necessary.
|
||||
*
|
||||
* @param i the index of the source image.
|
||||
* @param renderContext the RenderContext being applied to the operation.
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @param image the RenderableImage being rendered.
|
||||
* @return a <code>RenderContext</code> for
|
||||
* the source at the specified index of the parameters
|
||||
* Vector contained in the specified ParameterBlock.
|
||||
*/
|
||||
RenderContext mapRenderContext(int i,
|
||||
RenderContext renderContext,
|
||||
ParameterBlock paramBlock,
|
||||
RenderableImage image);
|
||||
|
||||
/**
|
||||
* Creates a rendering, given a RenderContext and a ParameterBlock
|
||||
* containing the operation's sources and parameters. The output
|
||||
* is a RenderedImage that takes the RenderContext into account to
|
||||
* determine its dimensions and placement on the image plane.
|
||||
* This method houses the "intelligence" that allows a
|
||||
* rendering-independent operation to adapt to a specific
|
||||
* RenderContext.
|
||||
*
|
||||
* @param renderContext The RenderContext specifying the rendering
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters
|
||||
* @return a <code>RenderedImage</code> from the sources and parameters
|
||||
* in the specified ParameterBlock and according to the
|
||||
* rendering instructions in the specified RenderContext.
|
||||
*/
|
||||
RenderedImage create(RenderContext renderContext,
|
||||
ParameterBlock paramBlock);
|
||||
|
||||
/**
|
||||
* Returns the bounding box for the output of the operation,
|
||||
* performed on a given set of sources, in rendering-independent
|
||||
* space. The bounds are returned as a Rectangle2D, that is, an
|
||||
* axis-aligned rectangle with floating-point corner coordinates.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @return a Rectangle2D specifying the rendering-independent
|
||||
* bounding box of the output.
|
||||
*/
|
||||
Rectangle2D getBounds2D(ParameterBlock paramBlock);
|
||||
|
||||
/**
|
||||
* Gets the appropriate instance of the property specified by the name
|
||||
* parameter. This method must determine which instance of a property to
|
||||
* return when there are multiple sources that each specify the property.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @param name a String naming the desired property.
|
||||
* @return an object reference to the value of the property requested.
|
||||
*/
|
||||
Object getProperty(ParameterBlock paramBlock, String name);
|
||||
|
||||
/**
|
||||
* Returns a list of names recognized by getProperty.
|
||||
* @return the list of property names.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* create(RenderContext, ParameterBlock)) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. It is always safe to return true.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDynamic();
|
||||
}
|
||||
725
jdkSrc/jdk8/java/awt/image/renderable/ParameterBlock.java
Normal file
725
jdkSrc/jdk8/java/awt/image/renderable/ParameterBlock.java
Normal file
@@ -0,0 +1,725 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.Serializable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* A <code>ParameterBlock</code> encapsulates all the information about sources and
|
||||
* parameters (Objects) required by a RenderableImageOp, or other
|
||||
* classes that process images.
|
||||
*
|
||||
* <p> Although it is possible to place arbitrary objects in the
|
||||
* source Vector, users of this class may impose semantic constraints
|
||||
* such as requiring all sources to be RenderedImages or
|
||||
* RenderableImage. <code>ParameterBlock</code> itself is merely a container and
|
||||
* performs no checking on source or parameter types.
|
||||
*
|
||||
* <p> All parameters in a <code>ParameterBlock</code> are objects; convenience
|
||||
* add and set methods are available that take arguments of base type and
|
||||
* construct the appropriate subclass of Number (such as
|
||||
* Integer or Float). Corresponding get methods perform a
|
||||
* downward cast and have return values of base type; an exception
|
||||
* will be thrown if the stored values do not have the correct type.
|
||||
* There is no way to distinguish between the results of
|
||||
* "short s; add(s)" and "add(new Short(s))".
|
||||
*
|
||||
* <p> Note that the get and set methods operate on references.
|
||||
* Therefore, one must be careful not to share references between
|
||||
* <code>ParameterBlock</code>s when this is inappropriate. For example, to create
|
||||
* a new <code>ParameterBlock</code> that is equal to an old one except for an
|
||||
* added source, one might be tempted to write:
|
||||
*
|
||||
* <pre>
|
||||
* ParameterBlock addSource(ParameterBlock pb, RenderableImage im) {
|
||||
* ParameterBlock pb1 = new ParameterBlock(pb.getSources());
|
||||
* pb1.addSource(im);
|
||||
* return pb1;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p> This code will have the side effect of altering the original
|
||||
* <code>ParameterBlock</code>, since the getSources operation returned a reference
|
||||
* to its source Vector. Both pb and pb1 share their source Vector,
|
||||
* and a change in either is visible to both.
|
||||
*
|
||||
* <p> A correct way to write the addSource function is to clone
|
||||
* the source Vector:
|
||||
*
|
||||
* <pre>
|
||||
* ParameterBlock addSource (ParameterBlock pb, RenderableImage im) {
|
||||
* ParameterBlock pb1 = new ParameterBlock(pb.getSources().clone());
|
||||
* pb1.addSource(im);
|
||||
* return pb1;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p> The clone method of <code>ParameterBlock</code> has been defined to
|
||||
* perform a clone of both the source and parameter Vectors for
|
||||
* this reason. A standard, shallow clone is available as
|
||||
* shallowClone.
|
||||
*
|
||||
* <p> The addSource, setSource, add, and set methods are
|
||||
* defined to return 'this' after adding their argument. This allows
|
||||
* use of syntax like:
|
||||
*
|
||||
* <pre>
|
||||
* ParameterBlock pb = new ParameterBlock();
|
||||
* op = new RenderableImageOp("operation", pb.add(arg1).add(arg2));
|
||||
* </pre>
|
||||
* */
|
||||
public class ParameterBlock implements Cloneable, Serializable {
|
||||
/** A Vector of sources, stored as arbitrary Objects. */
|
||||
protected Vector<Object> sources = new Vector<Object>();
|
||||
|
||||
/** A Vector of non-source parameters, stored as arbitrary Objects. */
|
||||
protected Vector<Object> parameters = new Vector<Object>();
|
||||
|
||||
/** A dummy constructor. */
|
||||
public ParameterBlock() {}
|
||||
|
||||
/**
|
||||
* Constructs a <code>ParameterBlock</code> with a given Vector
|
||||
* of sources.
|
||||
* @param sources a <code>Vector</code> of source images
|
||||
*/
|
||||
public ParameterBlock(Vector<Object> sources) {
|
||||
setSources(sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>ParameterBlock</code> with a given Vector of sources and
|
||||
* Vector of parameters.
|
||||
* @param sources a <code>Vector</code> of source images
|
||||
* @param parameters a <code>Vector</code> of parameters to be used in the
|
||||
* rendering operation
|
||||
*/
|
||||
public ParameterBlock(Vector<Object> sources,
|
||||
Vector<Object> parameters)
|
||||
{
|
||||
setSources(sources);
|
||||
setParameters(parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of a <code>ParameterBlock</code>. The source and
|
||||
* parameter Vectors are copied by reference -- additions or
|
||||
* changes will be visible to both versions.
|
||||
*
|
||||
* @return an Object clone of the <code>ParameterBlock</code>.
|
||||
*/
|
||||
public Object shallowClone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (Exception e) {
|
||||
// We can't be here since we implement Cloneable.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of a <code>ParameterBlock</code>. The source and parameter
|
||||
* Vectors are cloned, but the actual sources and parameters are
|
||||
* copied by reference. This allows modifications to the order
|
||||
* and number of sources and parameters in the clone to be invisible
|
||||
* to the original <code>ParameterBlock</code>. Changes to the shared sources or
|
||||
* parameters themselves will still be visible.
|
||||
*
|
||||
* @return an Object clone of the <code>ParameterBlock</code>.
|
||||
*/
|
||||
public Object clone() {
|
||||
ParameterBlock theClone;
|
||||
|
||||
try {
|
||||
theClone = (ParameterBlock) super.clone();
|
||||
} catch (Exception e) {
|
||||
// We can't be here since we implement Cloneable.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (sources != null) {
|
||||
theClone.setSources((Vector)sources.clone());
|
||||
}
|
||||
if (parameters != null) {
|
||||
theClone.setParameters((Vector)parameters.clone());
|
||||
}
|
||||
return (Object) theClone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an image to end of the list of sources. The image is
|
||||
* stored as an object in order to allow new node types in the
|
||||
* future.
|
||||
*
|
||||
* @param source an image object to be stored in the source list.
|
||||
* @return a new <code>ParameterBlock</code> containing the specified
|
||||
* <code>source</code>.
|
||||
*/
|
||||
public ParameterBlock addSource(Object source) {
|
||||
sources.addElement(source);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a source as a general Object. The caller must cast it into
|
||||
* an appropriate type.
|
||||
*
|
||||
* @param index the index of the source to be returned.
|
||||
* @return an <code>Object</code> that represents the source located
|
||||
* at the specified index in the <code>sources</code>
|
||||
* <code>Vector</code>.
|
||||
* @see #setSource(Object, int)
|
||||
*/
|
||||
public Object getSource(int index) {
|
||||
return sources.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an entry in the list of source with a new source.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param source the specified source image
|
||||
* @param index the index into the <code>sources</code>
|
||||
* <code>Vector</code> at which to
|
||||
* insert the specified <code>source</code>
|
||||
* @return a new <code>ParameterBlock</code> that contains the
|
||||
* specified <code>source</code> at the specified
|
||||
* <code>index</code>.
|
||||
* @see #getSource(int)
|
||||
*/
|
||||
public ParameterBlock setSource(Object source, int index) {
|
||||
int oldSize = sources.size();
|
||||
int newSize = index + 1;
|
||||
if (oldSize < newSize) {
|
||||
sources.setSize(newSize);
|
||||
}
|
||||
sources.setElementAt(source, index);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a source as a <code>RenderedImage</code>. This method is
|
||||
* a convenience method.
|
||||
* An exception will be thrown if the source is not a RenderedImage.
|
||||
*
|
||||
* @param index the index of the source to be returned
|
||||
* @return a <code>RenderedImage</code> that represents the source
|
||||
* image that is at the specified index in the
|
||||
* <code>sources</code> <code>Vector</code>.
|
||||
*/
|
||||
public RenderedImage getRenderedSource(int index) {
|
||||
return (RenderedImage) sources.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a source as a RenderableImage. This method is a
|
||||
* convenience method.
|
||||
* An exception will be thrown if the sources is not a RenderableImage.
|
||||
*
|
||||
* @param index the index of the source to be returned
|
||||
* @return a <code>RenderableImage</code> that represents the source
|
||||
* image that is at the specified index in the
|
||||
* <code>sources</code> <code>Vector</code>.
|
||||
*/
|
||||
public RenderableImage getRenderableSource(int index) {
|
||||
return (RenderableImage) sources.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of source images.
|
||||
* @return the number of source images in the <code>sources</code>
|
||||
* <code>Vector</code>.
|
||||
*/
|
||||
public int getNumSources() {
|
||||
return sources.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire Vector of sources.
|
||||
* @return the <code>sources</code> <code>Vector</code>.
|
||||
* @see #setSources(Vector)
|
||||
*/
|
||||
public Vector<Object> getSources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entire Vector of sources to a given Vector.
|
||||
* @param sources the <code>Vector</code> of source images
|
||||
* @see #getSources
|
||||
*/
|
||||
public void setSources(Vector<Object> sources) {
|
||||
this.sources = sources;
|
||||
}
|
||||
|
||||
/** Clears the list of source images. */
|
||||
public void removeSources() {
|
||||
sources = new Vector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of parameters (not including source images).
|
||||
* @return the number of parameters in the <code>parameters</code>
|
||||
* <code>Vector</code>.
|
||||
*/
|
||||
public int getNumParameters() {
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire Vector of parameters.
|
||||
* @return the <code>parameters</code> <code>Vector</code>.
|
||||
* @see #setParameters(Vector)
|
||||
*/
|
||||
public Vector<Object> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entire Vector of parameters to a given Vector.
|
||||
* @param parameters the specified <code>Vector</code> of
|
||||
* parameters
|
||||
* @see #getParameters
|
||||
*/
|
||||
public void setParameters(Vector<Object> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
/** Clears the list of parameters. */
|
||||
public void removeParameters() {
|
||||
parameters = new Vector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to the list of parameters.
|
||||
* @param obj the <code>Object</code> to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(Object obj) {
|
||||
parameters.addElement(obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Byte to the list of parameters.
|
||||
* @param b the byte to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(byte b) {
|
||||
return add(new Byte(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Character to the list of parameters.
|
||||
* @param c the char to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(char c) {
|
||||
return add(new Character(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Short to the list of parameters.
|
||||
* @param s the short to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(short s) {
|
||||
return add(new Short(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Integer to the list of parameters.
|
||||
* @param i the int to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(int i) {
|
||||
return add(new Integer(i));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Long to the list of parameters.
|
||||
* @param l the long to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(long l) {
|
||||
return add(new Long(l));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Float to the list of parameters.
|
||||
* @param f the float to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(float f) {
|
||||
return add(new Float(f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Double to the list of parameters.
|
||||
* @param d the double to add to the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock add(double d) {
|
||||
return add(new Double(d));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param obj the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(Object obj, int index) {
|
||||
int oldSize = parameters.size();
|
||||
int newSize = index + 1;
|
||||
if (oldSize < newSize) {
|
||||
parameters.setSize(newSize);
|
||||
}
|
||||
parameters.setElementAt(obj, index);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with a Byte.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param b the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(byte b, int index) {
|
||||
return set(new Byte(b), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with a Character.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param c the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(char c, int index) {
|
||||
return set(new Character(c), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with a Short.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param s the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(short s, int index) {
|
||||
return set(new Short(s), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with an Integer.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param i the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(int i, int index) {
|
||||
return set(new Integer(i), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with a Long.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param l the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(long l, int index) {
|
||||
return set(new Long(l), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with a Float.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param f the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(float f, int index) {
|
||||
return set(new Float(f), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an Object in the list of parameters with a Double.
|
||||
* If the index lies beyond the current source list,
|
||||
* the list is extended with nulls as needed.
|
||||
* @param d the parameter that replaces the
|
||||
* parameter at the specified index in the
|
||||
* <code>parameters</code> <code>Vector</code>
|
||||
* @param index the index of the parameter to be
|
||||
* replaced with the specified parameter
|
||||
* @return a new <code>ParameterBlock</code> containing
|
||||
* the specified parameter.
|
||||
*/
|
||||
public ParameterBlock set(double d, int index) {
|
||||
return set(new Double(d), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a parameter as an object.
|
||||
* @param index the index of the parameter to get
|
||||
* @return an <code>Object</code> representing the
|
||||
* the parameter at the specified index
|
||||
* into the <code>parameters</code>
|
||||
* <code>Vector</code>.
|
||||
*/
|
||||
public Object getObjectParameter(int index) {
|
||||
return parameters.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as a byte. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not a <code>Byte</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>byte</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Byte</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public byte getByteParameter(int index) {
|
||||
return ((Byte)parameters.elementAt(index)).byteValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as a char. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not a <code>Character</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>char</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Character</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public char getCharParameter(int index) {
|
||||
return ((Character)parameters.elementAt(index)).charValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as a short. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not a <code>Short</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>short</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Short</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public short getShortParameter(int index) {
|
||||
return ((Short)parameters.elementAt(index)).shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as an int. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not an <code>Integer</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>int</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Integer</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public int getIntParameter(int index) {
|
||||
return ((Integer)parameters.elementAt(index)).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as a long. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not a <code>Long</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>long</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Long</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public long getLongParameter(int index) {
|
||||
return ((Long)parameters.elementAt(index)).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as a float. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not a <code>Float</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>float</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Float</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public float getFloatParameter(int index) {
|
||||
return ((Float)parameters.elementAt(index)).floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method to return a parameter as a double. An
|
||||
* exception is thrown if the parameter is
|
||||
* <code>null</code> or not a <code>Double</code>.
|
||||
*
|
||||
* @param index the index of the parameter to be returned.
|
||||
* @return the parameter at the specified index
|
||||
* as a <code>double</code> value.
|
||||
* @throws ClassCastException if the parameter at the
|
||||
* specified index is not a <code>Double</code>
|
||||
* @throws NullPointerException if the parameter at the specified
|
||||
* index is <code>null</code>
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or not less than the current size of this
|
||||
* <code>ParameterBlock</code> object
|
||||
*/
|
||||
public double getDoubleParameter(int index) {
|
||||
return ((Double)parameters.elementAt(index)).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of Class objects describing the types
|
||||
* of the parameters.
|
||||
* @return an array of <code>Class</code> objects.
|
||||
*/
|
||||
public Class [] getParamClasses() {
|
||||
int numParams = getNumParameters();
|
||||
Class [] classes = new Class[numParams];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numParams; i++) {
|
||||
Object obj = getObjectParameter(i);
|
||||
if (obj instanceof Byte) {
|
||||
classes[i] = byte.class;
|
||||
} else if (obj instanceof Character) {
|
||||
classes[i] = char.class;
|
||||
} else if (obj instanceof Short) {
|
||||
classes[i] = short.class;
|
||||
} else if (obj instanceof Integer) {
|
||||
classes[i] = int.class;
|
||||
} else if (obj instanceof Long) {
|
||||
classes[i] = long.class;
|
||||
} else if (obj instanceof Float) {
|
||||
classes[i] = float.class;
|
||||
} else if (obj instanceof Double) {
|
||||
classes[i] = double.class;
|
||||
} else {
|
||||
classes[i] = obj.getClass();
|
||||
}
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
272
jdkSrc/jdk8/java/awt/image/renderable/RenderContext.java
Normal file
272
jdkSrc/jdk8/java/awt/image/renderable/RenderContext.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.util.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A RenderContext encapsulates the information needed to produce a
|
||||
* specific rendering from a RenderableImage. It contains the area to
|
||||
* be rendered specified in rendering-independent terms, the
|
||||
* resolution at which the rendering is to be performed, and hints
|
||||
* used to control the rendering process.
|
||||
*
|
||||
* <p> Users create RenderContexts and pass them to the
|
||||
* RenderableImage via the createRendering method. Most of the methods of
|
||||
* RenderContexts are not meant to be used directly by applications,
|
||||
* but by the RenderableImage and operator classes to which it is
|
||||
* passed.
|
||||
*
|
||||
* <p> The AffineTransform parameter passed into and out of this class
|
||||
* are cloned. The RenderingHints and Shape parameters are not
|
||||
* necessarily cloneable and are therefore only reference copied.
|
||||
* Altering RenderingHints or Shape instances that are in use by
|
||||
* instances of RenderContext may have undesired side effects.
|
||||
*/
|
||||
public class RenderContext implements Cloneable {
|
||||
|
||||
/** Table of hints. May be null. */
|
||||
RenderingHints hints;
|
||||
|
||||
/** Transform to convert user coordinates to device coordinates. */
|
||||
AffineTransform usr2dev;
|
||||
|
||||
/** The area of interest. May be null. */
|
||||
Shape aoi;
|
||||
|
||||
// Various constructors that allow different levels of
|
||||
// specificity. If the Shape is missing the whole renderable area
|
||||
// is assumed. If hints is missing no hints are assumed.
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform.
|
||||
* The area of interest is supplied as a Shape,
|
||||
* and the rendering hints are supplied as a RenderingHints object.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param aoi a Shape representing the area of interest.
|
||||
* @param hints a RenderingHints object containing rendering hints.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev,
|
||||
Shape aoi,
|
||||
RenderingHints hints) {
|
||||
this.hints = hints;
|
||||
this.aoi = aoi;
|
||||
this.usr2dev = (AffineTransform)usr2dev.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform.
|
||||
* The area of interest is taken to be the entire renderable area.
|
||||
* No rendering hints are used.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev) {
|
||||
this(usr2dev, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform and rendering hints.
|
||||
* The area of interest is taken to be the entire renderable area.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param hints a RenderingHints object containing rendering hints.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
|
||||
this(usr2dev, null, hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform and area of interest.
|
||||
* The area of interest is supplied as a Shape.
|
||||
* No rendering hints are used.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param aoi a Shape representing the area of interest.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev, Shape aoi) {
|
||||
this(usr2dev, aoi, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rendering hints of this <code>RenderContext</code>.
|
||||
* @return a <code>RenderingHints</code> object that represents
|
||||
* the rendering hints of this <code>RenderContext</code>.
|
||||
* @see #setRenderingHints(RenderingHints)
|
||||
*/
|
||||
public RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rendering hints of this <code>RenderContext</code>.
|
||||
* @param hints a <code>RenderingHints</code> object that represents
|
||||
* the rendering hints to assign to this <code>RenderContext</code>.
|
||||
* @see #getRenderingHints
|
||||
*/
|
||||
public void setRenderingHints(RenderingHints hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current user-to-device AffineTransform contained
|
||||
* in the RenderContext to a given transform.
|
||||
*
|
||||
* @param newTransform the new AffineTransform.
|
||||
* @see #getTransform
|
||||
*/
|
||||
public void setTransform(AffineTransform newTransform) {
|
||||
usr2dev = (AffineTransform)newTransform.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by prepending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [modTransform] x [this]
|
||||
* </pre>
|
||||
*
|
||||
* @param modTransform the AffineTransform to prepend to the
|
||||
* current usr2dev transform.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void preConcatenateTransform(AffineTransform modTransform) {
|
||||
this.preConcetenateTransform(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by prepending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [modTransform] x [this]
|
||||
* </pre>
|
||||
* This method does the same thing as the preConcatenateTransform
|
||||
* method. It is here for backward compatibility with previous releases
|
||||
* which misspelled the method name.
|
||||
*
|
||||
* @param modTransform the AffineTransform to prepend to the
|
||||
* current usr2dev transform.
|
||||
* @deprecated replaced by
|
||||
* <code>preConcatenateTransform(AffineTransform)</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public void preConcetenateTransform(AffineTransform modTransform) {
|
||||
usr2dev.preConcatenate(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by appending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [this] x [modTransform]
|
||||
* </pre>
|
||||
*
|
||||
* @param modTransform the AffineTransform to append to the
|
||||
* current usr2dev transform.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void concatenateTransform(AffineTransform modTransform) {
|
||||
this.concetenateTransform(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by appending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [this] x [modTransform]
|
||||
* </pre>
|
||||
* This method does the same thing as the concatenateTransform
|
||||
* method. It is here for backward compatibility with previous releases
|
||||
* which misspelled the method name.
|
||||
*
|
||||
* @param modTransform the AffineTransform to append to the
|
||||
* current usr2dev transform.
|
||||
* @deprecated replaced by
|
||||
* <code>concatenateTransform(AffineTransform)</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public void concetenateTransform(AffineTransform modTransform) {
|
||||
usr2dev.concatenate(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current user-to-device AffineTransform.
|
||||
*
|
||||
* @return a reference to the current AffineTransform.
|
||||
* @see #setTransform(AffineTransform)
|
||||
*/
|
||||
public AffineTransform getTransform() {
|
||||
return (AffineTransform)usr2dev.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current area of interest. The old area is discarded.
|
||||
*
|
||||
* @param newAoi The new area of interest.
|
||||
* @see #getAreaOfInterest
|
||||
*/
|
||||
public void setAreaOfInterest(Shape newAoi) {
|
||||
aoi = newAoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ares of interest currently contained in the
|
||||
* RenderContext.
|
||||
*
|
||||
* @return a reference to the area of interest of the RenderContext,
|
||||
* or null if none is specified.
|
||||
* @see #setAreaOfInterest(Shape)
|
||||
*/
|
||||
public Shape getAreaOfInterest() {
|
||||
return aoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of a RenderContext. The area of interest is copied
|
||||
* by reference. The usr2dev AffineTransform and hints are cloned,
|
||||
* while the area of interest is copied by reference.
|
||||
*
|
||||
* @return the new cloned RenderContext.
|
||||
*/
|
||||
public Object clone() {
|
||||
RenderContext newRenderContext = new RenderContext(usr2dev,
|
||||
aoi, hints);
|
||||
return newRenderContext;
|
||||
}
|
||||
}
|
||||
198
jdkSrc/jdk8/java/awt/image/renderable/RenderableImage.java
Normal file
198
jdkSrc/jdk8/java/awt/image/renderable/RenderableImage.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.util.Vector;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A RenderableImage is a common interface for rendering-independent
|
||||
* images (a notion which subsumes resolution independence). That is,
|
||||
* images which are described and have operations applied to them
|
||||
* independent of any specific rendering of the image. For example, a
|
||||
* RenderableImage can be rotated and cropped in
|
||||
* resolution-independent terms. Then, it can be rendered for various
|
||||
* specific contexts, such as a draft preview, a high-quality screen
|
||||
* display, or a printer, each in an optimal fashion.
|
||||
*
|
||||
* <p> A RenderedImage is returned from a RenderableImage via the
|
||||
* createRendering() method, which takes a RenderContext. The
|
||||
* RenderContext specifies how the RenderedImage should be
|
||||
* constructed. Note that it is not possible to extract pixels
|
||||
* directly from a RenderableImage.
|
||||
*
|
||||
* <p> The createDefaultRendering() and createScaledRendering() methods are
|
||||
* convenience methods that construct an appropriate RenderContext
|
||||
* internally. All of the rendering methods may return a reference to a
|
||||
* previously produced rendering.
|
||||
*/
|
||||
public interface RenderableImage {
|
||||
|
||||
/**
|
||||
* String constant that can be used to identify a property on
|
||||
* a RenderedImage obtained via the createRendering or
|
||||
* createScaledRendering methods. If such a property exists,
|
||||
* the value of the property will be a RenderingHints object
|
||||
* specifying which hints were observed in creating the rendering.
|
||||
*/
|
||||
static final String HINTS_OBSERVED = "HINTS_OBSERVED";
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderableImages that are the sources of
|
||||
* image data for this RenderableImage. Note that this method may
|
||||
* return an empty vector, to indicate that the image has no sources,
|
||||
* or null, to indicate that no information is available.
|
||||
*
|
||||
* @return a (possibly empty) Vector of RenderableImages, or null.
|
||||
*/
|
||||
Vector<RenderableImage> getSources();
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image.
|
||||
* If the property name is not recognized, java.awt.Image.UndefinedProperty
|
||||
* will be returned.
|
||||
*
|
||||
* @param name the name of the property to get, as a String.
|
||||
* @return a reference to the property Object, or the value
|
||||
* java.awt.Image.UndefinedProperty.
|
||||
*/
|
||||
Object getProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns a list of names recognized by getProperty.
|
||||
* @return a list of property names.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* createRendering() or createScaledRendering()) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. It is always safe to return true.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDynamic();
|
||||
|
||||
/**
|
||||
* Gets the width in user coordinate space. By convention, the
|
||||
* usual width of a RenderableImage is equal to the image's aspect
|
||||
* ratio (width divided by height).
|
||||
*
|
||||
* @return the width of the image in user coordinates.
|
||||
*/
|
||||
float getWidth();
|
||||
|
||||
/**
|
||||
* Gets the height in user coordinate space. By convention, the
|
||||
* usual height of a RenderedImage is equal to 1.0F.
|
||||
*
|
||||
* @return the height of the image in user coordinates.
|
||||
*/
|
||||
float getHeight();
|
||||
|
||||
/**
|
||||
* Gets the minimum X coordinate of the rendering-independent image data.
|
||||
* @return the minimum X coordinate of the rendering-independent image
|
||||
* data.
|
||||
*/
|
||||
float getMinX();
|
||||
|
||||
/**
|
||||
* Gets the minimum Y coordinate of the rendering-independent image data.
|
||||
* @return the minimum Y coordinate of the rendering-independent image
|
||||
* data.
|
||||
*/
|
||||
float getMinY();
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage instance of this image with width w, and
|
||||
* height h in pixels. The RenderContext is built automatically
|
||||
* with an appropriate usr2dev transform and an area of interest
|
||||
* of the full image. All the rendering hints come from hints
|
||||
* passed in.
|
||||
*
|
||||
* <p> If w == 0, it will be taken to equal
|
||||
* Math.round(h*(getWidth()/getHeight())).
|
||||
* Similarly, if h == 0, it will be taken to equal
|
||||
* Math.round(w*(getHeight()/getWidth())). One of
|
||||
* w or h must be non-zero or else an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param w the width of rendered image in pixels, or 0.
|
||||
* @param h the height of rendered image in pixels, or 0.
|
||||
* @param hints a RenderingHints object containing hints.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
|
||||
|
||||
/**
|
||||
* Returnd a RenderedImage instance of this image with a default
|
||||
* width and height in pixels. The RenderContext is built
|
||||
* automatically with an appropriate usr2dev transform and an area
|
||||
* of interest of the full image. The rendering hints are
|
||||
* empty. createDefaultRendering may make use of a stored
|
||||
* rendering for speed.
|
||||
*
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createDefaultRendering();
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage that represented a rendering of this image
|
||||
* using a given RenderContext. This is the most general way to obtain a
|
||||
* rendering of a RenderableImage.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* (from the RenderContext) were used to create the image.
|
||||
* In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param renderContext the RenderContext to use to produce the rendering.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createRendering(RenderContext renderContext);
|
||||
}
|
||||
350
jdkSrc/jdk8/java/awt/image/renderable/RenderableImageOp.java
Normal file
350
jdkSrc/jdk8/java/awt/image/renderable/RenderableImageOp.java
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.RenderingHints;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This class handles the renderable aspects of an operation with help
|
||||
* from its associated instance of a ContextualRenderedImageFactory.
|
||||
*/
|
||||
public class RenderableImageOp implements RenderableImage {
|
||||
|
||||
/** A ParameterBlock containing source and parameters. */
|
||||
ParameterBlock paramBlock;
|
||||
|
||||
/** The associated ContextualRenderedImageFactory. */
|
||||
ContextualRenderedImageFactory myCRIF;
|
||||
|
||||
/** The bounding box of the results of this RenderableImageOp. */
|
||||
Rectangle2D boundingBox;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a RenderedImageOp given a
|
||||
* ContextualRenderedImageFactory object, and
|
||||
* a ParameterBlock containing RenderableImage sources and other
|
||||
* parameters. Any RenderedImage sources referenced by the
|
||||
* ParameterBlock will be ignored.
|
||||
*
|
||||
* @param CRIF a ContextualRenderedImageFactory object
|
||||
* @param paramBlock a ParameterBlock containing this operation's source
|
||||
* images and other parameters necessary for the operation
|
||||
* to run.
|
||||
*/
|
||||
public RenderableImageOp(ContextualRenderedImageFactory CRIF,
|
||||
ParameterBlock paramBlock) {
|
||||
this.myCRIF = CRIF;
|
||||
this.paramBlock = (ParameterBlock) paramBlock.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderableImages that are the sources of
|
||||
* image data for this RenderableImage. Note that this method may
|
||||
* return an empty vector, to indicate that the image has no sources,
|
||||
* or null, to indicate that no information is available.
|
||||
*
|
||||
* @return a (possibly empty) Vector of RenderableImages, or null.
|
||||
*/
|
||||
public Vector<RenderableImage> getSources() {
|
||||
return getRenderableSources();
|
||||
}
|
||||
|
||||
private Vector getRenderableSources() {
|
||||
Vector sources = null;
|
||||
|
||||
if (paramBlock.getNumSources() > 0) {
|
||||
sources = new Vector();
|
||||
int i = 0;
|
||||
while (i < paramBlock.getNumSources()) {
|
||||
Object o = paramBlock.getSource(i);
|
||||
if (o instanceof RenderableImage) {
|
||||
sources.add((RenderableImage)o);
|
||||
i++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image.
|
||||
* If the property name is not recognized, java.awt.Image.UndefinedProperty
|
||||
* will be returned.
|
||||
*
|
||||
* @param name the name of the property to get, as a String.
|
||||
* @return a reference to the property Object, or the value
|
||||
* java.awt.Image.UndefinedProperty.
|
||||
*/
|
||||
public Object getProperty(String name) {
|
||||
return myCRIF.getProperty(paramBlock, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of names recognized by getProperty.
|
||||
* @return a list of property names.
|
||||
*/
|
||||
public String[] getPropertyNames() {
|
||||
return myCRIF.getPropertyNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* createRendering() or createScaledRendering()) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. The CRIF's isDynamic method will be called.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return myCRIF.isDynamic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width in user coordinate space. By convention, the
|
||||
* usual width of a RenderableImage is equal to the image's aspect
|
||||
* ratio (width divided by height).
|
||||
*
|
||||
* @return the width of the image in user coordinates.
|
||||
*/
|
||||
public float getWidth() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height in user coordinate space. By convention, the
|
||||
* usual height of a RenderedImage is equal to 1.0F.
|
||||
*
|
||||
* @return the height of the image in user coordinates.
|
||||
*/
|
||||
public float getHeight() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum X coordinate of the rendering-independent image data.
|
||||
*/
|
||||
public float getMinX() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getMinX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum Y coordinate of the rendering-independent image data.
|
||||
*/
|
||||
public float getMinY() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getMinY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current ParameterBlock of the operation, allowing
|
||||
* editing of image rendering chains. The effects of such a
|
||||
* change will be visible when a new rendering is created from
|
||||
* this RenderableImageOp or any dependent RenderableImageOp.
|
||||
*
|
||||
* @param paramBlock the new ParameterBlock.
|
||||
* @return the old ParameterBlock.
|
||||
* @see #getParameterBlock
|
||||
*/
|
||||
public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
|
||||
ParameterBlock oldParamBlock = this.paramBlock;
|
||||
this.paramBlock = (ParameterBlock)paramBlock.clone();
|
||||
return oldParamBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the current parameter block.
|
||||
* @return the <code>ParameterBlock</code> of this
|
||||
* <code>RenderableImageOp</code>.
|
||||
* @see #setParameterBlock(ParameterBlock)
|
||||
*/
|
||||
public ParameterBlock getParameterBlock() {
|
||||
return paramBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage instance of this image with width w, and
|
||||
* height h in pixels. The RenderContext is built automatically
|
||||
* with an appropriate usr2dev transform and an area of interest
|
||||
* of the full image. All the rendering hints come from hints
|
||||
* passed in.
|
||||
*
|
||||
* <p> If w == 0, it will be taken to equal
|
||||
* Math.round(h*(getWidth()/getHeight())).
|
||||
* Similarly, if h == 0, it will be taken to equal
|
||||
* Math.round(w*(getHeight()/getWidth())). One of
|
||||
* w or h must be non-zero or else an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param w the width of rendered image in pixels, or 0.
|
||||
* @param h the height of rendered image in pixels, or 0.
|
||||
* @param hints a RenderingHints object containing hints.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
public RenderedImage createScaledRendering(int w, int h,
|
||||
RenderingHints hints) {
|
||||
// DSR -- code to try to get a unit scale
|
||||
double sx = (double)w/getWidth();
|
||||
double sy = (double)h/getHeight();
|
||||
if (Math.abs(sx/sy - 1.0) < 0.01) {
|
||||
sx = sy;
|
||||
}
|
||||
AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
|
||||
RenderContext newRC = new RenderContext(usr2dev, hints);
|
||||
return createRendering(newRC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a RenderedImage instance of this image with a default
|
||||
* width and height in pixels. The RenderContext is built
|
||||
* automatically with an appropriate usr2dev transform and an area
|
||||
* of interest of the full image. All the rendering hints come
|
||||
* from hints passed in. Implementors of this interface must be
|
||||
* sure that there is a defined default width and height.
|
||||
*
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
public RenderedImage createDefaultRendering() {
|
||||
AffineTransform usr2dev = new AffineTransform(); // Identity
|
||||
RenderContext newRC = new RenderContext(usr2dev);
|
||||
return createRendering(newRC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage which represents this
|
||||
* RenderableImageOp (including its Renderable sources) rendered
|
||||
* according to the given RenderContext.
|
||||
*
|
||||
* <p> This method supports chaining of either Renderable or
|
||||
* RenderedImage operations. If sources in
|
||||
* the ParameterBlock used to construct the RenderableImageOp are
|
||||
* RenderableImages, then a three step process is followed:
|
||||
*
|
||||
* <ol>
|
||||
* <li> mapRenderContext() is called on the associated CRIF for
|
||||
* each RenderableImage source;
|
||||
* <li> createRendering() is called on each of the RenderableImage sources
|
||||
* using the backwards-mapped RenderContexts obtained in step 1,
|
||||
* resulting in a rendering of each source;
|
||||
* <li> ContextualRenderedImageFactory.create() is called
|
||||
* with a new ParameterBlock containing the parameters of
|
||||
* the RenderableImageOp and the RenderedImages that were created by the
|
||||
* createRendering() calls.
|
||||
* </ol>
|
||||
*
|
||||
* <p> If the elements of the source Vector of
|
||||
* the ParameterBlock used to construct the RenderableImageOp are
|
||||
* instances of RenderedImage, then the CRIF.create() method is
|
||||
* called immediately using the original ParameterBlock.
|
||||
* This provides a basis case for the recursion.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* (from the RenderContext) were used to create the image.
|
||||
* In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param renderContext The RenderContext to use to perform the rendering.
|
||||
* @return a RenderedImage containing the desired output image.
|
||||
*/
|
||||
public RenderedImage createRendering(RenderContext renderContext) {
|
||||
RenderedImage image = null;
|
||||
RenderContext rcOut = null;
|
||||
|
||||
// Clone the original ParameterBlock; if the ParameterBlock
|
||||
// contains RenderableImage sources, they will be replaced by
|
||||
// RenderedImages.
|
||||
ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
|
||||
Vector sources = getRenderableSources();
|
||||
|
||||
try {
|
||||
// This assumes that if there is no renderable source, that there
|
||||
// is a rendered source in paramBlock
|
||||
|
||||
if (sources != null) {
|
||||
Vector renderedSources = new Vector();
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
rcOut = myCRIF.mapRenderContext(i, renderContext,
|
||||
paramBlock, this);
|
||||
RenderedImage rdrdImage =
|
||||
((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
|
||||
if (rdrdImage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add this rendered image to the ParameterBlock's
|
||||
// list of RenderedImages.
|
||||
renderedSources.addElement(rdrdImage);
|
||||
}
|
||||
|
||||
if (renderedSources.size() > 0) {
|
||||
renderedParamBlock.setSources(renderedSources);
|
||||
}
|
||||
}
|
||||
|
||||
return myCRIF.create(renderContext, renderedParamBlock);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// This should never happen
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* An adapter class that implements ImageProducer to allow the
|
||||
* asynchronous production of a RenderableImage. The size of the
|
||||
* ImageConsumer is determined by the scale factor of the usr2dev
|
||||
* transform in the RenderContext. If the RenderContext is null, the
|
||||
* default rendering of the RenderableImage is used. This class
|
||||
* implements an asynchronous production that produces the image in
|
||||
* one thread at one resolution. This class may be subclassed to
|
||||
* implement versions that will render the image using several
|
||||
* threads. These threads could render either the same image at
|
||||
* progressively better quality, or different sections of the image at
|
||||
* a single resolution.
|
||||
*/
|
||||
public class RenderableImageProducer implements ImageProducer, Runnable {
|
||||
|
||||
/** The RenderableImage source for the producer. */
|
||||
RenderableImage rdblImage;
|
||||
|
||||
/** The RenderContext to use for producing the image. */
|
||||
RenderContext rc;
|
||||
|
||||
/** A Vector of image consumers. */
|
||||
Vector ics = new Vector();
|
||||
|
||||
/**
|
||||
* Constructs a new RenderableImageProducer from a RenderableImage
|
||||
* and a RenderContext.
|
||||
*
|
||||
* @param rdblImage the RenderableImage to be rendered.
|
||||
* @param rc the RenderContext to use for producing the pixels.
|
||||
*/
|
||||
public RenderableImageProducer(RenderableImage rdblImage,
|
||||
RenderContext rc) {
|
||||
this.rdblImage = rdblImage;
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new RenderContext to use for the next startProduction() call.
|
||||
*
|
||||
* @param rc the new RenderContext.
|
||||
*/
|
||||
public synchronized void setRenderContext(RenderContext rc) {
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* @param ic an ImageConsumer to be added to the interest list.
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic) {
|
||||
if (!ics.contains(ic)) {
|
||||
ics.addElement(ic);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an ImageConsumer is on the list of consumers
|
||||
* currently interested in data for this image.
|
||||
*
|
||||
* @param ic the ImageConsumer to be checked.
|
||||
* @return true if the ImageConsumer is on the list; false otherwise.
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic) {
|
||||
return ics.contains(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an ImageConsumer from the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* @param ic the ImageConsumer to be removed.
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic) {
|
||||
ics.removeElement(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image, and immediately starts delivery of the
|
||||
* image data through the ImageConsumer interface.
|
||||
*
|
||||
* @param ic the ImageConsumer to be added to the list of consumers.
|
||||
*/
|
||||
public synchronized void startProduction(ImageConsumer ic) {
|
||||
addConsumer(ic);
|
||||
// Need to build a runnable object for the Thread.
|
||||
Thread thread = new Thread(this, "RenderableImageProducer Thread");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a given ImageConsumer have the image data delivered
|
||||
* one more time in top-down, left-right order.
|
||||
*
|
||||
* @param ic the ImageConsumer requesting the resend.
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic) {
|
||||
// So far, all pixels are already sent in TDLR order
|
||||
}
|
||||
|
||||
/**
|
||||
* The runnable method for this class. This will produce an image using
|
||||
* the current RenderableImage and RenderContext and send it to all the
|
||||
* ImageConsumer currently registered with this class.
|
||||
*/
|
||||
public void run() {
|
||||
// First get the rendered image
|
||||
RenderedImage rdrdImage;
|
||||
if (rc != null) {
|
||||
rdrdImage = rdblImage.createRendering(rc);
|
||||
} else {
|
||||
rdrdImage = rdblImage.createDefaultRendering();
|
||||
}
|
||||
|
||||
// And its ColorModel
|
||||
ColorModel colorModel = rdrdImage.getColorModel();
|
||||
Raster raster = rdrdImage.getData();
|
||||
SampleModel sampleModel = raster.getSampleModel();
|
||||
DataBuffer dataBuffer = raster.getDataBuffer();
|
||||
|
||||
if (colorModel == null) {
|
||||
colorModel = ColorModel.getRGBdefault();
|
||||
}
|
||||
int minX = raster.getMinX();
|
||||
int minY = raster.getMinY();
|
||||
int width = raster.getWidth();
|
||||
int height = raster.getHeight();
|
||||
|
||||
Enumeration icList;
|
||||
ImageConsumer ic;
|
||||
// Set up the ImageConsumers
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.setDimensions(width,height);
|
||||
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
|
||||
ImageConsumer.COMPLETESCANLINES |
|
||||
ImageConsumer.SINGLEPASS |
|
||||
ImageConsumer.SINGLEFRAME);
|
||||
}
|
||||
|
||||
// Get RGB pixels from the raster scanline by scanline and
|
||||
// send to consumers.
|
||||
int pix[] = new int[width];
|
||||
int i,j;
|
||||
int numBands = sampleModel.getNumBands();
|
||||
int tmpPixel[] = new int[numBands];
|
||||
for (j = 0; j < height; j++) {
|
||||
for(i = 0; i < width; i++) {
|
||||
sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
|
||||
pix[i] = colorModel.getDataElement(tmpPixel, 0);
|
||||
}
|
||||
// Now send the scanline to the Consumers
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
|
||||
}
|
||||
}
|
||||
|
||||
// Now tell the consumers we're done.
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
/**
|
||||
* The RenderedImageFactory interface (often abbreviated RIF) is
|
||||
* intended to be implemented by classes that wish to act as factories
|
||||
* to produce different renderings, for example by executing a series
|
||||
* of BufferedImageOps on a set of sources, depending on a specific
|
||||
* set of parameters, properties, and rendering hints.
|
||||
*/
|
||||
public interface RenderedImageFactory {
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage representing the results of an imaging
|
||||
* operation (or chain of operations) for a given ParameterBlock and
|
||||
* RenderingHints. The RIF may also query any source images
|
||||
* referenced by the ParameterBlock for their dimensions,
|
||||
* SampleModels, properties, etc., as necessary.
|
||||
*
|
||||
* <p> The create() method can return null if the
|
||||
* RenderedImageFactory is not capable of producing output for the
|
||||
* given set of source images and parameters. For example, if a
|
||||
* RenderedImageFactory is only capable of performing a 3x3
|
||||
* convolution on single-banded image data, and the source image has
|
||||
* multiple bands or the convolution Kernel is 5x5, null should be
|
||||
* returned.
|
||||
*
|
||||
* <p> Hints should be taken into account, but can be ignored.
|
||||
* The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing sources and parameters
|
||||
* for the RenderedImage to be created.
|
||||
* @param hints a RenderingHints object containing hints.
|
||||
* @return A RenderedImage containing the desired output.
|
||||
*/
|
||||
RenderedImage create(ParameterBlock paramBlock,
|
||||
RenderingHints hints);
|
||||
}
|
||||
Reference in New Issue
Block a user