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

📄 pngimageproducer.java

📁 java 开源,Swing外观:JGoodies look & feel. ... JGoodies look&feels让你的Swing 应用程序与applets看起来更漂亮.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    private void insertPixels(int pix[], int offset, int samples) {
        switch (colorType) {
          case 0:
          case 4: {
            insertGreyPixels(pix, offset, samples);
            break;
          }
          case 2: {
            int j = 0;
            int ipix[] = ipixels;
            int cInc = colInc[pass];
            if (depth == 8) {
                for (j = 0; j < samples; offset += cInc) {
                    ipix[offset] = (pix[j++]<<16) | (pix[j++]<<8) | pix[j++];
                }
            } else {
                samples = samples<<1;
                for (j = 0; j < samples; j += 2, offset += cInc) {
                    ipix[offset] = (pix[j]<<16) | (pix[j+=2]<<8) | pix[j+=2];
                }
            }
            break;
          }
          case 3: {
            insertPalettedPixels(pix, offset, samples);
            break;
          }
          case 6: {
            int j = 0;
            int ipix[] = ipixels;
            int cInc = colInc[pass];
            if (depth == 8) {
                for (j = 0; j < samples; offset += cInc) {
                    ipix[offset] = (pix[j++]<<16) | (pix[j++]<<8) | pix[j++] |
                                    (pix[j++]<<24);
                }
            } else {
                samples = samples<<1;
                for (j = 0; j < samples; j += 2, offset += cInc) {
                    ipix[offset] = (pix[j]<<16) | (pix[j+=2]<<8) | pix[j+=2] |
                                    (pix[j+=2]<<24);
                }
            }
            break;
          }
          default:
            break;
        }
    }

    /**
     * This method determines if a given ImageConsumer object
     * is currently registered with this ImageProducer as one
     * of its consumers.
     * @see ImageConsumer
     */

    public synchronized boolean isConsumer(ImageConsumer ic) {
        return theConsumers.contains(ic);
    }

    /**
     * Read Image data in off of a compression stream
     **/

    private void readImageData() throws IOException {
        long time = System.currentTimeMillis();

        InputStream dataStream = new SequenceInputStream(
                                        new IDATEnumeration(this));

        DataInputStream dis = new DataInputStream(
                                new BufferedInputStream(
                                    new InflaterInputStream(dataStream,
                                                            new Inflater())));

        int bps, filterOffset;

        switch (colorType) {
          case 0:
          case 3:
            bps = depth;
            break;
          case 2:
            bps = 3 * depth;
            break;
          case 4:
            bps = depth<<1;
            break;
          case 6:
            bps = depth<<2;
            break;
          default:
            // should never happen
            throw new IOException("Unknown color type encountered.");
        }

        filterOffset = (bps + 7)>>3;

        for (pass = (multipass ? 1 : 0); pass < 8; pass++) {
            int pass = this.pass;
            int rInc = rowInc[pass];
            int cInc = colInc[pass];
            int sCol = startingCol[pass];

            int val = ((dataWidth - sCol + cInc - 1) / cInc);

            int samples = val * filterOffset;
            int rowSize = (val * bps)>>3;

            int sRow = startingRow[pass];

            if ((dataHeight <= sRow) || (rowSize == 0))
                continue;

            int sInc = rInc * dataWidth;

            byte inbuf[] = new byte[rowSize];
            int pix[] = new int[rowSize];
            int upix[] = null;
            int temp[] = new int[rowSize];

            // next Y value and number of rows to report to sendPixels
            int nextY = sRow;
            int rows = 0;
            int rowStart = sRow * dataWidth;

            for (int y = sRow; y < dataHeight; y += rInc, rowStart += sInc) {
                rows += rInc;

                int rowFilter = dis.read();
                dis.readFully(inbuf);

                if (!filterRow(inbuf, pix, upix, rowFilter, filterOffset)) {
                    throw new IOException("Unknown filter type: " + rowFilter);
                }

                insertPixels(pix, rowStart + sCol, samples);

                if (multipass && (pass < 6)) {
                    blockFill(rowStart);
                }

                upix = pix;
                pix = temp;
                temp = upix;

                if (!completePasses) {
                    long newTime = System.currentTimeMillis();
                    if ((newTime - time) > updateDelay) {
                        sendPixels(0, nextY, width, rows);
                        rows = 0;
                        nextY = y + rInc;
                        time = newTime;
                    }
                }
                Thread.yield();
            }
            if (!multipass)
                break;
            if (completePasses || (rows > 0)) {
                sendPixels(0, 0, width, height);
                time = System.currentTimeMillis();
            }
        }
        while(dis.read() != -1)
            System.err.println("Leftover data encountered.");
    }

    /**
    * Remove an ImageConsumer from the list of consumers interested in
    * data for this image.
    * @see ImageConsumer
    */

    public synchronized void removeConsumer(ImageConsumer ic) {
        theConsumers.removeElement(ic);
    }

    /**
    * Requests that a given ImageConsumer have the image data delivered
    * one more time in top-down, left-right order.
    * @see ImageConsumer
    */

    public void requestTopDownLeftRightResend(ImageConsumer ic) {
        // Ignored.  The data is either single frame and already in TDLR
        // format or it is multi-frame and TDLR resends aren't critical.
    }

    /**
     * Primary processing of Image data.
     **/

    public void run() {
        try {
            // Verify signature
            handleSignature();
            while (!complete && !error) {
                handleChunk();
            }
        } catch (Exception e) {
            System.err.println("PNGImageProducer: " + e);
            e.printStackTrace(System.err);
            error = true;
        }
        synchronized (this) {
            for (int c = 0; c < theConsumers.size(); c++) {
                ImageConsumer ic = (ImageConsumer) theConsumers.elementAt(c);
                if (error) {
                    ic.imageComplete(ImageConsumer.IMAGEERROR);
                } else {
                    ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
                }
            }
        }
    }

    private synchronized void sendPixels(int x, int y, int w, int h) {
        int off = dataWidth * y + x;
        Enumeration enum = theConsumers.elements();
        while (enum.hasMoreElements()) {
            ImageConsumer ic = (ImageConsumer) enum.nextElement();
            if ((pixels != null) && (isConsumer(ic))) {
                if (pixels instanceof byte[]) {
                    ic.setPixels(x, y, w, h, model, bpixels, off, dataWidth);
                } else {
                    ic.setPixels(x, y, w, h, model, ipixels, off, dataWidth);
                }
            }
        }
    }

    private void sendPixels(ImageConsumer ic, int x, int y, int w, int h) {
        int off = dataWidth * y + x;
        if ((pixels != null) && (isConsumer(ic))) {
            if (pixels instanceof byte[]) {
                ic.setPixels(x, y, w, h, model, bpixels, off, dataWidth);
            } else {
                ic.setPixels(x, y, w, h, model, ipixels, off, dataWidth);
            }
        }
    }

    private void setColorModel() throws IOException {
        int mask = 0;
        switch (depth) {
          case 1:
            mask = 0x1;
            break;
          case 2:
            mask = 0x3;
            break;
          case 4:
            mask = 0xf;
            break;
          case 8:
          case 16:
            mask = 0xff;
            break;
        }

        int count = width * height;

        switch (colorType) {
          case 3:
            if (palette == null)
                throw new IOException("No palette located");
            bpixels = new byte[count];
            pixels = bpixels;
            if (transparency) {
                model = new IndexColorModel(depth, palette.length/4, palette,
                                            0, true);
            } else {
                model = new IndexColorModel(depth, palette.length/3, palette,
                                            0, false);
            }
            break;
          case 0:
            ipixels = new int[count];
            pixels = ipixels;
            if (depth < 8) {
                model = new DirectColorModel(depth, mask, mask, mask);
            } else {
                model = new DirectColorModel(8, mask, mask, mask);
            }
            break;
          case 2:
            ipixels = new int[count];
            pixels = ipixels;
            model = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
            break;
          case 4:
            int smask;
            if (depth < 8) {
                smask = mask << depth;
                model = new DirectColorModel(depth * 2, smask, smask, smask,
                                                mask);
            } else {
                smask = mask << 8;
                model = new DirectColorModel(16, smask, smask, smask, mask);
            }
            ipixels = new int[count];
            pixels = ipixels;
            break;
          case 6:
            ipixels = new int[count];
            pixels = ipixels;
            model = ColorModel.getRGBdefault();
            break;
          default:
            throw new IOException("Image has unknown color type");
        }
    }

    private void start() {
        if (controlThread == null) {
            synchronized (this) {
                controlThread = new Thread(this);
                try {
                    controlThread.setPriority(Thread.NORM_PRIORITY - 2);
                } catch (Exception e) {}
                controlThread.start();
            }
        }
    }

    /**
    * Adds an ImageConsumer to the list of consumers interested in
    * data for this image, and immediately start delivery of the
    * image data through the ImageConsumer interface.
    * @see ImageConsumer
    */

    public void startProduction(ImageConsumer ic) {
        addConsumer(ic);
        start();
    }
}


/**
 * Support class, used to eat the IDAT headers dividing up the deflated stream
 **/

class IDATEnumeration implements Enumeration {
    InputStream underlyingStream;
    PNGImageProducer owner;
    boolean firstStream = true;

    public IDATEnumeration(PNGImageProducer owner) {
        this.owner = owner;
        this.underlyingStream = owner.underlyingStream;
    }

    public Object nextElement() {
        firstStream = false;
        return new MeteredInputStream(underlyingStream, owner.chunkLength);
    }

    public boolean hasMoreElements() {
        DataInputStream dis = new DataInputStream(underlyingStream);
        if (!firstStream) {
            try {
                int crc = dis.readInt();
                owner.needChunkInfo = false;
                owner.chunkLength = dis.readInt();
                owner.chunkType = dis.readInt();
            } catch (IOException ioe) {
                return false;
            }
        }
        if (owner.chunkType == PNGImageProducer.CHUNK_IDAT) {
            return true;
        }
        return false;
    }
}

⌨️ 快捷键说明

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