Search in sources :

Example 71 with SampleModel

use of java.awt.image.SampleModel in project imageio-ext by geosolutions-it.

the class EmptyImage method prepareWriteEmpty.

public void prepareWriteEmpty(IIOMetadata streamMetadata, ImageTypeSpecifier imageType, int width, int height, IIOMetadata imageMetadata, List thumbnails, ImageWriteParam param) throws IOException {
    checkParamsEmpty(imageType, width, height, thumbnails);
    this.isWritingEmpty = true;
    SampleModel emptySM = imageType.getSampleModel();
    RenderedImage emptyImage = new EmptyImage(0, 0, width, height, 0, 0, emptySM.getWidth(), emptySM.getHeight(), emptySM, imageType.getColorModel());
    write(streamMetadata, new IIOImage(emptyImage, null, imageMetadata), param, true, false);
}
Also used : ComponentSampleModel(java.awt.image.ComponentSampleModel) SampleModel(java.awt.image.SampleModel) SimpleRenderedImage(com.sun.media.imageioimpl.common.SimpleRenderedImage) RenderedImage(java.awt.image.RenderedImage) SingleTileRenderedImage(com.sun.media.imageioimpl.common.SingleTileRenderedImage) IIOImage(javax.imageio.IIOImage)

Example 72 with SampleModel

use of java.awt.image.SampleModel in project imageio-ext by geosolutions-it.

the class EmptyImage method replacePixels.

public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
    synchronized (replacePixelsLock) {
        // Check state and parameters vis-a-vis ImageWriter specification.
        if (stream == null) {
            throw new IllegalStateException("stream == null!");
        }
        if (image == null) {
            throw new IllegalArgumentException("image == null!");
        }
        if (!inReplacePixelsNest) {
            throw new IllegalStateException("No previous call to prepareReplacePixels!");
        }
        // Subsampling values.
        int stepX = 1, stepY = 1, gridX = 0, gridY = 0;
        // Initialize the ImageWriteParam.
        if (param == null) {
            // Use the default.
            param = getDefaultWriteParam();
        } else {
            // Make a copy of the ImageWriteParam.
            ImageWriteParam paramCopy = getDefaultWriteParam();
            // Force uncompressed.
            paramCopy.setCompressionMode(ImageWriteParam.MODE_DISABLED);
            // Force tiling to remain as in the already written image.
            paramCopy.setTilingMode(ImageWriteParam.MODE_COPY_FROM_METADATA);
            // Retain source and destination region and band settings.
            paramCopy.setDestinationOffset(param.getDestinationOffset());
            paramCopy.setSourceBands(param.getSourceBands());
            paramCopy.setSourceRegion(param.getSourceRegion());
            // Save original subsampling values for subsampling the
            // replacement data - not the data re-read from the image.
            stepX = param.getSourceXSubsampling();
            stepY = param.getSourceYSubsampling();
            gridX = param.getSubsamplingXOffset();
            gridY = param.getSubsamplingYOffset();
            // Replace the param.
            param = paramCopy;
        }
        // Check band count and bit depth compatibility.
        TIFFField f = replacePixelsMetadata.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
        if (f == null) {
            throw new IIOException("Cannot read destination BitsPerSample");
        }
        int[] dstBitsPerSample = f.getAsInts();
        int[] srcBitsPerSample = image.getSampleModel().getSampleSize();
        int[] sourceBands = param.getSourceBands();
        if (sourceBands != null) {
            if (sourceBands.length != dstBitsPerSample.length) {
                throw new IIOException("Source and destination have different SamplesPerPixel");
            }
            for (int i = 0; i < sourceBands.length; i++) {
                if (dstBitsPerSample[i] != srcBitsPerSample[sourceBands[i]]) {
                    throw new IIOException("Source and destination have different BitsPerSample");
                }
            }
        } else {
            int srcNumBands = image.getSampleModel().getNumBands();
            if (srcNumBands != dstBitsPerSample.length) {
                throw new IIOException("Source and destination have different SamplesPerPixel");
            }
            for (int i = 0; i < srcNumBands; i++) {
                if (dstBitsPerSample[i] != srcBitsPerSample[i]) {
                    throw new IIOException("Source and destination have different BitsPerSample");
                }
            }
        }
        // Get the source image bounds.
        Rectangle srcImageBounds = new Rectangle(image.getMinX(), image.getMinY(), image.getWidth(), image.getHeight());
        // Initialize the source rect.
        Rectangle srcRect = param.getSourceRegion();
        if (srcRect == null) {
            srcRect = srcImageBounds;
        }
        // Set subsampling grid parameters.
        int subPeriodX = stepX;
        int subPeriodY = stepY;
        int subOriginX = gridX + srcRect.x;
        int subOriginY = gridY + srcRect.y;
        // Intersect with the source bounds.
        if (!srcRect.equals(srcImageBounds)) {
            srcRect = srcRect.intersection(srcImageBounds);
            if (srcRect.isEmpty()) {
                throw new IllegalArgumentException("Source region does not intersect source image!");
            }
        }
        // Get the destination offset.
        Point dstOffset = param.getDestinationOffset();
        // Forward map source rectangle to determine destination width.
        int dMinX = XToTileX(srcRect.x, subOriginX, subPeriodX) + dstOffset.x;
        int dMinY = YToTileY(srcRect.y, subOriginY, subPeriodY) + dstOffset.y;
        int dMaxX = XToTileX(srcRect.x + srcRect.width, subOriginX, subPeriodX) + dstOffset.x;
        int dMaxY = YToTileY(srcRect.y + srcRect.height, subOriginY, subPeriodY) + dstOffset.y;
        // Initialize the destination rectangle.
        Rectangle dstRect = new Rectangle(dstOffset.x, dstOffset.y, dMaxX - dMinX, dMaxY - dMinY);
        // Intersect with the replacement region.
        dstRect = dstRect.intersection(replacePixelsRegion);
        if (dstRect.isEmpty()) {
            throw new IllegalArgumentException("Forward mapped source region does not intersect destination region!");
        }
        // Backward map to the active source region.
        int activeSrcMinX = (dstRect.x - dstOffset.x) * subPeriodX + subOriginX;
        int sxmax = (dstRect.x + dstRect.width - 1 - dstOffset.x) * subPeriodX + subOriginX;
        int activeSrcWidth = sxmax - activeSrcMinX + 1;
        int activeSrcMinY = (dstRect.y - dstOffset.y) * subPeriodY + subOriginY;
        int symax = (dstRect.y + dstRect.height - 1 - dstOffset.y) * subPeriodY + subOriginY;
        int activeSrcHeight = symax - activeSrcMinY + 1;
        Rectangle activeSrcRect = new Rectangle(activeSrcMinX, activeSrcMinY, activeSrcWidth, activeSrcHeight);
        if (activeSrcRect.intersection(srcImageBounds).isEmpty()) {
            throw new IllegalArgumentException("Backward mapped destination region does not intersect source image!");
        }
        if (reader == null) {
            reader = new TIFFImageReader(new TIFFImageReaderSpi());
        } else {
            reader.reset();
        }
        stream.mark();
        try {
            stream.seek(headerPosition);
            reader.setInput(stream);
            this.imageMetadata = replacePixelsMetadata;
            this.param = param;
            SampleModel sm = image.getSampleModel();
            ColorModel cm = image.getColorModel();
            this.numBands = sm.getNumBands();
            this.imageType = new ImageTypeSpecifier(image);
            this.periodX = param.getSourceXSubsampling();
            this.periodY = param.getSourceYSubsampling();
            this.sourceBands = null;
            int[] sBands = param.getSourceBands();
            if (sBands != null) {
                this.sourceBands = sBands;
                this.numBands = sourceBands.length;
            }
            setupMetadata(cm, sm, reader.getWidth(replacePixelsIndex), reader.getHeight(replacePixelsIndex));
            int[] scaleSampleSize = sm.getSampleSize();
            initializeScaleTables(scaleSampleSize);
            // Determine whether bilevel.
            this.isBilevel = ImageUtil.isBinary(image.getSampleModel());
            // Check for photometric inversion.
            this.isInverted = (nativePhotometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO && photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO) || (nativePhotometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO && photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO);
            // Analyze image data suitability for direct copy.
            this.isImageSimple = (isBilevel || (!isInverted && ImageUtil.imageIsContiguous(image))) && // no value rescaling
            !isRescaling && // no subbanding
            sourceBands == null && periodX == 1 && // no subsampling
            periodY == 1 && colorConverter == null;
            int minTileX = XToTileX(dstRect.x, 0, tileWidth);
            int minTileY = YToTileY(dstRect.y, 0, tileLength);
            int maxTileX = XToTileX(dstRect.x + dstRect.width - 1, 0, tileWidth);
            int maxTileY = YToTileY(dstRect.y + dstRect.height - 1, 0, tileLength);
            TIFFCompressor encoder = new TIFFNullCompressor();
            encoder.setWriter(this);
            encoder.setStream(stream);
            encoder.setMetadata(this.imageMetadata);
            Rectangle tileRect = new Rectangle();
            for (int ty = minTileY; ty <= maxTileY; ty++) {
                for (int tx = minTileX; tx <= maxTileX; tx++) {
                    int tileIndex = ty * tilesAcross + tx;
                    boolean isEmpty = replacePixelsByteCounts[tileIndex] == 0L;
                    WritableRaster raster;
                    if (isEmpty) {
                        SampleModel tileSM = sm.createCompatibleSampleModel(tileWidth, tileLength);
                        raster = Raster.createWritableRaster(tileSM, null);
                    } else {
                        BufferedImage tileImage = reader.readTile(replacePixelsIndex, tx, ty);
                        raster = tileImage.getRaster();
                    }
                    tileRect.setLocation(tx * tileWidth, ty * tileLength);
                    tileRect.setSize(raster.getWidth(), raster.getHeight());
                    raster = raster.createWritableTranslatedChild(tileRect.x, tileRect.y);
                    Rectangle replacementRect = tileRect.intersection(dstRect);
                    int srcMinX = (replacementRect.x - dstOffset.x) * subPeriodX + subOriginX;
                    int srcXmax = (replacementRect.x + replacementRect.width - 1 - dstOffset.x) * subPeriodX + subOriginX;
                    int srcWidth = srcXmax - srcMinX + 1;
                    int srcMinY = (replacementRect.y - dstOffset.y) * subPeriodY + subOriginY;
                    int srcYMax = (replacementRect.y + replacementRect.height - 1 - dstOffset.y) * subPeriodY + subOriginY;
                    int srcHeight = srcYMax - srcMinY + 1;
                    Rectangle srcTileRect = new Rectangle(srcMinX, srcMinY, srcWidth, srcHeight);
                    Raster replacementData = image.getData(srcTileRect);
                    if (subPeriodX == 1 && subPeriodY == 1 && subOriginX == 0 && subOriginY == 0) {
                        replacementData = replacementData.createChild(srcTileRect.x, srcTileRect.y, srcTileRect.width, srcTileRect.height, replacementRect.x, replacementRect.y, sourceBands);
                    } else {
                        replacementData = subsample(replacementData, sourceBands, subOriginX, subOriginY, subPeriodX, subPeriodY, dstOffset.x, dstOffset.y, replacementRect);
                        if (replacementData == null) {
                            continue;
                        }
                    }
                    raster.setRect(replacementData);
                    if (isEmpty) {
                        stream.seek(nextSpace);
                    } else {
                        stream.seek(replacePixelsTileOffsets[tileIndex]);
                    }
                    this.image = new SingleTileRenderedImage(raster, cm);
                    int numBytes = writeTile(tileRect, encoder);
                    if (isEmpty) {
                        // Update Strip/TileOffsets and
                        // Strip/TileByteCounts fields.
                        stream.mark();
                        stream.seek(replacePixelsOffsetsPosition + 4 * tileIndex);
                        stream.writeInt((int) nextSpace);
                        stream.seek(replacePixelsByteCountsPosition + 4 * tileIndex);
                        stream.writeInt(numBytes);
                        stream.reset();
                        // Increment location of next available space.
                        nextSpace += numBytes;
                    }
                }
            }
        } catch (IOException e) {
            throw e;
        } finally {
            stream.reset();
        }
    }
}
Also used : SingleTileRenderedImage(com.sun.media.imageioimpl.common.SingleTileRenderedImage) Raster(java.awt.image.Raster) WritableRaster(java.awt.image.WritableRaster) Rectangle(java.awt.Rectangle) IIOException(javax.imageio.IIOException) Point(java.awt.Point) IIOException(javax.imageio.IIOException) IOException(java.io.IOException) TIFFImageWriteParam(it.geosolutions.imageio.plugins.tiff.TIFFImageWriteParam) ImageWriteParam(javax.imageio.ImageWriteParam) Point(java.awt.Point) ImageTypeSpecifier(javax.imageio.ImageTypeSpecifier) BufferedImage(java.awt.image.BufferedImage) TIFFCompressor(it.geosolutions.imageio.plugins.tiff.TIFFCompressor) ComponentSampleModel(java.awt.image.ComponentSampleModel) SampleModel(java.awt.image.SampleModel) IndexColorModel(java.awt.image.IndexColorModel) ComponentColorModel(java.awt.image.ComponentColorModel) ColorModel(java.awt.image.ColorModel) WritableRaster(java.awt.image.WritableRaster) TIFFField(it.geosolutions.imageio.plugins.tiff.TIFFField)

Example 73 with SampleModel

use of java.awt.image.SampleModel in project imageio-ext by geosolutions-it.

the class PNMImageWriter method write.

public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException {
    clearAbortRequest();
    processImageStarted(0);
    if (param == null)
        param = getDefaultWriteParam();
    RenderedImage input = null;
    Raster inputRaster = null;
    boolean writeRaster = image.hasRaster();
    Rectangle sourceRegion = param.getSourceRegion();
    SampleModel sampleModel = null;
    ColorModel colorModel = null;
    if (writeRaster) {
        inputRaster = image.getRaster();
        sampleModel = inputRaster.getSampleModel();
        if (sourceRegion == null)
            sourceRegion = inputRaster.getBounds();
        else
            sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
    } else {
        input = image.getRenderedImage();
        sampleModel = input.getSampleModel();
        colorModel = input.getColorModel();
        Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(), input.getWidth(), input.getHeight());
        if (sourceRegion == null)
            sourceRegion = rect;
        else
            sourceRegion = sourceRegion.intersection(rect);
    }
    if (sourceRegion.isEmpty())
        throw new RuntimeException(I18N.getString("PNMImageWrite1"));
    ImageUtil.canEncodeImage(this, colorModel, sampleModel);
    int scaleX = param.getSourceXSubsampling();
    int scaleY = param.getSourceYSubsampling();
    int xOffset = param.getSubsamplingXOffset();
    int yOffset = param.getSubsamplingYOffset();
    sourceRegion.translate(xOffset, yOffset);
    sourceRegion.width -= xOffset;
    sourceRegion.height -= yOffset;
    int w = (sourceRegion.width + scaleX - 1) / scaleX;
    int h = (sourceRegion.height + scaleY - 1) / scaleY;
    int tileWidth = sampleModel.getWidth();
    // Raw data can only handle bytes, everything greater must be ASCII.
    int[] sampleSize = sampleModel.getSampleSize();
    int[] sourceBands = param.getSourceBands();
    int numBands = sampleModel.getNumBands();
    if (sourceBands != null) {
        sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
        colorModel = null;
        numBands = sampleModel.getNumBands();
    } else {
        sourceBands = new int[numBands];
        for (int i = 0; i < numBands; i++) sourceBands[i] = i;
    }
    // Colormap populated for non-bilevel IndexColorModel only.
    byte[] reds = null;
    byte[] greens = null;
    byte[] blues = null;
    // Flag indicating that PB data should be inverted before writing.
    boolean isPBMInverted = false;
    if (numBands == 1) {
        if (colorModel instanceof IndexColorModel) {
            IndexColorModel icm = (IndexColorModel) colorModel;
            int mapSize = icm.getMapSize();
            if (mapSize < (1 << sampleSize[0]))
                throw new RuntimeException(I18N.getString("PNMImageWrite2"));
            if (sampleSize[0] == 1) {
                variant = PBM_RAW;
                // Set PBM inversion flag if 1 maps to a higher color
                // value than 0: PBM expects white-is-zero so if this
                // does not obtain then inversion needs to occur.
                isPBMInverted = icm.getRed(1) > icm.getRed(0);
            } else {
                variant = PPM_RAW;
                reds = new byte[mapSize];
                greens = new byte[mapSize];
                blues = new byte[mapSize];
                icm.getReds(reds);
                icm.getGreens(greens);
                icm.getBlues(blues);
            }
        } else if (sampleSize[0] == 1) {
            variant = PBM_RAW;
        } else if (sampleSize[0] <= 8) {
            variant = PGM_RAW;
        } else {
            variant = PGM_ASCII;
        }
    } else if (numBands == 3) {
        if (sampleSize[0] <= 8 && sampleSize[1] <= 8 && sampleSize[2] <= 8) {
            // all 3 bands must be <= 8
            variant = PPM_RAW;
        } else {
            variant = PPM_ASCII;
        }
    } else {
        throw new RuntimeException(I18N.getString("PNMImageWrite3"));
    }
    IIOMetadata inputMetadata = image.getMetadata();
    ImageTypeSpecifier imageType;
    if (colorModel != null) {
        imageType = new ImageTypeSpecifier(colorModel, sampleModel);
    } else {
        int dataType = sampleModel.getDataType();
        switch(numBands) {
            case 1:
                imageType = ImageTypeSpecifier.createGrayscale(sampleSize[0], dataType, false);
                break;
            case 3:
                ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                imageType = ImageTypeSpecifier.createInterleaved(cs, new int[] { 0, 1, 2 }, dataType, false, false);
                break;
            default:
                throw new IIOException("Cannot encode image with " + numBands + " bands!");
        }
    }
    PNMMetadata metadata;
    if (inputMetadata != null) {
        // Convert metadata.
        metadata = (PNMMetadata) convertImageMetadata(inputMetadata, imageType, param);
    } else {
        // Use default.
        metadata = (PNMMetadata) getDefaultImageMetadata(imageType, param);
    }
    // Read parameters
    boolean isRawPNM;
    if (param instanceof PNMImageWriteParam) {
        isRawPNM = ((PNMImageWriteParam) param).getRaw();
    } else {
        isRawPNM = metadata.isRaw();
    }
    maxValue = metadata.getMaxValue();
    for (int i = 0; i < sampleSize.length; i++) {
        int v = (1 << sampleSize[i]) - 1;
        if (v > maxValue) {
            maxValue = v;
        }
    }
    if (isRawPNM) {
        // Raw output is desired.
        int maxBitDepth = metadata.getMaxBitDepth();
        if (!isRaw(variant) && maxBitDepth <= 8) {
            // Current variant is ASCII and the bit depth is acceptable
            // so convert to RAW variant by adding '3' to variant.
            variant += 0x3;
        } else if (isRaw(variant) && maxBitDepth > 8) {
            // Current variant is RAW and the bit depth it too large for
            // RAW so convert to ASCII.
            variant -= 0x3;
        }
    // Omitted cases are (variant == RAW && max <= 8) and
    // (variant == ASCII && max > 8) neither of which requires action.
    } else if (isRaw(variant)) {
        // Raw output is NOT desired so convert to ASCII
        variant -= 0x3;
    }
    // Write PNM file.
    // magic value: 'P'
    stream.writeByte('P');
    stream.writeByte(variant);
    stream.write(lineSeparator);
    // comment line
    stream.write(COMMENT.getBytes());
    // Write the comments provided in the metadata
    Iterator comments = metadata.getComments();
    if (comments != null) {
        while (comments.hasNext()) {
            stream.write(lineSeparator);
            String comment = "# " + (String) comments.next();
            stream.write(comment.getBytes());
        }
    }
    stream.write(lineSeparator);
    // width
    writeInteger(stream, w);
    stream.write(SPACE);
    // height
    writeInteger(stream, h);
    // Write sample max value for non-binary images
    if ((variant != PBM_RAW) && (variant != PBM_ASCII)) {
        stream.write(lineSeparator);
        writeInteger(stream, maxValue);
    }
    // last header value and the start of the raw data.
    if (variant == PBM_RAW || variant == PGM_RAW || variant == PPM_RAW) {
        stream.write('\n');
    }
    // Set flag for optimal image writing case: row-packed data with
    // correct band order if applicable.
    boolean writeOptimal = false;
    if (variant == PBM_RAW && sampleModel.getTransferType() == DataBuffer.TYPE_BYTE && sampleModel instanceof MultiPixelPackedSampleModel) {
        MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sampleModel;
        int originX = 0;
        if (writeRaster)
            originX = inputRaster.getMinX();
        else
            originX = input.getMinX();
        // Must have left-aligned bytes with unity bit stride.
        if (mppsm.getBitOffset((sourceRegion.x - originX) % tileWidth) == 0 && mppsm.getPixelBitStride() == 1 && scaleX == 1)
            writeOptimal = true;
    } else if ((variant == PGM_RAW || variant == PPM_RAW) && sampleModel instanceof ComponentSampleModel && !(colorModel instanceof IndexColorModel)) {
        ComponentSampleModel csm = (ComponentSampleModel) sampleModel;
        // Pixel stride must equal band count.
        if (csm.getPixelStride() == numBands && scaleX == 1) {
            writeOptimal = true;
            // Band offsets must equal band indices.
            if (variant == PPM_RAW) {
                int[] bandOffsets = csm.getBandOffsets();
                for (int b = 0; b < numBands; b++) {
                    if (bandOffsets[b] != b) {
                        writeOptimal = false;
                        break;
                    }
                }
            }
        }
    }
    // Write using an optimal approach if possible.
    if (writeOptimal) {
        int bytesPerRow = variant == PBM_RAW ? (w + 7) / 8 : w * sampleModel.getNumBands();
        byte[] bdata = null;
        byte[] invertedData = new byte[bytesPerRow];
        // Loop over tiles to minimize cobbling.
        for (int j = 0; j < sourceRegion.height; j++) {
            if (abortRequested())
                break;
            Raster lineRaster = null;
            if (writeRaster) {
                lineRaster = inputRaster.createChild(sourceRegion.x, j, sourceRegion.width, 1, 0, 0, null);
            } else {
                lineRaster = input.getData(new Rectangle(sourceRegion.x, sourceRegion.y + j, w, 1));
                lineRaster = lineRaster.createTranslatedChild(0, 0);
            }
            bdata = ((DataBufferByte) lineRaster.getDataBuffer()).getData();
            sampleModel = lineRaster.getSampleModel();
            int offset = 0;
            if (sampleModel instanceof ComponentSampleModel) {
                offset = ((ComponentSampleModel) sampleModel).getOffset(lineRaster.getMinX() - lineRaster.getSampleModelTranslateX(), lineRaster.getMinY() - lineRaster.getSampleModelTranslateY());
            } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
                offset = ((MultiPixelPackedSampleModel) sampleModel).getOffset(lineRaster.getMinX() - lineRaster.getSampleModelTranslateX(), lineRaster.getMinX() - lineRaster.getSampleModelTranslateY());
            }
            if (isPBMInverted) {
                for (int k = offset, m = 0; m < bytesPerRow; k++, m++) invertedData[m] = (byte) ~bdata[k];
                bdata = invertedData;
                offset = 0;
            }
            stream.write(bdata, offset, bytesPerRow);
            processImageProgress(100.0F * j / sourceRegion.height);
        }
        // Write all buffered bytes and return.
        stream.flush();
        if (abortRequested())
            processWriteAborted();
        else
            processImageComplete();
        return;
    }
    // Buffer for 1 rows of original pixels
    int size = sourceRegion.width * numBands;
    int[] pixels = new int[size];
    // Also allocate a buffer to hold the data to be written to the file,
    // so we can use array writes.
    byte[] bpixels = reds == null ? new byte[w * numBands] : new byte[w * 3];
    // The index of the sample being written, used to
    // place a line separator after every 16th sample in
    // ASCII mode.  Not used in raw mode.
    int count = 0;
    // Process line by line
    int lastRow = sourceRegion.y + sourceRegion.height;
    for (int row = sourceRegion.y; row < lastRow; row += scaleY) {
        if (abortRequested())
            break;
        // Grab the pixels
        Raster src = null;
        if (writeRaster)
            src = inputRaster.createChild(sourceRegion.x, row, sourceRegion.width, 1, sourceRegion.x, row, sourceBands);
        else
            src = input.getData(new Rectangle(sourceRegion.x, row, sourceRegion.width, 1));
        src.getPixels(sourceRegion.x, row, sourceRegion.width, 1, pixels);
        if (isPBMInverted)
            for (int i = 0; i < size; i += scaleX) bpixels[i] ^= 1;
        switch(variant) {
            case PBM_ASCII:
                for (int i = 0; i < size; i += scaleX) {
                    if ((count++ % 16) == 0)
                        stream.write(lineSeparator);
                    else
                        stream.write(SPACE);
                    writeInteger(stream, isPBMInverted ? (byte) ~pixels[i] : pixels[i]);
                }
                stream.write(lineSeparator);
                break;
            case PGM_ASCII:
                for (int i = 0; i < size; i += scaleX) {
                    if ((count++ % 16) == 0)
                        stream.write(lineSeparator);
                    else
                        stream.write(SPACE);
                    writeInteger(stream, pixels[i]);
                }
                stream.write(lineSeparator);
                break;
            case PPM_ASCII:
                if (reds == null) {
                    for (int i = 0; i < size; i += scaleX * numBands) {
                        for (int j = 0; j < numBands; j++) {
                            if ((count++ % 16) == 0)
                                stream.write(lineSeparator);
                            else
                                stream.write(SPACE);
                            writeInteger(stream, pixels[i + j]);
                        }
                    }
                } else {
                    for (int i = 0; i < size; i += scaleX) {
                        if ((count++ % 5) == 0)
                            stream.write(lineSeparator);
                        else
                            stream.write(SPACE);
                        writeInteger(stream, (reds[pixels[i]] & 0xFF));
                        stream.write(SPACE);
                        writeInteger(stream, (greens[pixels[i]] & 0xFF));
                        stream.write(SPACE);
                        writeInteger(stream, (blues[pixels[i]] & 0xFF));
                    }
                }
                stream.write(lineSeparator);
                break;
            case PBM_RAW:
                // 8 pixels packed into 1 byte, the leftovers are padded.
                int kdst = 0;
                int b = 0;
                int pos = 7;
                for (int i = 0; i < size; i += scaleX) {
                    b |= pixels[i] << pos;
                    pos--;
                    if (pos == -1) {
                        bpixels[kdst++] = (byte) b;
                        b = 0;
                        pos = 7;
                    }
                }
                if (pos != 7)
                    bpixels[kdst++] = (byte) b;
                stream.write(bpixels, 0, kdst);
                break;
            case PGM_RAW:
                for (int i = 0, j = 0; i < size; i += scaleX) {
                    bpixels[j++] = (byte) (pixels[i]);
                }
                stream.write(bpixels, 0, w);
                break;
            case PPM_RAW:
                if (reds == null) {
                    // no need to expand
                    for (int i = 0, k = 0; i < size; i += scaleX * numBands) {
                        for (int j = 0; j < numBands; j++) bpixels[k++] = (byte) (pixels[i + j] & 0xFF);
                    }
                } else {
                    for (int i = 0, j = 0; i < size; i += scaleX) {
                        bpixels[j++] = reds[pixels[i]];
                        bpixels[j++] = greens[pixels[i]];
                        bpixels[j++] = blues[pixels[i]];
                    }
                }
                stream.write(bpixels, 0, bpixels.length);
                break;
        }
        processImageProgress(100.0F * (row - sourceRegion.y) / sourceRegion.height);
    }
    // Force all buffered bytes to be written out.
    stream.flush();
    if (abortRequested())
        processWriteAborted();
    else
        processImageComplete();
}
Also used : ColorSpace(java.awt.color.ColorSpace) Raster(java.awt.image.Raster) PNMImageWriteParam(com.sun.media.imageio.plugins.pnm.PNMImageWriteParam) Rectangle(java.awt.Rectangle) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) IIOException(javax.imageio.IIOException) ComponentSampleModel(java.awt.image.ComponentSampleModel) ImageTypeSpecifier(javax.imageio.ImageTypeSpecifier) IIOMetadata(javax.imageio.metadata.IIOMetadata) ComponentSampleModel(java.awt.image.ComponentSampleModel) SampleModel(java.awt.image.SampleModel) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) ColorModel(java.awt.image.ColorModel) IndexColorModel(java.awt.image.IndexColorModel) Iterator(java.util.Iterator) RenderedImage(java.awt.image.RenderedImage) IndexColorModel(java.awt.image.IndexColorModel)

Example 74 with SampleModel

use of java.awt.image.SampleModel in project imageio-ext by geosolutions-it.

the class PNMMetadata method initialize.

void initialize(ImageTypeSpecifier imageType, ImageWriteParam param) {
    ImageTypeSpecifier destType = null;
    if (param != null) {
        destType = param.getDestinationType();
        if (destType == null) {
            destType = imageType;
        }
    } else {
        destType = imageType;
    }
    if (destType != null) {
        SampleModel sm = destType.getSampleModel();
        int[] sampleSize = sm.getSampleSize();
        this.width = sm.getWidth();
        this.height = sm.getHeight();
        for (int i = 0; i < sampleSize.length; i++) {
            if (sampleSize[i] > maxSampleSize) {
                maxSampleSize = sampleSize[i];
            }
        }
        this.maxSample = (1 << maxSampleSize) - 1;
        // default value
        boolean isRaw = true;
        if (param instanceof PNMImageWriteParam) {
            isRaw = ((PNMImageWriteParam) param).getRaw();
        }
        if (maxSampleSize == 1)
            variant = '1';
        else if (sm.getNumBands() == 1) {
            variant = '2';
        } else if (sm.getNumBands() == 3) {
            variant = '3';
        }
        // Force to Raw if the sample size is small enough.
        if (variant <= '3' && isRaw && maxSampleSize <= 8) {
            variant += 0x3;
        }
    }
}
Also used : SampleModel(java.awt.image.SampleModel) PNMImageWriteParam(com.sun.media.imageio.plugins.pnm.PNMImageWriteParam) ImageTypeSpecifier(javax.imageio.ImageTypeSpecifier)

Example 75 with SampleModel

use of java.awt.image.SampleModel in project imageio-ext by geosolutions-it.

the class TIFFDecompressor method decode.

/**
 * Decodes the input bit stream (located in the
 * <code>ImageInputStream</code> <code>stream</code>, at offset
 * <code>offset</code>, and continuing for <code>byteCount</code>
 * bytes) into the output <code>BufferedImage</code>
 * <code>image</code>.
 *
 * <p> The default implementation analyzes the destination image
 * to determine if it is suitable as the destination for the
 * <code>decodeRaw</code> method.  If not, a suitable image is
 * created.  Next, <code>decodeRaw</code> is called to perform the
 * actual decoding, and the results are copied into the
 * destination image if necessary.  Subsampling and offsetting are
 * performed automatically.
 *
 * <p> The precise responsibilities of this routine are as
 * follows.  The input bit stream is defined by the instance
 * variables <code>stream</code>, <code>offset</code>, and
 * <code>byteCount</code>.  These bits contain the data for the
 * region of the source image defined by <code>srcMinX</code>,
 * <code>srcMinY</code>, <code>srcWidth</code>, and
 * <code>srcHeight</code>.
 *
 * <p> The source data is required to be subsampling, starting at
 * the <code>sourceXOffset</code>th column and including
 * every <code>subsampleX</code>th pixel thereafter (and similarly
 * for <code>sourceYOffset</code> and
 * <code>subsampleY</code>).
 *
 * <p> Pixels are copied into the destination with an addition shift of
 * (<code>dstXOffset</code>, <code>dstYOffset</code>).  The complete
 * set of formulas relating the source and destination coordinate spaces
 * are:
 *
 * <pre>
 * dx = (sx - sourceXOffset)/subsampleX + dstXOffset;
 * dy = (sy - sourceYOffset)/subsampleY + dstYOffset;
 * </pre>
 *
 * Only source pixels such that <code>(sx - sourceXOffset) %
 * subsampleX == 0</code> and <code>(sy - sourceYOffset) %
 * subsampleY == 0</code> are copied.
 *
 * <p> The inverse mapping, from destination to source coordinates,
 * is one-to-one:
 *
 * <pre>
 * sx = (dx - dstXOffset)*subsampleX + sourceXOffset;
 * sy = (dy - dstYOffset)*subsampleY + sourceYOffset;
 * </pre>
 *
 * <p> The region of the destination image to be updated is given
 * by the instance variables <code>dstMinX</code>,
 * <code>dstMinY</code>, <code>dstWidth</code>, and
 * <code>dstHeight</code>.
 *
 * <p> It is possible that not all of the source data being read
 * will contribute to the destination image.  For example, the
 * destination offsets could be set such that some of the source
 * pixels land outside of the bounds of the image.  As a
 * convenience, the bounds of the active source region (that is,
 * the region of the strip or tile being read that actually
 * contributes to the destination image, taking clipping into
 * account) are available as <code>activeSrcMinX</code>,
 * <code>activeSrcMinY</code>, <code>activeSrcWidth</code> and
 * <code>activeSrcHeight</code>.  Thus, the source pixel at
 * (<code>activeSrcMinX</code>, <code>activeSrcMinY</code>) will
 * map to the destination pixel (<code>dstMinX</code>,
 * <code>dstMinY</code>).
 *
 * <p> The sequence of source bands given by
 * <code>sourceBands</code> are to be copied into the sequence of
 * bands in the destination given by
 * <code>destinationBands</code>.
 *
 * <p> Some standard tag information is provided the instance
 * variables <code>photometricInterpretation</code>,
 * <code>compression</code>, <code>samplesPerPixel</code>,
 * <code>bitsPerSample</code>, <code>sampleFormat</code>,
 * <code>extraSamples</code>, and <code>colorMap</code>.
 *
 * <p> In practice, unless there is a significant performance
 * advantage to be gained by overriding this routine, most users
 * will prefer to use the default implementation of this routine,
 * and instead override the <code>decodeRaw</code> and/or
 * <code>getRawImageType</code> methods.
 *
 * @exception IOException if an error occurs in
 * <code>decodeRaw</code>.
 */
public void decode() throws IOException {
    byte[] byteData = null;
    short[] shortData = null;
    int[] intData = null;
    float[] floatData = null;
    double[] doubleData = null;
    int dstOffset = 0;
    int pixelBitStride = 1;
    int scanlineStride = 0;
    if (useTurbo) {
        decodeRaw(byteData, dstOffset, pixelBitStride, scanlineStride);
    } else {
        // Analyze raw image
        this.rawImage = null;
        if (isImageSimple) {
            if (isBilevel) {
                rawImage = this.image;
            } else if (isContiguous) {
                rawImage = image.getSubimage(dstMinX, dstMinY, dstWidth, dstHeight);
            }
        }
        boolean isDirectCopy = rawImage != null;
        if (rawImage == null) {
            rawImage = createRawImage();
            if (rawImage == null) {
                throw new IIOException("Couldn't create image buffer!");
            }
        }
        WritableRaster ras = rawImage.getRaster();
        if (isBilevel) {
            Rectangle rect = isImageSimple ? new Rectangle(dstMinX, dstMinY, dstWidth, dstHeight) : ras.getBounds();
            byteData = ImageUtil.getPackedBinaryData(ras, rect);
            dstOffset = 0;
            pixelBitStride = 1;
            scanlineStride = (rect.width + 7) / 8;
        } else {
            SampleModel sm = ras.getSampleModel();
            DataBuffer db = ras.getDataBuffer();
            boolean isSupportedType = false;
            if (sm instanceof ComponentSampleModel) {
                ComponentSampleModel csm = (ComponentSampleModel) sm;
                dstOffset = csm.getOffset(-ras.getSampleModelTranslateX(), -ras.getSampleModelTranslateY());
                scanlineStride = csm.getScanlineStride();
                if (db instanceof DataBufferByte) {
                    DataBufferByte dbb = (DataBufferByte) db;
                    byteData = dbb.getData();
                    pixelBitStride = csm.getPixelStride() * 8;
                    isSupportedType = true;
                } else if (db instanceof DataBufferUShort) {
                    DataBufferUShort dbus = (DataBufferUShort) db;
                    shortData = dbus.getData();
                    pixelBitStride = csm.getPixelStride() * 16;
                    isSupportedType = true;
                } else if (db instanceof DataBufferShort) {
                    DataBufferShort dbs = (DataBufferShort) db;
                    shortData = dbs.getData();
                    pixelBitStride = csm.getPixelStride() * 16;
                    isSupportedType = true;
                } else if (db instanceof DataBufferInt) {
                    DataBufferInt dbi = (DataBufferInt) db;
                    intData = dbi.getData();
                    pixelBitStride = csm.getPixelStride() * 32;
                    isSupportedType = true;
                } else if (db instanceof DataBufferFloat) {
                    DataBufferFloat dbf = (DataBufferFloat) db;
                    floatData = dbf.getData();
                    pixelBitStride = csm.getPixelStride() * 32;
                    isSupportedType = true;
                } else if (db instanceof DataBufferDouble) {
                    DataBufferDouble dbf = (DataBufferDouble) db;
                    doubleData = dbf.getData();
                    pixelBitStride = csm.getPixelStride() * 64;
                    isSupportedType = true;
                }
            } else if (sm instanceof MultiPixelPackedSampleModel) {
                MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sm;
                dstOffset = mppsm.getOffset(-ras.getSampleModelTranslateX(), -ras.getSampleModelTranslateY());
                pixelBitStride = mppsm.getPixelBitStride();
                scanlineStride = mppsm.getScanlineStride();
                if (db instanceof DataBufferByte) {
                    DataBufferByte dbb = (DataBufferByte) db;
                    byteData = dbb.getData();
                    isSupportedType = true;
                } else if (db instanceof DataBufferUShort) {
                    DataBufferUShort dbus = (DataBufferUShort) db;
                    shortData = dbus.getData();
                    isSupportedType = true;
                } else if (db instanceof DataBufferInt) {
                    DataBufferInt dbi = (DataBufferInt) db;
                    intData = dbi.getData();
                    isSupportedType = true;
                }
            } else if (sm instanceof SinglePixelPackedSampleModel) {
                SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
                dstOffset = sppsm.getOffset(-ras.getSampleModelTranslateX(), -ras.getSampleModelTranslateY());
                scanlineStride = sppsm.getScanlineStride();
                if (db instanceof DataBufferByte) {
                    DataBufferByte dbb = (DataBufferByte) db;
                    byteData = dbb.getData();
                    pixelBitStride = 8;
                    isSupportedType = true;
                } else if (db instanceof DataBufferUShort) {
                    DataBufferUShort dbus = (DataBufferUShort) db;
                    shortData = dbus.getData();
                    pixelBitStride = 16;
                    isSupportedType = true;
                } else if (db instanceof DataBufferInt) {
                    DataBufferInt dbi = (DataBufferInt) db;
                    intData = dbi.getData();
                    pixelBitStride = 32;
                    isSupportedType = true;
                }
            }
            if (!isSupportedType) {
                throw new IIOException("Unsupported raw image type: SampleModel = " + sm + "; DataBuffer = " + db);
            }
        }
        if (isBilevel) {
            // Bilevel data are always in a contiguous byte buffer.
            decodeRaw(byteData, dstOffset, pixelBitStride, scanlineStride);
        } else {
            SampleModel sm = ras.getSampleModel();
            // bits except at the end of a row.
            if (isDataBufferBitContiguous(sm)) {
                // Use byte or float data directly.
                if (byteData != null) {
                    if (DEBUG) {
                        System.out.println("Decoding bytes directly");
                    }
                    if (offset == 0 && byteCount == 0 && noData != null) {
                        setEmptyTile(byteData, dstOffset, pixelBitStride, scanlineStride, noData.byteValue());
                    } else {
                        decodeRaw(byteData, dstOffset, pixelBitStride, scanlineStride);
                    }
                } else if (floatData != null) {
                    if (DEBUG) {
                        System.out.println("Decoding floats directly");
                    }
                    if (offset == 0 && byteCount == 0 && noData != null) {
                        setEmptyTile(floatData, dstOffset, pixelBitStride, scanlineStride, noData.floatValue());
                    } else {
                        decodeRaw(floatData, dstOffset, pixelBitStride, scanlineStride);
                    }
                } else if (doubleData != null) {
                    if (DEBUG) {
                        System.out.println("Decoding doubles directly");
                    }
                    if (offset == 0 && byteCount == 0 && noData != null) {
                        setEmptyTile(doubleData, dstOffset, pixelBitStride, scanlineStride, noData.doubleValue());
                    } else {
                        decodeRaw(doubleData, dstOffset, pixelBitStride, scanlineStride);
                    }
                } else {
                    if (shortData != null) {
                        if (offset == 0 && byteCount == 0 && noData != null) {
                            setEmptyTile(shortData, dstOffset, pixelBitStride, scanlineStride, noData.shortValue());
                        } else if (areSampleSizesEqual(sm) && sm.getSampleSize(0) == 16) {
                            if (DEBUG) {
                                System.out.println("Decoding shorts directly");
                            }
                            // Decode directly into short data.
                            decodeRaw(shortData, dstOffset, pixelBitStride, scanlineStride);
                        } else {
                            if (DEBUG) {
                                System.out.println("Decoding bytes->shorts");
                            }
                            // Decode into bytes and reformat into shorts.
                            int bpp = getBitsPerPixel(sm);
                            int bytesPerRow = (bpp * srcWidth + 7) / 8;
                            byte[] buf = new byte[bytesPerRow * srcHeight];
                            decodeRaw(buf, 0, bpp, bytesPerRow);
                            reformatData(buf, bytesPerRow, srcHeight, shortData, null, dstOffset, scanlineStride);
                        }
                    } else if (intData != null) {
                        if (offset == 0 && byteCount == 0 && noData != null) {
                            setEmptyTile(intData, dstOffset, pixelBitStride, scanlineStride, noData.intValue());
                        } else if (areSampleSizesEqual(sm) && sm.getSampleSize(0) == 32) {
                            if (DEBUG) {
                                System.out.println("Decoding ints directly");
                            }
                            // Decode directly into int data.
                            decodeRaw(intData, dstOffset, pixelBitStride, scanlineStride);
                        } else {
                            if (DEBUG) {
                                System.out.println("Decoding bytes->ints");
                            }
                            // Decode into bytes and reformat into ints.
                            int bpp = getBitsPerPixel(sm);
                            int bytesPerRow = (bpp * srcWidth + 7) / 8;
                            byte[] buf = new byte[bytesPerRow * srcHeight];
                            decodeRaw(buf, 0, bpp, bytesPerRow);
                            reformatData(buf, bytesPerRow, srcHeight, null, intData, dstOffset, scanlineStride);
                        }
                    }
                }
            } else {
                if (DEBUG) {
                    System.out.println("Decoding discontiguous data");
                }
                // Read discontiguous data into bytes and set the samples
                // into the Raster.
                int bpp = getBitsPerPixel(sm);
                int bytesPerRow = (bpp * srcWidth + 7) / 8;
                byte[] buf = new byte[bytesPerRow * srcHeight];
                decodeRaw(buf, 0, bpp, bytesPerRow);
                reformatDiscontiguousData(buf, bytesPerRow, srcWidth, srcHeight, ras);
            }
        }
        if (colorConverter != null) {
            float[] rgb = new float[3];
            if (byteData != null) {
                for (int j = 0; j < dstHeight; j++) {
                    int idx = dstOffset;
                    for (int i = 0; i < dstWidth; i++) {
                        float x0 = (float) (byteData[idx] & 0xff);
                        float x1 = (float) (byteData[idx + 1] & 0xff);
                        float x2 = (float) (byteData[idx + 2] & 0xff);
                        colorConverter.toRGB(x0, x1, x2, rgb);
                        byteData[idx] = (byte) (rgb[0]);
                        byteData[idx + 1] = (byte) (rgb[1]);
                        byteData[idx + 2] = (byte) (rgb[2]);
                        idx += 3;
                    }
                    dstOffset += scanlineStride;
                }
            } else if (shortData != null) {
                if (sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
                    for (int j = 0; j < dstHeight; j++) {
                        int idx = dstOffset;
                        for (int i = 0; i < dstWidth; i++) {
                            float x0 = (float) shortData[idx];
                            float x1 = (float) shortData[idx + 1];
                            float x2 = (float) shortData[idx + 2];
                            colorConverter.toRGB(x0, x1, x2, rgb);
                            shortData[idx] = (short) (rgb[0]);
                            shortData[idx + 1] = (short) (rgb[1]);
                            shortData[idx + 2] = (short) (rgb[2]);
                            idx += 3;
                        }
                        dstOffset += scanlineStride;
                    }
                } else {
                    for (int j = 0; j < dstHeight; j++) {
                        int idx = dstOffset;
                        for (int i = 0; i < dstWidth; i++) {
                            float x0 = (float) (shortData[idx] & 0xffff);
                            float x1 = (float) (shortData[idx + 1] & 0xffff);
                            float x2 = (float) (shortData[idx + 2] & 0xffff);
                            colorConverter.toRGB(x0, x1, x2, rgb);
                            shortData[idx] = (short) (rgb[0]);
                            shortData[idx + 1] = (short) (rgb[1]);
                            shortData[idx + 2] = (short) (rgb[2]);
                            idx += 3;
                        }
                        dstOffset += scanlineStride;
                    }
                }
            } else if (intData != null) {
                for (int j = 0; j < dstHeight; j++) {
                    int idx = dstOffset;
                    for (int i = 0; i < dstWidth; i++) {
                        float x0 = (float) intData[idx];
                        float x1 = (float) intData[idx + 1];
                        float x2 = (float) intData[idx + 2];
                        colorConverter.toRGB(x0, x1, x2, rgb);
                        intData[idx] = (int) (rgb[0]);
                        intData[idx + 1] = (int) (rgb[1]);
                        intData[idx + 2] = (int) (rgb[2]);
                        idx += 3;
                    }
                    dstOffset += scanlineStride;
                }
            } else if (floatData != null) {
                for (int j = 0; j < dstHeight; j++) {
                    int idx = dstOffset;
                    for (int i = 0; i < dstWidth; i++) {
                        float x0 = floatData[idx];
                        float x1 = floatData[idx + 1];
                        float x2 = floatData[idx + 2];
                        colorConverter.toRGB(x0, x1, x2, rgb);
                        floatData[idx] = rgb[0];
                        floatData[idx + 1] = rgb[1];
                        floatData[idx + 2] = rgb[2];
                        idx += 3;
                    }
                    dstOffset += scanlineStride;
                }
            }
        // int[] p = new int[3];
        // ras.getPixel(0, 0, p);
        // System.out.println("p00 = " +
        // p[0] + " " + p[1] + " " + p[2]);
        // ras.getPixel(1, 0, p);
        // System.out.println("p10 = " +
        // p[0] + " " + p[1] + " " + p[2]);
        // ras.getPixel(2, 0, p);
        // System.out.println("p20 = " +
        // p[0] + " " + p[1] + " " + p[2]);
        // ras.getPixel(3, 0, p);
        // System.out.println("p30 = " +
        // p[0] + " " + p[1] + " " + p[2]);
        // ColorSpace rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        // ColorConvertOp op = new ColorConvertOp(colorSpace, rgb, null);
        // WritableRaster dest = op.createCompatibleDestRaster(ras);
        // op.filter(ras, dest);
        // ras = dest;
        }
        if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO) {
            if (byteData != null) {
                int bytesPerRow = (srcWidth * pixelBitStride + 7) / 8;
                for (int y = 0; y < srcHeight; y++) {
                    int offset = dstOffset + y * scanlineStride;
                    for (int i = 0; i < bytesPerRow; i++) {
                        byteData[offset + i] ^= 0xff;
                    }
                }
            } else if (shortData != null) {
                int shortsPerRow = (srcWidth * pixelBitStride + 15) / 16;
                if (sampleFormat[0] == BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
                    for (int y = 0; y < srcHeight; y++) {
                        int offset = dstOffset + y * scanlineStride;
                        for (int i = 0; i < shortsPerRow; i++) {
                            int shortOffset = offset + i;
                            // XXX Does this make any sense?
                            shortData[shortOffset] = (short) (Short.MAX_VALUE - shortData[shortOffset]);
                        }
                    }
                } else {
                    for (int y = 0; y < srcHeight; y++) {
                        int offset = dstOffset + y * scanlineStride;
                        for (int i = 0; i < shortsPerRow; i++) {
                            shortData[offset + i] ^= 0xffff;
                        }
                    }
                }
            } else if (intData != null) {
                int intsPerRow = (srcWidth * pixelBitStride + 15) / 16;
                for (int y = 0; y < srcHeight; y++) {
                    int offset = dstOffset + y * scanlineStride;
                    for (int i = 0; i < intsPerRow; i++) {
                        int intOffset = offset + i;
                        // XXX Does this make any sense?
                        intData[intOffset] = Integer.MAX_VALUE - intData[intOffset];
                    }
                }
            } else if (floatData != null) {
                int floatsPerRow = (srcWidth * pixelBitStride + 15) / 16;
                for (int y = 0; y < srcHeight; y++) {
                    int offset = dstOffset + y * scanlineStride;
                    for (int i = 0; i < floatsPerRow; i++) {
                        int floatOffset = offset + i;
                        // XXX Does this make any sense?
                        floatData[floatOffset] = 1.0F - floatData[floatOffset];
                    }
                }
            }
        }
        if (isBilevel) {
            Rectangle rect = isImageSimple ? new Rectangle(dstMinX, dstMinY, dstWidth, dstHeight) : ras.getBounds();
            ImageUtil.setPackedBinaryData(byteData, ras, rect);
        }
        // equals the raster of 'image' or is a child thereof.
        if (isDirectCopy) {
            // rawImage == image) {
            return;
        }
    }
    // Copy the raw image data into the true destination image
    Raster src = rawImage.getRaster();
    // Create band child of source
    Raster srcChild = src.createChild(0, 0, srcWidth, srcHeight, srcMinX, srcMinY, planar ? null : sourceBands);
    WritableRaster dst = image.getRaster();
    // Create dst child covering area and bands to be written
    WritableRaster dstChild = dst.createWritableChild(dstMinX, dstMinY, dstWidth, dstHeight, dstMinX, dstMinY, destinationBands);
    if (subsampleX == 1 && subsampleY == 1 && !adjustBitDepths) {
        srcChild = srcChild.createChild(activeSrcMinX, activeSrcMinY, activeSrcWidth, activeSrcHeight, dstMinX, dstMinY, null);
        dstChild.setRect(srcChild);
    } else if (subsampleX == 1 && !adjustBitDepths) {
        int sy = activeSrcMinY;
        int dy = dstMinY;
        while (sy < srcMinY + srcHeight) {
            Raster srcRow = srcChild.createChild(activeSrcMinX, sy, activeSrcWidth, 1, dstMinX, dy, null);
            dstChild.setRect(srcRow);
            sy += subsampleY;
            ++dy;
        }
    } else {
        // /init vars
        int numBands = srcChild.getNumBands();
        int sy = activeSrcMinY;
        int dy = dstMinY;
        // get the databuffer type
        final int type = srcChild.getDataBuffer().getDataType();
        switch(type) {
            case DataBuffer.TYPE_BYTE:
            case DataBuffer.TYPE_INT:
            case DataBuffer.TYPE_SHORT:
            case DataBuffer.TYPE_USHORT:
                int[] p = srcChild.getPixel(srcMinX, srcMinY, (int[]) null);
                while (sy < activeSrcMinY + activeSrcHeight) {
                    int sx = activeSrcMinX;
                    int dx = dstMinX;
                    while (sx < activeSrcMinX + activeSrcWidth) {
                        srcChild.getPixel(sx, sy, p);
                        if (adjustBitDepths) {
                            for (int band = 0; band < numBands; band++) {
                                p[band] = bitDepthScale[band][p[band]];
                            }
                        }
                        dstChild.setPixel(dx, dy, p);
                        sx += subsampleX;
                        ++dx;
                    }
                    sy += subsampleY;
                    ++dy;
                }
                break;
            case DataBuffer.TYPE_DOUBLE:
                double[] d = srcChild.getPixel(srcMinX, srcMinY, (double[]) null);
                while (sy < activeSrcMinY + activeSrcHeight) {
                    int sx = activeSrcMinX;
                    int dx = dstMinX;
                    while (sx < activeSrcMinX + activeSrcWidth) {
                        srcChild.getPixel(sx, sy, d);
                        // if (adjustBitDepths) {
                        // for (int band = 0; band < numBands; band++) {
                        // d[band] = bitDepthScale[band][d[band]];
                        // }
                        // }
                        dstChild.setPixel(dx, dy, d);
                        sx += subsampleX;
                        ++dx;
                    }
                    sy += subsampleY;
                    ++dy;
                }
                break;
            case DataBuffer.TYPE_FLOAT:
                float[] f = srcChild.getPixel(srcMinX, srcMinY, (float[]) null);
                while (sy < activeSrcMinY + activeSrcHeight) {
                    int sx = activeSrcMinX;
                    int dx = dstMinX;
                    while (sx < activeSrcMinX + activeSrcWidth) {
                        srcChild.getPixel(sx, sy, f);
                        // if (adjustBitDepths) {
                        // for (int band = 0; band < numBands; band++) {
                        // d[band] = bitDepthScale[band][d[band]];
                        // }
                        // }
                        dstChild.setPixel(dx, dy, f);
                        sx += subsampleX;
                        ++dx;
                    }
                    sy += subsampleY;
                    ++dy;
                }
                break;
            default:
                break;
        }
    }
}
Also used : DataBufferDouble(java.awt.image.DataBufferDouble) Raster(java.awt.image.Raster) WritableRaster(java.awt.image.WritableRaster) Rectangle(java.awt.Rectangle) SinglePixelPackedSampleModel(java.awt.image.SinglePixelPackedSampleModel) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) IIOException(javax.imageio.IIOException) ComponentSampleModel(java.awt.image.ComponentSampleModel) DataBufferInt(java.awt.image.DataBufferInt) DataBufferByte(java.awt.image.DataBufferByte) DataBufferShort(java.awt.image.DataBufferShort) 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) WritableRaster(java.awt.image.WritableRaster) DataBufferFloat(java.awt.image.DataBufferFloat) DataBufferUShort(java.awt.image.DataBufferUShort) DataBuffer(java.awt.image.DataBuffer)

Aggregations

SampleModel (java.awt.image.SampleModel)97 ColorModel (java.awt.image.ColorModel)43 ComponentSampleModel (java.awt.image.ComponentSampleModel)38 Point (java.awt.Point)33 SinglePixelPackedSampleModel (java.awt.image.SinglePixelPackedSampleModel)33 DataBuffer (java.awt.image.DataBuffer)32 Rectangle (java.awt.Rectangle)30 IndexColorModel (java.awt.image.IndexColorModel)29 BufferedImage (java.awt.image.BufferedImage)27 MultiPixelPackedSampleModel (java.awt.image.MultiPixelPackedSampleModel)26 WritableRaster (java.awt.image.WritableRaster)26 PixelInterleavedSampleModel (java.awt.image.PixelInterleavedSampleModel)23 DataBufferByte (java.awt.image.DataBufferByte)20 ImageTypeSpecifier (javax.imageio.ImageTypeSpecifier)18 ComponentColorModel (java.awt.image.ComponentColorModel)17 DataBufferInt (java.awt.image.DataBufferInt)17 ColorSpace (java.awt.color.ColorSpace)15 Raster (java.awt.image.Raster)15 DataBufferUShort (java.awt.image.DataBufferUShort)13 BandedSampleModel (java.awt.image.BandedSampleModel)12