Search in sources :

Example 1 with BogusColorSpace

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;
}
Also used : ComponentSampleModel(java.awt.image.ComponentSampleModel) SampleModel(java.awt.image.SampleModel) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) SinglePixelPackedSampleModel(java.awt.image.SinglePixelPackedSampleModel) PixelInterleavedSampleModel(java.awt.image.PixelInterleavedSampleModel) ColorSpace(java.awt.color.ColorSpace) BogusColorSpace(com.sun.media.imageioimpl.common.BogusColorSpace) SimpleCMYKColorSpace(com.sun.media.imageioimpl.common.SimpleCMYKColorSpace) IndexColorModel(java.awt.image.IndexColorModel) ComponentColorModel(java.awt.image.ComponentColorModel) ColorModel(java.awt.image.ColorModel) ComponentColorModel(java.awt.image.ComponentColorModel) BogusColorSpace(com.sun.media.imageioimpl.common.BogusColorSpace) ImageTypeSpecifier(javax.imageio.ImageTypeSpecifier)

Aggregations

BogusColorSpace (com.sun.media.imageioimpl.common.BogusColorSpace)1 SimpleCMYKColorSpace (com.sun.media.imageioimpl.common.SimpleCMYKColorSpace)1 ColorSpace (java.awt.color.ColorSpace)1 ColorModel (java.awt.image.ColorModel)1 ComponentColorModel (java.awt.image.ComponentColorModel)1 ComponentSampleModel (java.awt.image.ComponentSampleModel)1 IndexColorModel (java.awt.image.IndexColorModel)1 MultiPixelPackedSampleModel (java.awt.image.MultiPixelPackedSampleModel)1 PixelInterleavedSampleModel (java.awt.image.PixelInterleavedSampleModel)1 SampleModel (java.awt.image.SampleModel)1 SinglePixelPackedSampleModel (java.awt.image.SinglePixelPackedSampleModel)1 ImageTypeSpecifier (javax.imageio.ImageTypeSpecifier)1