PngDecoderpublic class PngDecoder extends ImageDecoder
Fields Summary |
---|
private static final int | hintflags | private static final int | PNG_COLOR_TYPE_GRAY | private static final int | PNG_COLOR_TYPE_RGB | private static final int | PNG_COLOR_TYPE_PLTE | private static final int | PNG_COLOR_TYPE_GRAY_ALPHA | private static final int | PNG_COLOR_TYPE_RGBA | private static final int | INPUT_BUFFER_SIZE | private byte[] | buffer | byte[] | byteOut | int[] | intOut | private long | hNativeDecoder | int | imageWidth | int | imageHeight | int | colorType | int | bitDepth | byte[] | cmap | boolean | transferInts | int | dataElementsPerPixel | ColorModel | cm | int | updateFromScanline | int | numScanlines |
Methods Summary |
---|
private native long | decode(byte[] input, int bytesInBuffer, long hDecoder)
| public void | decodeImage()
try {
int bytesRead = 0;
int needBytes, offset, bytesInBuffer = 0;
// Read from the input stream
for (;;) {
needBytes = INPUT_BUFFER_SIZE - bytesInBuffer;
offset = bytesInBuffer;
bytesRead = inputStream.read(buffer, offset, needBytes);
if (bytesRead < 0) { // Break, nothing to read from buffer, image truncated?
releaseNativeDecoder(hNativeDecoder);
break;
}
// Keep track on how much bytes left in buffer
bytesInBuffer += bytesRead;
hNativeDecoder = decode(buffer, bytesInBuffer, hNativeDecoder);
// PNG decoder always consumes all bytes at once
bytesInBuffer = 0;
// if (bytesConsumed < 0)
//break; // Error exit
returnData();
// OK, we decoded all the picture in the right way...
if (hNativeDecoder == 0) {
break;
}
}
imageComplete(ImageConsumer.STATICIMAGEDONE);
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
imageComplete(ImageConsumer.IMAGEERROR);
throw e;
} finally {
closeStream();
}
| private static native void | initIDs()
| private static native void | releaseNativeDecoder(long hDecoder)
| private void | returnData()
// Send 1 or more scanlines to the consumer.
if (numScanlines > 0) {
// Native decoder could have returned
// some data from the next pass, handle it here
int pass1, pass2;
if (updateFromScanline + numScanlines > imageHeight) {
pass1 = imageHeight - updateFromScanline;
pass2 = updateFromScanline + numScanlines - imageHeight;
} else {
pass1 = numScanlines;
pass2 = 0;
}
transfer(updateFromScanline, pass1);
if (pass2 != 0) {
transfer(0, pass2);
}
}
| private void | returnHeader() // Called from native code
setDimensions(imageWidth, imageHeight);
switch (colorType) {
case PNG_COLOR_TYPE_GRAY: {
if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
// awt.3C=Unknown PNG color type
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
}
// Create gray color model
int numEntries = 1 << bitDepth;
int scaleFactor = 255 / (numEntries-1);
byte comps[] = new byte[numEntries];
for (int i = 0; i < numEntries; i++) {
comps[i] = (byte) (i * scaleFactor);
}
cm = new IndexColorModel(/*bitDepth*/8, numEntries, comps, comps, comps);
transferInts = false;
break;
}
case PNG_COLOR_TYPE_RGB: {
if (bitDepth != 8) {
// awt.3C=Unknown PNG color type
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
}
cm = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
transferInts = true;
break;
}
case PNG_COLOR_TYPE_PLTE: {
if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
// awt.3C=Unknown PNG color type
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
}
cm = new IndexColorModel(/*bitDepth*/8, cmap.length / 3, cmap, 0, false);
transferInts = false;
break;
}
case PNG_COLOR_TYPE_GRAY_ALPHA: {
if (bitDepth != 8) {
// awt.3C=Unknown PNG color type
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
}
cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
true, false,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
transferInts = false;
dataElementsPerPixel = 2;
break;
}
case PNG_COLOR_TYPE_RGBA: {
if (bitDepth != 8) {
// awt.3C=Unknown PNG color type
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
}
cm = ColorModel.getRGBdefault();
transferInts = true;
break;
}
default:
// awt.3C=Unknown PNG color type
throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
}
// Create output buffer
if (transferInts) {
intOut = new int[imageWidth * imageHeight];
} else {
byteOut = new byte[imageWidth * imageHeight * dataElementsPerPixel];
}
setColorModel(cm);
setHints(hintflags);
setProperties(new Hashtable<Object, Object>()); // Empty
| private void | transfer(int updateFromScanline, int numScanlines)
if (transferInts) {
setPixels(
0, updateFromScanline,
imageWidth, numScanlines,
cm, intOut,
updateFromScanline * imageWidth,
imageWidth
);
} else {
setPixels(
0, updateFromScanline,
imageWidth, numScanlines,
cm, byteOut,
updateFromScanline * imageWidth * dataElementsPerPixel,
imageWidth * dataElementsPerPixel
);
}
|
|