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);
}
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;
}
}
}
}
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;
}
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;
}
}
}
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);
}
Aggregations