From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; 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. --- .../classpath/java/awt/image/IndexColorModel.java | 736 +++++++++++++++++++++ 1 file changed, 736 insertions(+) create mode 100644 libjava/classpath/java/awt/image/IndexColorModel.java (limited to 'libjava/classpath/java/awt/image/IndexColorModel.java') diff --git a/libjava/classpath/java/awt/image/IndexColorModel.java b/libjava/classpath/java/awt/image/IndexColorModel.java new file mode 100644 index 000000000..340d38e89 --- /dev/null +++ b/libjava/classpath/java/awt/image/IndexColorModel.java @@ -0,0 +1,736 @@ +/* IndexColorModel.java -- Java class for interpreting Pixel objects + Copyright (C) 1999, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.awt.image; + +import gnu.java.awt.Buffers; + +import java.awt.color.ColorSpace; +import java.math.BigInteger; + +/** + * Color model similar to pseudo visual in X11. + *

+ * This color model maps linear pixel values to actual RGB and alpha colors. + * Thus, pixel values are indexes into the color map. Each color component is + * an 8-bit unsigned value. + *

+ * The IndexColorModel supports a map of valid pixels, allowing + * the representation of holes in the the color map. The valid map is + * represented as a {@link BigInteger} where each bit indicates the validity + * of the map entry with the same index. + *

+ * Colors can have alpha components for transparency support. If alpha + * component values aren't given, color values are opaque. The model also + * supports a reserved pixel value to represent completely transparent colors, + * no matter what the actual color component values are. + *

+ * IndexColorModel supports anywhere from 1 to 16 bit index + * values. The allowed transfer types are {@link DataBuffer#TYPE_BYTE} and + * {@link DataBuffer#TYPE_USHORT}. + * + * @author C. Brian Jones (cbj@gnu.org) + */ +public class IndexColorModel extends ColorModel +{ + private int map_size; + private boolean opaque; // no alpha, but doesn't account for trans + private int trans = -1; + private int[] rgb; + private BigInteger validBits = BigInteger.ZERO; + + /** + * Creates a new indexed color model for size color elements + * with no alpha component. Each array must contain at least + * size elements. For each array, the i-th color is described + * by reds[i], greens[i] and blues[i]. + * + * @param bits the number of bits needed to represent size + * colors. + * @param size the number of colors in the color map. + * @param reds the red component of all colors. + * @param greens the green component of all colors. + * @param blues the blue component of all colors. + * + * @throws IllegalArgumentException if bits < 1 or + * bits > 16. + * @throws NullPointerException if any of the arrays is null. + * @throws ArrayIndexOutOfBoundsException if size is greater + * than the length of the component arrays. + */ + public IndexColorModel(int bits, int size, byte[] reds, byte[] greens, + byte[] blues) + { + this(bits, size, reds, greens, blues, (byte[]) null); + } + + /** + * Creates a new indexed color model for size color elements. + * Each array must contain at least size elements. For each + * array, the i-th color is described by reds[i], greens[i] and blues[i]. + * All the colors are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent size + * colors + * @param size the number of colors in the color map + * @param reds the red component of all colors + * @param greens the green component of all colors + * @param blues the blue component of all colors + * @param trans the index of the transparent color (use -1 for no + * transparent color). + * + * @throws IllegalArgumentException if bits < 1 or + * bits > 16. + * @throws NullPointerException if any of the arrays is null. + * @throws ArrayIndexOutOfBoundsException if size is greater + * than the length of the component arrays. + */ + public IndexColorModel(int bits, int size, byte[] reds, byte[] greens, + byte[] blues, int trans) + { + super(bits, nArray(8, (0 <= trans && trans < size) ? 4 : 3), + ColorSpace.getInstance(ColorSpace.CS_sRGB), + (0 <= trans && trans < size), // hasAlpha + false, OPAQUE, + Buffers.smallestAppropriateTransferType(bits)); + if (bits < 1) + throw new IllegalArgumentException("bits < 1"); + if (bits > 16) + throw new IllegalArgumentException("bits > 16"); + if (size < 1) + throw new IllegalArgumentException("size < 1"); + map_size = size; + rgb = createColorMap(bits, size); + for (int i = 0; i < size; i++) + { + rgb[i] = (0xff000000 + | ((reds[i] & 0xff) << 16) + | ((greens[i] & 0xff) << 8) + | (blues[i] & 0xff)); + } + + setTransparentPixel(trans); + + // Generate a bigint with 1's for every pixel + validBits = validBits.setBit(size).subtract(BigInteger.ONE); + } + + /** + * Creates a new indexed color model for size color elements + * including alpha. Each array must contain at least size + * elements. For each array, the i-th color is described + * by reds[i], greens[i], blues[i] and alphas[i]. + * + * @param bits the number of bits needed to represent size + * colors. + * @param size the number of colors in the color map. + * @param reds the red component of all colors. + * @param greens the green component of all colors. + * @param blues the blue component of all colors. + * @param alphas the alpha component of all colors (null + * permitted). + * + * @throws IllegalArgumentException if bits < 1 or + * bits > 16. + * @throws NullPointerException if reds, greens or + * blues is null. + * @throws ArrayIndexOutOfBoundsException if size is greater + * than the length of the component arrays. + */ + public IndexColorModel(int bits, int size, byte[] reds, byte[] greens, + byte[] blues, byte[] alphas) + { + super(bits, nArray(8, (alphas == null ? 3 : 4)), + ColorSpace.getInstance(ColorSpace.CS_sRGB), + (alphas != null), false, TRANSLUCENT, + Buffers.smallestAppropriateTransferType(bits)); + if (bits < 1) + throw new IllegalArgumentException("bits < 1"); + if (bits > 16) + throw new IllegalArgumentException("bits > 16"); + if (size < 1) + throw new IllegalArgumentException("size < 1"); + map_size = size; + opaque = (alphas == null); + + rgb = createColorMap(bits, size); + if (alphas == null) + { + for (int i = 0; i < size; i++) + { + rgb[i] = (0xff000000 + | ((reds[i] & 0xff) << 16) + | ((greens[i] & 0xff) << 8) + | (blues[i] & 0xff)); + } + transparency = OPAQUE; + } + else + { + byte alphaZero = (byte) 0x00; + byte alphaOne = (byte) 0xFF; + for (int i = 0; i < size; i++) + { + alphaZero = (byte) (alphaZero | alphas[i]); + alphaOne = (byte) (alphaOne & alphas[i]); + rgb[i] = ((alphas[i] & 0xff) << 24 + | ((reds[i] & 0xff) << 16) + | ((greens[i] & 0xff) << 8) + | (blues[i] & 0xff)); + } + if ((alphaZero == (byte) 0x00) || (alphaOne == (byte) 0xFF)) + transparency = BITMASK; + else + transparency = TRANSLUCENT; + } + + // Generate a bigint with 1's for every pixel + validBits = validBits.setBit(size).subtract(BigInteger.ONE); + } + + /** + * Creates a new indexed color model using the color components in + * cmap. If hasAlpha is true then + * cmap contains an alpha component after each of the red, green + * and blue components. + * + * @param bits the number of bits needed to represent size + * colors + * @param size the number of colors in the color map + * @param cmap packed color components + * @param start the offset of the first color component in cmap + * @param hasAlpha cmap has alpha values + * @throws IllegalArgumentException if bits < 1, bits > 16, or size + * < 1. + * @throws NullPointerException if cmap is null. + */ + public IndexColorModel(int bits, int size, byte[] cmap, int start, + boolean hasAlpha) + { + this(bits, size, cmap, start, hasAlpha, -1); + } + + /** + * Construct an IndexColorModel from an array of red, green, blue, and + * optional alpha components. The component values are interleaved as RGB(A). + * + * @param bits the number of bits needed to represent size + * colors + * @param size the number of colors in the color map + * @param cmap interleaved color components + * @param start the offset of the first color component in cmap + * @param hasAlpha cmap has alpha values + * @param trans the index of the transparent color + * @throws IllegalArgumentException if bits < 1, bits > 16, or size + * < 1. + * @throws NullPointerException if cmap is null. + */ + public IndexColorModel(int bits, int size, byte[] cmap, int start, + boolean hasAlpha, int trans) + { + super(bits, nArray(8, hasAlpha || (0 <= trans && trans < size) ? 4 : 3), + ColorSpace.getInstance(ColorSpace.CS_sRGB), + hasAlpha || (0 <= trans && trans < size), false, OPAQUE, + Buffers.smallestAppropriateTransferType(bits)); + if (bits < 1) + throw new IllegalArgumentException("bits < 1"); + if (bits > 16) + throw new IllegalArgumentException("bits > 16"); + if (size < 1) + throw new IllegalArgumentException("size < 1"); + map_size = size; + opaque = !hasAlpha; + + rgb = createColorMap(bits, size); + if (hasAlpha) + { + int alpha; + int alphaZero = 0x00; // use to detect all zeros + int alphaOne = 0xff; // use to detect all ones + for (int i = 0; i < size; i++) { + alpha = cmap[4 * i + 3 + start] & 0xff; + alphaZero = alphaZero | alpha; + alphaOne = alphaOne & alpha; + rgb[i] = + ( alpha << 24 + // red + | ((cmap[4 * i + start] & 0xff) << 16) + // green + | ((cmap[4 * i + 1 + start] & 0xff) << 8) + // blue + | (cmap[4 * i + 2 + start] & 0xff)); + } + if (alphaZero == 0) + transparency = BITMASK; + else if (alphaOne == 255) + transparency = (trans != -1 ? BITMASK : OPAQUE); + else + transparency = TRANSLUCENT; + } + else + { + for (int i = 0; i < size; i++) + rgb[i] = (0xff000000 + // red + | ((cmap[3 * i + start] & 0xff) << 16) + // green + | ((cmap[3 * i + 1 + start] & 0xff) << 8) + // blue + | (cmap[3 * i + 2 + start] & 0xff)); + if (trans != -1) + transparency = BITMASK; + } + + setTransparentPixel(trans); + + // Generate a bigint with 1's for every pixel + validBits = validBits.setBit(size).subtract(BigInteger.ONE); + } + + /** + * Construct an IndexColorModel from an array of size packed + * colors. Each int element contains 8-bit red, green, blue, and optional + * alpha values packed in order. If hasAlpha is false, then all the colors + * are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent size + * colors + * @param size the number of colors in the color map + * @param cmap packed color components + * @param start the offset of the first color component in cmap + * @param hasAlpha cmap has alpha values + * @param trans the index of the transparent color + * @param transferType {@link DataBuffer#TYPE_BYTE} or + {@link DataBuffer#TYPE_USHORT}. + * @throws IllegalArgumentException if bits < 1, bits > 16, or size + * < 1. + * @throws IllegalArgumentException if transferType is something + * other than {@link DataBuffer#TYPE_BYTE} or + * {@link DataBuffer#TYPE_USHORT}. + */ + public IndexColorModel(int bits, int size, int[] cmap, int start, + boolean hasAlpha, int trans, int transferType) + { + super(bits, + nArray(8, 4), // bits for each channel + ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB + true, // has alpha + false, // not premultiplied + TRANSLUCENT, transferType); + if (transferType != DataBuffer.TYPE_BYTE + && transferType != DataBuffer.TYPE_USHORT) + throw new IllegalArgumentException(); + if (bits > 16) + throw new IllegalArgumentException("bits > 16"); + if (size < 1) + throw new IllegalArgumentException("size < 1"); + map_size = size; + opaque = !hasAlpha; + rgb = createColorMap(bits, size); + if (!hasAlpha) + for (int i = 0; i < size; i++) + rgb[i] = cmap[i + start] | 0xff000000; + else + System.arraycopy(cmap, start, rgb, 0, size); + + setTransparentPixel(trans); + + // Generate a bigint with 1's for every pixel + validBits = validBits.setBit(size).subtract(BigInteger.ONE); + } + + /** + * Construct an IndexColorModel using a colormap with holes. + *

+ * The IndexColorModel is built from the array of ints defining the + * colormap. Each element contains red, green, blue, and alpha + * components. The ColorSpace is sRGB. The transparency value is + * automatically determined. + *

+ * This constructor permits indicating which colormap entries are valid, + * using the validBits argument. Each entry in cmap is valid if the + * corresponding bit in validBits is set. + * + * @param bits the number of bits needed to represent size + * colors. + * @param size the number of colors in the color map. + * @param cmap packed color components. + * @param start the offset of the first color component in cmap. + * @param transferType {@link DataBuffer#TYPE_BYTE} or + * {@link DataBuffer#TYPE_USHORT}. + * @param validBits a map of the valid entries in cmap. + * @throws IllegalArgumentException if bits < 1, bits > 16, or size + * < 1. + * @throws IllegalArgumentException if transferType is something other than + * {@link DataBuffer#TYPE_BYTE} or {@link DataBuffer#TYPE_USHORT}. + */ + public IndexColorModel(int bits, int size, int[] cmap, int start, + int transferType, BigInteger validBits) + { + super(bits, // total bits, sRGB, four channels + nArray(8, 4), // bits for each channel + ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB + true, // has alpha + false, // not premultiplied + TRANSLUCENT, transferType); + if (transferType != DataBuffer.TYPE_BYTE + && transferType != DataBuffer.TYPE_USHORT) + throw new IllegalArgumentException(); + if (bits > 16) + throw new IllegalArgumentException("bits > 16"); + if (size < 1) + throw new IllegalArgumentException("size < 1"); + map_size = size; + opaque = false; + this.trans = -1; + this.validBits = validBits; + + rgb = createColorMap(bits, size); + if (!hasAlpha) + for (int i = 0; i < size; i++) + rgb[i] = cmap[i + start] | 0xff000000; + else + System.arraycopy(cmap, start, rgb, 0, size); + } + + /** + * Returns the size of the color lookup table. + * + * @return The size of the color lookup table. + */ + public final int getMapSize() + { + return map_size; + } + + /** + * Get the index of the transparent color in this color model. + * + * @return The index of the color that is considered transparent, or -1 if + * there is no transparent color. + */ + public final int getTransparentPixel() + { + return trans; + } + + /** + * Fills the supplied array with the red component of each color in the + * lookup table. + * + * @param r an array that is at least as large as {@link #getMapSize()}. + * @throws NullPointerException if r is null. + * @throws ArrayIndexOutOfBoundsException if r has less + * than {@link #getMapSize()} elements. + */ + public final void getReds(byte[] r) + { + int i; + for (i = 0; i < map_size; i++) + r[i] = (byte) ((0x00FF0000 & rgb[i]) >> 16); + } + + /** + * Fills the supplied array with the green component of each color in the + * lookup table. + * + * @param g an array that is at least as large as {@link #getMapSize()}. + * @throws NullPointerException if g is null. + * @throws ArrayIndexOutOfBoundsException if g has less + * than {@link #getMapSize()} elements. + */ + public final void getGreens(byte[] g) + { + int i; + for (i = 0; i < map_size; i++) + g[i] = (byte) ((0x0000FF00 & rgb[i]) >> 8); + } + + /** + * Fills the supplied array with the blue component of each color in the + * lookup table. + * + * @param b an array that is at least as large as {@link #getMapSize()}. + * @throws NullPointerException if b is null. + * @throws ArrayIndexOutOfBoundsException if b has less + * than {@link #getMapSize()} elements. + */ + public final void getBlues(byte[] b) + { + int i; + for (i = 0; i < map_size; i++) + b[i] = (byte) (0x000000FF & rgb[i]); + } + + /** + * Fills the supplied array with the alpha component of each color in the + * lookup table. If the model has a transparent pixel specified, the alpha + * for that pixel will be 0. + * + * @param a an array that is at least as large as {@link #getMapSize()}. + * @throws NullPointerException if a is null. + * @throws ArrayIndexOutOfBoundsException if a has less + * than {@link #getMapSize()} elements. + */ + public final void getAlphas(byte[] a) + { + int i; + for (i = 0; i < map_size; i++) + if (i == trans) + a[i] = (byte) 0; + else + a[i] = (byte) ((0xFF000000 & rgb[i]) >> 24); + } + + /** + * Returns the red component of the color in the lookup table for the + * given pixel value. + * + * @param pixel the pixel lookup value. + * + * @return The red component of the color in the lookup table. + * @throws ArrayIndexOutOfBoundsException if pixel is negative. + */ + public final int getRed(int pixel) + { + if (pixel < map_size) + return (0x00FF0000 & rgb[pixel]) >> 16; + + return 0; + } + + /** + * Returns the green component of the color in the lookup table for the + * given pixel value. + * + * @param pixel the pixel lookup value. + * + * @return The green component of the color in the lookup table. + * @throws ArrayIndexOutOfBoundsException if pixel is negative. + */ + public final int getGreen(int pixel) + { + if (pixel < map_size) + return (0x0000FF00 & rgb[pixel]) >> 8; + + return 0; + } + + /** + * Returns the blue component of the color in the lookup table for the + * given pixel value. + * + * @param pixel the pixel lookup value. + * + * @return The blue component of the color in the lookup table. + * @throws ArrayIndexOutOfBoundsException if pixel is negative. + */ + public final int getBlue(int pixel) + { + if (pixel < map_size) + return 0x000000FF & rgb[pixel]; + + return 0; + } + + /** + * Returns the alpha component of the color in the lookup table for the + * given pixel value. If no alpha channel was specified when the color model + * was created, then 255 is returned for all pixels except the transparent + * pixel (if one is defined - see {@link #getTransparentPixel()}) which + * returns an alpha of 0. + * + * @param pixel the pixel lookup value. + * + * @return The alpha component of the color in the lookup table (in the + * range 0 to 255). + * @throws ArrayIndexOutOfBoundsException if pixel is negative. + */ + public final int getAlpha(int pixel) + { + return (rgb[pixel] >> 24) & 0xFF; + } + + /** + * Get the RGB color value of the given pixel using the default + * RGB color model. + * + * @param pixel the pixel lookup value. + * @return The RGB color value. + * @throws ArrayIndexOutOfBoundsException if pixel is negative. + */ + public final int getRGB(int pixel) + { + if (pixel >= 0 && pixel < map_size) + return rgb[pixel]; + + return 0; + } + + /** + * Get the RGB color values of all pixels in the map using the default + * RGB color model. + * + * @param rgb The destination array. + */ + public final void getRGBs(int[] rgb) + { + System.arraycopy(this.rgb, 0, rgb, 0, map_size); + } + + /** + * Return true if the lookup table contains valid data for + * pixel, and false otherwise. + * + * @param pixel the pixel value used to index the color lookup table. + * @return true if pixel is valid, + * false otherwise. + */ + public boolean isValid(int pixel) + { + if (pixel >= 0) + return validBits.testBit(pixel); + return false; + } + + /** + * Return true if all pixels are valid, false + * otherwise. + * + * @return true if all pixels are valid, false + * otherwise. + */ + public boolean isValid() + { + // Generate a bigint with 1's for every pixel + BigInteger allbits = new BigInteger("0"); + allbits = allbits.setBit(map_size); + allbits = allbits.subtract(new BigInteger("1")); + return allbits.equals(validBits); + } + + /** + * Returns a binary value ({@link BigInteger}) where each bit represents an + * entry in the color lookup table. If the bit is on, the entry is valid. + * + * @return The binary value. + */ + public BigInteger getValidPixels() + { + return validBits; + } + + /** + * Construct a {@link BufferedImage} with rgb pixel values from a + * {@link Raster}. + * + * Constructs a new BufferedImage in which each pixel is an RGBA int from + * a Raster with index-valued pixels. If this model has no alpha component + * or transparent pixel, the type of the new BufferedImage is TYPE_INT_RGB. + * Otherwise the type is TYPE_INT_ARGB. If forceARGB is true, the type is + * forced to be TYPE_INT_ARGB no matter what. + * + * @param raster The source of pixel values. + * @param forceARGB True if type must be TYPE_INT_ARGB. + * @return New BufferedImage with RBGA int pixel values. + */ + public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB) + { + int type = forceARGB ? BufferedImage.TYPE_INT_ARGB + : ((opaque && trans == -1) ? BufferedImage.TYPE_INT_RGB : + BufferedImage.TYPE_INT_ARGB); + + // FIXME: assuming that raster has only 1 band since pixels are supposed + // to be int indexes. + // FIXME: it would likely be more efficient to fetch a complete array, + // but it would take much more memory. + // FIXME: I'm not sure if transparent pixels or alpha values need special + // handling here. + BufferedImage im = new BufferedImage(raster.width, raster.height, type); + for (int x = raster.minX; x < raster.width + raster.minX; x++) + for (int y = raster.minY; y < raster.height + raster.minY; y++) + im.setRGB(x, y, rgb[raster.getSample(x, y, 0)]); + + return im; + } + + /** + * Creates a {@link SampleModel} that is compatible to this color model. + * This will be a {@link MultiPixelPackedSampleModel} for bits/pixel of + * 1, 2 or 4, or a {@link ComponentColorModel} for the other cases. + * + * @param w the width of the sample model to create + * @param h the height of the sample model to create + * + * @return a compatible sample model + */ + public SampleModel createCompatibleSampleModel(int w, int h) + { + SampleModel sm; + if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) + sm = new MultiPixelPackedSampleModel(transferType, w, h, pixel_bits); + else + sm = new ComponentSampleModel(transferType, w, h, 1, w, new int[]{0}); + return sm; + } + + /** + * Sets the transparent pixel. This is called by the various constructors. + * + * @param t the transparent pixel + */ + private void setTransparentPixel(int t) + { + if (t >= 0 && t < map_size) + { + rgb[t] &= 0xffffff; // Make the value transparent. + trans = t; + if (transparency == OPAQUE) + { + transparency = BITMASK; + hasAlpha = true; + } + } + } + + private int[] createColorMap(int bits, int size) + { + // According to a Mauve test, the RI allocates at least 256 entries here. + int realSize = Math.max(256, Math.max(1 << bits, size)); + return new int[realSize]; + } +} -- cgit v1.2.3