summaryrefslogtreecommitdiff
path: root/libjava/java/awt/image/DirectColorModel.java
diff options
context:
space:
mode:
authorRolf W. Rasmussen <rolfwr@ii.uib.no>2000-07-25 19:53:30 +0200
committerRolf Rasmussen <rolfwr@gcc.gnu.org>2000-07-25 17:53:30 +0000
commit69b1b29156c348ffd39c85043b21d0ffd6cb4a73 (patch)
tree63ee8beca6a86986c9b97b7ab1cf2dced5a16fb5 /libjava/java/awt/image/DirectColorModel.java
parent4c31fe99c3f0d0c94771ec3ff8ee08840b7c553a (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.java338
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();
+ }
+}