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 + -
显示快捷键?