use of com.sun.media.imageioimpl.common.BogusColorSpace in project imageio-ext by geosolutions-it.
the class TIFFDecompressor method getRawImageTypeSpecifier.
/**
* A utility method that returns an
* <code>ImageTypeSpecifier</code> suitable for decoding an image
* with the given parameters.
*
* @param photometricInterpretation the value of the
* <code>PhotometricInterpretation</code> field.
* @param compression the value of the <code>Compression</code> field.
* @param samplesPerPixel the value of the
* <code>SamplesPerPixel</code> field.
* @param bitsPerSample the value of the <code>BitsPerSample</code> field.
* @param sampleFormat the value of the <code>SampleFormat</code> field.
* @param extraSamples the value of the <code>ExtraSamples</code> field.
* @param colorMap the value of the <code>ColorMap</code> field.
*
* @return a suitable <code>ImageTypeSpecifier</code>, or
* <code>null</code> if it is not possible to create one.
*/
public static ImageTypeSpecifier getRawImageTypeSpecifier(int photometricInterpretation, int compression, int samplesPerPixel, int[] bitsPerSample, int[] sampleFormat, int[] extraSamples, char[] colorMap) {
if (DEBUG) {
System.out.println("\n ---- samplesPerPixel = " + samplesPerPixel + "\n ---- bitsPerSample[0] = " + bitsPerSample[0] + "\n ---- sampleFormat[0] = " + sampleFormat[0]);
}
// 1, 2, 4, 8, or 16 bit grayscale or indexed images
if (samplesPerPixel == 1 && (bitsPerSample[0] == 1 || bitsPerSample[0] == 2 || bitsPerSample[0] == 4 || bitsPerSample[0] == 8 || bitsPerSample[0] == 16)) {
if (colorMap == null) {
// Grayscale
boolean isSigned = (sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER);
int dataType;
if (bitsPerSample[0] <= 8) {
dataType = DataBuffer.TYPE_BYTE;
} else {
dataType = sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
}
return ImageTypeSpecifier.createGrayscale(bitsPerSample[0], dataType, isSigned);
} else {
// Indexed
int mapSize = 1 << bitsPerSample[0];
byte[] redLut = new byte[mapSize];
byte[] greenLut = new byte[mapSize];
byte[] blueLut = new byte[mapSize];
byte[] alphaLut = null;
int idx = 0;
for (int i = 0; i < mapSize; i++) {
redLut[i] = (byte) ((colorMap[i] * 255) / 65535);
greenLut[i] = (byte) ((colorMap[mapSize + i] * 255) / 65535);
blueLut[i] = (byte) ((colorMap[2 * mapSize + i] * 255) / 65535);
}
int dataType = bitsPerSample[0] <= 8 ? DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT;
return ImageTypeSpecifier.createIndexed(redLut, greenLut, blueLut, alphaLut, bitsPerSample[0], dataType);
}
}
// 8-bit gray-alpha
if (samplesPerPixel == 2 && bitsPerSample[0] == 8 && bitsPerSample[1] == 8) {
int dataType = DataBuffer.TYPE_BYTE;
boolean alphaPremultiplied = false;
if (extraSamples != null && extraSamples[0] == BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
// System.out.println("alphaPremultiplied = "+alphaPremultiplied);//XXX
return ImageTypeSpecifier.createGrayscale(8, dataType, false, alphaPremultiplied);
}
// 16-bit gray-alpha
if (samplesPerPixel == 2 && bitsPerSample[0] == 16 && bitsPerSample[1] == 16) {
int dataType = sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
boolean alphaPremultiplied = false;
if (extraSamples != null && extraSamples[0] == BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
// System.out.println("alphaPremultiplied = "+alphaPremultiplied);//XXX
boolean isSigned = dataType == DataBuffer.TYPE_SHORT;
return ImageTypeSpecifier.createGrayscale(16, dataType, isSigned, alphaPremultiplied);
}
ColorSpace rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
// 8-bit RGB
if (samplesPerPixel == 3 && bitsPerSample[0] == 8 && bitsPerSample[1] == 8 && bitsPerSample[2] == 8) {
int[] bandOffsets = new int[3];
bandOffsets[0] = 0;
bandOffsets[1] = 1;
bandOffsets[2] = 2;
int dataType = DataBuffer.TYPE_BYTE;
ColorSpace theColorSpace;
if ((photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR && compression != BaselineTIFFTagSet.COMPRESSION_JPEG && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) || photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB) {
theColorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
} else {
theColorSpace = rgb;
}
return ImageTypeSpecifier.createInterleaved(theColorSpace, bandOffsets, dataType, false, false);
}
// 8-bit RGBA
if (samplesPerPixel == 4 && bitsPerSample[0] == 8 && bitsPerSample[1] == 8 && bitsPerSample[2] == 8 && bitsPerSample[3] == 8) {
int[] bandOffsets = new int[4];
bandOffsets[0] = 0;
bandOffsets[1] = 1;
bandOffsets[2] = 2;
bandOffsets[3] = 3;
int dataType = DataBuffer.TYPE_BYTE;
ColorSpace theColorSpace;
boolean hasAlpha;
boolean alphaPremultiplied = false;
if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK) {
theColorSpace = SimpleCMYKColorSpace.getInstance();
hasAlpha = false;
} else {
theColorSpace = rgb;
hasAlpha = true;
if (extraSamples != null && extraSamples[0] == BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
}
return ImageTypeSpecifier.createInterleaved(theColorSpace, bandOffsets, dataType, hasAlpha, alphaPremultiplied);
}
// 16-bit RGB
if (samplesPerPixel == 3 && bitsPerSample[0] == 16 && bitsPerSample[1] == 16 && bitsPerSample[2] == 16) {
int[] bandOffsets = new int[3];
bandOffsets[0] = 0;
bandOffsets[1] = 1;
bandOffsets[2] = 2;
int dataType = sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
return ImageTypeSpecifier.createInterleaved(rgb, bandOffsets, dataType, false, false);
}
// 16-bit RGBA
if (samplesPerPixel == 4 && bitsPerSample[0] == 16 && bitsPerSample[1] == 16 && bitsPerSample[2] == 16 && bitsPerSample[3] == 16) {
int[] bandOffsets = new int[4];
bandOffsets[0] = 0;
bandOffsets[1] = 1;
bandOffsets[2] = 2;
bandOffsets[3] = 3;
int dataType = sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
boolean alphaPremultiplied = false;
if (extraSamples != null && extraSamples[0] == BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
alphaPremultiplied = true;
}
return ImageTypeSpecifier.createInterleaved(rgb, bandOffsets, dataType, true, alphaPremultiplied);
}
// in more than 1 channel
if ((photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK) && (bitsPerSample[0] == 1 || bitsPerSample[0] == 2 || 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;
case 64:
if (sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
dataType = DataBuffer.TYPE_DOUBLE;
} else
throw new IllegalStateException("Unsupported sample format for 64 bits data.");
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, // hasAlpha
false, // alphaPremultiplied
false);
}
// System.out.println(cm); // XXX
return new ImageTypeSpecifier(cm, sm);
}
}
}
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, // hasAlpha
false, // alphaPremultiplied
false);
return new ImageTypeSpecifier(cm, sm);
}
}
if (DEBUG) {
System.out.println("\nNo raw ITS available:");
System.out.println("photometricInterpretation = " + photometricInterpretation);
System.out.println("compression = " + compression);
System.out.println("samplesPerPixel = " + samplesPerPixel);
if (bitsPerSample != null) {
for (int i = 0; i < bitsPerSample.length; i++) {
System.out.println("bitsPerSample[" + i + "] = " + (int) bitsPerSample[i]);
}
}
if (sampleFormat != null) {
for (int i = 0; i < sampleFormat.length; i++) {
System.out.println("sampleFormat[" + i + "] = " + (int) sampleFormat[i]);
}
}
if (extraSamples != null) {
for (int i = 0; i < extraSamples.length; i++) {
System.out.println("extraSamples[" + i + "] = " + (int) extraSamples[i]);
}
}
System.out.println("colorMap = " + colorMap);
if (colorMap != null) {
System.out.println("colorMap.length = " + colorMap.length);
}
throw new RuntimeException("Unable to create an ImageTypeSpecifier");
}
return null;
}
Aggregations