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 + -
显示快捷键?