bitsPerSample[0] == 4)) {
ColorSpace cs = null;
if(samplesPerPixel == 4)
cs = SimpleCMYKColorSpace.getInstance();
else
cs = new BogusColorSpace(samplesPerPixel);
// By specifying the bits per sample the color values
// will scale on display
ColorModel cm =
new ComponentColorModel(cs, bitsPerSample, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
return new ImageTypeSpecifier(cm,
cm.createCompatibleSampleModel(1, 1));
}
// Compute bits per pixel.
int totalBits = 0;
for (int i = 0; i < bitsPerSample.length; i++) {
totalBits += bitsPerSample[i];
}
// Packed: 3- or 4-band, 8- or 16-bit.
if ((samplesPerPixel == 3 || samplesPerPixel == 4) &&
(totalBits == 8 || totalBits == 16)) {
int redMask = createMask(bitsPerSample, 0);
int greenMask = createMask(bitsPerSample, 1);
int blueMask = createMask(bitsPerSample, 2);
int alphaMask = (samplesPerPixel == 4) ?
createMask(bitsPerSample, 3) : 0;
int transferType = totalBits == 8 ?
DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT;
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
return ImageTypeSpecifier.createPacked(rgb,
redMask,
greenMask,
blueMask,
alphaMask,
transferType,
alphaPremultiplied);
}
// Generic components with 8X bits per sample.
if(bitsPerSample[0] % 8 == 0) {
// Check whether all bands have same bit depth.
boolean allSameBitDepth = true;
for(int i = 1; i < bitsPerSample.length; i++) {
if(bitsPerSample[i] != bitsPerSample[i-1]) {
allSameBitDepth = false;
break;
}
}
// Proceed if all bands have same bit depth.
if(allSameBitDepth) {
// Determine the data type.
int dataType = -1;
boolean isDataTypeSet = false;
switch(bitsPerSample[0]) {
case 8:
if(sampleFormat[0] !=
BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
// Ignore whether signed or unsigned:
// treat all as unsigned.
dataType = DataBuffer.TYPE_BYTE;
isDataTypeSet = true;
}
break;
case 16:
if(sampleFormat[0] !=
BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
if(sampleFormat[0] ==
BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
dataType = DataBuffer.TYPE_SHORT;
} else {
dataType = DataBuffer.TYPE_USHORT;
}
isDataTypeSet = true;
}
break;
case 32:
if(sampleFormat[0] ==
BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
dataType = DataBuffer.TYPE_FLOAT;
} else {
dataType = DataBuffer.TYPE_INT;
}
isDataTypeSet = true;
break;
}
if(isDataTypeSet) {
// Create the SampleModel.
SampleModel sm = createInterleavedSM(dataType,
samplesPerPixel);
// Create the ColorModel.
ColorModel cm;
if(samplesPerPixel >= 1 && samplesPerPixel <= 4 &&
(dataType == DataBuffer.TYPE_INT ||
dataType == DataBuffer.TYPE_FLOAT)) {
// Handle the 32-bit cases for 1-4 bands.
ColorSpace cs = samplesPerPixel <= 2 ?
ColorSpace.getInstance(ColorSpace.CS_GRAY) : rgb;
boolean hasAlpha = ((samplesPerPixel % 2) == 0);
boolean alphaPremultiplied = false;
if(hasAlpha && extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
cm = createComponentCM(cs,
samplesPerPixel,
dataType,
hasAlpha,
alphaPremultiplied);
} else {
ColorSpace cs = new BogusColorSpace(samplesPerPixel);
cm = createComponentCM(cs,
samplesPerPixel,
dataType,
false, // hasAlpha
false); // alphaPremultiplied
}
//System.out.println(cm); // XXX
return new ImageTypeSpecifier(cm, sm);
}
}
}
// Other more bizarre cases including discontiguous DataBuffers
// such as for the image in bug 4918959.
if(colorMap == null &&
sampleFormat[0] !=
BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
// Determine size of largest sample.
int maxBitsPerSample = 0;
for(int i = 0; i < bitsPerSample.length; i++) {
if(bitsPerSample[i] > maxBitsPerSample) {
maxBitsPerSample = bitsPerSample[i];
}
}
// Determine whether data are signed.
boolean isSigned =
(sampleFormat[0] ==
BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER);
// Grayscale
if(samplesPerPixel == 1) {
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
return ImageTypeSpecifier.createGrayscale(maxBitsPerSample,
dataType,
isSigned);
}
// Gray-alpha
if (samplesPerPixel == 2) {
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
return ImageTypeSpecifier.createGrayscale(maxBitsPerSample,
dataType,
false,
alphaPremultiplied);
}
if (samplesPerPixel == 3 || samplesPerPixel == 4) {
if(totalBits <= 32 && !isSigned) {
// Packed RGB or RGBA
int redMask = createMask(bitsPerSample, 0);
int greenMask = createMask(bitsPerSample, 1);
int blueMask = createMask(bitsPerSample, 2);
int alphaMask = (samplesPerPixel == 4) ?
createMask(bitsPerSample, 3) : 0;
int transferType =
getDataTypeFromNumBits(totalBits, false);
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
return ImageTypeSpecifier.createPacked(rgb,
redMask,
greenMask,
blueMask,
alphaMask,
transferType,
alphaPremultiplied);
} else if(samplesPerPixel == 3) {
// Interleaved RGB
int[] bandOffsets = new int[] {0, 1, 2};
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
return ImageTypeSpecifier.createInterleaved(rgb,
bandOffsets,
dataType,
false,
false);
} else if(samplesPerPixel == 4) {
// Interleaved RGBA
int[] bandOffsets = new int[] {0, 1, 2, 3};
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
boolean alphaPremultiplied = false;
if (extraSamples != null &&
extraSamples[0] ==
BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
return ImageTypeSpecifier.createInterleaved(rgb,
bandOffsets,
dataType,
true,
alphaPremultiplied);
}
} else {
// Arbitrary Interleaved.
int dataType =
getDataTypeFromNumBits(maxBitsPerSample, isSigned);
SampleModel sm = createInterleavedSM(dataType,
samplesPerPixel);
ColorSpace cs = new BogusColorSpace(samplesPerPixel);
ColorModel cm = createComponentCM(cs,
samplesPerPixel,
dataType,
false, // hasAlpha
false); // alphaPremultiplied