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

ImageDecoder

public abstract class ImageDecoder extends Object
This class contains common functionality for all image decoders.

Fields Summary
public static final int
GENERIC_DECODER
Image types
public static final int
JPG_DECODER
public static final int
GIF_DECODER
public static final int
PNG_DECODER
private static final int
MAX_BYTES_IN_SIGNATURE
protected List
consumers
protected InputStream
inputStream
protected DecodingImageSource
src
protected boolean
terminated
Constructors Summary
protected ImageDecoder(DecodingImageSource _src, InputStream is)

        src = _src;
        consumers = src.consumers;
        inputStream = is;
    
Methods Summary
public synchronized voidcloseStream()

        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
            }
        }
    
static org.apache.harmony.awt.gl.image.ImageDecodercreateDecoder(DecodingImageSource src, java.io.InputStream is)
Chooses appropriate image decoder by looking into input stream and checking the image signature.

param
src - image producer, required for passing data to it from the created decoder via callbacks
param
is - stream
return
decoder


                                              
          
        InputStream markable;

        if (!is.markSupported()) {
            // BEGIN android-modified
            markable = new BufferedInputStream(is, 8192);
            // END android-modified
        } else {
            markable = is;
        }
            
        // Read the signature from the stream and then reset it back
        try {
            markable.mark(MAX_BYTES_IN_SIGNATURE);

            byte[] signature = new byte[MAX_BYTES_IN_SIGNATURE];
            markable.read(signature, 0, MAX_BYTES_IN_SIGNATURE);
            markable.reset();

            if ((signature[0] & 0xFF) == 0xFF &&
                    (signature[1] & 0xFF) == 0xD8 &&
                    (signature[2] & 0xFF) == 0xFF) { // JPEG
                return loadDecoder(PNG_DECODER, src, is);
            } else if ((signature[0] & 0xFF) == 0x47 && // G
                    (signature[1] & 0xFF) == 0x49 && // I
                    (signature[2] & 0xFF) == 0x46) { // F
                return loadDecoder(GIF_DECODER, src, is);
            } else if ((signature[0] & 0xFF) == 137 && // PNG signature: 137 80 78 71 13 10 26 10
                    (signature[1] & 0xFF) == 80 &&
                    (signature[2] & 0xFF) == 78 &&
                    (signature[3] & 0xFF) == 71 &&
                    (signature[4] & 0xFF) == 13 &&
                    (signature[5] & 0xFF) == 10 &&
                    (signature[6] & 0xFF) == 26 &&
                    (signature[7] & 0xFF) == 10) {
                return loadDecoder(JPG_DECODER, src, is);
            }

            return loadDecoder(GENERIC_DECODER, src, is);
            
        } catch (IOException e) { // Silently
        }

        return null;
    
public abstract voiddecodeImage()

protected voidimageComplete(int status)

        if (terminated) {
            return;
        }

        src.lockDecoder(this);

        ImageConsumer ic = null;

        for (Iterator<ImageConsumer> i = consumers.iterator(); i.hasNext();) {
            try {
                ic = i.next();
            } catch (ConcurrentModificationException e) {
                i = consumers.iterator();
                continue;
            }
            ic.imageComplete(status);
        }
    
private static org.apache.harmony.awt.gl.image.ImageDecoderloadDecoder(int type, DecodingImageSource src, java.io.InputStream is)

        return new AndroidImageDecoder(src, is);
    
protected voidsetColorModel(java.awt.image.ColorModel cm)

        if (terminated) {
            return;
        }

        for (ImageConsumer ic : consumers) {
            ic.setColorModel(cm);
        }
    
protected voidsetDimensions(int w, int h)

        if (terminated) {
            return;
        }

        for (ImageConsumer ic : consumers) {
            ic.setDimensions(w, h);
        }
    
protected voidsetHints(int hints)

        if (terminated) {
            return;
        }

        for (ImageConsumer ic : consumers) {
            ic.setHints(hints);
        }
    
protected voidsetPixels(int x, int y, int w, int h, java.awt.image.ColorModel model, byte[] pix, int off, int scansize)

        if (terminated) {
            return;
        }

        src.lockDecoder(this);

        for (ImageConsumer ic : consumers) {
            ic.setPixels(x, y, w, h, model, pix, off, scansize);
        }
    
protected voidsetPixels(int x, int y, int w, int h, java.awt.image.ColorModel model, int[] pix, int off, int scansize)

        if (terminated) {
            return;
        }

        src.lockDecoder(this);

        for (ImageConsumer ic : consumers) {
            ic.setPixels(x, y, w, h, model, pix, off, scansize);
        }
    
protected voidsetProperties(java.util.Hashtable props)

        if (terminated) {
            return;
        }

        for (ImageConsumer ic : consumers) {
            ic.setProperties(props);
        }
    
public voidterminate()
Stops the decoding by interrupting the current decoding thread. Used when all consumers are removed and there's no more need to run the decoder.

        src.lockDecoder(this);
        closeStream();

        AccessController.doPrivileged(
                new PrivilegedAction<Void>() {
                    public Void run() {
                        Thread.currentThread().interrupt();
                        return null;
                    }
                }
        );

        terminated = true;