⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pngimageproducer.java

📁 java 开源,Swing外观:JGoodies look & feel. ... JGoodies look&feels让你的Swing 应用程序与applets看起来更漂亮.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) 1997, Jason Marshall.  All Rights Reserved
//
// The author makes no representations or warranties regarding the suitability,
// reliability or stability of this code.  This code is provided AS IS.  The
// author shall not be liable for any damages suffered as a result of using,
// modifying or redistributing this software or any derivitives thereof.
// Permission to use, reproduce, modify and/or (re)distribute this software is
// hereby granted.

package com.oyoaha.swing.plaf.oyoaha;

/**
 * @(#)PNGImageProducer.java	0.88 97/4/14 Jason Marshall
 **/

import java.awt.image.*;
import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.zip.*;

// TODO:  Need an ImageFormatException or somesuch..  instead of throwing
// IOExceptions all over the place.  -JDM

/**
 * ImageProducer which produces an Image from a PNG image
 * Note that making this implement the Runnable interface it but one way to
 * handle the problems inherent with asynchronous image production.  This class
 * is provided more as a proof of concept, and sample implementation of the PNG
 * decoder in Java.
 *
 * @version	0.88 14 May 1997
 * @author 	Jason Marshall
 */

public class PNGImageProducer implements ImageProducer, Runnable {
    private int dataWidth;
    private int dataHeight;
    private int width = -1;
    private int height = -1;
    private int sigmask = 0xffff;
    private ColorModel model;
    private Object pixels;
    private int ipixels[];
    private byte bpixels[];
    private Hashtable properties;
    private Vector theConsumers;
    private boolean multipass;
    private boolean complete;
    private boolean error;
    // TODO: make private when inner class created -JDM
    InputStream underlyingStream;
    // TODO: make private when inner class created -JDM
    DataInputStream inputStream;
    private Thread controlThread;
    private boolean infoAvailable = false;
    private boolean completePasses = false;

    //TODO: set from system properties -JDM
    private int updateDelay = 750;

    // Image decoding state variables

    private boolean headerFound = false;
    private int compressionMethod = -1;
    private int depth = -1;
    private int colorType = -1;
    private int filterMethod = -1;
    private int interlaceMethod = -1;
    private int pass;
    private byte palette[];
    private boolean transparency;

    // TODO: make private when innerclass created -JDM
    int chunkLength;
    // TODO: make private when innerclass created -JDM
    int chunkType;
    // TODO: make private when innerclass created -JDM
    boolean needChunkInfo = true;

    static final int CHUNK_bKGD = 0x624B4744;   // "bKGD"
    static final int CHUNK_cHRM = 0x6348524D;   // "cHRM"
    static final int CHUNK_gAMA = 0x67414D41;   // "gAMA"
    static final int CHUNK_hIST = 0x68495354;   // "hIST"
    static final int CHUNK_IDAT = 0x49444154;   // "IDAT"
    static final int CHUNK_IEND = 0x49454E44;   // "IEND"
    static final int CHUNK_IHDR = 0x49484452;   // "IHDR"
    static final int CHUNK_PLTE = 0x504C5445;   // "PLTE"
    static final int CHUNK_pHYs = 0x70485973;   // "pHYs"
    static final int CHUNK_sBIT = 0x73424954;   // "sBIT"
    static final int CHUNK_tEXt = 0x74455874;   // "tEXt"
    static final int CHUNK_tIME = 0x74494D45;   // "tIME"
    static final int CHUNK_tRNS = 0x74524E53;   // "tIME"
    static final int CHUNK_zTXt = 0x7A545874;   // "zTXt"

    static final int startingRow[]  =  { 0, 0, 0, 4, 0, 2, 0, 1 };
    static final int startingCol[]  =  { 0, 0, 4, 0, 2, 0, 1, 0 };
    static final int rowInc[]       =  { 1, 8, 8, 8, 4, 4, 2, 2 };
    static final int colInc[]       =  { 1, 8, 8, 4, 4, 2, 2, 1 };
    static final int blockHeight[]  =  { 1, 8, 8, 4, 4, 2, 2, 1 };
    static final int blockWidth[]   =  { 1, 8, 4, 4, 2, 2, 1, 1 };

    /**
     *
     **/

    public PNGImageProducer(InputStream is) {
        theConsumers = new Vector();
        properties = new Hashtable();
        if (!(is instanceof BufferedInputStream))
            is = new BufferedInputStream(is, 1024);
        underlyingStream = is;
        inputStream = new DataInputStream(underlyingStream);
    }

    public void dispose()
    {
      try
      {
        if(underlyingStream!=null)
        {
          underlyingStream.close();
          underlyingStream = null;
        }

        if(inputStream!=null)
        {
          inputStream.close();
          inputStream = null;
        }
      }
      catch(Exception e)
      {

      }
    }

    public synchronized void addConsumer(ImageConsumer ic) {
        if (theConsumers.contains(ic)) {
            return;
        }

        theConsumers.addElement(ic);

        try {
            initConsumer(ic);
            sendPixels(ic, 0, 0, width, height);
            if ((complete) && (isConsumer(ic))) {
                if (error) {
                    ic.imageComplete(ImageConsumer.IMAGEERROR);
                } else {
                    ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
                }
                removeConsumer(ic);
            }
        } catch (Exception e) {
            if (isConsumer(ic)) {
                ic.imageComplete(ImageConsumer.IMAGEERROR);
            }
        }
    }

    private void blockFill(int rowStart) {
        int counter;
        int dw = dataWidth;
        int pass = this.pass;
        int w = blockWidth[pass];
        int sCol = startingCol[pass];
        int cInc = colInc[pass];
        int wInc = cInc - w;
        int maxW = rowStart + dw - w;
        int len;

        int h = blockHeight[pass];
        int maxH = rowStart + (dw * h);
        int startPos = rowStart + sCol;

        counter = startPos;

        if (colorType == 3) {
            byte bpix[] = bpixels;
            byte pixel;
            len = bpix.length;

            for (; counter <= maxW;) {
                int end = counter + w;
                pixel = bpix[counter++];
                for (; counter < end; counter++) {
                    bpix[counter] = pixel;
                }
                counter += wInc;
            }
            maxW += w;

            if (counter < maxW) {
                for (pixel = bpix[counter++]; counter < maxW; counter++) {
                    bpix[counter] = pixel;
                }
            }

            if (len < maxH)
                maxH = len;

            for (counter = startPos + dw; counter < maxH; counter += dw) {
                System.arraycopy(bpix, startPos, bpix, counter, dw - sCol);
            }
        } else {
            int ipix[] = ipixels;
            int pixel;
            len = ipix.length;

            for (; counter <= maxW;) {
                int end = counter + w;
                pixel = ipix[counter++];
                for (; counter < end; counter++) {
                    ipix[counter] = pixel;
                }
                counter += wInc;
            }

            maxW += w;

            if (counter < maxW) {
                for (pixel = ipix[counter++]; counter < maxW; counter++) {
                    ipix[counter] = pixel;
                }
            }

            if (len < maxH)
                maxH = len;

            for (counter = startPos + dw; counter < maxH; counter += dw) {
                System.arraycopy(ipix, startPos, ipix, counter, dw - sCol);
            }
        }
    }

    private boolean filterRow(byte inbuf[], int pix[], int upix[], int rowFilter, int boff) 
    {
        int rowWidth = pix.length;

        switch (rowFilter) 
        {
          case 0:
            for (int x = 0; x < rowWidth; x++) 
            {
                pix[x] = 0xff & inbuf[x];
            }
            break;
          case 1: 
          {
            int x = 0;
            for ( ; x < boff; x++) 
            {
                pix[x] = 0xff & inbuf[x];
            }
            for ( ; x < rowWidth; x++) 
            {
                pix[x] = 0xff & (inbuf[x] + pix[x - boff]);
            }
            break;
          }
          case 2: 
          {
            if (upix != null)
            {
                for (int x = 0; x < rowWidth; x++) 
                {
                    pix[x] = 0xff & (upix[x] + inbuf[x]);
                }
            } 
            else 
            {
                for (int x = 0; x < rowWidth; x++) 
                {
                    pix[x] = 0xff & inbuf[x];
                }
            }
            break;
          }
          case 3: 
          {
            if (upix != null) 
            {
                int x = 0;
                for ( ; x < boff; x++) 
                {
                    int rval = upix[x];
                    pix[x] = 0xff & ((rval>>1) + inbuf[x]);
                }
                for ( ; x < rowWidth; x++) 
                {
                    int rval = upix[x] + pix[x - boff];
                    pix[x] = 0xff & ((rval>>1) + inbuf[x]);
                }
            } 
            else 
            {
                int x = 0;
                for ( ; x < boff; x++) 
                {
                    pix[x] = 0xff & inbuf[x];
                }
                for ( ; x < rowWidth; x++) 
                {
                    int rval = pix[x - boff];
                    pix[x] = 0xff & ((rval>>1) + inbuf[x]);
                }
            }
            break;
          }
          case 4: {
            if (upix != null) 
            {
                int x = 0;
                for ( ; x < boff; x++) 
                {
                    pix[x] = 0xff & (upix[x] + inbuf[x]);
                }
                for ( ; x < rowWidth; x++) {
                    int a, b, c, p, pa, pb, pc, rval;
                    a = pix[x - boff];
                    b = upix[x];
                    c = upix[x - boff];
                    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;
                    if ((pa <= pb) && (pa <= pc)) 
                    {
                        rval = a;
                    } 
                    else 
                    if (pb <= pc) 
                    {
                        rval = b;
                    } 
                    else 
                    {
                        rval = c;
                    }
                    pix[x] = 0xff & (rval + inbuf[x]);
                }
            } else {
                int x = 0;
                for ( ; x < boff; x++) {
                    pix[x] = 0xff & inbuf[x];
                }
                for ( ; x < rowWidth; x++) {
                    int rval = pix[x - boff];
                    pix[x] = 0xff & (rval + inbuf[x]);
                }
            }
            break;
          }
          default:
            return false;
        }
        return true;
    }

    private void handlebKGD() throws IOException {
        inputStream.skip(chunkLength);
    }

    private void handlecHRM() throws IOException {
        inputStream.skip(chunkLength);
    }

    private void handleChunk() throws IOException {
        if (needChunkInfo) {
            chunkLength = inputStream.readInt();
            chunkType = inputStream.readInt();
            needChunkInfo = false;
        }

        // Guarantee that chunks can't overread their bounds
        /*inputStream = new DataInputStream(
                        new MeteredInputStream(underlyingStream,
                                                chunkLength));

⌨️ 快捷键说明

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