diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/java/awt/image/ColorModel.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/java/awt/image/ColorModel.java')
-rw-r--r-- | libjava/classpath/java/awt/image/ColorModel.java | 794 |
1 files changed, 794 insertions, 0 deletions
diff --git a/libjava/classpath/java/awt/image/ColorModel.java b/libjava/classpath/java/awt/image/ColorModel.java new file mode 100644 index 000000000..ede9e31d8 --- /dev/null +++ b/libjava/classpath/java/awt/image/ColorModel.java @@ -0,0 +1,794 @@ +/* ColorModel.java -- + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2006 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt.image; + +import gnu.java.awt.Buffers; + +import java.awt.Point; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import java.util.Arrays; + +/** + * A color model operates with colors in several formats: + * + * <ul> + * <li>normalized: component samples are in range [0.0, 1.0].</li> + * + * <li>color model pixel value: all the color component samples for a + * sigle pixel packed/encoded in a way natural for the color + * model.</li> + * + * <li>color model pixel int value: only makes sense if the natural + * encoding of a single pixel can fit in a single int value.</li> + * + * <li>array of transferType containing a single pixel: the pixel is + * encoded in the natural way of the color model, taking up as many + * array elements as needed.</li> + * + * <li>sRGB pixel int value: a pixel in sRGB color space, encoded in + * default 0xAARRGGBB format, assumed not alpha premultiplied.</li> + * + * <li>single [0, 255] scaled int samples from default sRGB color + * space. These are always assumed to be alpha non-premultiplied.</li> + * + * <li>arrays of unnormalized component samples of single pixel: these + * samples are scaled and multiplied according to the color model, but + * is otherwise not packed or encoded. Each element of the array is one + * separate component sample. The color model only operate on the + * components from one pixel at a time, but using offsets, allows + * manipulation of arrays that contain the components of more than one + * pixel.</li> + * + * </ul> + * + * @author Rolf W. Rasmussen (rolfwr@ii.uib.no) + * @author C. Brian Jones (cbj@gnu.org) + */ +public abstract class ColorModel implements Transparency +{ + protected int pixel_bits; + protected int transferType; + + int[] bits; + ColorSpace cspace; + int transparency; + boolean hasAlpha; + boolean isAlphaPremultiplied; + + /** + * The standard color model for the common sRGB. + */ + private static final ColorModel S_RGB_MODEL = new SRGBColorModel(); + + static int[] nArray(int value, int times) + { + int[] array = new int[times]; + java.util.Arrays.fill(array, value); + return array; + } + + static byte[] nArray(byte value, int times) + { + byte[] array = new byte[times]; + java.util.Arrays.fill(array, value); + return array; + } + + /** + * Constructs the default color model. The default color model + * can be obtained by calling <code>getRGBdefault</code> of this + * class. + * @param bits the number of bits wide used for bit size of pixel values + */ + public ColorModel(int bits) + { + this(bits * 4, // total bits, sRGB, four channels + nArray(bits, 4), // bits for each channel + ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB + true, // has alpha + false, // not premultiplied + TRANSLUCENT, + Buffers.smallestAppropriateTransferType(bits * 4)); + } + + /** + * Constructs a ColorModel that translates pixel values to + * color/alpha components. + * + * @exception IllegalArgumentException If the length of the bit array is less + * than the number of color or alpha components in this ColorModel, or if the + * transparency is not a valid value, or if the sum of the number of bits in + * bits is less than 1 or if any of the elements in bits is less than 0. + */ + protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace, + boolean hasAlpha, boolean isAlphaPremultiplied, + int transparency, int transferType) + { + int bits_sum = 0; + for (int i = 0; i < bits.length; i++) + { + if (bits [i] < 0) + throw new IllegalArgumentException (); + + bits_sum |= bits [i]; + } + + if ((bits.length < cspace.getNumComponents()) + || (bits_sum < 1)) + throw new IllegalArgumentException (); + + this.pixel_bits = pixel_bits; + this.bits = bits; + this.cspace = cspace; + this.hasAlpha = hasAlpha; + this.isAlphaPremultiplied = isAlphaPremultiplied; + this.transparency = transparency; + this.transferType = transferType; + } + + public void finalize() + { + // Do nothing here. + } + + /** + * Returns the default color model which in Sun's case is an instance + * of <code>DirectColorModel</code>. + */ + public static ColorModel getRGBdefault() + { + return S_RGB_MODEL; + } + + public final boolean hasAlpha() + { + return hasAlpha; + } + + public final boolean isAlphaPremultiplied() + { + return isAlphaPremultiplied; + } + + /** + * Get get number of bits wide used for the bit size of pixel values + */ + public int getPixelSize() + { + return pixel_bits; + } + + public int getComponentSize(int componentIdx) + { + return bits[componentIdx]; + } + + public int[] getComponentSize() + { + return bits; + } + + public int getTransparency() + { + return transparency; + } + + public int getNumComponents() + { + return getNumColorComponents() + (hasAlpha ? 1 : 0); + } + + public int getNumColorComponents() + { + return cspace.getNumComponents(); + } + + /** + * Converts pixel value to sRGB and extract red int sample scaled + * to range [0, 255]. + * + * @param pixel pixel value that will be interpreted according to + * the color model, (assumed alpha premultiplied if color model says + * so.) + * + * @return red sample scaled to range [0, 255], from default color + * space sRGB, alpha non-premultiplied. + */ + public abstract int getRed(int pixel); + + /** + * Converts pixel value to sRGB and extract green int sample + * scaled to range [0, 255]. + * + * @see #getRed(int) + */ + public abstract int getGreen(int pixel); + + /** + * Converts pixel value to sRGB and extract blue int sample + * scaled to range [0, 255]. + * + * @see #getRed(int) + */ + public abstract int getBlue(int pixel); + + /** + * Extract alpha int sample from pixel value, scaled to [0, 255]. + * + * @param pixel pixel value that will be interpreted according to + * the color model. + * + * @return alpha sample, scaled to range [0, 255]. + */ + public abstract int getAlpha(int pixel); + + /** + * Converts a pixel int value of the color space of the color + * model to a sRGB pixel int value. + * + * This method is typically overriden in subclasses to provide a + * more efficient implementation. + * + * @param pixel pixel value that will be interpreted according to + * the color model. + * + * @return a pixel in sRGB color space, encoded in default + * 0xAARRGGBB format. */ + public int getRGB(int pixel) + { + return + ((getAlpha(pixel) & 0xff) << 24) | + (( getRed(pixel) & 0xff) << 16) | + ((getGreen(pixel) & 0xff) << 8) | + (( getBlue(pixel) & 0xff) << 0); + } + + + /** + * In this color model we know that the whole pixel value will + * always be contained within the first element of the pixel + * array. + */ + final int getPixelFromArray(Object inData) { + DataBuffer data = + Buffers.createBufferFromData(transferType, inData, 1); + Object da = Buffers.getData(data); + + return data.getElem(0); + } + + /** + * Converts pixel in the given array to sRGB and extract blue int + * sample scaled to range [0-255]. + * + * This method is typically overriden in subclasses to provide a + * more efficient implementation. + * + * @param inData array of transferType containing a single pixel. The + * pixel should be encoded in the natural way of the color model. + */ + public int getRed(Object inData) + { + return getRed(getPixelFromArray(inData)); + } + + /** + * @see #getRed(Object) + */ + public int getGreen(Object inData) + { + return getGreen(getPixelFromArray(inData)); + } + + /** + * @see #getRed(Object) + */ + public int getBlue(Object inData) { + return getBlue(getPixelFromArray(inData)); + } + + /** + * @see #getRed(Object) + */ + public int getAlpha(Object inData) { + return getAlpha(getPixelFromArray(inData)); + } + + /** + * Converts a pixel in the given array of the color space of the + * color model to an sRGB pixel int value. + * + * <p>This method performs the inverse function of + * <code>getDataElements(int rgb, Object pixel)</code>. + * I.e. <code>(rgb == cm.getRGB(cm.getDataElements(rgb, + * null)))</code>. + * + * @param inData array of transferType containing a single pixel. The + * pixel should be encoded in the natural way of the color model. + * + * @return a pixel in sRGB color space, encoded in default + * 0xAARRGGBB format. + * + * @see #getDataElements(int, Object) + */ + public int getRGB(Object inData) + { + return + ((getAlpha(inData) & 0xff) << 24) | + (( getRed(inData) & 0xff) << 16) | + ((getGreen(inData) & 0xff) << 8) | + (( getBlue(inData) & 0xff) << 0); + } + + /** + * Converts an sRGB pixel int value to an array containing a + * single pixel of the color space of the color model. + * + * <p>This method performs the inverse function of + * <code>getRGB(Object inData)</code>. + * + * Outline of conversion process: + * + * <ol> + * + * <li>Convert rgb to normalized [0.0, 1.0] sRGB values.</li> + * + * <li>Convert to color space components using fromRGB in + * ColorSpace.</li> + * + * <li>If color model has alpha and should be premultiplied, + * multiply color space components with alpha value</li> + * + * <li>Scale the components to the correct number of bits.</li> + * + * <li>Arrange the components in the output array</li> + * + * </ol> + * + * @param rgb The color to be converted to dataElements. A pixel + * in sRGB color space, encoded in default 0xAARRGGBB format, + * assumed not alpha premultiplied. + * + * @param pixel to avoid needless creation of arrays, an array to + * use to return the pixel can be given. If null, a suitable array + * will be created. + * + * @return An array of transferType values representing the color, + * in the color model format. The color model defines whether the + * + * @see #getRGB(Object) + */ + public Object getDataElements(int rgb, Object pixel) + { + // subclasses has to implement this method. + throw new UnsupportedOperationException(); + } + + /** + * Fills an array with the unnormalized component samples from a + * pixel value. I.e. decompose the pixel, but not perform any + * color conversion. + * + * This method is typically overriden in subclasses to provide a + * more efficient implementation. + * + * @param pixel pixel value encoded according to the color model. + * + * @return arrays of unnormalized component samples of single + * pixel. The scale and multiplication state of the samples are + * according to the color model. Each component sample is stored + * as a separate element in the array. + */ + public int[] getComponents(int pixel, int[] components, int offset) + { + // subclasses has to implement this method. + throw new UnsupportedOperationException(); + } + + /** + * Fills an array with the unnormalized component samples from an + * array of transferType containing a single pixel. I.e. decompose + * the pixel, but not perform any color conversion. + * + * This method is typically overriden in subclasses to provide a + * more efficient implementation. + * + * @param pixel an array of transferType containing a single pixel. The + * pixel should be encoded in the natural way of the color model. If + * this argument is not an array, as expected, a {@link ClassCastException} + * will be thrown. + * @param components an array that will be filled with the color component + * of the pixel. If this is null, a new array will be allocated + * @param offset index into the components array at which the result + * will be stored + * + * @return arrays of unnormalized component samples of single + * pixel. The scale and multiplication state of the samples are + * according to the color model. Each component sample is stored + * as a separate element in the array. + */ + public int[] getComponents(Object pixel, int[] components, int offset) + { + // subclasses has to implement this method. + throw new UnsupportedOperationException(); + } + + /** + * Convert normalized components to unnormalized components. + */ + public int[] getUnnormalizedComponents(float[] normComponents, + int normOffset, + int[] components, + int offset) + { + int numComponents = getNumComponents(); + if (components == null) + { + components = new int[offset + numComponents]; + } + + for (int i=0; i<numComponents; i++) + { + float in = normComponents[normOffset++]; + int out = (int) (in * ((1<<getComponentSize(i)) - 1)); + components[offset++] = out; + } + return components; + } + + /** + * Convert unnormalized components to normalized components. + */ + public float[] getNormalizedComponents(int[] components, + int offset, + float[] normComponents, + int normOffset) + { + int numComponents = getNumComponents(); + if (normComponents == null) + { + normComponents = new float[normOffset + numComponents]; + } + + for (int i=0; i<numComponents; i++) + { + float in = components[offset++]; + float out = in / ((1<<getComponentSize(i)) - 1); + normComponents[normOffset++] = out; + } + return normComponents; + } + + /** + * Convert unnormalized components to normalized components. + * + * @since 1.4 + */ + public float[] getNormalizedComponents (Object pixel, + float[] normComponents, + int normOffset) + { + int[] components = getComponents(pixel, null, 0); + return getNormalizedComponents(components, 0, normComponents, normOffset); + } + + /** + * Converts the unnormalized component samples from an array to a + * pixel value. I.e. composes the pixel from component samples, but + * does not perform any color conversion or scaling of the samples. + * + * This method performs the inverse function of + * <code>getComponents(int pixel, int[] components, + * int offset)</code>. I.e. + * + * <code>(pixel == cm.getDataElement(cm.getComponents(pixel, null, + * 0), 0))</code>. + * + * This method is overriden in subclasses since this abstract class throws + * UnsupportedOperationException(). + * + * @param components Array of unnormalized component samples of single + * pixel. The scale and multiplication state of the samples are according + * to the color model. Each component sample is stored as a separate element + * in the array. + * @param offset Position of the first value of the pixel in components. + * + * @return pixel value encoded according to the color model. + */ + public int getDataElement(int[] components, int offset) + { + // subclasses have to implement this method. + throw new UnsupportedOperationException(); + } + + /** + * Converts the normalized component samples from an array to a pixel + * value. I.e. composes the pixel from component samples, but does not + * perform any color conversion or scaling of the samples. + * + * This method is typically overriden in subclasses to provide a + * more efficient implementation. The method provided by this abstract + * class converts the components to unnormalized form and returns + * getDataElement(int[], int). + * + * @param components Array of normalized component samples of single pixel. + * The scale and multiplication state of the samples are according to the + * color model. Each component sample is stored as a separate element in the + * array. + * @param offset Position of the first value of the pixel in components. + * + * @return pixel value encoded according to the color model. + * @since 1.4 + */ + public int getDataElement (float[] components, int offset) + { + return + getDataElement(getUnnormalizedComponents(components, offset, null, 0), + 0); + } + + public Object getDataElements(int[] components, int offset, Object obj) + { + // subclasses have to implement this method. + throw new UnsupportedOperationException(); + } + + /** + * Converts the normalized component samples from an array to an array of + * TransferType values. I.e. composes the pixel from component samples, but + * does not perform any color conversion or scaling of the samples. + * + * If obj is null, a new array of TransferType is allocated and returned. + * Otherwise the results are stored in obj and obj is returned. If obj is + * not long enough, ArrayIndexOutOfBounds is thrown. If obj is not an array + * of primitives, ClassCastException is thrown. + * + * This method is typically overriden in subclasses to provide a + * more efficient implementation. The method provided by this abstract + * class converts the components to unnormalized form and returns + * getDataElement(int[], int, Object). + * + * @param components Array of normalized component samples of single pixel. + * The scale and multiplication state of the samples are according to the + * color model. Each component sample is stored as a separate element in the + * array. + * @param offset Position of the first value of the pixel in components. + * @param obj Array of TransferType or null. + * + * @return pixel value encoded according to the color model. + * @throws ArrayIndexOutOfBoundsException + * @throws ClassCastException + * @since 1.4 + */ + public Object getDataElements(float[] components, int offset, Object obj) + { + return + getDataElements(getUnnormalizedComponents(components, offset, null, 0), + 0, obj); + } + + public boolean equals(Object obj) + { + if (!(obj instanceof ColorModel)) return false; + + ColorModel o = (ColorModel) obj; + return + (pixel_bits == o.pixel_bits) && + (transferType == o.transferType) && + (transparency == o.transparency) && + (hasAlpha == o.hasAlpha) && + (isAlphaPremultiplied == o.isAlphaPremultiplied) && + Arrays.equals(bits, o.bits) && + (cspace.equals(o.cspace)); + } + + public final ColorSpace getColorSpace() + { + return cspace; + } + + public ColorModel coerceData(WritableRaster raster, + boolean isAlphaPremultiplied) + { + // This method should always be overridden, but is not abstract. + throw new UnsupportedOperationException(); + } + + void coerceDataWorker(WritableRaster raster, + boolean isAlphaPremultiplied) + { + int w = raster.getWidth(); + int h = raster.getHeight(); + int x = raster.getMinX(); + int y = raster.getMinY(); + int size = w * h; + int numColors = getNumColorComponents(); + int numComponents = getNumComponents(); + int alphaScale = (1 << getComponentSize(numColors)) - 1; + double[] pixels = raster.getPixels(x, y, w, h, (double[]) null); + + for (int i = 0; i < size; i++) + { + double alpha = pixels[i * numComponents + numColors] / alphaScale; + for (int c = 0; c < numColors; c++) + { + int offset = i * numComponents + c; + if (isAlphaPremultiplied) + pixels[offset] = Math.round(pixels[offset] * alpha); + else + pixels[offset] = Math.round(pixels[offset] / alpha); + } + } + + raster.setPixels(0, 0, w, h, pixels); + } + + /** + * Checks if the given raster has a compatible data-layout (SampleModel). + * @param raster The Raster to test. + * @return true if raster is compatible. + */ + public boolean isCompatibleRaster(Raster raster) + { + SampleModel sampleModel = raster.getSampleModel(); + return isCompatibleSampleModel(sampleModel); + } + + // Typically overridden + public WritableRaster createCompatibleWritableRaster(int w, int h) + { + return new WritableRaster(createCompatibleSampleModel(w, h), + new Point(0, 0)); + } + + // Typically overridden + public SampleModel createCompatibleSampleModel(int w, int h) + { + throw new UnsupportedOperationException(); + } + + // Typically overridden + public boolean isCompatibleSampleModel(SampleModel sm) + { + return sm.getTransferType() == transferType; + } + + public final int getTransferType () + { + return transferType; + } + + /** + * Subclasses must override this method if it is possible for the + * color model to have an alpha channel. + * + * @return null, as per JDK 1.3 doc. Subclasses will only return + * null if no alpha raster exists. + */ + public WritableRaster getAlphaRaster(WritableRaster raster) + { + return null; + + /* It is a mystery to me why we couldn't use the following code... + + + if (!hasAlpha()) return null; + + SampleModel sm = raster.getSampleModel(); + int[] alphaBand = { sm.getNumBands() - 1 }; + SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand); + DataBuffer buffer = raster.getDataBuffer(); + Point origin = new Point(0, 0); + return Raster.createWritableRaster(alphaModel, buffer, origin); + + + ...here, and avoided overriding the method in subclasses, + but the Sun docs state that this method always will return + null, and that overriding is required. Oh, well. + */ + } + + String stringParam() + { + return "pixel_bits=" + pixel_bits + + ", cspace=" + cspace + + ", transferType=" + transferType + + ", transparency=" + transparency + + ", hasAlpha=" + hasAlpha + + ", isAlphaPremultiplied=" + isAlphaPremultiplied; + } + + public String toString() + { + return getClass().getName() + "[" + stringParam() + "]"; + } + + /** + * A color model optimized for standard sRGB. + */ + private static class SRGBColorModel + extends DirectColorModel + { + + SRGBColorModel() + { + super(32,0x00FF0000,0x0000FF00,0x000000FF,0xFF000000); + } + + public int getAlpha(Object inData) + { + return ((((int[]) inData)[0]) >> 24) & 0xFF; + } + + public int getBlue(Object inData) + { + return ((((int[]) inData)[0])) & 0xFF; + } + + public int getGreen(Object inData) + { + return ((((int[]) inData)[0]) >> 8) & 0xFF; + } + + public int getRed(Object inData) + { + return ((((int[]) inData)[0]) >> 16) & 0xFF; + } + + public int getRGB(Object inData) + { + return ((int[]) inData)[0]; + } + + public Object getDataElements(int rgb, Object pixel) + { + if(pixel == null) + { + pixel = new int[]{rgb}; + } + else + { + ((int[]) pixel)[0] = rgb; + } + + return pixel; + } + } +} |