Search in sources :

Example 21 with DataBuffer

use of java.awt.image.DataBuffer in project jdk8u_jdk by JetBrains.

the class WritableRasterNative method createNativeRaster.

public static WritableRasterNative createNativeRaster(ColorModel cm, SurfaceData sd, int width, int height) {
    SampleModel smHw = null;
    int dataType = 0;
    int scanStride = width;
    switch(cm.getPixelSize()) {
        case 8:
        case 12:
            // 8-bits uses PixelInterleavedSampleModel
            if (cm.getPixelSize() == 8) {
                dataType = DataBuffer.TYPE_BYTE;
            } else {
                dataType = DataBuffer.TYPE_USHORT;
            }
            int[] bandOffsets = new int[1];
            bandOffsets[0] = 0;
            smHw = new PixelInterleavedSampleModel(dataType, width, height, 1, scanStride, bandOffsets);
            break;
        // all others use SinglePixelPackedSampleModel
        case 15:
        case 16:
            dataType = DataBuffer.TYPE_USHORT;
            int[] bitMasks = new int[3];
            DirectColorModel dcm = (DirectColorModel) cm;
            bitMasks[0] = dcm.getRedMask();
            bitMasks[1] = dcm.getGreenMask();
            bitMasks[2] = dcm.getBlueMask();
            smHw = new SinglePixelPackedSampleModel(dataType, width, height, scanStride, bitMasks);
            break;
        case 24:
        case 32:
            dataType = DataBuffer.TYPE_INT;
            bitMasks = new int[3];
            dcm = (DirectColorModel) cm;
            bitMasks[0] = dcm.getRedMask();
            bitMasks[1] = dcm.getGreenMask();
            bitMasks[2] = dcm.getBlueMask();
            smHw = new SinglePixelPackedSampleModel(dataType, width, height, scanStride, bitMasks);
            break;
        default:
            throw new InternalError("Unsupported depth " + cm.getPixelSize());
    }
    DataBuffer dbn = new DataBufferNative(sd, dataType, width, height);
    return new WritableRasterNative(smHw, dbn);
}
Also used : PixelInterleavedSampleModel(java.awt.image.PixelInterleavedSampleModel) SinglePixelPackedSampleModel(java.awt.image.SinglePixelPackedSampleModel) PixelInterleavedSampleModel(java.awt.image.PixelInterleavedSampleModel) SampleModel(java.awt.image.SampleModel) DirectColorModel(java.awt.image.DirectColorModel) SinglePixelPackedSampleModel(java.awt.image.SinglePixelPackedSampleModel) Point(java.awt.Point) DataBuffer(java.awt.image.DataBuffer)

Example 22 with DataBuffer

use of java.awt.image.DataBuffer in project jdk8u_jdk by JetBrains.

the class ImageUtil method setPackedBinaryData.

/**
     * Sets the supplied <code>Raster</code>'s data from an array
     * of packed binary data of the form returned by
     * <code>getPackedBinaryData()</code>.
     *
     * @throws IllegalArgumentException if <code>isBinary()</code> returns
     * <code>false</code> with the <code>SampleModel</code> of the
     * supplied <code>Raster</code> as argument.
     */
public static void setPackedBinaryData(byte[] binaryDataArray, WritableRaster raster, Rectangle rect) {
    SampleModel sm = raster.getSampleModel();
    if (!isBinary(sm)) {
        throw new IllegalArgumentException(I18N.getString("ImageUtil0"));
    }
    int rectX = rect.x;
    int rectY = rect.y;
    int rectWidth = rect.width;
    int rectHeight = rect.height;
    DataBuffer dataBuffer = raster.getDataBuffer();
    int dx = rectX - raster.getSampleModelTranslateX();
    int dy = rectY - raster.getSampleModelTranslateY();
    MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
    int lineStride = mpp.getScanlineStride();
    int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
    int bitOffset = mpp.getBitOffset(dx);
    int b = 0;
    if (bitOffset == 0) {
        if (dataBuffer instanceof DataBufferByte) {
            byte[] data = ((DataBufferByte) dataBuffer).getData();
            if (data == binaryDataArray) {
                // Optimal case: simply return.
                return;
            }
            int stride = (rectWidth + 7) / 8;
            int offset = 0;
            for (int y = 0; y < rectHeight; y++) {
                System.arraycopy(binaryDataArray, offset, data, eltOffset, stride);
                offset += stride;
                eltOffset += lineStride;
            }
        } else if (dataBuffer instanceof DataBufferShort || dataBuffer instanceof DataBufferUShort) {
            short[] data = dataBuffer instanceof DataBufferShort ? ((DataBufferShort) dataBuffer).getData() : ((DataBufferUShort) dataBuffer).getData();
            for (int y = 0; y < rectHeight; y++) {
                int xRemaining = rectWidth;
                int i = eltOffset;
                while (xRemaining > 8) {
                    data[i++] = (short) (((binaryDataArray[b++] & 0xFF) << 8) | (binaryDataArray[b++] & 0xFF));
                    xRemaining -= 16;
                }
                if (xRemaining > 0) {
                    data[i++] = (short) ((binaryDataArray[b++] & 0xFF) << 8);
                }
                eltOffset += lineStride;
            }
        } else if (dataBuffer instanceof DataBufferInt) {
            int[] data = ((DataBufferInt) dataBuffer).getData();
            for (int y = 0; y < rectHeight; y++) {
                int xRemaining = rectWidth;
                int i = eltOffset;
                while (xRemaining > 24) {
                    data[i++] = (int) (((binaryDataArray[b++] & 0xFF) << 24) | ((binaryDataArray[b++] & 0xFF) << 16) | ((binaryDataArray[b++] & 0xFF) << 8) | (binaryDataArray[b++] & 0xFF));
                    xRemaining -= 32;
                }
                int shift = 24;
                while (xRemaining > 0) {
                    data[i] |= (int) ((binaryDataArray[b++] & 0xFF) << shift);
                    shift -= 8;
                    xRemaining -= 8;
                }
                eltOffset += lineStride;
            }
        }
    } else {
        // bitOffset != 0
        int stride = (rectWidth + 7) / 8;
        int offset = 0;
        if (dataBuffer instanceof DataBufferByte) {
            byte[] data = ((DataBufferByte) dataBuffer).getData();
            if ((bitOffset & 7) == 0) {
                for (int y = 0; y < rectHeight; y++) {
                    System.arraycopy(binaryDataArray, offset, data, eltOffset, stride);
                    offset += stride;
                    eltOffset += lineStride;
                }
            } else {
                // bitOffset % 8 != 0
                int rightShift = bitOffset & 7;
                int leftShift = 8 - rightShift;
                int leftShift8 = 8 + leftShift;
                int mask = (byte) (255 << leftShift);
                int mask1 = (byte) ~mask;
                for (int y = 0; y < rectHeight; y++) {
                    int i = eltOffset;
                    int xRemaining = rectWidth;
                    while (xRemaining > 0) {
                        byte datum = binaryDataArray[b++];
                        if (xRemaining > leftShift8) {
                            // when all the bits in this BYTE will be set
                            // into the data buffer.
                            data[i] = (byte) ((data[i] & mask) | ((datum & 0xFF) >>> rightShift));
                            data[++i] = (byte) ((datum & 0xFF) << leftShift);
                        } else if (xRemaining > leftShift) {
                            // All the "leftShift" high bits will be set
                            // into the data buffer.  But not all the
                            // "rightShift" low bits will be set.
                            data[i] = (byte) ((data[i] & mask) | ((datum & 0xFF) >>> rightShift));
                            i++;
                            data[i] = (byte) ((data[i] & mask1) | ((datum & 0xFF) << leftShift));
                        } else {
                            // Less than "leftShift" high bits will be set.
                            int remainMask = (1 << leftShift - xRemaining) - 1;
                            data[i] = (byte) ((data[i] & (mask | remainMask)) | (datum & 0xFF) >>> rightShift & ~remainMask);
                        }
                        xRemaining -= 8;
                    }
                    eltOffset += lineStride;
                }
            }
        } else if (dataBuffer instanceof DataBufferShort || dataBuffer instanceof DataBufferUShort) {
            short[] data = dataBuffer instanceof DataBufferShort ? ((DataBufferShort) dataBuffer).getData() : ((DataBufferUShort) dataBuffer).getData();
            int rightShift = bitOffset & 7;
            int leftShift = 8 - rightShift;
            int leftShift16 = 16 + leftShift;
            int mask = (short) (~(255 << leftShift));
            int mask1 = (short) (65535 << leftShift);
            int mask2 = (short) ~mask1;
            for (int y = 0; y < rectHeight; y++) {
                int bOffset = bitOffset;
                int xRemaining = rectWidth;
                for (int x = 0; x < rectWidth; x += 8, bOffset += 8, xRemaining -= 8) {
                    int i = eltOffset + (bOffset >> 4);
                    int mod = bOffset & 15;
                    int datum = binaryDataArray[b++] & 0xFF;
                    if (mod <= 8) {
                        // This BYTE is set into one SHORT
                        if (xRemaining < 8) {
                            // Mask the bits to be set.
                            datum &= 255 << 8 - xRemaining;
                        }
                        data[i] = (short) ((data[i] & mask) | (datum << leftShift));
                    } else if (xRemaining > leftShift16) {
                        // This BYTE will be set into two SHORTs
                        data[i] = (short) ((data[i] & mask1) | ((datum >>> rightShift) & 0xFFFF));
                        data[++i] = (short) ((datum << leftShift) & 0xFFFF);
                    } else if (xRemaining > leftShift) {
                        // This BYTE will be set into two SHORTs;
                        // But not all the low bits will be set into SHORT
                        data[i] = (short) ((data[i] & mask1) | ((datum >>> rightShift) & 0xFFFF));
                        i++;
                        data[i] = (short) ((data[i] & mask2) | ((datum << leftShift) & 0xFFFF));
                    } else {
                        // Only some of the high bits will be set into
                        // SHORTs
                        int remainMask = (1 << leftShift - xRemaining) - 1;
                        data[i] = (short) ((data[i] & (mask1 | remainMask)) | ((datum >>> rightShift) & 0xFFFF & ~remainMask));
                    }
                }
                eltOffset += lineStride;
            }
        } else if (dataBuffer instanceof DataBufferInt) {
            int[] data = ((DataBufferInt) dataBuffer).getData();
            int rightShift = bitOffset & 7;
            int leftShift = 8 - rightShift;
            int leftShift32 = 32 + leftShift;
            int mask = 0xFFFFFFFF << leftShift;
            int mask1 = ~mask;
            for (int y = 0; y < rectHeight; y++) {
                int bOffset = bitOffset;
                int xRemaining = rectWidth;
                for (int x = 0; x < rectWidth; x += 8, bOffset += 8, xRemaining -= 8) {
                    int i = eltOffset + (bOffset >> 5);
                    int mod = bOffset & 31;
                    int datum = binaryDataArray[b++] & 0xFF;
                    if (mod <= 24) {
                        // This BYTE is set into one INT
                        int shift = 24 - mod;
                        if (xRemaining < 8) {
                            // Mask the bits to be set.
                            datum &= 255 << 8 - xRemaining;
                        }
                        data[i] = (data[i] & (~(255 << shift))) | (datum << shift);
                    } else if (xRemaining > leftShift32) {
                        // All the bits of this BYTE will be set into two INTs
                        data[i] = (data[i] & mask) | (datum >>> rightShift);
                        data[++i] = datum << leftShift;
                    } else if (xRemaining > leftShift) {
                        // This BYTE will be set into two INTs;
                        // But not all the low bits will be set into INT
                        data[i] = (data[i] & mask) | (datum >>> rightShift);
                        i++;
                        data[i] = (data[i] & mask1) | (datum << leftShift);
                    } else {
                        // Only some of the high bits will be set into INT
                        int remainMask = (1 << leftShift - xRemaining) - 1;
                        data[i] = (data[i] & (mask | remainMask)) | (datum >>> rightShift & ~remainMask);
                    }
                }
                eltOffset += lineStride;
            }
        }
    }
}
Also used : 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) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) DataBufferInt(java.awt.image.DataBufferInt) DataBufferByte(java.awt.image.DataBufferByte) DataBufferUShort(java.awt.image.DataBufferUShort) Point(java.awt.Point) DataBuffer(java.awt.image.DataBuffer)

Example 23 with DataBuffer

use of java.awt.image.DataBuffer in project jdk8u_jdk by JetBrains.

the class ImageUtil method getPackedBinaryData.

/**
     * For the case of binary data (<code>isBinary()</code> returns
     * <code>true</code>), return the binary data as a packed byte array.
     * The data will be packed as eight bits per byte with no bit offset,
     * i.e., the first bit in each image line will be the left-most of the
     * first byte of the line.  The line stride in bytes will be
     * <code>(int)((getWidth()+7)/8)</code>.  The length of the returned
     * array will be the line stride multiplied by <code>getHeight()</code>
     *
     * @return the binary data as a packed array of bytes with zero offset
     * of <code>null</code> if the data are not binary.
     * @throws IllegalArgumentException if <code>isBinary()</code> returns
     * <code>false</code> with the <code>SampleModel</code> of the
     * supplied <code>Raster</code> as argument.
     */
public static byte[] getPackedBinaryData(Raster raster, Rectangle rect) {
    SampleModel sm = raster.getSampleModel();
    if (!isBinary(sm)) {
        throw new IllegalArgumentException(I18N.getString("ImageUtil0"));
    }
    int rectX = rect.x;
    int rectY = rect.y;
    int rectWidth = rect.width;
    int rectHeight = rect.height;
    DataBuffer dataBuffer = raster.getDataBuffer();
    int dx = rectX - raster.getSampleModelTranslateX();
    int dy = rectY - raster.getSampleModelTranslateY();
    MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
    int lineStride = mpp.getScanlineStride();
    int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
    int bitOffset = mpp.getBitOffset(dx);
    int numBytesPerRow = (rectWidth + 7) / 8;
    if (dataBuffer instanceof DataBufferByte && eltOffset == 0 && bitOffset == 0 && numBytesPerRow == lineStride && ((DataBufferByte) dataBuffer).getData().length == numBytesPerRow * rectHeight) {
        return ((DataBufferByte) dataBuffer).getData();
    }
    byte[] binaryDataArray = new byte[numBytesPerRow * rectHeight];
    int b = 0;
    if (bitOffset == 0) {
        if (dataBuffer instanceof DataBufferByte) {
            byte[] data = ((DataBufferByte) dataBuffer).getData();
            int stride = numBytesPerRow;
            int offset = 0;
            for (int y = 0; y < rectHeight; y++) {
                System.arraycopy(data, eltOffset, binaryDataArray, offset, stride);
                offset += stride;
                eltOffset += lineStride;
            }
        } else if (dataBuffer instanceof DataBufferShort || dataBuffer instanceof DataBufferUShort) {
            short[] data = dataBuffer instanceof DataBufferShort ? ((DataBufferShort) dataBuffer).getData() : ((DataBufferUShort) dataBuffer).getData();
            for (int y = 0; y < rectHeight; y++) {
                int xRemaining = rectWidth;
                int i = eltOffset;
                while (xRemaining > 8) {
                    short datum = data[i++];
                    binaryDataArray[b++] = (byte) ((datum >>> 8) & 0xFF);
                    binaryDataArray[b++] = (byte) (datum & 0xFF);
                    xRemaining -= 16;
                }
                if (xRemaining > 0) {
                    binaryDataArray[b++] = (byte) ((data[i] >>> 8) & 0XFF);
                }
                eltOffset += lineStride;
            }
        } else if (dataBuffer instanceof DataBufferInt) {
            int[] data = ((DataBufferInt) dataBuffer).getData();
            for (int y = 0; y < rectHeight; y++) {
                int xRemaining = rectWidth;
                int i = eltOffset;
                while (xRemaining > 24) {
                    int datum = data[i++];
                    binaryDataArray[b++] = (byte) ((datum >>> 24) & 0xFF);
                    binaryDataArray[b++] = (byte) ((datum >>> 16) & 0xFF);
                    binaryDataArray[b++] = (byte) ((datum >>> 8) & 0xFF);
                    binaryDataArray[b++] = (byte) (datum & 0xFF);
                    xRemaining -= 32;
                }
                int shift = 24;
                while (xRemaining > 0) {
                    binaryDataArray[b++] = (byte) ((data[i] >>> shift) & 0xFF);
                    shift -= 8;
                    xRemaining -= 8;
                }
                eltOffset += lineStride;
            }
        }
    } else {
        // bitOffset != 0
        if (dataBuffer instanceof DataBufferByte) {
            byte[] data = ((DataBufferByte) dataBuffer).getData();
            if ((bitOffset & 7) == 0) {
                int stride = numBytesPerRow;
                int offset = 0;
                for (int y = 0; y < rectHeight; y++) {
                    System.arraycopy(data, eltOffset, binaryDataArray, offset, stride);
                    offset += stride;
                    eltOffset += lineStride;
                }
            } else {
                // bitOffset % 8 != 0
                int leftShift = bitOffset & 7;
                int rightShift = 8 - leftShift;
                for (int y = 0; y < rectHeight; y++) {
                    int i = eltOffset;
                    int xRemaining = rectWidth;
                    while (xRemaining > 0) {
                        if (xRemaining > rightShift) {
                            binaryDataArray[b++] = (byte) (((data[i++] & 0xFF) << leftShift) | ((data[i] & 0xFF) >>> rightShift));
                        } else {
                            binaryDataArray[b++] = (byte) ((data[i] & 0xFF) << leftShift);
                        }
                        xRemaining -= 8;
                    }
                    eltOffset += lineStride;
                }
            }
        } else if (dataBuffer instanceof DataBufferShort || dataBuffer instanceof DataBufferUShort) {
            short[] data = dataBuffer instanceof DataBufferShort ? ((DataBufferShort) dataBuffer).getData() : ((DataBufferUShort) dataBuffer).getData();
            for (int y = 0; y < rectHeight; y++) {
                int bOffset = bitOffset;
                for (int x = 0; x < rectWidth; x += 8, bOffset += 8) {
                    int i = eltOffset + bOffset / 16;
                    int mod = bOffset % 16;
                    int left = data[i] & 0xFFFF;
                    if (mod <= 8) {
                        binaryDataArray[b++] = (byte) (left >>> (8 - mod));
                    } else {
                        int delta = mod - 8;
                        int right = data[i + 1] & 0xFFFF;
                        binaryDataArray[b++] = (byte) ((left << delta) | (right >>> (16 - delta)));
                    }
                }
                eltOffset += lineStride;
            }
        } else if (dataBuffer instanceof DataBufferInt) {
            int[] data = ((DataBufferInt) dataBuffer).getData();
            for (int y = 0; y < rectHeight; y++) {
                int bOffset = bitOffset;
                for (int x = 0; x < rectWidth; x += 8, bOffset += 8) {
                    int i = eltOffset + bOffset / 32;
                    int mod = bOffset % 32;
                    int left = data[i];
                    if (mod <= 24) {
                        binaryDataArray[b++] = (byte) (left >>> (24 - mod));
                    } else {
                        int delta = mod - 24;
                        int right = data[i + 1];
                        binaryDataArray[b++] = (byte) ((left << delta) | (right >>> (32 - delta)));
                    }
                }
                eltOffset += lineStride;
            }
        }
    }
    return binaryDataArray;
}
Also used : 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) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) DataBufferInt(java.awt.image.DataBufferInt) DataBufferByte(java.awt.image.DataBufferByte) DataBufferUShort(java.awt.image.DataBufferUShort) Point(java.awt.Point) DataBuffer(java.awt.image.DataBuffer)

Example 24 with DataBuffer

use of java.awt.image.DataBuffer in project jdk8u_jdk by JetBrains.

the class ImageUtil method setUnpackedBinaryData.

/**
     * Copies data into the packed array of the <code>Raster</code>
     * from an array of unpacked data of the form returned by
     * <code>getUnpackedBinaryData()</code>.
     *
     * <p> If the data are binary, then the target bit will be set if
     * and only if the corresponding byte is non-zero.
     *
     * @throws IllegalArgumentException if <code>isBinary()</code> returns
     * <code>false</code> with the <code>SampleModel</code> of the
     * supplied <code>Raster</code> as argument.
     */
public static void setUnpackedBinaryData(byte[] bdata, WritableRaster raster, Rectangle rect) {
    SampleModel sm = raster.getSampleModel();
    if (!isBinary(sm)) {
        throw new IllegalArgumentException(I18N.getString("ImageUtil0"));
    }
    int rectX = rect.x;
    int rectY = rect.y;
    int rectWidth = rect.width;
    int rectHeight = rect.height;
    DataBuffer dataBuffer = raster.getDataBuffer();
    int dx = rectX - raster.getSampleModelTranslateX();
    int dy = rectY - raster.getSampleModelTranslateY();
    MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel) sm;
    int lineStride = mpp.getScanlineStride();
    int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy);
    int bitOffset = mpp.getBitOffset(dx);
    int k = 0;
    if (dataBuffer instanceof DataBufferByte) {
        byte[] data = ((DataBufferByte) dataBuffer).getData();
        for (int y = 0; y < rectHeight; y++) {
            int bOffset = eltOffset * 8 + bitOffset;
            for (int x = 0; x < rectWidth; x++) {
                if (bdata[k++] != (byte) 0) {
                    data[bOffset / 8] |= (byte) (0x00000001 << (7 - bOffset & 7));
                }
                bOffset++;
            }
            eltOffset += lineStride;
        }
    } else if (dataBuffer instanceof DataBufferShort || dataBuffer instanceof DataBufferUShort) {
        short[] data = dataBuffer instanceof DataBufferShort ? ((DataBufferShort) dataBuffer).getData() : ((DataBufferUShort) dataBuffer).getData();
        for (int y = 0; y < rectHeight; y++) {
            int bOffset = eltOffset * 16 + bitOffset;
            for (int x = 0; x < rectWidth; x++) {
                if (bdata[k++] != (byte) 0) {
                    data[bOffset / 16] |= (short) (0x00000001 << (15 - bOffset % 16));
                }
                bOffset++;
            }
            eltOffset += lineStride;
        }
    } else if (dataBuffer instanceof DataBufferInt) {
        int[] data = ((DataBufferInt) dataBuffer).getData();
        for (int y = 0; y < rectHeight; y++) {
            int bOffset = eltOffset * 32 + bitOffset;
            for (int x = 0; x < rectWidth; x++) {
                if (bdata[k++] != (byte) 0) {
                    data[bOffset / 32] |= (int) (0x00000001 << (31 - bOffset % 32));
                }
                bOffset++;
            }
            eltOffset += lineStride;
        }
    }
}
Also used : 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) MultiPixelPackedSampleModel(java.awt.image.MultiPixelPackedSampleModel) DataBufferInt(java.awt.image.DataBufferInt) DataBufferByte(java.awt.image.DataBufferByte) DataBufferUShort(java.awt.image.DataBufferUShort) Point(java.awt.Point) DataBuffer(java.awt.image.DataBuffer)

Example 25 with DataBuffer

use of java.awt.image.DataBuffer in project jdk8u_jdk by JetBrains.

the class PNGImageReader method decodePass.

private void decodePass(int passNum, int xStart, int yStart, int xStep, int yStep, int passWidth, int passHeight) throws IOException {
    if ((passWidth == 0) || (passHeight == 0)) {
        return;
    }
    WritableRaster imRas = theImage.getWritableTile(0, 0);
    int dstMinX = imRas.getMinX();
    int dstMaxX = dstMinX + imRas.getWidth() - 1;
    int dstMinY = imRas.getMinY();
    int dstMaxY = dstMinY + imRas.getHeight() - 1;
    // Determine which pixels will be updated in this pass
    int[] vals = ReaderUtil.computeUpdatedPixels(sourceRegion, destinationOffset, dstMinX, dstMinY, dstMaxX, dstMaxY, sourceXSubsampling, sourceYSubsampling, xStart, yStart, passWidth, passHeight, xStep, yStep);
    int updateMinX = vals[0];
    int updateMinY = vals[1];
    int updateWidth = vals[2];
    int updateXStep = vals[4];
    int updateYStep = vals[5];
    int bitDepth = metadata.IHDR_bitDepth;
    int inputBands = inputBandsForColorType[metadata.IHDR_colorType];
    int bytesPerPixel = (bitDepth == 16) ? 2 : 1;
    bytesPerPixel *= inputBands;
    int bytesPerRow = (inputBands * passWidth * bitDepth + 7) / 8;
    int eltsPerRow = (bitDepth == 16) ? bytesPerRow / 2 : bytesPerRow;
    // If no pixels need updating, just skip the input data
    if (updateWidth == 0) {
        for (int srcY = 0; srcY < passHeight; srcY++) {
            // Update count of pixels read
            updateImageProgress(passWidth);
            // Skip filter byte and the remaining row bytes
            pixelStream.skipBytes(1 + bytesPerRow);
        }
        return;
    }
    // Backwards map from destination pixels
    // (dstX = updateMinX + k*updateXStep)
    // to source pixels (sourceX), and then
    // to offset and skip in passRow (srcX and srcXStep)
    int sourceX = (updateMinX - destinationOffset.x) * sourceXSubsampling + sourceRegion.x;
    int srcX = (sourceX - xStart) / xStep;
    // Compute the step factor in the source
    int srcXStep = updateXStep * sourceXSubsampling / xStep;
    byte[] byteData = null;
    short[] shortData = null;
    byte[] curr = new byte[bytesPerRow];
    byte[] prior = new byte[bytesPerRow];
    // Create a 1-row tall Raster to hold the data
    WritableRaster passRow = createRaster(passWidth, 1, inputBands, eltsPerRow, bitDepth);
    // Create an array suitable for holding one pixel
    int[] ps = passRow.getPixel(0, 0, (int[]) null);
    DataBuffer dataBuffer = passRow.getDataBuffer();
    int type = dataBuffer.getDataType();
    if (type == DataBuffer.TYPE_BYTE) {
        byteData = ((DataBufferByte) dataBuffer).getData();
    } else {
        shortData = ((DataBufferUShort) dataBuffer).getData();
    }
    processPassStarted(theImage, passNum, sourceMinProgressivePass, sourceMaxProgressivePass, updateMinX, updateMinY, updateXStep, updateYStep, destinationBands);
    // Handle source and destination bands
    if (sourceBands != null) {
        passRow = passRow.createWritableChild(0, 0, passRow.getWidth(), 1, 0, 0, sourceBands);
    }
    if (destinationBands != null) {
        imRas = imRas.createWritableChild(0, 0, imRas.getWidth(), imRas.getHeight(), 0, 0, destinationBands);
    }
    // Determine if all of the relevant output bands have the
    // same bit depth as the source data
    boolean adjustBitDepths = false;
    int[] outputSampleSize = imRas.getSampleModel().getSampleSize();
    int numBands = outputSampleSize.length;
    for (int b = 0; b < numBands; b++) {
        if (outputSampleSize[b] != bitDepth) {
            adjustBitDepths = true;
            break;
        }
    }
    // If the bit depths differ, create a lookup table per band to perform
    // the conversion
    int[][] scale = null;
    if (adjustBitDepths) {
        int maxInSample = (1 << bitDepth) - 1;
        int halfMaxInSample = maxInSample / 2;
        scale = new int[numBands][];
        for (int b = 0; b < numBands; b++) {
            int maxOutSample = (1 << outputSampleSize[b]) - 1;
            scale[b] = new int[maxInSample + 1];
            for (int s = 0; s <= maxInSample; s++) {
                scale[b][s] = (s * maxOutSample + halfMaxInSample) / maxInSample;
            }
        }
    }
    // Limit passRow to relevant area for the case where we
    // will can setRect to copy a contiguous span
    boolean useSetRect = srcXStep == 1 && updateXStep == 1 && !adjustBitDepths && (imRas instanceof ByteInterleavedRaster);
    if (useSetRect) {
        passRow = passRow.createWritableChild(srcX, 0, updateWidth, 1, 0, 0, null);
    }
    // Decode the (sub)image row-by-row
    for (int srcY = 0; srcY < passHeight; srcY++) {
        // Update count of pixels read
        updateImageProgress(passWidth);
        // Read the filter type byte and a row of data
        int filter = pixelStream.read();
        try {
            // Swap curr and prior
            byte[] tmp = prior;
            prior = curr;
            curr = tmp;
            pixelStream.readFully(curr, 0, bytesPerRow);
        } catch (java.util.zip.ZipException ze) {
            // TODO - throw a more meaningful exception
            throw ze;
        }
        switch(filter) {
            case PNG_FILTER_NONE:
                break;
            case PNG_FILTER_SUB:
                decodeSubFilter(curr, 0, bytesPerRow, bytesPerPixel);
                break;
            case PNG_FILTER_UP:
                decodeUpFilter(curr, 0, prior, 0, bytesPerRow);
                break;
            case PNG_FILTER_AVERAGE:
                decodeAverageFilter(curr, 0, prior, 0, bytesPerRow, bytesPerPixel);
                break;
            case PNG_FILTER_PAETH:
                decodePaethFilter(curr, 0, prior, 0, bytesPerRow, bytesPerPixel);
                break;
            default:
                throw new IIOException("Unknown row filter type (= " + filter + ")!");
        }
        // Copy data into passRow byte by byte
        if (bitDepth < 16) {
            System.arraycopy(curr, 0, byteData, 0, bytesPerRow);
        } else {
            int idx = 0;
            for (int j = 0; j < eltsPerRow; j++) {
                shortData[j] = (short) ((curr[idx] << 8) | (curr[idx + 1] & 0xff));
                idx += 2;
            }
        }
        // True Y position in source
        int sourceY = srcY * yStep + yStart;
        if ((sourceY >= sourceRegion.y) && (sourceY < sourceRegion.y + sourceRegion.height) && (((sourceY - sourceRegion.y) % sourceYSubsampling) == 0)) {
            int dstY = destinationOffset.y + (sourceY - sourceRegion.y) / sourceYSubsampling;
            if (dstY < dstMinY) {
                continue;
            }
            if (dstY > dstMaxY) {
                break;
            }
            if (useSetRect) {
                imRas.setRect(updateMinX, dstY, passRow);
            } else {
                int newSrcX = srcX;
                for (int dstX = updateMinX; dstX < updateMinX + updateWidth; dstX += updateXStep) {
                    passRow.getPixel(newSrcX, 0, ps);
                    if (adjustBitDepths) {
                        for (int b = 0; b < numBands; b++) {
                            ps[b] = scale[b][ps[b]];
                        }
                    }
                    imRas.setPixel(dstX, dstY, ps);
                    newSrcX += srcXStep;
                }
            }
            processImageUpdate(theImage, updateMinX, dstY, updateWidth, 1, updateXStep, updateYStep, destinationBands);
            // processReadAborted will be called later
            if (abortRequested()) {
                return;
            }
        }
    }
    processPassComplete(theImage);
}
Also used : ByteInterleavedRaster(sun.awt.image.ByteInterleavedRaster) IIOException(javax.imageio.IIOException) Point(java.awt.Point) WritableRaster(java.awt.image.WritableRaster) DataBuffer(java.awt.image.DataBuffer)

Aggregations

DataBuffer (java.awt.image.DataBuffer)28 DataBufferInt (java.awt.image.DataBufferInt)16 SampleModel (java.awt.image.SampleModel)14 DataBufferByte (java.awt.image.DataBufferByte)13 BufferedImage (java.awt.image.BufferedImage)11 SinglePixelPackedSampleModel (java.awt.image.SinglePixelPackedSampleModel)10 DataBufferShort (java.awt.image.DataBufferShort)9 Point (java.awt.Point)8 WritableRaster (java.awt.image.WritableRaster)8 ComponentSampleModel (java.awt.image.ComponentSampleModel)6 MultiPixelPackedSampleModel (java.awt.image.MultiPixelPackedSampleModel)6 DataBufferUShort (java.awt.image.DataBufferUShort)5 DirectColorModel (java.awt.image.DirectColorModel)4 Graphics2D (java.awt.Graphics2D)3 PixelInterleavedSampleModel (java.awt.image.PixelInterleavedSampleModel)3 Rectangle (java.awt.Rectangle)2 ColorSpace (java.awt.color.ColorSpace)2 ColorModel (java.awt.image.ColorModel)2 Raster (java.awt.image.Raster)2 ByteBuffer (java.nio.ByteBuffer)2