xtifftilecodecimpl.java

来自「OpenMap是一个基于JavaBeansTM的开发工具包。利用OpenMap你」· Java 代码 · 共 762 行 · 第 1/2 页

JAVA
762
字号
package org.libtiff.jai.codec;import java.awt.Point;import java.awt.Rectangle;import java.awt.image.DataBuffer;import java.awt.image.DataBufferByte;import java.awt.image.DataBufferShort;import java.awt.image.DataBufferUShort;import java.awt.image.Raster;import java.awt.image.RenderedImage;import java.awt.image.SampleModel;import java.awt.image.WritableRaster;import java.awt.image.renderable.ParameterBlock;import java.io.IOException;import javax.media.jai.JAI;import javax.media.jai.RasterFactory;import org.libtiff.jai.util.JaiI18N;/** * Provides a base class for writing TIFF tile codecs, to be registered with the * XTIFFDirectory. This codec allows for both decoding and (optionally) encoding * of tiles, and also handles the colorspace conversion in decoding. * <p> * At the minimum you will need to implement the two methods decodeTilePixels() * for byte and short data, as well as the methods register() and create(). If * your decoder requires additional parameters from the tags, set them up in * initializeDecoding(), and initializeEncoding() for encoding. * <p> * To implement encoding, you must override the canEncode() method to return * true, and implement encodeTilePixels(). *  * @author Niles Ritter * @see XTIFFTileCodec */public abstract class XTIFFTileCodecImpl implements XTIFFTileCodec {    // ////////////////////////////////////////////////////    // // Implementation Section    // // Override or implement methods here    // ////////////////////////////////////////////////////    /**     * Registration method. Must be implemented by the extended class to     * register itself with the XTIFFDirectory for all compression codes it     * supports (e.g Fax codec supports 3 codes).     *      * @see XTIFFDirectory     */    public abstract void register();    /**     * Implement this to return the corresponding empty codec object.     */    public abstract XTIFFTileCodec create();    /**     * Indicate whether this codec can encode data. Override to return true only     * if your codec implments encoding.     */    public boolean canEncode() {        return false;    }    /**     * The initialization method particular to decoding. Extend for whatever     * compression-specific information or parameters is needed. The decoding     * parameter has already been assigned at this point, as well as the     * XTIFFDirectory parsed from the input stream, and so all XTIFFFields are     * available.     */    public void initializeDecoding() {}    /**     * The initialization method particular to encoding. Extend for whatever     * compression-specific information or parameters is needed. The decoding     * parameter has already been assigned at this point, as well as the     * XTIFFDirectory parsed from the input stream, and so all XTIFFFields are     * available.     */    public void initializeEncoding() {}    /**     * decode bpixel byte array of data into pixels, packed for 1,2,4 8 bit     * pixels. Must implment this.     *      * @param bpixels the byte array of compressed input data     * @param rect the rectangular shape of the target pixels     * @param pixels the target decompressed pixels.     */    public abstract void decodeTilePixels(byte[] bpixels, Rectangle rect,                                          byte[] pixels);    /**     * decode bpixel byte array of data into pixels, packed for 16 bit pixels.     * Must implment this.     *      * @param bpixels the byte array of compressed input data     * @param rect the rectangular shape of the target pixels     * @param pixels the target decompressed pixels.     */    public abstract void decodeTilePixels(byte[] bpixels, Rectangle rect,                                          short[] pixels);    /**     * encode the tile in pixels into bpixels and return the byte size of the     * compressed data. Override this method if canEncode() = true;     *      * @param pixels input pixels     * @param rect the array dimensions of samples     * @param bpixels the target array of compressed byte data     */    public int encodeTilePixels(int[] pixels, Rectangle rect, byte[] bpixels) {        return 0;    }    // ////////////////////////////////////////////////////    // // Common Section    // ////////////////////////////////////////////////////    protected XTIFFDirectory directory = null;    protected RenderedImage image = null;    protected int minY;    protected int minX;    protected int width;    protected int length;    protected int numBands;    protected int tileLength;    protected int tileWidth;    protected int compression;    protected SampleModel sampleModel;    protected int[] sampleSize;    protected char[] bitsPerSample;    protected char[] colormap = null;    /**     * The empty constructor.     */    public XTIFFTileCodecImpl() {}    /**     * The method for initializing information common to both encoder and     * decoder.     */    public void initialize() {        width = (int) getLongField(XTIFF.TIFFTAG_IMAGE_WIDTH);        length = (int) getLongField(XTIFF.TIFFTAG_IMAGE_LENGTH);        isTiled = directory.isTiled();        if (isTiled) {            tileWidth = (int) getLongField(XTIFF.TIFFTAG_TILE_WIDTH);            tileLength = (int) getLongField(XTIFF.TIFFTAG_TILE_LENGTH);        } else {            tileWidth = width;            tileLength = (int) getLongField(XTIFF.TIFFTAG_ROWS_PER_STRIP);        }        // Figure out what compression if any, is being used.        XTIFFField compField = directory.getField(XTIFF.TIFFTAG_COMPRESSION);        if (compField != null) {            compression = compField.getAsInt(0);        } else {            compression = XTIFF.COMPRESSION_NONE;        }        XTIFFField cfield = directory.getField(XTIFF.TIFFTAG_COLORMAP);        if (cfield != null)            colormap = cfield.getAsChars();        // Read the TIFFTAG_BITS_PER_SAMPLE field        XTIFFField bitsField = directory.getField(XTIFF.TIFFTAG_BITS_PER_SAMPLE);        if (bitsField == null) {            // Default            bitsPerSample = new char[1];            bitsPerSample[0] = 1;        } else {            bitsPerSample = bitsField.getAsChars();        }        image_type = directory.getImageType();    }    /**     * A common utility method for accessing the XTIFFFields in the current     * image directory.     */    protected long getLongField(int fld) {        XTIFFField field = directory.getField(fld);        if (field == null)            return 0;        else            return field.getAsLong(0);    }    /**     * This method may be used by the implementations register() method to     * register itself with the XTIFFDirectory.     *      * @see XTIFFDirectory     */    public void register(int comp) {        XTIFFDirectory.registerTileCodec(comp, this);    }    /**     * One-time common image parameter setup     *      * @param img the source image that will be encoded into a TIFF formatted     *        stream, or the TIFF image from which Raster tiles will be decoded.     */    protected void setupSourceImage(RenderedImage img) {        image = img;        // Get raster parameters        minY = image.getMinY();        minX = image.getMinX();        sampleModel = image.getSampleModel();        numBands = sampleModel.getNumBands();        sampleSize = sampleModel.getSampleSize();    }    /**     * Returns the TIFF compression type     */    public int getCompression() {        return compression;    }    // ////////////////////////////////////////////////////    // // Encoding Section    // ////////////////////////////////////////////////////    protected XTIFFEncodeParam encodeParam = null;    private int _pixels[];    protected boolean isTiled;    /**     * The method for creating an encoder from the XTIFFEncodeParam information.     */    public XTIFFTileCodec create(XTIFFEncodeParam param) throws IOException {        XTIFFTileCodecImpl codec = (XTIFFTileCodecImpl) create();        codec.initialize(param);        return codec;    }    protected void initialize(XTIFFEncodeParam param) throws IOException {        if (!canEncode())            throw new IOException("encoding not supported");        encodeParam = param;        directory = param.getDirectory();        initialize();        initializeEncoding();    }    /**     * Encode the data into buffer and return byte count Normally you will not     * need to override this method, but instead implement the     * <code>encodeTilePixels()</code> method.     */    public int encode(RenderedImage img, Rectangle rect, byte[] bpixels) {        if (image == null) {            setupSourceImage(img);            setupBufferForEncoding();        }        // Fill tile buffer, padding right with zeroes.        getTilePixels(rect);        // encode and return number of bytes compressed        return encodeTilePixels(_pixels, rect, bpixels);    }    /**     * One-time setup for encoding     */    protected void setupBufferForEncoding() {        // Set up input tile/strip buffer        _pixels = new int[tileWidth * tileLength * numBands];        // if padding necessary do it now.        int padRight = (tileWidth - (width % tileWidth)) % tileWidth;        int padBottom = (tileLength - (length % tileLength)) % tileLength;        if (!isTiled)            padBottom = 0;        if (padRight > 0 || padBottom > 0) {            ParameterBlock pb = new ParameterBlock();            pb.addSource(image);            pb.add(null)                    .add(padRight)                    .add(null)                    .add(padBottom)                    .add(null)                    .add(null);            image = JAI.create("border", pb);        }    }    /**     * Get the portion of tile fitting into buffer. You probably won't need to     * override this.     *      * @param rect the region to extract from image.     */    protected void getTilePixels(Rectangle rect) {        // Grab the pixels        Raster src = image.getData(rect);        int col = (int) rect.getX();        int row = (int) rect.getY();        int rows = (int) rect.getHeight();        int cols = (int) rect.getWidth();        src.getPixels(col, row, cols, rows, _pixels);    }    /**     * If derived classes can make a better estimate for the maximum size of a     * compressed tile, they should override this, which assumes conservatively     * that it won't be worse than twice the original size.     *      * @param im the rendered image containing the image data     */    public int getCompressedTileSize(RenderedImage im) {        sampleModel = im.getSampleModel();        numBands = sampleModel.getNumBands();        sampleSize = sampleModel.getSampleSize();        return (int) Math.ceil(2 * tileWidth * tileLength * numBands                * (sampleSize[0] / 8.0));    }    // ////////////////////////////////////////////////////    // // Decoding Section    // ////////////////////////////////////////////////////    protected XTIFFDecodeParam decodeParam = null;    protected boolean decodePaletteAsShorts = false;    protected int unitsInThisTile;    protected byte _bdata[] = null;    protected short _sdata[] = null;    protected byte[] bpixvals = null;    protected short[] spixvals = null;    protected DataBuffer buffer = null;    protected int dataType;    protected int image_type;    /**     * The standard decoder creation method     */    public XTIFFTileCodec create(XTIFFDecodeParam param) throws IOException {        XTIFFTileCodecImpl codec = (XTIFFTileCodecImpl) create();        codec.initialize(param);        return codec;    }    protected void initialize(XTIFFDecodeParam param) throws IOException {        decodeParam = param;        decodePaletteAsShorts = param.getDecodePaletteAsShorts();        directory = param.getDirectory();        initialize();        initializeDecoding();    }    /**     * One-time setup for encoding. Some configurations require a temp array for     * unpacking 16-bit palette data.     */    protected void setupBufferForDecoding() {        // int length;        buffer = sampleModel.createDataBuffer();        dataType = sampleModel.getDataType();        if (dataType == DataBuffer.TYPE_BYTE) {            _bdata = ((DataBufferByte) buffer).getData();            bpixvals = _bdata;        } else if (dataType == DataBuffer.TYPE_USHORT) {            _sdata = ((DataBufferUShort) buffer).getData();            if (!decodePaletteAsShorts)                spixvals = _sdata;        } else if (dataType == DataBuffer.TYPE_SHORT) {            _sdata = ((DataBufferShort) buffer).getData();            if (!decodePaletteAsShorts)

⌨️ 快捷键说明

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