📄 pngimage.java
字号:
void decodePass( int xOffset, int yOffset, int xStep, int yStep, int passWidth, int passHeight) { if ((passWidth == 0) || (passHeight == 0)) { return; } int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8; byte[] curr = new byte[bytesPerRow]; byte[] prior = new byte[bytesPerRow]; // Decode the (sub)image row-by-row int srcY, dstY; for (srcY = 0, dstY = yOffset; srcY < passHeight; srcY++, dstY += yStep) { // Read the filter type byte and a row of data int filter = 0; try { filter = dataStream.read(); dataStream.readFully(curr, 0, bytesPerRow); } catch (Exception e) { // empty on purpose } switch (filter) { case PNG_FILTER_NONE: break; case PNG_FILTER_SUB: decodeSubFilter(curr, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_UP: decodeUpFilter(curr, prior, bytesPerRow); break; case PNG_FILTER_AVERAGE: decodeAverageFilter(curr, prior, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_PAETH: decodePaethFilter(curr, prior, bytesPerRow, bytesPerPixel); break; default: // Error -- uknown filter type throw new RuntimeException("PNG filter unknown."); } processPixels(curr, xOffset, xStep, dstY, passWidth); // Swap curr and prior byte[] tmp = prior; prior = curr; curr = tmp; } } void processPixels(byte curr[], int xOffset, int step, int y, int width) { int srcX, dstX; int out[] = getPixel(curr); int sizes = 0; switch (colorType) { case 0: case 3: case 4: sizes = 1; break; case 2: case 6: sizes = 3; break; } if (image != null) { dstX = xOffset; int yStride = (sizes*this.width*(bitDepth == 16 ? 8 : bitDepth)+ 7)/8; for (srcX = 0; srcX < width; srcX++) { setPixel(image, out, inputBands * srcX, sizes, dstX, y, bitDepth, yStride); dstX += step; } } if (palShades) { if ((colorType & 4) != 0) { if (bitDepth == 16) { for (int k = 0; k < width; ++k) out[k * inputBands + sizes] >>>= 8; } int yStride = this.width; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { setPixel(smask, out, inputBands * srcX + sizes, 1, dstX, y, 8, yStride); dstX += step; } } else { //colorType 3 int yStride = this.width; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int idx = out[srcX]; if (idx < trans.length) v[0] = trans[idx]; setPixel(smask, v, 0, 1, dstX, y, 8, yStride); dstX += step; } } } else if (genBWMask) { switch (colorType) { case 3: { int yStride = (this.width + 7) / 8; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int idx = out[srcX]; if (idx < trans.length) v[0] = (trans[idx] == 0 ? 1 : 0); setPixel(smask, v, 0, 1, dstX, y, 1, yStride); dstX += step; } break; } case 0: { int yStride = (this.width + 7) / 8; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int g = out[srcX]; v[0] = (g == transRedGray ? 1 : 0); setPixel(smask, v, 0, 1, dstX, y, 1, yStride); dstX += step; } break; } case 2: { int yStride = (this.width + 7) / 8; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int markRed = inputBands * srcX; v[0] = (out[markRed] == transRedGray && out[markRed + 1] == transGreen && out[markRed + 2] == transBlue ? 1 : 0); setPixel(smask, v, 0, 1, dstX, y, 1, yStride); dstX += step; } break; } } } } static int getPixel(byte image[], int x, int y, int bitDepth, int bytesPerRow) { if (bitDepth == 8) { int pos = bytesPerRow * y + x; return image[pos] & 0xff; } else { int pos = bytesPerRow * y + x / (8 / bitDepth); int v = image[pos] >> (8 - bitDepth * (x % (8 / bitDepth))- bitDepth); return v & ((1 << bitDepth) - 1); } } static void setPixel(byte image[], int data[], int offset, int size, int x, int y, int bitDepth, int bytesPerRow) { if (bitDepth == 8) { int pos = bytesPerRow * y + size * x; for (int k = 0; k < size; ++k) image[pos + k] = (byte)data[k + offset]; } else if (bitDepth == 16) { int pos = bytesPerRow * y + size * x; for (int k = 0; k < size; ++k) image[pos + k] = (byte)(data[k + offset] >>> 8); } else { int pos = bytesPerRow * y + x / (8 / bitDepth); int v = data[offset] << (8 - bitDepth * (x % (8 / bitDepth))- bitDepth); image[pos] |= v; } } int[] getPixel(byte curr[]) { switch (bitDepth) { case 8: { int out[] = new int[curr.length]; for (int k = 0; k < out.length; ++k) out[k] = curr[k] & 0xff; return out; } case 16: { int out[] = new int[curr.length / 2]; for (int k = 0; k < out.length; ++k) out[k] = ((curr[k * 2] & 0xff) << 8) + (curr[k * 2 + 1] & 0xff); return out; } default: { int out[] = new int[curr.length * 8 / bitDepth]; int idx = 0; int passes = 8 / bitDepth; int mask = (1 << bitDepth) - 1; for (int k = 0; k < curr.length; ++k) { for (int j = passes - 1; j >= 0; --j) { out[idx++] = (curr[k] >>> (bitDepth * j)) & mask; } } return out; } } } private static void decodeSubFilter(byte[] curr, int count, int bpp) { for (int i = bpp; i < count; i++) { int val; val = curr[i] & 0xff; val += curr[i - bpp] & 0xff; curr[i] = (byte)val; } } private static void decodeUpFilter(byte[] curr, byte[] prev, int count) { for (int i = 0; i < count; i++) { int raw = curr[i] & 0xff; int prior = prev[i] & 0xff; curr[i] = (byte)(raw + prior); } } private static void decodeAverageFilter(byte[] curr, byte[] prev, int count, int bpp) { int raw, priorPixel, priorRow; for (int i = 0; i < bpp; i++) { raw = curr[i] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow/2); } for (int i = bpp; i < count; i++) { raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + (priorPixel + priorRow)/2); } } private static int paethPredictor(int a, int b, int c) { int p = a + b - c; int pa = Math.abs(p - a); int pb = Math.abs(p - b); int pc = Math.abs(p - c); if ((pa <= pb) && (pa <= pc)) { return a; } else if (pb <= pc) { return b; } else { return c; } } private static void decodePaethFilter(byte[] curr, byte[] prev, int count, int bpp) { int raw, priorPixel, priorRow, priorRowPixel; for (int i = 0; i < bpp; i++) { raw = curr[i] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow); } for (int i = bpp; i < count; i++) { raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; priorRow = prev[i] & 0xff; priorRowPixel = prev[i - bpp] & 0xff; curr[i] = (byte)(raw + paethPredictor(priorPixel, priorRow, priorRowPixel)); } } static class NewByteArrayOutputStream extends ByteArrayOutputStream { public byte[] getBuf() { return buf; } }/** * Gets an <CODE>int</CODE> from an <CODE>InputStream</CODE>. * * @param is an <CODE>InputStream</CODE> * @return the value of an <CODE>int</CODE> */ public static final int getInt(InputStream is) throws IOException { return (is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read(); } /** * Gets a <CODE>word</CODE> from an <CODE>InputStream</CODE>. * * @param is an <CODE>InputStream</CODE> * @return the value of an <CODE>int</CODE> */ public static final int getWord(InputStream is) throws IOException { return (is.read() << 8) + is.read(); } /** * Gets a <CODE>String</CODE> from an <CODE>InputStream</CODE>. * * @param is an <CODE>InputStream</CODE> * @return the value of an <CODE>int</CODE> */ public static final String getString(InputStream is) throws IOException { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 4; i++) { buf.append((char)is.read()); } return buf.toString(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -