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

📄 pngimagewriter.java

📁 Mobile 应用程序使用 Java Micro Edition (Java ME) 平台
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * @(#)PNGImageWriter.java	1.37 07/09/12 * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.imageio.plugins.png;import java.awt.Rectangle;import java.awt.image.ColorModel;import java.awt.image.IndexColorModel;import java.awt.image.Raster;import java.awt.image.WritableRaster;import java.awt.image.RenderedImage;import java.awt.image.SampleModel;import java.io.ByteArrayOutputStream;import java.io.DataOutput;import java.io.IOException;import java.io.OutputStream;import java.util.Iterator;import java.util.Locale;import java.util.zip.Deflater;import java.util.zip.DeflaterOutputStream;import javax.imageio.IIOException;import javax.imageio.IIOImage;import javax.imageio.ImageTypeSpecifier;import javax.imageio.ImageWriteParam;import javax.imageio.ImageWriter;import javax.imageio.metadata.IIOMetadata;import javax.imageio.metadata.IIOMetadata;import javax.imageio.spi.ImageWriterSpi;import javax.imageio.stream.ImageOutputStream;import javax.imageio.stream.ImageOutputStreamImpl;class CRC {    private static int[] crcTable = new int[256];    private int crc = 0xffffffff;    static {        // Initialize CRC table        for (int n = 0; n < 256; n++) {            int c = n;            for (int k = 0; k < 8; k++) {                if ((c & 1) == 1) {                    c = 0xedb88320 ^ (c >>> 1);                } else {                    c >>>= 1;                }                crcTable[n] = c;            }        }    }    public CRC() {}    public void reset() {        crc = 0xffffffff;    }    public void update(byte[] data, int off, int len) {        for (int n = 0; n < len; n++) {            crc = crcTable[(crc ^ data[off + n]) & 0xff] ^ (crc >>> 8);        }    }    public void update(int data) {        crc = crcTable[(crc ^ data) & 0xff] ^ (crc >>> 8);    }    public int getValue() {        return crc ^ 0xffffffff;    }}final class ChunkStream extends ImageOutputStreamImpl {        private ImageOutputStream stream;    private long startPos;    private CRC crc = new CRC();    public ChunkStream(int type, ImageOutputStream stream) throws IOException {        this.stream = stream;        this.startPos = stream.getStreamPosition();                stream.writeInt(-1); // length, will backpatch        writeInt(type);    }    public int read() throws IOException {        throw new RuntimeException("Method not available");    }    public int read(byte[] b, int off, int len) throws IOException {        throw new RuntimeException("Method not available");    }    public void write(byte[] b, int off, int len) throws IOException {        crc.update(b, off, len);        stream.write(b, off, len);    }    public void write(int b) throws IOException {        crc.update(b);        stream.write(b);    }    public void finish() throws IOException {        // Write CRC        stream.writeInt(crc.getValue());        // Write length        long pos = stream.getStreamPosition();        stream.seek(startPos);        stream.writeInt((int)(pos - startPos) - 12);        // Return to end of chunk and flush to minimize buffering        stream.seek(pos);        stream.flushBefore(pos);    }    protected void finalize() throws Throwable {        // Empty finalizer (for improved performance; no need to call        // super.finalize() in this case)    }}// Compress output and write as a series of 'IDAT' chunks of// fixed length.final class IDATOutputStream extends ImageOutputStreamImpl {        private static byte[] chunkType = {        (byte)'I', (byte)'D', (byte)'A', (byte)'T'    };    private ImageOutputStream stream;    private int chunkLength;    private long startPos;    private CRC crc = new CRC();    Deflater def = new Deflater(Deflater.BEST_COMPRESSION);    byte[] buf = new byte[512];    private int bytesRemaining;    public IDATOutputStream(ImageOutputStream stream, int chunkLength)         throws IOException {        this.stream = stream;        this.chunkLength = chunkLength;        startChunk();    }    private void startChunk() throws IOException {        crc.reset();        this.startPos = stream.getStreamPosition();        stream.writeInt(-1); // length, will backpatch        crc.update(chunkType, 0, 4);        stream.write(chunkType, 0, 4);        this.bytesRemaining = chunkLength;    }    private void finishChunk() throws IOException {        // Write CRC        stream.writeInt(crc.getValue());        // Write length        long pos = stream.getStreamPosition();        stream.seek(startPos);        stream.writeInt((int)(pos - startPos) - 12);        // Return to end of chunk and flush to minimize buffering        stream.seek(pos);        stream.flushBefore(pos);    }    public int read() throws IOException {        throw new RuntimeException("Method not available");    }    public int read(byte[] b, int off, int len) throws IOException {        throw new RuntimeException("Method not available");    }    public void write(byte[] b, int off, int len) throws IOException {        if (len == 0) {            return;        }	if (!def.finished()) {	    def.setInput(b, off, len);	    while (!def.needsInput()) {		deflate();	    }	}    }    public void deflate() throws IOException {	int len = def.deflate(buf, 0, buf.length);        int off = 0;        while (len > 0) {            if (bytesRemaining == 0) {                finishChunk();                startChunk();            }            int nbytes = Math.min(len, bytesRemaining);            crc.update(buf, off, nbytes);            stream.write(buf, off, nbytes);            off += nbytes;            len -= nbytes;            bytesRemaining -= nbytes;        }    }    public void write(int b) throws IOException {        byte[] wbuf = new byte[1];        wbuf[0] = (byte)b;        write(wbuf, 0, 1);    }    public void finish() throws IOException {	if (!def.finished()) {	    def.finish();	    while (!def.finished()) {		deflate();	    }	}        finishChunk();    }    protected void finalize() throws Throwable {        // Empty finalizer (for improved performance; no need to call        // super.finalize() in this case)    }}class PNGImageWriteParam extends ImageWriteParam {        public PNGImageWriteParam(Locale locale) {        super();        this.canWriteProgressive = true;        this.locale = locale;    }}/** * @version 0.5 */public class PNGImageWriter extends ImageWriter {    ImageOutputStream stream = null;    PNGMetadata metadata = null;    // Factors from the ImageWriteParam    int sourceXOffset = 0;    int sourceYOffset = 0;    int sourceWidth = 0;    int sourceHeight = 0;    int[] sourceBands = null;    int periodX = 1;    int periodY = 1;    int numBands;    int bpp;    RowFilter rowFilter = new RowFilter();    byte[] prevRow = null;    byte[] currRow = null;    byte[][] filteredRows = null;    // Per-band scaling tables    //    // After the first call to initializeScaleTables, either scale and scale0    // will be valid, or scaleh and scalel will be valid, but not both.    //    // The tables will be designed for use with a set of input but depths    // given by sampleSize, and an output bit depth given by scalingBitDepth.    //    int[] sampleSize = null; // Sample size per band, in bits    int scalingBitDepth = -1; // Output bit depth of the scaling tables    // Tables for 1, 2, 4, or 8 bit output    byte[][] scale = null; // 8 bit table    byte[] scale0 = null; // equivalent to scale[0]    // Tables for 16 bit output    byte[][] scaleh = null; // High bytes of output    byte[][] scalel = null; // Low bytes of output    int totalPixels; // Total number of pixels to be written by write_IDAT    int pixelsDone; // Running count of pixels written by write_IDAT    public PNGImageWriter(ImageWriterSpi originatingProvider) {        super(originatingProvider);    }     public void setOutput(Object output) {        super.setOutput(output);        if (output != null) {            if (!(output instanceof ImageOutputStream)) {                throw new IllegalArgumentException("output not an ImageOutputStream!");            }            this.stream = (ImageOutputStream)output;        } else {            this.stream = null;        }    }    private static int[] allowedProgressivePasses = { 1, 7 };    public ImageWriteParam getDefaultWriteParam() {        return new PNGImageWriteParam(getLocale());    }    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {        return null;    }    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,                                               ImageWriteParam param) {        PNGMetadata m = new PNGMetadata();        m.initialize(imageType, imageType.getSampleModel().getNumBands());        return m;    }    public IIOMetadata convertStreamMetadata(IIOMetadata inData,                                             ImageWriteParam param) {        return null;    }    public IIOMetadata convertImageMetadata(IIOMetadata inData,                                            ImageTypeSpecifier imageType,                                            ImageWriteParam param) {        // TODO - deal with imageType        if (inData instanceof PNGMetadata) {            return (PNGMetadata)((PNGMetadata)inData).clone();        } else {            return new PNGMetadata(inData);        }    }    private void write_magic() throws IOException {        // Write signature        byte[] magic = { (byte)137, 80, 78, 71, 13, 10, 26, 10 };        stream.write(magic);    }    private void write_IHDR() throws IOException {        // Write IHDR chunk        ChunkStream cs = new ChunkStream(PNGImageReader.IHDR_TYPE, stream);        cs.writeInt(metadata.IHDR_width);        cs.writeInt(metadata.IHDR_height);        cs.writeByte(metadata.IHDR_bitDepth);        cs.writeByte(metadata.IHDR_colorType);        if (metadata.IHDR_compressionMethod != 0) {            throw new IIOException("Only compression method 0 is defined in PNG 1.1");        }        cs.writeByte(metadata.IHDR_compressionMethod);        if (metadata.IHDR_filterMethod != 0) {            throw new IIOException("Only filter method 0 is defined in PNG 1.1");        }        cs.writeByte(metadata.IHDR_filterMethod);        if (metadata.IHDR_interlaceMethod < 0 ||            metadata.IHDR_interlaceMethod > 1) {            throw new IIOException("Only interlace methods 0 (node) and 1 (adam7) are defined in PNG 1.1");        }        cs.writeByte(metadata.IHDR_interlaceMethod);        cs.finish();    }    private void write_cHRM() throws IOException {        if (metadata.cHRM_present) {            ChunkStream cs = new ChunkStream(PNGImageReader.cHRM_TYPE, stream);            cs.writeInt(metadata.cHRM_whitePointX);

⌨️ 快捷键说明

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