diff options
| author | Rolf W. Rasmussen <rolfwr@ii.uib.no> | 2000-07-25 19:53:30 +0200 |
|---|---|---|
| committer | Rolf Rasmussen <rolfwr@gcc.gnu.org> | 2000-07-25 17:53:30 +0000 |
| commit | 69b1b29156c348ffd39c85043b21d0ffd6cb4a73 (patch) | |
| tree | 63ee8beca6a86986c9b97b7ab1cf2dced5a16fb5 /libjava/java/awt/image/DirectColorModel.java | |
| parent | 4c31fe99c3f0d0c94771ec3ff8ee08840b7c553a (diff) | |
ColorModel.java: New file...
2000-07-23 Rolf W. Rasmussen <rolfwr@ii.uib.no>
* libjava/java/awt/image/ColorModel.java: New file, replaces the
stub libjava/java/awt/ColorModel.java which was located in the
wrong package.
* libjava/java/awt/image/ComponentColorModel.java: New file.
* libjava/java/awt/image/ComponentSampleModel.java: New file.
* libjava/java/awt/image/DataBuffer.java: New file.
* libjava/java/awt/image/DataBufferByte.java: New file.
* libjava/java/awt/image/DataBufferInt.java: New file.
* libjava/java/awt/image/DataBufferUShort.java: New file.
* libjava/java/awt/image/DirectColorModel.java: New file.
* libjava/java/awt/image/PackedColorModel.java: New file.
* libjava/java/awt/image/Raster.java: New file.
* libjava/java/awt/image/SampleModel.java: New file.
* libjava/java/awt/image/SinglePixelPackedSampleModel.java: New
file.
* libjava/java/awt/image/IndexColorModel.java: New file.
* libjava/java/awt/image/ImageConsumer.java: Removed import of
java.awt.ColorModel stub.
* gnu/gcj/util/BitMaskExtent.java: New file, utility class.
* gnu/gcj/util/Buffers.java: New file, utility class.
* libjava/Makefile.am: Updated to include new files.
* libjava/Makefile.in: Rebuilt.
From-SVN: r35245
Diffstat (limited to 'libjava/java/awt/image/DirectColorModel.java')
| -rw-r--r-- | libjava/java/awt/image/DirectColorModel.java | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/libjava/java/awt/image/DirectColorModel.java b/libjava/java/awt/image/DirectColorModel.java new file mode 100644 index 00000000000..8e092d1a324 --- /dev/null +++ b/libjava/java/awt/image/DirectColorModel.java @@ -0,0 +1,338 @@ +/* Copyright © 2000 Free Software Foundation + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.awt.image; + +import java.awt.Point; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import gnu.gcj.awt.Buffers; + +/** + * @author Rolf W. Rasmussen <rolfwr@ii.uib.no> + */ +public class DirectColorModel extends PackedColorModel +{ + public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask) + { + this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits, + rmask, gmask, bmask, 0, + false, // not alpha premultiplied + Buffers.smallestAppropriateTransferType(pixelBits) // find type + ); + } + + public DirectColorModel(int pixelBits, + int rmask, int gmask, int bmask, int amask) + { + this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits, + rmask, gmask, bmask, amask, + false, // not alpha premultiplied + Buffers.smallestAppropriateTransferType(pixelBits) // find type + ); + } + + public DirectColorModel(ColorSpace cspace, int pixelBits, + int rmask, int gmask, int bmask, int amask, + boolean isAlphaPremultiplied, + int transferType) + { + super(cspace, pixelBits, + rmask, gmask, bmask, amask, isAlphaPremultiplied, + ((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT), + transferType); + } + + public final int getRedMask() + { + return getMask(0); + } + + public final int getGreenMask() + { + return getMask(1); + } + + public final int getBlueMask() + { + return getMask(2); + } + + public final int getAlphaMask() + { + return hasAlpha() ? getMask(3) : 0; + } + + public final int getRed(int pixel) + { + return extractAndNormalizeSample(pixel, 0); + } + + public final int getGreen(int pixel) + { + return extractAndNormalizeSample(pixel, 1); + } + + public final int getBlue(int pixel) + { + return extractAndNormalizeSample(pixel, 2); + } + + public final int getAlpha(int pixel) + { + if (!hasAlpha()) return 0; + return extractAndScaleSample(pixel, 3); + } + + private final int extractAndNormalizeSample(int pixel, int component) + { + int value = extractAndScaleSample(pixel, component); + if (hasAlpha() && isAlphaPremultiplied()) + value = value*255/getAlpha(pixel); + return value; + } + + private final int extractAndScaleSample(int pixel, int component) + { + int field = pixel & getMask(component); + int to8BitShift = + 8 - shifts[component] - getComponentSize(component); + return (to8BitShift>0) ? + (field << to8BitShift) : + (field >>> (-to8BitShift)); + } + + + /* FIXME: The Sun docs show that this method is overridden, but I don't + see any way to improve on the superclass implementation. */ + public final int getRGB(int pixel) + { + return super.getRGB(pixel); + } + + public int getRed(Object inData) + { + return getRed(getPixelFromArray(inData)); + } + + public int getGreen(Object inData) + { + return getGreen(getPixelFromArray(inData)); + } + + public int getBlue(Object inData) + { + return getBlue(getPixelFromArray(inData)); + } + + public int getAlpha(Object inData) + { + return getAlpha(getPixelFromArray(inData)); + } + + public int getRGB(Object inData) + { + return getRGB(getPixelFromArray(inData)); + } + + /** + * Converts a normalized pixel int value in the sRGB color + * space to an array containing a single pixel of the color space + * of the color model. + * + * <p>This method performs the inverse function of + * <code>getRGB(Object inData)</code>. + * + * @param rgb pixel as a normalized sRGB, 0xAARRGGBB value. + * + * @param pixel to avoid needless creation of arrays, an array to + * use to return the pixel can be given. If null, a suitable array + * will be created. + * + * @return array of transferType containing a single pixel. The + * pixel should be encoded in the natural way of the color model. + * + * @see #getRGB(Object) + */ + public Object getDataElements(int rgb, Object pixel) + { + // FIXME: handle alpha multiply + + int pixelValue = 0; + int a = 0; + if (hasAlpha()) { + a = (rgb >>> 24) & 0xff; + pixelValue = valueToField(a, 3, 8); + } + + if (hasAlpha() && isAlphaPremultiplied()) + { + int r, g, b; + /* if r=0xff and a=0xff, then resulting + value will be (r*a)>>>8 == 0xfe... This seems wrong. + We should divide by 255 rather than shifting >>>8 after + multiplying. + + Too bad, shifting is probably less expensive. + r = ((rgb >>> 16) & 0xff)*a; + g = ((rgb >>> 8) & 0xff)*a; + b = ((rgb >>> 0) & 0xff)*a; */ + /* The r, g, b values we calculate are 16 bit. This allows + us to avoid discarding the lower 8 bits obtained if + multiplying with the alpha band. */ + + // using 16 bit values + r = ((rgb >>> 8) & 0xff00)*a/255; + g = ((rgb >>> 0) & 0xff00)*a/255; + b = ((rgb << 8) & 0xff00)*a/255; + pixelValue |= + valueToField(r, 0, 16) | // Red + valueToField(g, 1, 16) | // Green + valueToField(b, 2, 16); // Blue + } + else + { + int r, g, b; + // using 8 bit values + r = (rgb >>> 16) & 0xff; + g = (rgb >>> 8) & 0xff; + b = (rgb >>> 0) & 0xff; + + pixelValue |= + valueToField(r, 0, 8) | // Red + valueToField(g, 1, 8) | // Green + valueToField(b, 2, 8); // Blue + } + + /* In this color model, the whole pixel fits in the first element + of the array. */ + DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1); + buffer.setElem(0, pixelValue); + return Buffers.getData(buffer); + } + + /** + * Converts a value to the correct field bits based on the + * information derived from the field masks. + * + * @param highBit the position of the most significant bit in the + * val parameter. + */ + private final int valueToField(int val, int component, int highBit) + { + int toFieldShift = + getComponentSize(component) + shifts[component] - highBit; + int ret = (toFieldShift>0) ? + (val << toFieldShift) : + (val >>> (-toFieldShift)); + return ret & getMask(component); + } + + /** + * Converts a 16 bit value to the correct field bits based on the + * information derived from the field masks. + */ + private final int value16ToField(int val, int component) + { + int toFieldShift = getComponentSize(component) + shifts[component] - 16; + return (toFieldShift>0) ? + (val << toFieldShift) : + (val >>> (-toFieldShift)); + } + + /** + * Fills an array with the unnormalized component samples from a + * pixel value. I.e. decompose the pixel, but not perform any + * color conversion. + */ + public final int[] getComponents(int pixel, int[] components, int offset) + { + int numComponents = getNumComponents(); + if (components == null) components = new int[offset + numComponents]; + + for (int b=0; b<numComponents; b++) + components[offset++] = (pixel&getMask(b)) >>> shifts[b]; + + return components; + } + + public final int[] getComponents(Object pixel, int[] components, + int offset) + { + return getComponents(getPixelFromArray(pixel), components, offset); + } + + public final WritableRaster createCompatibleWritableRaster(int w, int h) + { + SampleModel sm = createCompatibleSampleModel(w, h); + Point origin = new Point(0, 0); + return Raster.createWritableRaster(sm, origin); + } + + public int getDataElement(int[] components, int offset) + { + int numComponents = getNumComponents(); + int pixelValue = 0; + + for (int c=0; c<numComponents; c++) + pixelValue |= (components[offset++] << shifts[c]) & getMask(c); + + return pixelValue; + } + + public Object getDataElements(int[] components, int offset, Object obj) + { + /* In this color model, the whole pixel fits in the first element + of the array. */ + int pixelValue = getDataElement(components, offset); + + DataBuffer buffer = Buffers.createBuffer(transferType, obj, 1); + buffer.setElem(0, pixelValue); + return Buffers.getData(buffer); + } + + public ColorModel coerceData(WritableRaster raster, + boolean isAlphaPremultiplied) + { + if (this.isAlphaPremultiplied == isAlphaPremultiplied) + return this; + + /* TODO: provide better implementation based on the + assumptions we can make due to the specific type of the + color model. */ + super.coerceData(raster, isAlphaPremultiplied); + + return new ComponentColorModel(cspace, bits, hasAlpha(), + isAlphaPremultiplied, // argument + transparency, transferType); + } + + public boolean isCompatibleRaster(Raster raster) + { + /* FIXME: the Sun docs say this method is overridden here, + but I don't see any way to improve upon the implementation + in ColorModel. */ + return super.isCompatibleRaster(raster); + } + + String stringParam() + { + return super.stringParam() + + ", redMask=" + Integer.toHexString(getRedMask()) + + ", greenMask=" + Integer.toHexString(getGreenMask()) + + ", blueMask=" + Integer.toHexString(getBlueMask()) + + ", alphaMask=" + Integer.toHexString(getAlphaMask()); + } + + public String toString() + { + /* FIXME: Again, docs say override, but how do we improve upon the + superclass implementation? */ + return super.toString(); + } +} |
