pngimagedecoder.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 911 行 · 第 1/3 页

JAVA
911
字号
        switch (rowFilter) {        case 0:            break;        case 1:            for (x = bytesPerSample; x < rowByteWidth; x++)                rowByteBuffer[x] += rowByteBuffer[x - bytesPerSample];            break;        case 2:            if (prevRow != null)                for (; x < rowByteWidth; x++)                     rowByteBuffer[x] += prevRow[x];            break;        case 3:            if (prevRow != null) {                for (; x < bytesPerSample; x++)                    rowByteBuffer[x] += (0xff & prevRow[x]) >> 1;                for (; x < rowByteWidth; x++)                    rowByteBuffer[x] += ((prevRow[x] & 0xFF) + (rowByteBuffer[x - bytesPerSample] & 0xFF)) >> 1;            } else                for (x = bytesPerSample; x < rowByteWidth; x++)                    rowByteBuffer[x] += (rowByteBuffer[x - bytesPerSample] & 0xFF) >> 1;            break;        case 4:            if (prevRow != null) {                for (; x < bytesPerSample; x++)                    rowByteBuffer[x] += prevRow[x];                for (; x < rowByteWidth; x++) {                    int a, b, c, p, pa, pb, pc;                    a = rowByteBuffer[x - bytesPerSample] & 0xFF;                    b = prevRow[x] & 0xFF;                    c = prevRow[x - bytesPerSample] & 0xFF;                    p = a + b - c;                    pa = p > a ? p - a : a - p;                    pb = p > b ? p - b : b - p;                    pc = p > c ? p - c : c - p;                    rowByteBuffer[x] += (pa <= pb) && (pa <= pc) ? a : pb <= pc ? b : c;                }            } else                for (x = bytesPerSample; x < rowByteWidth; x++)                    rowByteBuffer[x] += rowByteBuffer[x - bytesPerSample];            break;        default:            throw new PNGException("Illegal filter");        }    }    private static final byte[] startingRow =  { 0, 0, 0, 4, 0, 2, 0, 1 };    private static final byte[] startingCol =  { 0, 0, 4, 0, 2, 0, 1, 0 };    private static final byte[] rowIncrement = { 1, 8, 8, 8, 4, 4, 2, 2 };    private static final byte[] colIncrement = { 1, 8, 8, 4, 4, 2, 2, 1 };    private static final byte[] blockHeight =  { 1, 8, 8, 4, 4, 2, 2, 1 };    private static final byte[] blockWidth =   { 1, 8, 4, 4, 2, 2, 1, 1 };        //abstract public class ChunkReader extends FilterInputStream {    int pos, limit;    int chunkStart;    int chunkKey, chunkLength, chunkCRC;    boolean seenEOF;        private static final byte[] signature = { (byte) 137, (byte) 80, (byte) 78,        (byte) 71, (byte) 13, (byte) 10, (byte) 26, (byte) 10 };    PNGFilterInputStream inputStream;    InputStream underlyingInputStream;    /* code changed     public PNGImageDecoder(InputStream in, ImageConsumer t) throws IOException {     */    public PNGImageDecoder(InputStreamImageSource src, InputStream input) throws IOException {        // code added        super(src, input);        inputStream = new PNGFilterInputStream(this, input);        underlyingInputStream = inputStream.underlyingInputStream;        // end of adding        /* code changed         super(in);         target = t;         waitTurn();         new Thread(this).start();         */    }    /* code changed to make it work with ImageDecoder architecture     static int ThreadLimit = 10;     private synchronized static void waitTurn() {     try {     while(ThreadLimit<=0) PNGImageDecoder.class.wait(1000);     } catch(InterruptedException e){}     ThreadLimit--;     }     private synchronized static void endTurn() {     if(ThreadLimit<=0) PNGImageDecoder.class.notify();     ThreadLimit++;     }     */    byte[] inbuf = new byte[4096];    private void fill() throws IOException {        if (!seenEOF) {            if (pos > 0 && pos < limit) {                System.arraycopy(inbuf, pos, inbuf, 0, limit - pos);                limit = limit - pos;                pos = 0;            } else if (pos >= limit) {                pos = 0;                limit = 0;            }            int bsize = inbuf.length;            while (limit < bsize) {                int n = underlyingInputStream.read(inbuf, limit, bsize - limit);                if (n <= 0) {                    seenEOF = true;                    break;                }                limit += n;            }        }    }    private boolean need(int n) throws IOException {        if (limit - pos >= n) return true;        fill();        if (limit - pos >= n) return true;        if (seenEOF) return false;        byte nin[] = new byte[n + 100];        System.arraycopy(inbuf, pos, nin, 0, limit - pos);        limit = limit - pos;        pos = 0;        inbuf = nin;        fill();        return limit - pos >= n;    }    private final int getInt(int pos) {        return ((inbuf[pos  ] & 0xFF) << 24)            | ((inbuf[pos + 1] & 0xFF) << 16)            | ((inbuf[pos + 2] & 0xFF) << 8)            | ((inbuf[pos + 3] & 0xFF));    }    private final int getShort(int pos) {        return (short) (((inbuf[pos  ] & 0xFF) << 8)                | ((inbuf[pos + 1] & 0xFF)));    }    private final int getByte(int pos) {        return inbuf[pos] & 0xFF;    }    private final boolean getChunk() throws IOException {        chunkLength = 0;        if (!need(8)) return false;        chunkLength = getInt(pos);        chunkKey = getInt(pos+4);        if(chunkLength<0) throw new PNGException("bogus length: "+chunkLength);        if (!need(chunkLength+12)) return false;        chunkCRC = getInt(pos+8+chunkLength);        chunkStart = pos+8;        int calcCRC = crc(inbuf,pos+4,chunkLength+4);        if(chunkCRC!=calcCRC && checkCRC) throw new PNGException("crc corruption");        pos+=chunkLength+12;        return true;    }    private void readAll() throws IOException {        while (getChunk()) handleChunk(chunkKey, inbuf, chunkStart, chunkLength);    }    boolean getData() throws IOException {        while (chunkLength == 0 && getChunk())            if (handleChunk(chunkKey, inbuf, chunkStart, chunkLength))                chunkLength = 0;        return chunkLength > 0;    }    //abstract protected boolean handleChunk(int key, byte[] buf, int st, int len)    //    throws IOException;    private static boolean checkCRC = true;    public static boolean getCheckCRC() {        return checkCRC;    }    public static void setCheckCRC(boolean c) {        checkCRC = c;    }    protected void wrc(int c) {        c = c & 0xFF;        if (c <= ' ' || c > 'z') c = '?';        System.out.write(c);    }    protected void wrk(int n) {        wrc(n >> 24);        wrc(n >> 16);        wrc(n >> 8);        wrc(n);    }    public void print() {        wrk(chunkKey);        System.out.print(" " + chunkLength + "\n");    }    /* Table of CRCs of all 8-bit messages. */    private static final int[] crc_table = new int[256];    /* Make the table for a fast CRC. */    static {        for (int n = 0; n < 256; n++) {            int c = n;            for (int k = 0; k < 8; k++)                if ((c & 1) != 0)                    c = 0xedb88320 ^ (c >>> 1);                else                    c = c >>> 1;            crc_table[n] = c;        }    }    /* Update a running CRC with the bytes buf[0..len-1]--the CRC     should be initialized to all 1's, and the transmitted value     is the 1's complement of the final running CRC (see the     crc() routine below)). */    static private int update_crc(int crc, byte[] buf, int offset, int len) {        int c = crc;        while (--len >= 0)            c = crc_table[(c ^ buf[offset++]) & 0xff] ^ (c >>> 8);        return c;    }    /* Return the CRC of the bytes buf[0..len-1]. */    static private int crc(byte[] buf, int offset, int len) {        return update_crc(0xffffffff, buf, offset, len) ^ 0xffffffff;    }    public static class Chromaticities {        public float whiteX, whiteY, redX, redY, greenX, greenY, blueX, blueY;        Chromaticities(int wx, int wy, int rx, int ry, int gx, int gy, int bx, int by) {            whiteX = wx / 100000.0f;            whiteY = wy / 100000.0f;            redX = rx / 100000.0f;            redY = ry / 100000.0f;            greenX = gx / 100000.0f;            greenY = gy / 100000.0f;            blueX = bx / 100000.0f;            blueY = by / 100000.0f;        }        public String toString() {            return "Chromaticities(white=" + whiteX + "," + whiteY + ";red=" +                redX + "," + redY + ";green=" +                greenX + "," + greenY + ";blue=" +                blueX + "," + blueY + ")";        }    }}// the following class are added to make it work with ImageDecoder architectureclass PNGFilterInputStream extends FilterInputStream {    PNGImageDecoder owner;    public InputStream underlyingInputStream;    public PNGFilterInputStream(PNGImageDecoder owner, InputStream is) {        super(is);        underlyingInputStream = in;        this.owner = owner;    }      public int available() throws IOException {        return owner.limit - owner.pos + in.available();    }    public boolean markSupported() {        return false;    }    public int read() throws IOException {        if (owner.chunkLength <= 0) if (!owner.getData()) return -1;        owner.chunkLength--;        return owner.inbuf[owner.chunkStart++] & 0xFF;    }    public int read(byte[] b) throws IOException {        return read(b, 0, b.length);    }    public int read(byte[] b, int st, int len) throws IOException {        if (owner.chunkLength <= 0) if (!owner.getData()) return -1;        if (owner.chunkLength < len) len = owner.chunkLength;        System.arraycopy(owner.inbuf, owner.chunkStart, b, st, len);        owner.chunkLength -= len;        owner.chunkStart += len;        return len;    }    public long skip(long n) throws IOException {        int i;        for (i = 0; i < n && read() >= 0; i++);        return i;    } }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?