xtiffdirectory.java

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

JAVA
851
字号
package org.libtiff.jai.codec;/* * XTIFF: eXtensible TIFF libraries for JAI. *  * The contents of this file are subject to the  JAVA ADVANCED IMAGING * SAMPLE INPUT-OUTPUT CODECS AND WIDGET HANDLING SOURCE CODE  License * Version 1.0 (the "License"); You may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.sun.com/software/imaging/JAI/index.html * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License.  * * The Original Code is JAVA ADVANCED IMAGING SAMPLE INPUT-OUTPUT CODECS * AND WIDGET HANDLING SOURCE CODE.  * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. * Portions created by: Niles Ritter  * are Copyright (C): Niles Ritter, GeoTIFF.org, 1999,2000. * All Rights Reserved. * Contributor(s): Niles Ritter */import java.io.IOException;import java.util.Hashtable;import java.util.Iterator;import java.util.TreeMap;import java.util.Vector;import org.libtiff.jai.codecimpl.XTIFFImage;import org.libtiff.jai.operator.XTIFFDescriptor;import org.libtiff.jai.util.JaiI18N;import com.sun.media.jai.codec.SeekableStream;/** * XTIFFDirectory is an extensible TIFF directory object. This class may be * extended without changing the XTIFF codec by overriding the XTIFFFactory * instance registered in this class. In addition, this class is the repository * of all XTIFFTileCodec's which may be augmented with new codecs, again without * overriding the ImageCodec. If the jai "tiff" codec has been overridden * through the <code>XTIFFDescriptor.register()</code> method, each XTIFF * image will possess a property called "tiff.directory" which will be an object * of the type created by the factory. The class is declared as serializable to * permit its transmission to remote images as a set of parameters to the codec, * and to be able to survive as an instantiated property of the RenderedImage. *  *  * @serializable * @author Niles Ritter * @see XTIFFDescriptor * @see XTIFFField * @see XTIFFTileCodec * @see XTIFFFactory */public class XTIFFDirectory extends Object implements java.io.Serializable {    private int imageType;    /** default directory factory */    protected static XTIFFFactory factory = new XTIFFFactory();    protected static Hashtable tileCodecs = new Hashtable();    /** The stream being read. Not persisted */    transient protected SeekableStream stream;    /** A boolean storing the endianness of the stream. */    boolean isBigEndian;    /** A boolean indicating tiled tagset */    boolean _isTiled = false;    /** for dynamically adding fields in sorted order */    TreeMap fieldIndex = new TreeMap();    /** The default constructor. Publicized for Serializability */    public XTIFFDirectory() {}    private static boolean isValidEndianTag(int endian) {        return ((endian == 0x4949) || (endian == 0x4d4d));    }    /**     * If true this image uses TIFF 6.0 tiling     */    public boolean isTiled() {        return _isTiled;    }    /**     * reads the TIFF header. Not likely to be overridden.     */    protected void readHeader() throws IOException {        // Read the TIFF header        stream.seek(0L);        int endian = stream.readUnsignedShort();        if (!isValidEndianTag(endian)) {            throw new IllegalArgumentException(JaiI18N.getString("XTIFFDirectory1"));        }        isBigEndian = (endian == 0x4d4d);        // Verify that Douglas Addams still has influence in software:        int magic = readUnsignedShort(stream);        if (magic != 42) {            throw new IllegalArgumentException(JaiI18N.getString("XTIFFDirectory2"));        }    }    /**     * Constructs a XTIFFDirectory from a SeekableStream. The directory     * parameter specifies which directory to read from the linked list present     * in the stream; directory 0 is normally read but it is possible to store     * multiple images in a single TIFF file by maintaing multiple directories.     *      * @param stream a SeekableStream to read from.     * @param directory the index of the directory to read.     */    protected XTIFFDirectory(SeekableStream stream, int directory)            throws IOException {        this.stream = stream;        long global_save_offset = stream.getFilePointer();        long ifd_offset;        readHeader();        // Get the initial ifd offset as an unsigned int (using a long)        ifd_offset = readUnsignedInt(stream);        for (int i = 0; i < directory; i++) {            if (ifd_offset == 0L) {                throw new IllegalArgumentException(JaiI18N.getString("XTIFFDirectory3"));            }            stream.seek(ifd_offset);            int entries = readUnsignedShort(stream);            stream.skip(12 * entries);            ifd_offset = readUnsignedInt(stream);        }        stream.seek(ifd_offset);        initialize();        stream.seek(global_save_offset);    }    /**     * Constructs a XTIFFDirectory by reading a SeekableStream. The ifd_offset     * parameter specifies the stream offset from which to begin reading; this     * mechanism is sometimes used to store private IFDs within a TIFF file that     * are not part of the normal sequence of IFDs.     *      * @param stream a SeekableStream to read from.     * @param ifd_offset the long byte offset of the directory.     */    protected XTIFFDirectory(SeekableStream stream, long ifd_offset)            throws IOException {        this.stream = stream;        long global_save_offset = stream.getFilePointer();        readHeader();        stream.seek(ifd_offset);        initialize();        stream.seek(global_save_offset);    }    private static final int[] _sizeOfType = { 0, // 0 = n/a            1, // 1 = byte            1, // 2 = ascii            2, // 3 = short            4, // 4 = long            8, // 5 = rational            1, // 6 = sbyte            1, // 7 = undefined            2, // 8 = sshort            4, // 9 = slong            8, // 10 = srational            4, // 11 = float            8 // 12 = double    };    /**     * Return the size of a data type. Extend if you need to define new TIFF     * field types. Also override the createField() method of the XTIFFFactory,     * the XTIFFField class, and the readFieldValue() method here.     *      * @param type the XTIFFField type code     * @see XTIFFField     * @see XTIFFFactory     */    public int sizeOfType(int type) throws ArrayIndexOutOfBoundsException {        return _sizeOfType[type];    }    /**     * Create and add a TIFF field to this directory.     *      * @param tag the TIFF tag listed in XTIFF     * @param type the TIFF field type listed in XTIFFField     * @param count the number of values in array obj     * @param obj the array of values     * @see XTIFFField     * @see XTIFF     */    public void addField(int tag, int type, int count, Object obj) {        addField(factory.createField(tag, type, count, obj));    }    /**     * Create a TIFF field     *      * @param tag the TIFF tag listed in XTIFF     * @param type the TIFF field type listed in XTIFFField     * @param count the number of values in array obj     * @param obj the array of values     * @see XTIFFField     * @see XTIFF     */    public static XTIFFField createField(int tag, int type, int count,                                         Object obj) {        return factory.createField(tag, type, count, obj);    }    /**     * Add an existing TIFF field to this directory.     *      * @param type the XTIFFField type code     * @see XTIFFField     */    public void addField(XTIFFField field) {        fieldIndex.put(new Integer(field.tag), field);    }    /**     * Initialize the directory from a stream     */    protected void initialize() throws IOException {        XTIFFField field;//        long nextTagOffset;        int numEntries = readUnsignedShort(stream);        for (int i = 0; i < numEntries; i++) {            try {                field = readField();            } catch (ArrayIndexOutOfBoundsException ae) {                // if the data type is unknown we should skip this TIFF Field                continue;            }            addField(field);        }    }    /** Returns the number of directory entries. */    public int getNumEntries() {        return fieldIndex.size();    }    /**     * Returns the value of a given tag as a XTIFFField, or null if the tag is     * not present.     */    public XTIFFField getField(int tag) {        return (XTIFFField) fieldIndex.get(new Integer(tag));    }    /**     * Returns true if a tag appears in the directory.     */    public boolean isTagPresent(int tag) {        return fieldIndex.containsKey(new Integer(tag));    }    /**     * Returns an ordered array of ints indicating the tag values.     */    public int[] getTags() {        int[] tags = new int[fieldIndex.size()];        Iterator it = fieldIndex.keySet().iterator();        int i = 0;        while (it.hasNext()) {            tags[i++] = ((Integer) it.next()).intValue();        }        return tags;    }    /**     * Returns an array of XTIFFFields containing all the fields in this     * directory.     */    public XTIFFField[] getFields() {        XTIFFField[] fields = new XTIFFField[fieldIndex.size()];        Iterator it = fieldIndex.values().iterator();        int i = 0;        while (it.hasNext()) {            fields[i++] = (XTIFFField) it.next();        }        return fields;    }    /**     * Returns the value of a particular index of a given tag as a byte. The     * caller is responsible for ensuring that the tag is present and has type     * XTIFFField.TIFF_SBYTE, TIFF_BYTE, or TIFF_UNDEFINED.     */    public byte getFieldAsByte(int tag, int index) {        return (getField(tag).getAsBytes())[index];    }    /**     * Returns the value of index 0 of a given tag as a byte. The caller is     * responsible for ensuring that the tag is present and has type     * XTIFFField.TIFF_SBYTE, TIFF_BYTE, or TIFF_UNDEFINED.     */    public byte getFieldAsByte(int tag) {        return getFieldAsByte(tag, 0);    }    /**     * Returns the value of a particular index of a given tag as a long. The     * caller is responsible for ensuring that the tag is present and has type     * TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, TIFF_SSHORT,     * TIFF_SLONG or TIFF_LONG.     */    public long getFieldAsLong(int tag, int index) {        return getField(tag).getAsLong(index);    }    /**     * Returns the value of index 0 of a given tag as a long. The caller is     * responsible for ensuring that the tag is present and has type TIFF_BYTE,     * TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or     * TIFF_LONG.     */    public long getFieldAsLong(int tag) {        return getFieldAsLong(tag, 0);    }    /**     * Returns the value of a particular index of a given tag as a float. The     * caller is responsible for ensuring that the tag is present and has     * numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).     */    public float getFieldAsFloat(int tag, int index) {        return getField(tag).getAsFloat(index);    }    /**     * Returns the value of index 0 of a given tag as a float. The caller is     * responsible for ensuring that the tag is present and has numeric type     * (all but TIFF_UNDEFINED and TIFF_ASCII).     */    public float getFieldAsFloat(int tag) {        return getFieldAsFloat(tag, 0);    }    /**     * Returns the value of a particular index of a given tag as a double. The     * caller is responsible for ensuring that the tag is present and has     * numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).     */    public double getFieldAsDouble(int tag, int index) {        return getField(tag).getAsDouble(index);    }    /**     * Returns the value of index 0 of a given tag as a double. The caller is     * responsible for ensuring that the tag is present and has numeric type     * (all but TIFF_UNDEFINED and TIFF_ASCII).     */    public double getFieldAsDouble(int tag) {        return getFieldAsDouble(tag, 0);    }    /**     * TIFF field-value reader. Override if there are new field types. Also     * override sizeOfType() and, possibly the createField method of the     * factory, if the field needs new accessors.     */    public Object readFieldValue(int tag, int type, int count)            throws IOException, ArrayIndexOutOfBoundsException {        int j;        Object obj = null;        switch (type) {        case XTIFFField.TIFF_BYTE:        case XTIFFField.TIFF_SBYTE:        case XTIFFField.TIFF_UNDEFINED:        case XTIFFField.TIFF_ASCII:            byte[] bvalues = new byte[count];            stream.readFully(bvalues, 0, count);            if (type == XTIFFField.TIFF_ASCII) {                // Can be multiple strings                int index = 0, prevIndex = 0;                Vector v = new Vector();                while (index < count) {                    while ((index < count) && (bvalues[index++] != 0))                        ;                    // When we encountered zero, means one string has ended                    v.add(new String(bvalues, prevIndex, (index - prevIndex)));                    prevIndex = index;                }                count = v.size();                String strings[] = new String[count];                for (int c = 0; c < count; c++) {                    strings[c] = (String) v.elementAt(c);                }                obj = strings;            } else {                obj = bvalues;            }            break;

⌨️ 快捷键说明

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