FileDocCategorySizeDatePackage
JpegDecoder.javaAPI DocAndroid 1.5 API7743Wed May 06 22:41:54 BST 2009org.apache.harmony.awt.gl.image

JpegDecoder

public class JpegDecoder extends ImageDecoder
author
Oleg V. Khaschansky
version
$Revision$

Fields Summary
public static final int
JCS_GRAYSCALE
public static final int
JCS_RGB
private static final int
hintflagsProgressive
private static final int
hintflagsSingle
private static final int
BUFFER_SIZE
private byte[]
buffer
private static ColorModel
cmRGB
private static ColorModel
cmGray
private long
hNativeDecoder
private boolean
headerDone
private int
imageWidth
private int
imageHeight
private boolean
progressive
private int
jpegColorSpace
private int
bytesConsumed
private int
currScanline
private ColorModel
cm
Constructors Summary
public JpegDecoder(DecodingImageSource src, InputStream is)


     
        System.loadLibrary("jpegdecoder"); //$NON-NLS-1$

        cmGray = new ComponentColorModel(
                ColorSpace.getInstance(ColorSpace.CS_GRAY),
                false, false,
                Transparency.OPAQUE, DataBuffer.TYPE_BYTE
        );

        // Create RGB color model
        cmRGB = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);

        initIDs();
    
        super(src, is);
    
Methods Summary
private native java.lang.Objectdecode(byte[] input, int bytesInBuffer, long hDecoder)

return
- not NULL if call is successful

public voiddecodeImage()

        try {
            int bytesRead = 0, dataLength = 0;
            boolean eosReached = false;
            int needBytes, offset, bytesInBuffer = 0;
            byte byteOut[] = null;
            int intOut[] = null;
            // Read from the input stream
            for (;;) {
                needBytes = BUFFER_SIZE - bytesInBuffer;
                offset = bytesInBuffer;

                bytesRead = inputStream.read(buffer, offset, needBytes);

                if (bytesRead < 0) {
                    bytesRead = 0;//break;
                    eosReached = true;
                } // Don't break, maybe something left in buffer

                // Keep track on how much bytes left in buffer
                bytesInBuffer += bytesRead;

                // Here we pass overall number of bytes left in the java buffer
                // (bytesInBuffer) since jpeg decoder has its own buffer and consumes
                // as many bytes as it can. If there are any unconsumed bytes
                // it didn't add them to its buffer...
                Object arr = decode(
                        buffer,
                        bytesInBuffer,
                        hNativeDecoder);

                // Keep track on how much bytes left in buffer
                bytesInBuffer -= bytesConsumed;

                if (!headerDone && imageWidth != -1) {
                    returnHeader();
                    headerDone = true;
                }

                if (bytesConsumed < 0) {
                    break; // Error exit
                }

                if (arr instanceof byte[]) {
                    byteOut = (byte[]) arr;
                    dataLength = byteOut.length;
                    returnData(byteOut, currScanline);
                } else if (arr instanceof int[]) {
                    intOut = (int[]) arr;
                    dataLength = intOut.length;
                    returnData(intOut, currScanline);
                } else {
                    dataLength = 0;
                }

                if (hNativeDecoder == 0) {
                    break;
                }

                if (dataLength == 0 && eosReached) {
                    releaseNativeDecoder(hNativeDecoder);
                    break; // Probably image is truncated
                }
            }
            imageComplete(ImageConsumer.STATICIMAGEDONE);
        } catch (IOException e) {
            throw e;
        } finally {
            closeStream();
        }
    
private static native voidinitIDs()

private static native voidreleaseNativeDecoder(long hDecoder)

public voidreturnData(int[] data, int currScanLine)

        // Send 1 or more scanlines to the consumer.
        int numScanlines = data.length / imageWidth;
        if (numScanlines > 0) {
            setPixels(
                    0, currScanLine - numScanlines,
                    imageWidth, numScanlines,
                    cm, data, 0, imageWidth
            );
        }
    
public voidreturnData(byte[] data, int currScanLine)

        int numScanlines = data.length / imageWidth;
        if (numScanlines > 0) {
            setPixels(
                    0, currScanLine - numScanlines,
                    imageWidth, numScanlines,
                    cm, data, 0, imageWidth
            );
        }
    
public voidreturnHeader()

        setDimensions(imageWidth, imageHeight);

        switch (jpegColorSpace) {
            case JCS_GRAYSCALE: cm = cmGray; break;
            case JCS_RGB: cm = cmRGB; break;
            default: 
                // awt.3D=Unknown colorspace
                throw new IllegalArgumentException(Messages.getString("awt.3D")); //$NON-NLS-1$
        }
        setColorModel(cm);

        setHints(progressive ? hintflagsProgressive : hintflagsSingle);

        setProperties(new Hashtable<Object, Object>()); // Empty