pngimagedecoder.java

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

JAVA
911
字号
/* * @(#)PNGImageDecoder.java	1.17 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  * */package sun.awt.image;import java.io.*;import java.util.*;import java.util.zip.*;import java.awt.image.*;import java.awt.Color;/** PNG - Portable Network Graphics - image file reader.    See <a href=ftp://ds.internic.net/rfc/rfc2083.txt>RFC2083</a> for details. *//* this is changedpublic class PNGImageDecoder extends FilterInputStream implements Runnable{ */public class PNGImageDecoder extends ImageDecoder{    private static final int GRAY=0;    private static final int PALETTE=1;    private static final int COLOR=2;    private static final int ALPHA=4;    private static final int bKGDChunk = 0x624B4744;    private static final int cHRMChunk = 0x6348524D;    private static final int gAMAChunk = 0x67414D41;    private static final int hISTChunk = 0x68495354;    private static final int IDATChunk = 0x49444154;    private static final int IENDChunk = 0x49454E44;    private static final int IHDRChunk = 0x49484452;    private static final int PLTEChunk = 0x504C5445;    private static final int pHYsChunk = 0x70485973;    private static final int sBITChunk = 0x73424954;    private static final int tEXtChunk = 0x74455874;    private static final int tIMEChunk = 0x74494D45;    private static final int tRNSChunk = 0x74524E53;    private static final int zTXtChunk = 0x7A545874;    private int width;    private int height;    private int bitDepth;    private int colorType;    private int compressionMethod;    private int filterMethod;    private int interlaceMethod;    private int gamma = 100000;    // 4679080 - create instance of properties as in JPEG and GIF image architecture.    private Hashtable properties = new Hashtable();    /* this is not needed     ImageConsumer target;     */    private ColorModel cm;    private byte[] red_map, green_map, blue_map, alpha_map;    private int transparentPixel = -1;    private static ColorModel greyModels[] = new ColorModel[4];    /* this is not needed     PNGImageDecoder next;     */    private void property(String key, Object value) {        if (value == null) return;        properties.put(key, value);    }    private void property(String key, float value) {        property(key, new Float(value));    }    private final void verify(boolean b) throws IOException {        if (!b) {            PNGException e = new PNGException("Broken file");            e.printStackTrace();            throw e;        }    }    protected boolean handleChunk(int key, byte[] buf, int st, int len)        throws IOException {        switch (key) {        case bKGDChunk:            Color c = null;            switch (colorType) {            case COLOR:            case COLOR | ALPHA:                verify(len == 6);                c = new Color(buf[st] & 0xff, buf[st + 2] & 0xff, buf[st + 4] & 0xff);                break;            case COLOR | PALETTE:            case COLOR | PALETTE | ALPHA:                verify(len == 1);                int ix = buf[st] & 0xFF;                verify(red_map != null && ix < red_map.length);                c = new Color(red_map[ix] & 0xff, green_map[ix] & 0xff, blue_map[ix] & 0xff);                break;            case GRAY:            case GRAY | ALPHA:                verify(len == 2);                int t = buf[st] & 0xFF;                c = new Color(t, t, t);                break;            }            if (c != null) property("background", c);            break;        case cHRMChunk:            property("chromaticities",                new Chromaticities(                    getInt(st),                    getInt(st + 4),                    getInt(st + 8),                    getInt(st + 12),                    getInt(st + 16),                    getInt(st + 20),                    getInt(st + 24),                    getInt(st + 28)));            break;        case gAMAChunk:            if (len != 4) throw new PNGException("bogus gAMA");            gamma = getInt(st);            if (gamma != 100000) property("gamma", gamma / 100000.0f);            break;        case hISTChunk:            break;        case IDATChunk:            return false;        case IENDChunk:            break;        case IHDRChunk:            if (len != 13                || (width = getInt(st)) == 0                || (height = getInt(st + 4)) == 0            ) throw new PNGException("bogus IHDR");            bitDepth = getByte(st + 8);            colorType = getByte(st + 9);            compressionMethod = getByte(st + 10);            filterMethod = getByte(st + 11);            interlaceMethod = getByte(st + 12);            /* this is not needed             if(target!=null) target.setDimensions(width,height);             */            break;        case PLTEChunk: {                int tsize = len / 3;                red_map = new byte[tsize];                green_map = new byte[tsize];                blue_map = new byte[tsize];                for (int i = 0, j = st; i < tsize; i++, j += 3) {                    red_map[i] = buf[j];                    green_map[i] = buf[j + 1];                    blue_map[i] = buf[j + 2];                }            }            break;        case pHYsChunk:            break;        case sBITChunk:            break;        case tEXtChunk:            int klen = 0;            while (klen < len && buf[st + klen] != 0) klen++;            if (klen < len) {                String tkey = new String(buf, st, klen);                String tvalue = new String(buf, st + klen + 1, len - klen - 1);                property(tkey, tvalue);            }            break;        case tIMEChunk:            property("modtime", new GregorianCalendar(                    getShort(st + 0),                    getByte(st + 2) - 1,                    getByte(st + 3),                    getByte(st + 4),                    getByte(st + 5),                    getByte(st + 6)).getTime());            break;        case tRNSChunk:            switch (colorType) {            case PALETTE | COLOR:            case PALETTE | COLOR | ALPHA:                int alen = len;                if (red_map != null) alen = red_map.length;                alpha_map = new byte[alen];                System.arraycopy(buf, st, alpha_map, 0, len < alen ? len : alen);                while (--alen >= len) alpha_map[alen] = (byte) 0xFF;                break;            case COLOR: // doesn't deal with 16 bit colors properly            case COLOR | ALPHA: // doesn't deal with 16 bit colors properly                verify(len == 6);                transparentPixel =                        ((buf[st + 0] & 0xFF) << 16)                        | ((buf[st + 2] & 0xFF) << 8)                        | ((buf[st + 4] & 0xFF));                break;            case GRAY:  // doesn't deal with 16 bit colors properly            case GRAY | ALPHA:  // doesn't deal with 16 bit colors properly                verify(len == 2);                int t = buf[st] & 0xFF;                transparentPixel = (t << 16) | (t << 8) | t;                break;            }            break;        case zTXtChunk:            break;        }        return true;    }    public class PNGException extends IOException {        PNGException(String s) {            super(s);        }    }    /* this is changed     public void run() {     */    public void produceImage() throws IOException, ImageFormatException {        /* this is not needed         ImageConsumer t = target;         if(t!=null) try {         */        try {            for (int i = 0; i < signature.length; i++)                if ((signature[i] & 0xFF) != underlyingInputStream.read())                    throw new PNGException("Chunk signature mismatch");            InputStream is = new BufferedInputStream(new InflaterInputStream(inputStream, new Inflater()));            getData();            byte[] bPixels = null;            int[] wPixels = null;            int pixSize = width;            int rowStride;            int logDepth = 0;            switch (bitDepth) {            case  1:                logDepth = 0;                break;            case  2:                logDepth = 1;                break;            case  4:                logDepth = 2;                break;            case  8:                logDepth = 3;                break;            case 16:                logDepth = 4;                break;            default:                throw new PNGException("invalid depth");            }            if (interlaceMethod != 0) {                pixSize *= height;                rowStride = width;            } else rowStride = 0;            int combinedType = colorType | (bitDepth << 3);            int bitMask = (1 << (bitDepth >= 8 ? 8 : bitDepth)) - 1;            //Figure out the color model            switch (colorType) {

⌨️ 快捷键说明

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