tileHeight,
sampleSize);
if (imageType == TYPE_BILEVEL) {
byte[] map = new byte[] {(byte)(isWhiteZero ? 255 : 0),
(byte)(isWhiteZero ? 0 : 255)};
colorModel = new IndexColorModel(1, 2, map, map, map);
} else {
byte [] map = new byte[16];
if (isWhiteZero) {
for (int i = 0; i < map.length; i++) {
map[i] = (byte)(255 - (16 * i));
}
} else {
for (int i = 0; i < map.length; i++) {
map[i] = (byte)(16 * i);
}
}
colorModel = new IndexColorModel(4, 16, map, map, map);
}
break;
case TYPE_GRAY:
case TYPE_GRAY_ALPHA:
case TYPE_RGB:
case TYPE_RGB_ALPHA:
// Create a pixel interleaved SampleModel with decreasing
// band offsets.
int[] reverseOffsets = new int[numBands];
for (int i = 0; i < numBands; i++) {
reverseOffsets[i] = numBands - 1 - i;
}
sampleModel = new PixelInterleavedSampleModel
(dataType, tileWidth, tileHeight,
numBands, numBands * tileWidth, reverseOffsets);
if (imageType == TYPE_GRAY) {
colorModel = new ComponentColorModel
(ColorSpace.getInstance(ColorSpace.CS_GRAY),
new int[] {sampleSize}, false, false,
Transparency.OPAQUE, dataType);
} else if (imageType == TYPE_RGB) {
colorModel = new ComponentColorModel
(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {sampleSize, sampleSize, sampleSize},
false, false, Transparency.OPAQUE, dataType);
} else { // hasAlpha
// Transparency.OPAQUE signifies image data that is
// completely opaque, meaning that all pixels have an alpha
// value of 1.0. So the extra band gets ignored, which is
// what we want.
int transparency = Transparency.OPAQUE;
if (extraSamples == 1) { // associated (premultiplied) alpha
transparency = Transparency.TRANSLUCENT;
} else if (extraSamples == 2) { // unassociated alpha
transparency = Transparency.BITMASK;
}
colorModel =
createAlphaComponentColorModel(dataType,
numBands,
extraSamples == 1,
transparency);
}
break;
case TYPE_GENERIC:
case TYPE_YCBCR_SUB:
// For this case we can't display the image, so we create a
// SampleModel with increasing bandOffsets, and keep the
// ColorModel as null, as there is no appropriate ColorModel.
int[] bandOffsets = new int[numBands];
for (int i = 0; i < numBands; i++) {
bandOffsets[i] = i;
}
sampleModel = new PixelInterleavedSampleModel
(dataType, tileWidth, tileHeight,
numBands, numBands * tileWidth, bandOffsets);
colorModel = null;
break;
case TYPE_PALETTE:
// Get the colormap
TIFFField cfield = dir.getField(TIFFImageDecoder.TIFF_COLORMAP);
if (cfield == null) {
throw new RuntimeException(PropertyUtil.getString("TIFFImage11"));
} else {
colormap = cfield.getAsChars();
}
// Could be either 1 or 3 bands depending on whether we use
// IndexColorModel or not.
if (decodePaletteAsShorts) {
numBands = 3;
// If no SampleFormat tag was specified and if the
// sampleSize is less than or equal to 8, then the
// dataType was initially set to byte, but now we want to
// expand the palette as shorts, so the dataType should
// be ushort.
if (dataType == DataBuffer.TYPE_BYTE) {
dataType = DataBuffer.TYPE_USHORT;
}
// Data will have to be unpacked into a 3 band short image
// as we do not have a IndexColorModel that can deal with
// a colormodel whose entries are of short data type.
sampleModel = createPixelInterleavedSampleModel
(dataType, tileWidth, tileHeight, numBands);
colorModel = new ComponentColorModel
(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {16, 16, 16}, false, false,
Transparency.OPAQUE, dataType);
} else {
numBands = 1;
if (sampleSize == 4) {
// Pixel data will not be unpacked, will use
// MPPSM to store packed data and
// IndexColorModel to do the unpacking.
sampleModel = new MultiPixelPackedSampleModel
(DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
sampleSize);
} else if (sampleSize == 8) {
sampleModel = createPixelInterleavedSampleModel
(DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
numBands);
} else if (sampleSize == 16) {
// Here datatype has to be unsigned since we
// are storing indices into the
// IndexColorModel palette. Ofcourse the
// actual palette entries are allowed to be
// negative.
dataType = DataBuffer.TYPE_USHORT;
sampleModel = createPixelInterleavedSampleModel
(DataBuffer.TYPE_USHORT, tileWidth, tileHeight,
numBands);
}
int bandLength = colormap.length / 3;
byte[] r = new byte[bandLength];
byte[] g = new byte[bandLength];
byte[] b = new byte[bandLength];
int gIndex = bandLength;
int bIndex = bandLength * 2;
if (dataType == DataBuffer.TYPE_SHORT) {
for (int i = 0; i < bandLength; i++) {
r[i] = param.decodeSigned16BitsTo8Bits
((short)colormap[i]);
g[i] = param.decodeSigned16BitsTo8Bits
((short)colormap[gIndex + i]);
b[i] = param.decodeSigned16BitsTo8Bits
((short)colormap[bIndex + i]);
}
} else {
for (int i = 0; i < bandLength; i++) {
r[i] = param.decode16BitsTo8Bits
(colormap[i] & 0xffff);
g[i] = param.decode16BitsTo8Bits
(colormap[gIndex + i] & 0xffff);
b[i] = param.decode16BitsTo8Bits
(colormap[bIndex + i] & 0xffff);
}
}
colorModel = new IndexColorModel(sampleSize,
bandLength, r, g, b);
}
break;
default: