blob: 0b06acda61047f4faa8fb97d63bf706a801d1fc3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Igor V. Stolyarov
* @version $Revision$
*/
package java.awt.image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.math.BigInteger;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The Class IndexColorModel represents a color model in which the color values
* of the pixels are read from a palette.
*
* @since Android 1.0
*/
public class IndexColorModel extends ColorModel {
/**
* The color map.
*/
private int colorMap[]; // Color Map
/**
* The map size.
*/
private int mapSize; // Color Map size
/**
* The transparent index.
*/
private int transparentIndex; // Index of fully transparent pixel
/**
* The gray palette.
*/
private boolean grayPalette; // Color Model has Color Map with Gray Pallete
/**
* The valid bits.
*/
private BigInteger validBits; // Specify valid Color Map values
/**
* The Constant CACHESIZE.
*/
private static final int CACHESIZE = 20; // Cache size. Cache used for
// improving performace of selection
// nearest color in Color Map
/**
* The cachetable.
*/
private final int cachetable[] = new int[CACHESIZE * 2]; // Cache table -
// used for
// storing RGB values and that appropriate indices
// in the Color Map
/**
* The next insert idx.
*/
private int nextInsertIdx = 0; // Next index for insertion into Cache table
/**
* The total inserted.
*/
private int totalInserted = 0; // Number of inserted values into Cache table
/**
* Instantiates a new index color model.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param cmap
* the array that gives the color mapping.
* @param start
* the start index of the color mapping data within the cmap
* array.
* @param transferType
* the transfer type (primitive java type to use for the
* components).
* @param validBits
* a list of which bits represent valid colormap values, or null
* if all are valid.
* @throws IllegalArgumentException
* if the size of the color map is less than one.
*/
public IndexColorModel(int bits, int size, int cmap[], int start, int transferType,
BigInteger validBits) {
super(bits, IndexColorModel.createBits(true), ColorSpace.getInstance(ColorSpace.CS_sRGB),
true, false, Transparency.OPAQUE, validateTransferType(transferType));
if (size < 1) {
// awt.264=Size of the color map is less than 1
throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
}
mapSize = size;
colorMap = new int[mapSize];
transparentIndex = -1;
if (validBits != null) {
for (int i = 0; i < mapSize; i++) {
if (!validBits.testBit(i)) {
this.validBits = validBits;
}
break;
}
}
transparency = Transparency.OPAQUE;
int alphaMask = 0xff000000;
int alpha = 0;
for (int i = 0; i < mapSize; i++, start++) {
colorMap[i] = cmap[start];
alpha = cmap[start] & alphaMask;
if (alpha == alphaMask) {
continue;
}
if (alpha == 0) {
if (transparentIndex < 0) {
transparentIndex = i;
}
if (transparency == Transparency.OPAQUE) {
transparency = Transparency.BITMASK;
}
} else if (alpha != alphaMask && transparency != Transparency.TRANSLUCENT) {
transparency = Transparency.TRANSLUCENT;
}
}
checkPalette();
}
/**
* Instantiates a new index color model.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param cmap
* the array that gives the color mapping.
* @param start
* the start index of the color mapping data within the cmap
* array.
* @param hasalpha
* whether this color model uses alpha.
* @param trans
* the transparency supported, @see java.awt.Transparency.
* @param transferType
* the transfer type (primitive java type to use for the
* components).
* @throws IllegalArgumentException
* if the size of the color map is less than one.
*/
public IndexColorModel(int bits, int size, int cmap[], int start, boolean hasalpha, int trans,
int transferType) {
super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)), ColorSpace
.getInstance(ColorSpace.CS_sRGB), (hasalpha || (trans >= 0)), false,
Transparency.OPAQUE, validateTransferType(transferType));
if (size < 1) {
// awt.264=Size of the color map is less than 1
throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
}
mapSize = size;
colorMap = new int[mapSize];
if (trans >= 0 && trans < mapSize) {
transparentIndex = trans;
transparency = Transparency.BITMASK;
} else {
transparentIndex = -1;
transparency = Transparency.OPAQUE;
}
int alphaMask = 0xff000000;
int alpha = 0;
for (int i = 0; i < mapSize; i++, start++) {
if (transparentIndex == i) {
colorMap[i] = cmap[start] & 0x00ffffff;
continue;
}
if (hasalpha) {
alpha = cmap[start] & alphaMask;
colorMap[i] = cmap[start];
if (alpha == alphaMask) {
continue;
}
if (alpha == 0) {
if (trans < 0) {
trans = i;
}
if (transparency == Transparency.OPAQUE) {
transparency = Transparency.BITMASK;
}
} else if (alpha != 0 && transparency != Transparency.TRANSLUCENT) {
transparency = Transparency.TRANSLUCENT;
}
} else {
colorMap[i] = alphaMask | cmap[start];
}
}
checkPalette();
}
/**
* Instantiates a new index color model by building the color map from
* arrays of red, green, blue, and alpha values.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param r
* the array giving the red components of the entries in the
* color map.
* @param g
* the array giving the green components of the entries in the
* color map.
* @param b
* the array giving the blue components of the entries in the
* color map.
* @param a
* the array giving the alpha components of the entries in the
* color map.
* @throws IllegalArgumentException
* if the size of the color map is less than one.
* @throws ArrayIndexOutOfBoundsException
* if the size of one of the component arrays is less than the
* size of the color map.
*/
public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[], byte a[]) {
super(bits, IndexColorModel.createBits(true), ColorSpace.getInstance(ColorSpace.CS_sRGB),
true, false, Transparency.OPAQUE, validateTransferType(ColorModel
.getTransferType(bits)));
createColorMap(size, r, g, b, a, -1);
checkPalette();
}
/**
* Instantiates a new index color model by building the color map from
* arrays of red, green, and blue values.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param r
* the array giving the red components of the entries in the
* color map.
* @param g
* the array giving the green components of the entries in the
* color map.
* @param b
* the array giving the blue components of the entries in the
* color map.
* @param trans
* the transparency supported, @see java.awt.Transparency.
* @throws IllegalArgumentException
* if the size of the color map is less than one.
* @throws ArrayIndexOutOfBoundsException
* if the size of one of the component arrays is less than the
* size of the color map.
*/
public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[], int trans) {
super(bits, IndexColorModel.createBits((trans >= 0)), ColorSpace
.getInstance(ColorSpace.CS_sRGB), (trans >= 0), false, Transparency.OPAQUE,
validateTransferType(ColorModel.getTransferType(bits)));
createColorMap(size, r, g, b, null, trans);
checkPalette();
}
/**
* Instantiates a new index color model by building the color map from
* arrays of red, green, and blue values.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param r
* the array giving the red components of the entries in the
* color map.
* @param g
* the array giving the green components of the entries in the
* color map.
* @param b
* the array giving the blue components of the entries in the
* color map.
* @throws IllegalArgumentException
* if the size of the color map is less than one.
* @throws ArrayIndexOutOfBoundsException
* if the size of one of the component arrays is less than the
* size of the color map.
*/
public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[]) {
super(bits, IndexColorModel.createBits(false), ColorSpace.getInstance(ColorSpace.CS_sRGB),
false, false, Transparency.OPAQUE, validateTransferType(ColorModel
.getTransferType(bits)));
createColorMap(size, r, g, b, null, -1);
checkPalette();
}
/**
* Instantiates a new index color model.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param cmap
* the array that gives the color mapping.
* @param start
* the start index of the color mapping data within the cmap
* array.
* @param hasalpha
* whether this color model uses alpha.
* @param trans
* the transparency supported, @see java.awt.Transparency.
* @throws IllegalArgumentException
* if the size of the color map is less than one.
*/
public IndexColorModel(int bits, int size, byte cmap[], int start, boolean hasalpha, int trans) {
super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)), ColorSpace
.getInstance(ColorSpace.CS_sRGB), (hasalpha || (trans >= 0)), false,
Transparency.OPAQUE, validateTransferType(ColorModel.getTransferType(bits)));
if (size < 1) {
// awt.264=Size of the color map is less than 1
throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
}
mapSize = size;
colorMap = new int[mapSize];
transparentIndex = -1;
transparency = Transparency.OPAQUE;
int alpha = 0xff000000;
for (int i = 0; i < mapSize; i++) {
colorMap[i] = (cmap[start++] & 0xff) << 16 | (cmap[start++] & 0xff) << 8
| (cmap[start++] & 0xff);
if (trans == i) {
if (transparency == Transparency.OPAQUE) {
transparency = Transparency.BITMASK;
}
if (hasalpha) {
start++;
}
continue;
}
if (hasalpha) {
alpha = cmap[start++] & 0xff;
if (alpha == 0) {
if (transparency == Transparency.OPAQUE) {
transparency = Transparency.BITMASK;
if (trans < 0) {
trans = i;
}
}
} else {
if (alpha != 0xff && transparency != Transparency.TRANSLUCENT) {
transparency = Transparency.TRANSLUCENT;
}
}
alpha <<= 24;
}
colorMap[i] |= alpha;
}
if (trans >= 0 && trans < mapSize) {
transparentIndex = trans;
}
checkPalette();
}
/**
* Instantiates a new index color model.
*
* @param bits
* the array of component masks.
* @param size
* the size of the color map.
* @param cmap
* the array that gives the color mapping.
* @param start
* the start index of the color mapping data within the cmap
* array.
* @param hasalpha
* whether this color model uses alpha.
* @throws IllegalArgumentException
* if the size of the color map is less than one.
*/
public IndexColorModel(int bits, int size, byte cmap[], int start, boolean hasalpha) {
this(bits, size, cmap, start, hasalpha, -1);
}
@Override
public Object getDataElements(int[] components, int offset, Object pixel) {
int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
| components[offset + 2];
if (hasAlpha) {
rgb |= components[offset + 3] << 24;
} else {
rgb |= 0xff000000;
}
return getDataElements(rgb, pixel);
}
@Override
public synchronized Object getDataElements(int rgb, Object pixel) {
int red = (rgb >> 16) & 0xff;
int green = (rgb >> 8) & 0xff;
int blue = rgb & 0xff;
int alpha = rgb >>> 24;
int pixIdx = 0;
for (int i = 0; i < totalInserted; i++) {
int idx = i * 2;
if (rgb == cachetable[idx]) {
return createDataObject(cachetable[idx + 1], pixel);
}
}
if (!hasAlpha && grayPalette) {
int grey = (red * 77 + green * 150 + blue * 29 + 128) >>> 8;
int minError = 255;
int error = 0;
for (int i = 0; i < mapSize; i++) {
error = Math.abs((colorMap[i] & 0xff) - grey);
if (error < minError) {
pixIdx = i;
if (error == 0) {
break;
}
minError = error;
}
}
} else if (alpha == 0 && transparentIndex > -1) {
pixIdx = transparentIndex;
} else {
int minAlphaError = 255;
int minError = 195075; // 255^2 + 255^2 + 255^2
int alphaError;
int error = 0;
for (int i = 0; i < mapSize; i++) {
int pix = colorMap[i];
if (rgb == pix) {
pixIdx = i;
break;
}
alphaError = Math.abs(alpha - (pix >>> 24));
if (alphaError <= minAlphaError) {
minAlphaError = alphaError;
int buf = ((pix >> 16) & 0xff) - red;
error = buf * buf;
if (error < minError) {
buf = ((pix >> 8) & 0xff) - green;
error += buf * buf;
if (error < minError) {
buf = (pix & 0xff) - blue;
error += buf * buf;
if (error < minError) {
pixIdx = i;
minError = error;
}
}
}
}
}
}
cachetable[nextInsertIdx] = rgb;
cachetable[nextInsertIdx + 1] = pixIdx;
nextInsertIdx = (nextInsertIdx + 2) % (CACHESIZE * 2);
if (totalInserted < CACHESIZE) {
totalInserted++;
}
return createDataObject(pixIdx, pixel);
}
/**
* Converts an image from indexed to RGB format.
*
* @param raster
* the raster containing the source image.
* @param forceARGB
* whether to use the default RGB color model.
* @return the buffered image.
* @throws IllegalArgumentException
* if the raster is not compatible with this color model.
*/
public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB) {
if (!isCompatibleRaster(raster)) {
// awt.265=The raster argument is not compatible with this
// IndexColorModel
throw new IllegalArgumentException(Messages.getString("awt.265")); //$NON-NLS-1$
}
ColorModel model;
if (forceARGB || transparency == Transparency.TRANSLUCENT) {
model = ColorModel.getRGBdefault();
} else if (transparency == Transparency.BITMASK) {
model = new DirectColorModel(25, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x01000000);
} else {
model = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
}
int w = raster.getWidth();
int h = raster.getHeight();
WritableRaster distRaster = model.createCompatibleWritableRaster(w, h);
int minX = raster.getMinX();
int minY = raster.getMinY();
Object obj = null;
int pixels[] = null;
for (int i = 0; i < h; i++, minY++) {
obj = raster.getDataElements(minX, minY, w, 1, obj);
if (obj instanceof byte[]) {
byte ba[] = (byte[])obj;
if (pixels == null) {
pixels = new int[ba.length];
}
for (int j = 0; j < ba.length; j++) {
pixels[j] = colorMap[ba[j] & 0xff];
}
} else if (obj instanceof short[]) {
short sa[] = (short[])obj;
if (pixels == null) {
pixels = new int[sa.length];
}
for (int j = 0; j < sa.length; j++) {
pixels[j] = colorMap[sa[j] & 0xffff];
}
}
if (obj instanceof int[]) {
int ia[] = (int[])obj;
if (pixels == null) {
pixels = new int[ia.length];
}
for (int j = 0; j < ia.length; j++) {
pixels[j] = colorMap[ia[j]];
}
}
distRaster.setDataElements(0, i, w, 1, pixels);
}
return new BufferedImage(model, distRaster, false, null);
}
/**
* Gets the valid pixels.
*
* @return the valid pixels.
*/
public BigInteger getValidPixels() {
return validBits;
}
@Override
public String toString() {
// The output format based on 1.5 release behaviour.
// It could be reveled such way:
// BufferedImage bi = new BufferedImage(1, 1,
// BufferedImage.TYPE_BYTE_INDEXED);
// ColorModel cm = bi.getColorModel();
// System.out.println(cm.toString());
String str = "IndexColorModel: #pixel_bits = " + pixel_bits + //$NON-NLS-1$
" numComponents = " + numComponents + " color space = " + cs + //$NON-NLS-1$ //$NON-NLS-2$
" transparency = "; //$NON-NLS-1$
if (transparency == Transparency.OPAQUE) {
str = str + "Transparency.OPAQUE"; //$NON-NLS-1$
} else if (transparency == Transparency.BITMASK) {
str = str + "Transparency.BITMASK"; //$NON-NLS-1$
} else {
str = str + "Transparency.TRANSLUCENT"; //$NON-NLS-1$
}
str = str + " transIndex = " + transparentIndex + " has alpha = " + //$NON-NLS-1$ //$NON-NLS-2$
hasAlpha + " isAlphaPre = " + isAlphaPremultiplied; //$NON-NLS-1$
return str;
}
@Override
public int[] getComponents(Object pixel, int components[], int offset) {
int pixIdx = -1;
if (pixel instanceof byte[]) {
byte ba[] = (byte[])pixel;
pixIdx = ba[0] & 0xff;
} else if (pixel instanceof short[]) {
short sa[] = (short[])pixel;
pixIdx = sa[0] & 0xffff;
} else if (pixel instanceof int[]) {
int ia[] = (int[])pixel;
pixIdx = ia[0];
} else {
// awt.219=This transferType is not supported by this color model
throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
}
return getComponents(pixIdx, components, offset);
}
@Override
public WritableRaster createCompatibleWritableRaster(int w, int h) {
WritableRaster raster;
if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, 1, pixel_bits, null);
} else if (pixel_bits <= 8) {
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h, 1, null);
} else if (pixel_bits <= 16) {
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, w, h, 1, null);
} else {
// awt.266=The number of bits in a pixel is greater than 16
throw new UnsupportedOperationException(Messages.getString("awt.266")); //$NON-NLS-1$
}
return raster;
}
@Override
public boolean isCompatibleSampleModel(SampleModel sm) {
if (sm == null) {
return false;
}
if (!(sm instanceof MultiPixelPackedSampleModel) && !(sm instanceof ComponentSampleModel)) {
return false;
}
if (sm.getTransferType() != transferType) {
return false;
}
if (sm.getNumBands() != 1) {
return false;
}
return true;
}
@Override
public SampleModel createCompatibleSampleModel(int w, int h) {
if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
return new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, pixel_bits);
}
int bandOffsets[] = new int[1];
bandOffsets[0] = 0;
return new ComponentSampleModel(transferType, w, h, 1, w, bandOffsets);
}
@Override
public boolean isCompatibleRaster(Raster raster) {
int sampleSize = raster.getSampleModel().getSampleSize(0);
return (raster.getTransferType() == transferType && raster.getNumBands() == 1 && (1 << sampleSize) >= mapSize);
}
@Override
public int getDataElement(int components[], int offset) {
int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
| components[offset + 2];
if (hasAlpha) {
rgb |= components[offset + 3] << 24;
} else {
rgb |= 0xff000000;
}
int pixel;
switch (transferType) {
case DataBuffer.TYPE_BYTE:
byte ba[] = (byte[])getDataElements(rgb, null);
pixel = ba[0] & 0xff;
break;
case DataBuffer.TYPE_USHORT:
short sa[] = (short[])getDataElements(rgb, null);
pixel = sa[0] & 0xffff;
break;
default:
// awt.267=The transferType is invalid
throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
}
return pixel;
}
/**
* Gets the color map.
*
* @param rgb
* the destination array where the color map is written.
*/
public final void getRGBs(int rgb[]) {
System.arraycopy(colorMap, 0, rgb, 0, mapSize);
}
/**
* Gets the red component of the color map.
*
* @param r
* the destination array.
*/
public final void getReds(byte r[]) {
for (int i = 0; i < mapSize; i++) {
r[i] = (byte)(colorMap[i] >> 16);
}
}
/**
* Gets the green component of the color map.
*
* @param g
* the destination array.
*/
public final void getGreens(byte g[]) {
for (int i = 0; i < mapSize; i++) {
g[i] = (byte)(colorMap[i] >> 8);
}
}
/**
* Gets the blue component of the color map.
*
* @param b
* the destination array.
*/
public final void getBlues(byte b[]) {
for (int i = 0; i < mapSize; i++) {
b[i] = (byte)colorMap[i];
}
}
/**
* Gets the alpha component of the color map.
*
* @param a
* the destination array.
*/
public final void getAlphas(byte a[]) {
for (int i = 0; i < mapSize; i++) {
a[i] = (byte)(colorMap[i] >> 24);
}
}
@Override
public int[] getComponents(int pixel, int components[], int offset) {
if (components == null) {
components = new int[offset + numComponents];
}
components[offset + 0] = getRed(pixel);
components[offset + 1] = getGreen(pixel);
components[offset + 2] = getBlue(pixel);
if (hasAlpha && (components.length - offset) > 3) {
components[offset + 3] = getAlpha(pixel);
}
return components;
}
/**
* Checks if the specified pixel is valid for this color model.
*
* @param pixel
* the pixel.
* @return true, if the pixel is valid.
*/
public boolean isValid(int pixel) {
if (validBits == null) {
return (pixel >= 0 && pixel < mapSize);
}
return (pixel < mapSize && validBits.testBit(pixel));
}
@Override
public final int getRed(int pixel) {
return (colorMap[pixel] >> 16) & 0xff;
}
@Override
public final int getRGB(int pixel) {
return colorMap[pixel];
}
@Override
public final int getGreen(int pixel) {
return (colorMap[pixel] >> 8) & 0xff;
}
@Override
public final int getBlue(int pixel) {
return colorMap[pixel] & 0xff;
}
@Override
public final int getAlpha(int pixel) {
return (colorMap[pixel] >> 24) & 0xff;
}
@Override
public int[] getComponentSize() {
return bits.clone();
}
/**
* Checks if this color model validates pixels.
*
* @return true, if all pixels are valid, otherwise false.
*/
public boolean isValid() {
return (validBits == null);
}
@Override
public void finalize() {
// TODO: implement
return;
}
/**
* Gets the index that represents the transparent pixel.
*
* @return the index that represents the transparent pixel.
*/
public final int getTransparentPixel() {
return transparentIndex;
}
@Override
public int getTransparency() {
return transparency;
}
/**
* Gets the size of the color map.
*
* @return the map size.
*/
public final int getMapSize() {
return mapSize;
}
/**
* Creates the color map.
*
* @param size
* the size.
* @param r
* the r.
* @param g
* the g.
* @param b
* the b.
* @param a
* the a.
* @param trans
* the trans.
*/
private void createColorMap(int size, byte r[], byte g[], byte b[], byte a[], int trans) {
if (size < 1) {
// awt.264=Size of the color map is less than 1
throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
}
mapSize = size;
colorMap = new int[mapSize];
if (trans >= 0 && trans < mapSize) {
transparency = Transparency.BITMASK;
transparentIndex = trans;
} else {
transparency = Transparency.OPAQUE;
transparentIndex = -1;
}
int alpha = 0;
for (int i = 0; i < mapSize; i++) {
colorMap[i] = ((r[i] & 0xff) << 16) | ((g[i] & 0xff) << 8) | (b[i] & 0xff);
if (trans == i) {
continue;
}
if (a == null) {
colorMap[i] |= 0xff000000;
} else {
alpha = a[i] & 0xff;
if (alpha == 0xff) {
colorMap[i] |= 0xff000000;
} else if (alpha == 0) {
if (transparency == Transparency.OPAQUE) {
transparency = Transparency.BITMASK;
}
if (transparentIndex < 0) {
transparentIndex = i;
}
} else {
colorMap[i] |= (a[i] & 0xff) << 24;
if (transparency != Transparency.TRANSLUCENT) {
transparency = Transparency.TRANSLUCENT;
}
}
}
}
}
/**
* This method checking, if Color Map has Gray palette.
*/
private void checkPalette() {
grayPalette = false;
if (transparency > Transparency.OPAQUE) {
return;
}
int rgb = 0;
for (int i = 0; i < mapSize; i++) {
rgb = colorMap[i];
if (((rgb >> 16) & 0xff) != ((rgb >> 8) & 0xff) || ((rgb >> 8) & 0xff) != (rgb & 0xff)) {
return;
}
}
grayPalette = true;
}
/**
* Construction an array pixel representation.
*
* @param colorMapIdx
* the index into Color Map.
* @param pixel
* the pixel
* @return the pixel representation array.
*/
private Object createDataObject(int colorMapIdx, Object pixel) {
if (pixel == null) {
switch (transferType) {
case DataBuffer.TYPE_BYTE:
byte[] ba = new byte[1];
ba[0] = (byte)colorMapIdx;
pixel = ba;
break;
case DataBuffer.TYPE_USHORT:
short[] sa = new short[1];
sa[0] = (short)colorMapIdx;
pixel = sa;
break;
default:
// awt.267=The transferType is invalid
throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
}
} else if (pixel instanceof byte[] && transferType == DataBuffer.TYPE_BYTE) {
byte ba[] = (byte[])pixel;
ba[0] = (byte)colorMapIdx;
pixel = ba;
} else if (pixel instanceof short[] && transferType == DataBuffer.TYPE_USHORT) {
short[] sa = (short[])pixel;
sa[0] = (short)colorMapIdx;
pixel = sa;
} else if (pixel instanceof int[]) {
int ia[] = (int[])pixel;
ia[0] = colorMapIdx;
pixel = ia;
} else {
// awt.268=The pixel is not a primitive array of type transferType
throw new ClassCastException(Messages.getString("awt.268")); //$NON-NLS-1$
}
return pixel;
}
/**
* Creates the bits.
*
* @param hasAlpha
* the has alpha.
* @return the int[].
*/
private static int[] createBits(boolean hasAlpha) {
int numChannels;
if (hasAlpha) {
numChannels = 4;
} else {
numChannels = 3;
}
int bits[] = new int[numChannels];
for (int i = 0; i < numChannels; i++) {
bits[i] = 8;
}
return bits;
}
/**
* Validate transfer type.
*
* @param transferType
* the transfer type.
* @return the int.
*/
private static int validateTransferType(int transferType) {
if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT) {
// awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or
// DataBuffer.TYPE_USHORT
throw new IllegalArgumentException(Messages.getString("awt.269")); //$NON-NLS-1$
}
return transferType;
}
/**
* Checks if is gray palette.
*
* @return true, if is gray palette.
*/
boolean isGrayPallete() {
return grayPalette;
}
}