Search in sources :

Example 21 with ICC_ColorSpace

use of java.awt.color.ICC_ColorSpace in project jdk8u_jdk by JetBrains.

the class BMPImageReader method readHeader.

/**
     * Process the image header.
     *
     * @exception IllegalStateException if source stream is not set.
     *
     * @exception IOException if image stream is corrupted.
     *
     * @exception IllegalArgumentException if the image stream does not contain
     *             a BMP image, or if a sample model instance to describe the
     *             image can not be created.
     */
protected void readHeader() throws IOException, IllegalArgumentException {
    if (gotHeader)
        return;
    if (iis == null) {
        throw new IllegalStateException("Input source not set!");
    }
    int profileData = 0, profileSize = 0;
    this.metadata = new BMPMetadata();
    iis.mark();
    // read and check the magic marker
    byte[] marker = new byte[2];
    iis.read(marker);
    if (marker[0] != 0x42 || marker[1] != 0x4d)
        throw new IllegalArgumentException(I18N.getString("BMPImageReader1"));
    // Read file size
    bitmapFileSize = iis.readUnsignedInt();
    // skip the two reserved fields
    iis.skipBytes(4);
    // Offset to the bitmap from the beginning
    bitmapOffset = iis.readUnsignedInt();
    // End File Header
    // Start BitmapCoreHeader
    long size = iis.readUnsignedInt();
    if (size == 12) {
        width = iis.readShort();
        height = iis.readShort();
    } else {
        width = iis.readInt();
        height = iis.readInt();
    }
    metadata.width = width;
    metadata.height = height;
    int planes = iis.readUnsignedShort();
    bitsPerPixel = iis.readUnsignedShort();
    //metadata.colorPlane = planes;
    metadata.bitsPerPixel = (short) bitsPerPixel;
    // As BMP always has 3 rgb bands, except for Version 5,
    // which is bgra
    numBands = 3;
    if (size == 12) {
        // Windows 2.x and OS/2 1.x
        metadata.bmpVersion = VERSION_2;
        // Classify the image type
        if (bitsPerPixel == 1) {
            imageType = VERSION_2_1_BIT;
        } else if (bitsPerPixel == 4) {
            imageType = VERSION_2_4_BIT;
        } else if (bitsPerPixel == 8) {
            imageType = VERSION_2_8_BIT;
        } else if (bitsPerPixel == 24) {
            imageType = VERSION_2_24_BIT;
        }
        // Read in the palette
        int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 3);
        int sizeOfPalette = numberOfEntries * 3;
        palette = new byte[sizeOfPalette];
        iis.readFully(palette, 0, sizeOfPalette);
        metadata.palette = palette;
        metadata.paletteSize = numberOfEntries;
    } else {
        compression = iis.readUnsignedInt();
        imageSize = iis.readUnsignedInt();
        long xPelsPerMeter = iis.readInt();
        long yPelsPerMeter = iis.readInt();
        long colorsUsed = iis.readUnsignedInt();
        long colorsImportant = iis.readUnsignedInt();
        metadata.compression = (int) compression;
        metadata.xPixelsPerMeter = (int) xPelsPerMeter;
        metadata.yPixelsPerMeter = (int) yPelsPerMeter;
        metadata.colorsUsed = (int) colorsUsed;
        metadata.colorsImportant = (int) colorsImportant;
        if (size == 40) {
            // Windows 3.x and Windows NT
            switch((int) compression) {
                case BI_JPEG:
                case BI_PNG:
                    metadata.bmpVersion = VERSION_3;
                    imageType = VERSION_3_XP_EMBEDDED;
                    break;
                // No compression
                case BI_RGB:
                // 8-bit RLE compression
                case BI_RLE8:
                case // 4-bit RLE compression
                BI_RLE4:
                    // Read in the palette
                    if (bitmapOffset < (size + 14)) {
                        throw new IIOException(I18N.getString("BMPImageReader7"));
                    }
                    int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 4);
                    int sizeOfPalette = numberOfEntries * 4;
                    palette = new byte[sizeOfPalette];
                    iis.readFully(palette, 0, sizeOfPalette);
                    metadata.palette = palette;
                    metadata.paletteSize = numberOfEntries;
                    if (bitsPerPixel == 1) {
                        imageType = VERSION_3_1_BIT;
                    } else if (bitsPerPixel == 4) {
                        imageType = VERSION_3_4_BIT;
                    } else if (bitsPerPixel == 8) {
                        imageType = VERSION_3_8_BIT;
                    } else if (bitsPerPixel == 24) {
                        imageType = VERSION_3_24_BIT;
                    } else if (bitsPerPixel == 16) {
                        imageType = VERSION_3_NT_16_BIT;
                        redMask = 0x7C00;
                        greenMask = 0x3E0;
                        // 0x1F;
                        blueMask = (1 << 5) - 1;
                        metadata.redMask = redMask;
                        metadata.greenMask = greenMask;
                        metadata.blueMask = blueMask;
                    } else if (bitsPerPixel == 32) {
                        imageType = VERSION_3_NT_32_BIT;
                        redMask = 0x00FF0000;
                        greenMask = 0x0000FF00;
                        blueMask = 0x000000FF;
                        metadata.redMask = redMask;
                        metadata.greenMask = greenMask;
                        metadata.blueMask = blueMask;
                    }
                    metadata.bmpVersion = VERSION_3;
                    break;
                case BI_BITFIELDS:
                    if (bitsPerPixel == 16) {
                        imageType = VERSION_3_NT_16_BIT;
                    } else if (bitsPerPixel == 32) {
                        imageType = VERSION_3_NT_32_BIT;
                    }
                    // BitsField encoding
                    redMask = (int) iis.readUnsignedInt();
                    greenMask = (int) iis.readUnsignedInt();
                    blueMask = (int) iis.readUnsignedInt();
                    metadata.redMask = redMask;
                    metadata.greenMask = greenMask;
                    metadata.blueMask = blueMask;
                    if (colorsUsed != 0) {
                        // there is a palette
                        sizeOfPalette = (int) colorsUsed * 4;
                        palette = new byte[sizeOfPalette];
                        iis.readFully(palette, 0, sizeOfPalette);
                        metadata.palette = palette;
                        metadata.paletteSize = (int) colorsUsed;
                    }
                    metadata.bmpVersion = VERSION_3_NT;
                    break;
                default:
                    throw new IIOException(I18N.getString("BMPImageReader2"));
            }
        } else if (size == 108 || size == 124) {
            // Windows 4.x BMP
            if (size == 108)
                metadata.bmpVersion = VERSION_4;
            else if (size == 124)
                metadata.bmpVersion = VERSION_5;
            // rgb masks, valid only if comp is BI_BITFIELDS
            redMask = (int) iis.readUnsignedInt();
            greenMask = (int) iis.readUnsignedInt();
            blueMask = (int) iis.readUnsignedInt();
            // Only supported for 32bpp BI_RGB argb
            alphaMask = (int) iis.readUnsignedInt();
            long csType = iis.readUnsignedInt();
            int redX = iis.readInt();
            int redY = iis.readInt();
            int redZ = iis.readInt();
            int greenX = iis.readInt();
            int greenY = iis.readInt();
            int greenZ = iis.readInt();
            int blueX = iis.readInt();
            int blueY = iis.readInt();
            int blueZ = iis.readInt();
            long gammaRed = iis.readUnsignedInt();
            long gammaGreen = iis.readUnsignedInt();
            long gammaBlue = iis.readUnsignedInt();
            if (size == 124) {
                metadata.intent = iis.readInt();
                profileData = iis.readInt();
                profileSize = iis.readInt();
                iis.skipBytes(4);
            }
            metadata.colorSpace = (int) csType;
            if (csType == LCS_CALIBRATED_RGB) {
                // All the new fields are valid only for this case
                metadata.redX = redX;
                metadata.redY = redY;
                metadata.redZ = redZ;
                metadata.greenX = greenX;
                metadata.greenY = greenY;
                metadata.greenZ = greenZ;
                metadata.blueX = blueX;
                metadata.blueY = blueY;
                metadata.blueZ = blueZ;
                metadata.gammaRed = (int) gammaRed;
                metadata.gammaGreen = (int) gammaGreen;
                metadata.gammaBlue = (int) gammaBlue;
            }
            // Read in the palette
            int numberOfEntries = (int) ((bitmapOffset - 14 - size) / 4);
            int sizeOfPalette = numberOfEntries * 4;
            palette = new byte[sizeOfPalette];
            iis.readFully(palette, 0, sizeOfPalette);
            metadata.palette = palette;
            metadata.paletteSize = numberOfEntries;
            switch((int) compression) {
                case BI_JPEG:
                case BI_PNG:
                    if (size == 108) {
                        imageType = VERSION_4_XP_EMBEDDED;
                    } else if (size == 124) {
                        imageType = VERSION_5_XP_EMBEDDED;
                    }
                    break;
                default:
                    if (bitsPerPixel == 1) {
                        imageType = VERSION_4_1_BIT;
                    } else if (bitsPerPixel == 4) {
                        imageType = VERSION_4_4_BIT;
                    } else if (bitsPerPixel == 8) {
                        imageType = VERSION_4_8_BIT;
                    } else if (bitsPerPixel == 16) {
                        imageType = VERSION_4_16_BIT;
                        if ((int) compression == BI_RGB) {
                            redMask = 0x7C00;
                            greenMask = 0x3E0;
                            blueMask = 0x1F;
                        }
                    } else if (bitsPerPixel == 24) {
                        imageType = VERSION_4_24_BIT;
                    } else if (bitsPerPixel == 32) {
                        imageType = VERSION_4_32_BIT;
                        if ((int) compression == BI_RGB) {
                            redMask = 0x00FF0000;
                            greenMask = 0x0000FF00;
                            blueMask = 0x000000FF;
                        }
                    }
                    metadata.redMask = redMask;
                    metadata.greenMask = greenMask;
                    metadata.blueMask = blueMask;
                    metadata.alphaMask = alphaMask;
            }
        } else {
            throw new IIOException(I18N.getString("BMPImageReader3"));
        }
    }
    if (height > 0) {
        // bottom up image
        isBottomUp = true;
    } else {
        // top down image
        isBottomUp = false;
        height = Math.abs(height);
    }
    // Reset Image Layout so there's only one tile.
    //Define the color space
    ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
    if (metadata.colorSpace == PROFILE_LINKED || metadata.colorSpace == PROFILE_EMBEDDED) {
        iis.mark();
        iis.skipBytes(profileData - size);
        byte[] profile = new byte[profileSize];
        iis.readFully(profile, 0, profileSize);
        iis.reset();
        try {
            if (metadata.colorSpace == PROFILE_LINKED && isLinkedProfileAllowed() && !isUncOrDevicePath(profile)) {
                String path = new String(profile, "windows-1252");
                colorSpace = new ICC_ColorSpace(ICC_Profile.getInstance(path));
            } else {
                colorSpace = new ICC_ColorSpace(ICC_Profile.getInstance(profile));
            }
        } catch (Exception e) {
            colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        }
    }
    if (bitsPerPixel == 0 || compression == BI_JPEG || compression == BI_PNG) {
        // the colorModel and sampleModel will be initialzed
        // by the  reader of embedded image
        colorModel = null;
        sampleModel = null;
    } else if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8) {
        // When number of bitsPerPixel is <= 8, we use IndexColorModel.
        numBands = 1;
        if (bitsPerPixel == 8) {
            int[] bandOffsets = new int[numBands];
            for (int i = 0; i < numBands; i++) {
                bandOffsets[i] = numBands - 1 - i;
            }
            sampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, width, height, numBands, numBands * width, bandOffsets);
        } else {
            // 1 and 4 bit pixels can be stored in a packed format.
            sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, width, height, bitsPerPixel);
        }
        // Create IndexColorModel from the palette.
        byte[] r, g, b;
        if (imageType == VERSION_2_1_BIT || imageType == VERSION_2_4_BIT || imageType == VERSION_2_8_BIT) {
            size = palette.length / 3;
            if (size > 256) {
                size = 256;
            }
            int off;
            r = new byte[(int) size];
            g = new byte[(int) size];
            b = new byte[(int) size];
            for (int i = 0; i < (int) size; i++) {
                off = 3 * i;
                b[i] = palette[off];
                g[i] = palette[off + 1];
                r[i] = palette[off + 2];
            }
        } else {
            size = palette.length / 4;
            if (size > 256) {
                size = 256;
            }
            int off;
            r = new byte[(int) size];
            g = new byte[(int) size];
            b = new byte[(int) size];
            for (int i = 0; i < size; i++) {
                off = 4 * i;
                b[i] = palette[off];
                g[i] = palette[off + 1];
                r[i] = palette[off + 2];
            }
        }
        if (ImageUtil.isIndicesForGrayscale(r, g, b))
            colorModel = ImageUtil.createColorModel(null, sampleModel);
        else
            colorModel = new IndexColorModel(bitsPerPixel, (int) size, r, g, b);
    } else if (bitsPerPixel == 16) {
        numBands = 3;
        sampleModel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT, width, height, new int[] { redMask, greenMask, blueMask });
        colorModel = new DirectColorModel(colorSpace, 16, redMask, greenMask, blueMask, 0, false, DataBuffer.TYPE_USHORT);
    } else if (bitsPerPixel == 32) {
        numBands = alphaMask == 0 ? 3 : 4;
        // The number of bands in the SampleModel is determined by
        // the length of the mask array passed in.
        int[] bitMasks = numBands == 3 ? new int[] { redMask, greenMask, blueMask } : new int[] { redMask, greenMask, blueMask, alphaMask };
        sampleModel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, width, height, bitMasks);
        colorModel = new DirectColorModel(colorSpace, 32, redMask, greenMask, blueMask, alphaMask, false, DataBuffer.TYPE_INT);
    } else {
        numBands = 3;
        // Create SampleModel
        int[] bandOffsets = new int[numBands];
        for (int i = 0; i < numBands; i++) {
            bandOffsets[i] = numBands - 1 - i;
        }
        sampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, width, height, numBands, numBands * width, bandOffsets);
        colorModel = ImageUtil.createColorModel(colorSpace, sampleModel);
    }
    originalSampleModel = sampleModel;
    originalColorModel = colorModel;
    // Reset to the start of bitmap; then jump to the
    //start of image data
    iis.reset();
    iis.skipBytes(bitmapOffset);
    gotHeader = true;
}
Also used : PixelInterleavedSampleModel(java.awt.image.PixelInterleavedSampleModel) ColorSpace(java.awt.color.ColorSpace) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) SinglePixelPackedSampleModel(java.awt.image.SinglePixelPackedSampleModel) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) IIOException(javax.imageio.IIOException) Point(java.awt.Point) IIOException(javax.imageio.IIOException) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) DirectColorModel(java.awt.image.DirectColorModel) IndexColorModel(java.awt.image.IndexColorModel)

Example 22 with ICC_ColorSpace

use of java.awt.color.ICC_ColorSpace in project checker-framework by typetools.

the class ColorModel method getGray16TosRGB8LUT.

/*
     * Return a byte LUT that converts 16-bit gray values in the grayCS
     * ColorSpace to the appropriate 8-bit sRGB value.  I.e., if lut
     * is the byte array returned by this method and sval = lut[gval],
     * then the sRGB triple (sval,sval,sval) is the best match to gval.
     * Cache references to any computed LUT in a Map.
     */
static byte[] getGray16TosRGB8LUT(ICC_ColorSpace grayCS) {
    if (isLinearGRAYspace(grayCS)) {
        return getLinearRGB16TosRGB8LUT();
    }
    if (g16Tos8Map != null) {
        byte[] g16Tos8LUT = g16Tos8Map.get(grayCS);
        if (g16Tos8LUT != null) {
            return g16Tos8LUT;
        }
    }
    short[] tmp = new short[65536];
    for (int i = 0; i <= 65535; i++) {
        tmp[i] = (short) i;
    }
    ColorTransform[] transformList = new ColorTransform[2];
    PCMM mdl = CMSManager.getModule();
    ICC_ColorSpace srgbCS = (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB);
    transformList[0] = mdl.createTransform(grayCS.getProfile(), ColorTransform.Any, ColorTransform.In);
    transformList[1] = mdl.createTransform(srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
    ColorTransform t = mdl.createTransform(transformList);
    tmp = t.colorConvert(tmp, null);
    byte[] g16Tos8LUT = new byte[65536];
    for (int i = 0, j = 2; i <= 65535; i++, j += 3) {
        // All three components of tmp should be equal, since
        // the input color space to colorConvert is a gray scale
        // space.  However, there are slight anomalies in the results.
        // Copy tmp starting at index 2, since colorConvert seems
        // to be slightly more accurate for the third component!
        // scale unsigned short (0 - 65535) to unsigned byte (0 - 255)
        g16Tos8LUT[i] = (byte) (((float) (tmp[j] & 0xffff)) * (1.0f / 257.0f) + 0.5f);
    }
    if (g16Tos8Map == null) {
        g16Tos8Map = Collections.synchronizedMap(new WeakHashMap<ICC_ColorSpace, byte[]>(2));
    }
    g16Tos8Map.put(grayCS, g16Tos8LUT);
    return g16Tos8LUT;
}
Also used : ColorTransform(sun.java2d.cmm.ColorTransform) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) PCMM(sun.java2d.cmm.PCMM) WeakHashMap(java.util.WeakHashMap)

Example 23 with ICC_ColorSpace

use of java.awt.color.ICC_ColorSpace in project jdk8u_jdk by JetBrains.

the class JPEGImageWriter method writeOnThread.

private void writeOnThread(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException {
    if (ios == null) {
        throw new IllegalStateException("Output has not been set!");
    }
    if (image == null) {
        throw new IllegalArgumentException("image is null!");
    }
    // if streamMetadata is not null, issue a warning
    if (streamMetadata != null) {
        warningOccurred(WARNING_STREAM_METADATA_IGNORED);
    }
    // Obtain the raster and image, if there is one
    boolean rasterOnly = image.hasRaster();
    RenderedImage rimage = null;
    if (rasterOnly) {
        srcRas = image.getRaster();
    } else {
        rimage = image.getRenderedImage();
        if (rimage instanceof BufferedImage) {
            // Use the Raster directly.
            srcRas = ((BufferedImage) rimage).getRaster();
        } else if (rimage.getNumXTiles() == 1 && rimage.getNumYTiles() == 1) {
            // Get the unique tile.
            srcRas = rimage.getTile(rimage.getMinTileX(), rimage.getMinTileY());
            // as the tile dimensions might differ.
            if (srcRas.getWidth() != rimage.getWidth() || srcRas.getHeight() != rimage.getHeight()) {
                srcRas = srcRas.createChild(srcRas.getMinX(), srcRas.getMinY(), rimage.getWidth(), rimage.getHeight(), srcRas.getMinX(), srcRas.getMinY(), null);
            }
        } else {
            // Image is tiled so get a contiguous raster by copying.
            srcRas = rimage.getData();
        }
    }
    // Now determine if we are using a band subset
    // By default, we are using all source bands
    int numSrcBands = srcRas.getNumBands();
    indexed = false;
    indexCM = null;
    ColorModel cm = null;
    ColorSpace cs = null;
    isAlphaPremultiplied = false;
    srcCM = null;
    if (!rasterOnly) {
        cm = rimage.getColorModel();
        if (cm != null) {
            cs = cm.getColorSpace();
            if (cm instanceof IndexColorModel) {
                indexed = true;
                indexCM = (IndexColorModel) cm;
                numSrcBands = cm.getNumComponents();
            }
            if (cm.isAlphaPremultiplied()) {
                isAlphaPremultiplied = true;
                srcCM = cm;
            }
        }
    }
    srcBands = JPEG.bandOffsets[numSrcBands - 1];
    int numBandsUsed = numSrcBands;
    if (param != null) {
        int[] sBands = param.getSourceBands();
        if (sBands != null) {
            if (indexed) {
                warningOccurred(WARNING_NO_BANDS_ON_INDEXED);
            } else {
                srcBands = sBands;
                numBandsUsed = srcBands.length;
                if (numBandsUsed > numSrcBands) {
                    throw new IIOException("ImageWriteParam specifies too many source bands");
                }
            }
        }
    }
    boolean usingBandSubset = (numBandsUsed != numSrcBands);
    boolean fullImage = ((!rasterOnly) && (!usingBandSubset));
    int[] bandSizes = null;
    if (!indexed) {
        bandSizes = srcRas.getSampleModel().getSampleSize();
        // If this is a subset, we must adjust bandSizes
        if (usingBandSubset) {
            int[] temp = new int[numBandsUsed];
            for (int i = 0; i < numBandsUsed; i++) {
                temp[i] = bandSizes[srcBands[i]];
            }
            bandSizes = temp;
        }
    } else {
        int[] tempSize = srcRas.getSampleModel().getSampleSize();
        bandSizes = new int[numSrcBands];
        for (int i = 0; i < numSrcBands; i++) {
            // All the same
            bandSizes[i] = tempSize[0];
        }
    }
    for (int i = 0; i < bandSizes.length; i++) {
        // per sample.
        if (bandSizes[i] <= 0 || bandSizes[i] > 8) {
            throw new IIOException("Illegal band size: should be 0 < size <= 8");
        }
        // to 8-bit.
        if (indexed) {
            bandSizes[i] = 8;
        }
    }
    if (debug) {
        System.out.println("numSrcBands is " + numSrcBands);
        System.out.println("numBandsUsed is " + numBandsUsed);
        System.out.println("usingBandSubset is " + usingBandSubset);
        System.out.println("fullImage is " + fullImage);
        System.out.print("Band sizes:");
        for (int i = 0; i < bandSizes.length; i++) {
            System.out.print(" " + bandSizes[i]);
        }
        System.out.println();
    }
    // Destination type, if there is one
    ImageTypeSpecifier destType = null;
    if (param != null) {
        destType = param.getDestinationType();
        // Ignore dest type if we are writing a complete image
        if ((fullImage) && (destType != null)) {
            warningOccurred(WARNING_DEST_IGNORED);
            destType = null;
        }
    }
    // Examine the param
    sourceXOffset = srcRas.getMinX();
    sourceYOffset = srcRas.getMinY();
    int imageWidth = srcRas.getWidth();
    int imageHeight = srcRas.getHeight();
    sourceWidth = imageWidth;
    sourceHeight = imageHeight;
    int periodX = 1;
    int periodY = 1;
    int gridX = 0;
    int gridY = 0;
    JPEGQTable[] qTables = null;
    JPEGHuffmanTable[] DCHuffmanTables = null;
    JPEGHuffmanTable[] ACHuffmanTables = null;
    boolean optimizeHuffman = false;
    JPEGImageWriteParam jparam = null;
    int progressiveMode = ImageWriteParam.MODE_DISABLED;
    if (param != null) {
        Rectangle sourceRegion = param.getSourceRegion();
        if (sourceRegion != null) {
            Rectangle imageBounds = new Rectangle(sourceXOffset, sourceYOffset, sourceWidth, sourceHeight);
            sourceRegion = sourceRegion.intersection(imageBounds);
            sourceXOffset = sourceRegion.x;
            sourceYOffset = sourceRegion.y;
            sourceWidth = sourceRegion.width;
            sourceHeight = sourceRegion.height;
        }
        if (sourceWidth + sourceXOffset > imageWidth) {
            sourceWidth = imageWidth - sourceXOffset;
        }
        if (sourceHeight + sourceYOffset > imageHeight) {
            sourceHeight = imageHeight - sourceYOffset;
        }
        periodX = param.getSourceXSubsampling();
        periodY = param.getSourceYSubsampling();
        gridX = param.getSubsamplingXOffset();
        gridY = param.getSubsamplingYOffset();
        switch(param.getCompressionMode()) {
            case ImageWriteParam.MODE_DISABLED:
                throw new IIOException("JPEG compression cannot be disabled");
            case ImageWriteParam.MODE_EXPLICIT:
                float quality = param.getCompressionQuality();
                quality = JPEG.convertToLinearQuality(quality);
                qTables = new JPEGQTable[2];
                qTables[0] = JPEGQTable.K1Luminance.getScaledInstance(quality, true);
                qTables[1] = JPEGQTable.K2Chrominance.getScaledInstance(quality, true);
                break;
            case ImageWriteParam.MODE_DEFAULT:
                qTables = new JPEGQTable[2];
                qTables[0] = JPEGQTable.K1Div2Luminance;
                qTables[1] = JPEGQTable.K2Div2Chrominance;
                break;
        }
        progressiveMode = param.getProgressiveMode();
        if (param instanceof JPEGImageWriteParam) {
            jparam = (JPEGImageWriteParam) param;
            optimizeHuffman = jparam.getOptimizeHuffmanTables();
        }
    }
    // Now examine the metadata
    IIOMetadata mdata = image.getMetadata();
    if (mdata != null) {
        if (mdata instanceof JPEGMetadata) {
            metadata = (JPEGMetadata) mdata;
            if (debug) {
                System.out.println("We have metadata, and it's JPEG metadata");
            }
        } else {
            if (!rasterOnly) {
                ImageTypeSpecifier type = destType;
                if (type == null) {
                    type = new ImageTypeSpecifier(rimage);
                }
                metadata = (JPEGMetadata) convertImageMetadata(mdata, type, param);
            } else {
                warningOccurred(WARNING_METADATA_NOT_JPEG_FOR_RASTER);
            }
        }
    }
    // First set a default state
    // If it's there, use it
    ignoreJFIF = false;
    // If it's there, use it
    ignoreAdobe = false;
    // Change if needed
    newAdobeTransform = JPEG.ADOBE_IMPOSSIBLE;
    writeDefaultJFIF = false;
    writeAdobe = false;
    // By default we'll do no conversion:
    int inCsType = JPEG.JCS_UNKNOWN;
    int outCsType = JPEG.JCS_UNKNOWN;
    JFIFMarkerSegment jfif = null;
    AdobeMarkerSegment adobe = null;
    SOFMarkerSegment sof = null;
    if (metadata != null) {
        jfif = (JFIFMarkerSegment) metadata.findMarkerSegment(JFIFMarkerSegment.class, true);
        adobe = (AdobeMarkerSegment) metadata.findMarkerSegment(AdobeMarkerSegment.class, true);
        sof = (SOFMarkerSegment) metadata.findMarkerSegment(SOFMarkerSegment.class, true);
    }
    // By default don't write one
    iccProfile = null;
    // PhotoYCC does this
    convertTosRGB = false;
    converted = null;
    if (destType != null) {
        if (numBandsUsed != destType.getNumBands()) {
            throw new IIOException("Number of source bands != number of destination bands");
        }
        cs = destType.getColorModel().getColorSpace();
        // Check the metadata against the destination type
        if (metadata != null) {
            checkSOFBands(sof, numBandsUsed);
            checkJFIF(jfif, destType, false);
            // Do we want to write an ICC profile?
            if ((jfif != null) && (ignoreJFIF == false)) {
                if (JPEG.isNonStandardICC(cs)) {
                    iccProfile = ((ICC_ColorSpace) cs).getProfile();
                }
            }
            checkAdobe(adobe, destType, false);
        } else {
            // If we can add a JFIF or an Adobe marker segment, do so
            if (JPEG.isJFIFcompliant(destType, false)) {
                writeDefaultJFIF = true;
                // Do we want to write an ICC profile?
                if (JPEG.isNonStandardICC(cs)) {
                    iccProfile = ((ICC_ColorSpace) cs).getProfile();
                }
            } else {
                int transform = JPEG.transformForType(destType, false);
                if (transform != JPEG.ADOBE_IMPOSSIBLE) {
                    writeAdobe = true;
                    newAdobeTransform = transform;
                }
            }
            // re-create the metadata
            metadata = new JPEGMetadata(destType, null, this);
        }
        inCsType = getSrcCSType(destType);
        outCsType = getDefaultDestCSType(destType);
    } else {
        // no destination type
        if (metadata == null) {
            if (fullImage) {
                // no dest, no metadata, full image
                // Use default metadata matching the image and param
                metadata = new JPEGMetadata(new ImageTypeSpecifier(rimage), param, this);
                if (metadata.findMarkerSegment(JFIFMarkerSegment.class, true) != null) {
                    cs = rimage.getColorModel().getColorSpace();
                    if (JPEG.isNonStandardICC(cs)) {
                        iccProfile = ((ICC_ColorSpace) cs).getProfile();
                    }
                }
                inCsType = getSrcCSType(rimage);
                outCsType = getDefaultDestCSType(rimage);
            }
        // else no dest, no metadata, not an image,
        // so no special headers, no color conversion
        } else {
            // no dest type, but there is metadata
            checkSOFBands(sof, numBandsUsed);
            if (fullImage) {
                // no dest, metadata, image
                // Check that the metadata and the image match
                ImageTypeSpecifier inputType = new ImageTypeSpecifier(rimage);
                inCsType = getSrcCSType(rimage);
                if (cm != null) {
                    boolean alpha = cm.hasAlpha();
                    switch(cs.getType()) {
                        case ColorSpace.TYPE_GRAY:
                            if (!alpha) {
                                outCsType = JPEG.JCS_GRAYSCALE;
                            } else {
                                if (jfif != null) {
                                    ignoreJFIF = true;
                                    warningOccurred(WARNING_IMAGE_METADATA_JFIF_MISMATCH);
                                }
                            // out colorspace remains unknown
                            }
                            if ((adobe != null) && (adobe.transform != JPEG.ADOBE_UNKNOWN)) {
                                newAdobeTransform = JPEG.ADOBE_UNKNOWN;
                                warningOccurred(WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
                            }
                            break;
                        case ColorSpace.TYPE_RGB:
                            if (!alpha) {
                                if (jfif != null) {
                                    outCsType = JPEG.JCS_YCbCr;
                                    if (JPEG.isNonStandardICC(cs) || ((cs instanceof ICC_ColorSpace) && (jfif.iccSegment != null))) {
                                        iccProfile = ((ICC_ColorSpace) cs).getProfile();
                                    }
                                } else if (adobe != null) {
                                    switch(adobe.transform) {
                                        case JPEG.ADOBE_UNKNOWN:
                                            outCsType = JPEG.JCS_RGB;
                                            break;
                                        case JPEG.ADOBE_YCC:
                                            outCsType = JPEG.JCS_YCbCr;
                                            break;
                                        default:
                                            warningOccurred(WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
                                            newAdobeTransform = JPEG.ADOBE_UNKNOWN;
                                            outCsType = JPEG.JCS_RGB;
                                            break;
                                    }
                                } else {
                                    // consult the ids
                                    int outCS = sof.getIDencodedCSType();
                                    // consult the sampling factors
                                    if (outCS != JPEG.JCS_UNKNOWN) {
                                        outCsType = outCS;
                                    } else {
                                        boolean subsampled = isSubsampled(sof.componentSpecs);
                                        if (subsampled) {
                                            outCsType = JPEG.JCS_YCbCr;
                                        } else {
                                            outCsType = JPEG.JCS_RGB;
                                        }
                                    }
                                }
                            } else {
                                // RGBA
                                if (jfif != null) {
                                    ignoreJFIF = true;
                                    warningOccurred(WARNING_IMAGE_METADATA_JFIF_MISMATCH);
                                }
                                if (adobe != null) {
                                    if (adobe.transform != JPEG.ADOBE_UNKNOWN) {
                                        newAdobeTransform = JPEG.ADOBE_UNKNOWN;
                                        warningOccurred(WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
                                    }
                                    outCsType = JPEG.JCS_RGBA;
                                } else {
                                    // consult the ids
                                    int outCS = sof.getIDencodedCSType();
                                    // consult the sampling factors
                                    if (outCS != JPEG.JCS_UNKNOWN) {
                                        outCsType = outCS;
                                    } else {
                                        boolean subsampled = isSubsampled(sof.componentSpecs);
                                        outCsType = subsampled ? JPEG.JCS_YCbCrA : JPEG.JCS_RGBA;
                                    }
                                }
                            }
                            break;
                        case ColorSpace.TYPE_3CLR:
                            if (cs == JPEG.JCS.getYCC()) {
                                if (!alpha) {
                                    if (jfif != null) {
                                        convertTosRGB = true;
                                        convertOp = new ColorConvertOp(cs, JPEG.JCS.sRGB, null);
                                        outCsType = JPEG.JCS_YCbCr;
                                    } else if (adobe != null) {
                                        if (adobe.transform != JPEG.ADOBE_YCC) {
                                            newAdobeTransform = JPEG.ADOBE_YCC;
                                            warningOccurred(WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
                                        }
                                        outCsType = JPEG.JCS_YCC;
                                    } else {
                                        outCsType = JPEG.JCS_YCC;
                                    }
                                } else {
                                    // PhotoYCCA
                                    if (jfif != null) {
                                        ignoreJFIF = true;
                                        warningOccurred(WARNING_IMAGE_METADATA_JFIF_MISMATCH);
                                    } else if (adobe != null) {
                                        if (adobe.transform != JPEG.ADOBE_UNKNOWN) {
                                            newAdobeTransform = JPEG.ADOBE_UNKNOWN;
                                            warningOccurred(WARNING_IMAGE_METADATA_ADOBE_MISMATCH);
                                        }
                                    }
                                    outCsType = JPEG.JCS_YCCA;
                                }
                            }
                    }
                }
            }
        // else no dest, metadata, not an image.  Defaults ok
        }
    }
    boolean metadataProgressive = false;
    int[] scans = null;
    if (metadata != null) {
        if (sof == null) {
            sof = (SOFMarkerSegment) metadata.findMarkerSegment(SOFMarkerSegment.class, true);
        }
        if ((sof != null) && (sof.tag == JPEG.SOF2)) {
            metadataProgressive = true;
            if (progressiveMode == ImageWriteParam.MODE_COPY_FROM_METADATA) {
                // Might still be null
                scans = collectScans(metadata, sof);
            } else {
                numScans = 0;
            }
        }
        if (jfif == null) {
            jfif = (JFIFMarkerSegment) metadata.findMarkerSegment(JFIFMarkerSegment.class, true);
        }
    }
    thumbnails = image.getThumbnails();
    int numThumbs = image.getNumThumbnails();
    forceJFIF = false;
    // then thumbnails can be written
    if (!writeDefaultJFIF) {
        // If there is no metadata, then we can't write thumbnails
        if (metadata == null) {
            thumbnails = null;
            if (numThumbs != 0) {
                warningOccurred(WARNING_IGNORING_THUMBS);
            }
        } else {
            // then the user must specify JFIF on the metadata
            if (fullImage == false) {
                if (jfif == null) {
                    // Or we can't include thumbnails
                    thumbnails = null;
                    if (numThumbs != 0) {
                        warningOccurred(WARNING_IGNORING_THUMBS);
                    }
                }
            } else {
                // It is a full image, and there is metadata
                if (jfif == null) {
                    // Can it have JFIF?
                    if ((outCsType == JPEG.JCS_GRAYSCALE) || (outCsType == JPEG.JCS_YCbCr)) {
                        if (numThumbs != 0) {
                            forceJFIF = true;
                            warningOccurred(WARNING_FORCING_JFIF);
                        }
                    } else {
                        // Nope, not JFIF-compatible
                        thumbnails = null;
                        if (numThumbs != 0) {
                            warningOccurred(WARNING_IGNORING_THUMBS);
                        }
                    }
                }
            }
        }
    }
    // Set up a boolean to indicate whether we need to call back to
    // write metadata
    boolean haveMetadata = ((metadata != null) || writeDefaultJFIF || writeAdobe);
    // Now that we have dealt with metadata, finalize our tables set up
    // Are we going to write tables?  By default, yes.
    boolean writeDQT = true;
    boolean writeDHT = true;
    // But if the metadata has no tables, no.
    DQTMarkerSegment dqt = null;
    DHTMarkerSegment dht = null;
    int restartInterval = 0;
    if (metadata != null) {
        dqt = (DQTMarkerSegment) metadata.findMarkerSegment(DQTMarkerSegment.class, true);
        dht = (DHTMarkerSegment) metadata.findMarkerSegment(DHTMarkerSegment.class, true);
        DRIMarkerSegment dri = (DRIMarkerSegment) metadata.findMarkerSegment(DRIMarkerSegment.class, true);
        if (dri != null) {
            restartInterval = dri.restartInterval;
        }
        if (dqt == null) {
            writeDQT = false;
        }
        if (dht == null) {
            // Ignored if optimizeHuffman is true
            writeDHT = false;
        }
    }
    // to use
    if (qTables == null) {
        // Get them from metadata, or use defaults
        if (dqt != null) {
            qTables = collectQTablesFromMetadata(metadata);
        } else if (streamQTables != null) {
            qTables = streamQTables;
        } else if ((jparam != null) && (jparam.areTablesSet())) {
            qTables = jparam.getQTables();
        } else {
            qTables = JPEG.getDefaultQTables();
        }
    }
    // If we are optimizing, we don't want any tables.
    if (optimizeHuffman == false) {
        // If they were for progressive scans, we can't use them.
        if ((dht != null) && (metadataProgressive == false)) {
            DCHuffmanTables = collectHTablesFromMetadata(metadata, true);
            ACHuffmanTables = collectHTablesFromMetadata(metadata, false);
        } else if (streamDCHuffmanTables != null) {
            DCHuffmanTables = streamDCHuffmanTables;
            ACHuffmanTables = streamACHuffmanTables;
        } else if ((jparam != null) && (jparam.areTablesSet())) {
            DCHuffmanTables = jparam.getDCHuffmanTables();
            ACHuffmanTables = jparam.getACHuffmanTables();
        } else {
            DCHuffmanTables = JPEG.getDefaultHuffmanTables(true);
            ACHuffmanTables = JPEG.getDefaultHuffmanTables(false);
        }
    }
    // By default, ids are 1 - N, no subsampling
    int[] componentIds = new int[numBandsUsed];
    int[] HsamplingFactors = new int[numBandsUsed];
    int[] VsamplingFactors = new int[numBandsUsed];
    int[] QtableSelectors = new int[numBandsUsed];
    for (int i = 0; i < numBandsUsed; i++) {
        // JFIF compatible
        componentIds[i] = i + 1;
        HsamplingFactors[i] = 1;
        VsamplingFactors[i] = 1;
        QtableSelectors[i] = 0;
    }
    // Now override them with the contents of sof, if there is one,
    if (sof != null) {
        for (int i = 0; i < numBandsUsed; i++) {
            if (forceJFIF == false) {
                // else use JFIF-compatible default
                componentIds[i] = sof.componentSpecs[i].componentId;
            }
            HsamplingFactors[i] = sof.componentSpecs[i].HsamplingFactor;
            VsamplingFactors[i] = sof.componentSpecs[i].VsamplingFactor;
            QtableSelectors[i] = sof.componentSpecs[i].QtableSelector;
        }
    }
    sourceXOffset += gridX;
    sourceWidth -= gridX;
    sourceYOffset += gridY;
    sourceHeight -= gridY;
    int destWidth = (sourceWidth + periodX - 1) / periodX;
    int destHeight = (sourceHeight + periodY - 1) / periodY;
    // Create an appropriate 1-line databuffer for writing
    int lineSize = sourceWidth * numBandsUsed;
    DataBufferByte buffer = new DataBufferByte(lineSize);
    // Create a raster from that
    int[] bandOffs = JPEG.bandOffsets[numBandsUsed - 1];
    raster = Raster.createInterleavedRaster(buffer, sourceWidth, 1, lineSize, numBandsUsed, bandOffs, null);
    // Call the writer, who will call back for every scanline
    clearAbortRequest();
    cbLock.lock();
    try {
        processImageStarted(currentImage);
    } finally {
        cbLock.unlock();
    }
    boolean aborted = false;
    if (debug) {
        System.out.println("inCsType: " + inCsType);
        System.out.println("outCsType: " + outCsType);
    }
    // Note that getData disables acceleration on buffer, but it is
    // just a 1-line intermediate data transfer buffer that does not
    // affect the acceleration of the source image.
    aborted = writeImage(structPointer, buffer.getData(), inCsType, outCsType, numBandsUsed, bandSizes, sourceWidth, destWidth, destHeight, periodX, periodY, qTables, writeDQT, DCHuffmanTables, ACHuffmanTables, writeDHT, optimizeHuffman, (progressiveMode != ImageWriteParam.MODE_DISABLED), numScans, scans, componentIds, HsamplingFactors, VsamplingFactors, QtableSelectors, haveMetadata, restartInterval);
    cbLock.lock();
    try {
        if (aborted) {
            processWriteAborted();
        } else {
            processImageComplete();
        }
        ios.flush();
    } finally {
        cbLock.unlock();
    }
    // After a successful write
    currentImage++;
}
Also used : ColorSpace(java.awt.color.ColorSpace) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) Rectangle(java.awt.Rectangle) JPEGQTable(javax.imageio.plugins.jpeg.JPEGQTable) DataBufferByte(java.awt.image.DataBufferByte) BufferedImage(java.awt.image.BufferedImage) ImageTypeSpecifier(javax.imageio.ImageTypeSpecifier) JPEGHuffmanTable(javax.imageio.plugins.jpeg.JPEGHuffmanTable) IndexColorModel(java.awt.image.IndexColorModel) ColorModel(java.awt.image.ColorModel) JPEGImageWriteParam(javax.imageio.plugins.jpeg.JPEGImageWriteParam) IndexColorModel(java.awt.image.IndexColorModel) IIOException(javax.imageio.IIOException) IIOMetadata(javax.imageio.metadata.IIOMetadata) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) ColorConvertOp(java.awt.image.ColorConvertOp) RenderedImage(java.awt.image.RenderedImage)

Example 24 with ICC_ColorSpace

use of java.awt.color.ICC_ColorSpace in project imageio-ext by geosolutions-it.

the class JP2KKakaduImageReader method parseBoxes.

/**
 * Get basic image properties by querying several JP2Boxes. Then, properly
 * set the ColorModel of the input object.
 *
 * @param codestreamP
 */
private void parseBoxes(JP2KCodestreamProperties codestreamP) {
    if (isRawSource)
        return;
    short numComp = 1;
    byte[] bitDepths = null;
    byte[] maps = null;
    int bitDepth = -1;
    ICC_Profile profile = null;
    int colorSpaceType = -1;
    // //
    // 
    // ImageHeader Box
    // 
    // //
    final ImageHeaderBox ihBox = (ImageHeaderBox) getJp2Box(ImageHeaderBox.BOX_TYPE);
    if (ihBox != null) {
        numComp = ihBox.getNumComponents();
        bitDepth = ihBox.getBitDepth();
    }
    // //
    // 
    // ColorSpecification Box
    // 
    // //
    final ColorSpecificationBox csBox = (ColorSpecificationBox) getJp2Box(ColorSpecificationBox.BOX_TYPE);
    if (csBox != null) {
        profile = csBox.getICCProfile();
        colorSpaceType = csBox.getEnumeratedColorSpace();
    }
    // //
    // 
    // ComponentMapping Box
    // 
    // //
    final ComponentMappingBox cmBox = (ComponentMappingBox) getJp2Box(ComponentMappingBox.BOX_TYPE);
    if (cmBox != null) {
        maps = cmBox.getComponentAssociation();
    }
    // //
    // 
    // Palette Box
    // 
    // //
    final PaletteBox palBox = (PaletteBox) getJp2Box(PaletteBox.BOX_TYPE);
    if (palBox != null) {
        byte[][] lookUpTable = palBox.getLUT();
        if (lookUpTable != null && numComp == 1) {
            int tableComps = lookUpTable.length;
            int maxDepth = 1 + (bitDepth & 0x7F);
            if (maps == null) {
                maps = new byte[tableComps];
                for (int i = 0; i < tableComps; i++) maps[i] = (byte) i;
            }
            if (tableComps == 3) {
                codestreamP.setColorModel(new IndexColorModel(maxDepth, lookUpTable[0].length, lookUpTable[maps[0]], lookUpTable[maps[1]], lookUpTable[maps[2]]));
                return;
            } else if (tableComps == 4) {
                codestreamP.setColorModel(new IndexColorModel(maxDepth, lookUpTable[0].length, lookUpTable[maps[0]], lookUpTable[maps[1]], lookUpTable[maps[2]], lookUpTable[maps[3]]));
                return;
            }
        }
    }
    // //
    // 
    // BitsPerComponent Box
    // 
    // //
    final BitsPerComponentBox bpcBox = (BitsPerComponentBox) getJp2Box(BitsPerComponentBox.BOX_TYPE);
    if (bpcBox != null) {
        bitDepths = bpcBox.getBitDepth();
    }
    // //
    // 
    // ChannelDefinition Box
    // 
    // //
    final ChannelDefinitionBox chBox = (ChannelDefinitionBox) getJp2Box(ChannelDefinitionBox.BOX_TYPE);
    if (chBox != null) {
        final short[] channels = chBox.getChannel();
        final short[] associations = chBox.getAssociation();
        final int[] cType = chBox.getTypes();
        boolean hasAlpha = false;
        final int alphaChannel = numComp - 1;
        for (int i = 0; i < channels.length; i++) {
            if (cType[i] == 1 && channels[i] == alphaChannel)
                hasAlpha = true;
        }
        boolean[] isPremultiplied = new boolean[] { false };
        if (hasAlpha) {
            isPremultiplied = new boolean[alphaChannel];
            for (int i = 0; i < alphaChannel; i++) isPremultiplied[i] = false;
            for (int i = 0; i < channels.length; i++) {
                if (cType[i] == 2)
                    isPremultiplied[associations[i] - 1] = true;
            }
            for (int i = 1; i < alphaChannel; i++) isPremultiplied[0] &= isPremultiplied[i];
        }
        ColorSpace cs = null;
        // RGBN Workaround
        if (associations.length == 4) /* && associations[0]==1 && associations[1]==2 && associations[2]==3*/
        {
            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
            hasAlpha = true;
        } else if (profile != null)
            cs = new ICC_ColorSpace(profile);
        else if (colorSpaceType == ColorSpecificationBox.ECS_sRGB)
            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        else if (colorSpaceType == ColorSpecificationBox.ECS_GRAY)
            cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
        else if (colorSpaceType == ColorSpecificationBox.ECS_YCC)
            cs = ColorSpace.getInstance(ColorSpace.CS_PYCC);
        else
            LOGGER.warning("JP2 type only handle sRGB, GRAY and YCC Profiles");
        // TODO: Check these settings
        int[] bits = new int[numComp];
        for (int i = 0; i < numComp; i++) if (bitDepths != null)
            bits[i] = (bitDepths[i] & 0x7F) + 1;
        else
            bits[i] = (bitDepth & 0x7F) + 1;
        int maxBitDepth = 1 + (bitDepth & 0x7F);
        boolean isSigned = (bitDepth & 0x80) == 0x80;
        if (bitDepths != null)
            isSigned = (bitDepths[0] & 0x80) == 0x80;
        if (bitDepths != null)
            for (int i = 0; i < numComp; i++) if (bits[i] > maxBitDepth)
                maxBitDepth = bits[i];
        int type = -1;
        if (maxBitDepth <= 8)
            type = DataBuffer.TYPE_BYTE;
        else if (maxBitDepth <= 16)
            type = isSigned ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
        else if (maxBitDepth <= 32)
            type = DataBuffer.TYPE_INT;
        if (type == -1)
            return;
        if (cs != null) {
            codestreamP.setColorModel(new ComponentColorModel(cs, bits, hasAlpha, isPremultiplied[0], hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE, type));
        }
    }
}
Also used : ICC_ColorSpace(java.awt.color.ICC_ColorSpace) ColorSpace(java.awt.color.ColorSpace) ComponentColorModel(java.awt.image.ComponentColorModel) PaletteBox(it.geosolutions.imageio.plugins.jp2k.box.PaletteBox) ColorSpecificationBox(it.geosolutions.imageio.plugins.jp2k.box.ColorSpecificationBox) ChannelDefinitionBox(it.geosolutions.imageio.plugins.jp2k.box.ChannelDefinitionBox) BitsPerComponentBox(it.geosolutions.imageio.plugins.jp2k.box.BitsPerComponentBox) ICC_ColorSpace(java.awt.color.ICC_ColorSpace) ImageHeaderBox(it.geosolutions.imageio.plugins.jp2k.box.ImageHeaderBox) ComponentMappingBox(it.geosolutions.imageio.plugins.jp2k.box.ComponentMappingBox) ICC_Profile(java.awt.color.ICC_Profile) IndexColorModel(java.awt.image.IndexColorModel)

Example 25 with ICC_ColorSpace

use of java.awt.color.ICC_ColorSpace in project acs-aem-commons by Adobe-Consulting-Services.

the class CMYKJPEGImageReader method createRGBImageFromCMYK.

/**
 * Creates a buffered image from a raster in the CMYK color space, converting
 * the colors to RGB using the provided CMYK ICC_Profile.
 *
 * As seen from a comment made by 'phelps' at
 * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4799903
 *
 * @param cmykRaster A raster with (at least) 4 bands of samples.
 * @param cmykProfile An ICC_Profile for conversion from the CMYK color space
 * to the RGB color space. If this parameter is null, a default profile is used.
 * @return a BufferedImage in the RGB color space.
 */
public static BufferedImage createRGBImageFromCMYK(Raster cmykRaster, ICC_Profile cmykProfile) {
    BufferedImage image;
    int w = cmykRaster.getWidth();
    int h = cmykRaster.getHeight();
    if (cmykProfile != null) {
        ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);
        image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        WritableRaster rgbRaster = image.getRaster();
        ColorSpace rgbCS = image.getColorModel().getColorSpace();
        ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
        cmykToRgb.filter(cmykRaster, rgbRaster);
    } else {
        int[] rgb = new int[w * h];
        int[] C = cmykRaster.getSamples(0, 0, w, h, 0, (int[]) null);
        int[] M = cmykRaster.getSamples(0, 0, w, h, 1, (int[]) null);
        int[] Y = cmykRaster.getSamples(0, 0, w, h, 2, (int[]) null);
        int[] K = cmykRaster.getSamples(0, 0, w, h, 3, (int[]) null);
        for (int i = 0, imax = C.length; i < imax; i++) {
            int k = K[i];
            rgb[i] = (255 - Math.min(255, C[i] + k)) << 16 | (255 - Math.min(255, M[i] + k)) << 8 | (255 - Math.min(255, Y[i] + k));
        }
        Raster rgbRaster = Raster.createPackedRaster(new DataBufferInt(rgb, rgb.length), w, h, w, new int[] { 0xff0000, 0xff00, 0xff }, null);
        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        ColorModel cm = new DirectColorModel(cs, 24, 0xff0000, 0xff00, 0xff, 0x0, false, DataBuffer.TYPE_INT);
        image = new BufferedImage(cm, (WritableRaster) rgbRaster, true, null);
    }
    return image;
}
Also used : ICC_ColorSpace(java.awt.color.ICC_ColorSpace) ColorSpace(java.awt.color.ColorSpace) ICC_ColorSpace(java.awt.color.ICC_ColorSpace)

Aggregations

ICC_ColorSpace (java.awt.color.ICC_ColorSpace)28 ColorSpace (java.awt.color.ColorSpace)10 ICC_Profile (java.awt.color.ICC_Profile)10 WeakHashMap (java.util.WeakHashMap)8 ColorTransform (sun.java2d.cmm.ColorTransform)8 PCMM (sun.java2d.cmm.PCMM)8 BufferedImage (java.awt.image.BufferedImage)5 IndexColorModel (java.awt.image.IndexColorModel)4 IOException (java.io.IOException)4 CMMException (java.awt.color.CMMException)3 ColorConvertOp (java.awt.image.ColorConvertOp)3 ComponentColorModel (java.awt.image.ComponentColorModel)3 InputStream (java.io.InputStream)3 IIOException (javax.imageio.IIOException)3 TIFFField (it.geosolutions.imageio.plugins.tiff.TIFFField)2 Point (java.awt.Point)2 ColorModel (java.awt.image.ColorModel)2 ImageTypeSpecifier (javax.imageio.ImageTypeSpecifier)2 IIOMetadata (javax.imageio.metadata.IIOMetadata)2 PDDocument (org.apache.pdfbox.pdmodel.PDDocument)2