/*
 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.imageio.plugins.tiff;

import java.util.StringTokenizer;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.sun.imageio.plugins.tiff.TIFFFieldNode;
import com.sun.imageio.plugins.tiff.TIFFIFD;

/**
 * A class representing a field in a TIFF 6.0 Image File Directory.
 *
 * <p> A field in a TIFF Image File Directory (IFD) is defined as a
 * tag number accompanied by a sequence of values of identical data type.
 * TIFF 6.0 defines 12 data types; a 13th type {@code IFD} is
 * defined in TIFF Tech Note 1 of TIFF Specification Supplement 1. These
 * TIFF data types are referred to by Java constants and mapped internally
 * onto Java language data types and type names as follows:
 *
 * <br>
 * <br>
 * <table border="1">
 * <caption>TIFF Data Type to Java Data Type Mapping</caption>
 *
 * <tr>
 * <th>
 * <b>TIFF Data Type</b>
 * </th>
 * <th>
 * <b>Java Constant</b>
 * </th>
 * <th>
 * <b>Java Data Type</b>
 * </th>
 * <th>
 * <b>Java Type Name</b>
 * </th>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>BYTE</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_BYTE}
 * </td>
 * <td>
 * {@code byte}
 * </td>
 * <td>
 * {@code "Byte"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>ASCII</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_ASCII}
 * </td>
 * <td>
 * {@code String}
 * </td>
 * <td>
 * {@code "Ascii"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>SHORT</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_SHORT}
 * </td>
 * <td>
 * {@code char}
 * </td>
 * <td>
 * {@code "Short"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>LONG</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_LONG}
 * </td>
 * <td>
 * {@code long}
 * </td>
 * <td>
 * {@code "Long"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>RATIONAL</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_RATIONAL}
 * </td>
 * <td>
 * {@code long[2]} {numerator, denominator}
 * </td>
 * <td>
 * {@code "Rational"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>SBYTE</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_SBYTE}
 * </td>
 * <td>
 * {@code byte}
 * </td>
 * <td>
 * {@code "SByte"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>UNDEFINED</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_UNDEFINED}
 * </td>
 * <td>
 * {@code byte}
 * </td>
 * <td>
 * {@code "Undefined"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>SSHORT</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_SSHORT}
 * </td>
 * <td>
 * {@code short}
 * </td>
 * <td>
 * {@code "SShort"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>SLONG</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_SLONG}
 * </td>
 * <td>
 * {@code int}
 * </td>
 * <td>
 * {@code "SLong"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>SRATIONAL</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_SRATIONAL}
 * </td>
 * <td>
 * {@code int[2]} {numerator, denominator}
 * </td>
 * <td>
 * {@code "SRational"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>FLOAT</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_FLOAT}
 * </td>
 * <td>
 * {@code float}
 * </td>
 * <td>
 * {@code "Float"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>DOUBLE</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_DOUBLE}
 * </td>
 * <td>
 * {@code double}
 * </td>
 * <td>
 * {@code "Double"}
 * </td>
 * </tr>
 *
 * <tr>
 * <td>
 * <tt>IFD</tt>
 * </td>
 * <td>
 * {@link TIFFTag#TIFF_IFD_POINTER}
 * </td>
 * <td>
 * {@code long}
 * </td>
 * <td>
 * {@code "IFDPointer"}
 * </td>
 * </tr>
 *
 * </table>
 *
 * @since 9
 * @see   TIFFDirectory
 * @see   TIFFTag
 */
public class TIFFField implements Cloneable {

    private static final String[] typeNames = {
        null,
        "Byte", "Ascii", "Short", "Long", "Rational",
        "SByte", "Undefined", "SShort", "SLong", "SRational",
        "Float", "Double", "IFDPointer"
    };

    private static final boolean[] isIntegral = {
        false,
        true, false, true, true, false,
        true, true, true, true, false,
        false, false, false
    };

    /** The tag. */
    private TIFFTag tag;

    /** The tag number. */
    private int tagNumber;

    /** The tag type. */
    private int type;

    /** The number of data items present in the field. */
    private int count;

    /** The field data. */
    private Object data;

    /** The IFD contents if available. This will usually be a TIFFIFD. */
    private TIFFDirectory dir;

    /** The default constructor. */
    private TIFFField() {}

    private static String getAttribute(Node node, String attrName) {
        NamedNodeMap attrs = node.getAttributes();
        return attrs.getNamedItem(attrName).getNodeValue();
    }

    private static void initData(Node node,
                                 int[] otype, int[] ocount, Object[] odata) {
        int type;
        int count;
        Object data = null;

        String typeName = node.getNodeName();
        typeName = typeName.substring(4);
        typeName = typeName.substring(0, typeName.length() - 1);
        type = TIFFField.getTypeByName(typeName);
        if (type == -1) {
            throw new IllegalArgumentException("typeName = " + typeName);
        }

        Node child = node.getFirstChild();

        count = 0;
        while (child != null) {
            String childTypeName = child.getNodeName().substring(4);
            if (!typeName.equals(childTypeName)) {
                // warning
            }

            ++count;
            child = child.getNextSibling();
        }

        if (count > 0) {
            data = createArrayForType(type, count);
            child = node.getFirstChild();
            int idx = 0;
            while (child != null) {
                String value = getAttribute(child, "value");

                String numerator, denominator;
                int slashPos;

                switch (type) {
                case TIFFTag.TIFF_ASCII:
                    ((String[])data)[idx] = value;
                    break;
                case TIFFTag.TIFF_BYTE:
                case TIFFTag.TIFF_SBYTE:
                    ((byte[])data)[idx] =
                        (byte)Integer.parseInt(value);
                    break;
                case TIFFTag.TIFF_SHORT:
                    ((char[])data)[idx] =
                        (char)Integer.parseInt(value);
                    break;
                case TIFFTag.TIFF_SSHORT:
                    ((short[])data)[idx] =
                        (short)Integer.parseInt(value);
                    break;
                case TIFFTag.TIFF_SLONG:
                    ((int[])data)[idx] =
                        Integer.parseInt(value);
                    break;
                case TIFFTag.TIFF_LONG:
                case TIFFTag.TIFF_IFD_POINTER:
                    ((long[])data)[idx] =
                        Long.parseLong(value);
                    break;
                case TIFFTag.TIFF_FLOAT:
                    ((float[])data)[idx] =
                        Float.parseFloat(value);
                    break;
                case TIFFTag.TIFF_DOUBLE:
                    ((double[])data)[idx] =
                        Double.parseDouble(value);
                    break;
                case TIFFTag.TIFF_SRATIONAL:
                    slashPos = value.indexOf("/");
                    numerator = value.substring(0, slashPos);
                    denominator = value.substring(slashPos + 1);

                    ((int[][])data)[idx] = new int[2];
                    ((int[][])data)[idx][0] =
                        Integer.parseInt(numerator);
                    ((int[][])data)[idx][1] =
                        Integer.parseInt(denominator);
                    break;
                case TIFFTag.TIFF_RATIONAL:
                    slashPos = value.indexOf("/");
                    numerator = value.substring(0, slashPos);
                    denominator = value.substring(slashPos + 1);

                    ((long[][])data)[idx] = new long[2];
                    ((long[][])data)[idx][0] =
                        Long.parseLong(numerator);
                    ((long[][])data)[idx][1] =
                        Long.parseLong(denominator);
                    break;
                default:
                    // error
                }

                idx++;
                child = child.getNextSibling();
            }
        }

        otype[0] = type;
        ocount[0] = count;
        odata[0] = data;
    }

    /**
     * Creates a {@code TIFFField} from a TIFF native image
     * metadata node. If the value of the <tt>"number"</tt> attribute
     * of the node is not found in {@code tagSet} then a new
     * {@code TIFFTag} with name {@code TIFFTag.UNKNOWN_TAG_NAME}
     * will be created and assigned to the field.
     *
     * @param tagSet The {@code TIFFTagSet} to which the
     * {@code TIFFTag} of the field belongs.
     * @param node A native TIFF image metadata {@code TIFFField} node.
     * @throws NullPointerException if {@code node} is
     * {@code null}.
     * @throws IllegalArgumentException if the name of the node is not
     * {@code "TIFFField"}.
     * @throws NullPointerException if the node does not contain any data.
     * @throws IllegalArgumentException if the combination of node attributes
     * and data is not legal per the {@link #TIFFField(TIFFTag,int,int,Object)}
     * constructor specification.
     * @return A new {@code TIFFField}.
     */
    public static TIFFField createFromMetadataNode(TIFFTagSet tagSet,
                                                   Node node) {
        if (node == null) {
            throw new NullPointerException("node == null!");
        }
        String name = node.getNodeName();
        if (!name.equals("TIFFField")) {
            throw new IllegalArgumentException("!name.equals(\"TIFFField\")");
        }

        int tagNumber = Integer.parseInt(getAttribute(node, "number"));
        TIFFTag tag = null;
        if (tagSet != null) {
            tag = tagSet.getTag(tagNumber);
        }

        int type = TIFFTag.TIFF_UNDEFINED;
        int count = 0;
        Object data = null;

        Node child = node.getFirstChild();
        if (child != null) {
            String typeName = child.getNodeName();
            if (typeName.equals("TIFFUndefined")) {
                String values = getAttribute(child, "value");
                StringTokenizer st = new StringTokenizer(values, ",");
                count = st.countTokens();

                byte[] bdata = new byte[count];
                for (int i = 0; i < count; i++) {
                    bdata[i] = (byte)Integer.parseInt(st.nextToken());
                }

                type = TIFFTag.TIFF_UNDEFINED;
                data = bdata;
            } else {
                int[] otype = new int[1];
                int[] ocount = new int[1];
                Object[] odata = new Object[1];

                initData(node.getFirstChild(), otype, ocount, odata);
                type = otype[0];
                count = ocount[0];
                data = odata[0];
            }
        } else if (tag != null) {
            int t = TIFFTag.MAX_DATATYPE;
            while(t >= TIFFTag.MIN_DATATYPE && !tag.isDataTypeOK(t)) {
                t--;
            }
            type = t;
        }

        if (tag == null) {
            tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber, 1 << type);
        }

        return new TIFFField(tag, type, count, data);
    }

    /**
     * Constructs a {@code TIFFField} with arbitrary data. The
     * {@code type} parameter must be a value for which
     * {@link TIFFTag#isDataTypeOK tag.isDataTypeOK()}
     * returns {@code true}. The {@code data} parameter must
     * be an array of a Java type appropriate for the type of the TIFF
     * field.
     *
     * <p>Note that the value (data) of the {@code TIFFField}
     * will always be the actual field value regardless of the number of
     * bytes required for that value. This is the case despite the fact
     * that the TIFF <i>IFD Entry</i> corresponding to the field may
     * actually contain the offset to the value of the field rather than
     * the value itself (the latter occurring if and only if the
     * value fits into 4 bytes). In other words, the value of the
     * field will already have been read from the TIFF stream. (An exception
     * to this case may occur when the field represents the contents of a
     * non-baseline IFD. In that case the data will be a {@code long[]}
     * containing the offset to the IFD and the {@code TIFFDirectory}
     * returned by {@link #getDirectory()} will be its contents.)
     *
     * @param tag The tag to associated with this field.
     * @param type One of the {@code TIFFTag.TIFF_*} constants
     * indicating the data type of the field as written to the TIFF stream.
     * @param count The number of data values.
     * @param data The actual data content of the field.
     *
     * @throws NullPointerException if {@code tag&nbsp;==&nbsp;null}.
     * @throws IllegalArgumentException if {@code type} is not
     * one of the {@code TIFFTag.TIFF_*} data type constants.
     * @throws IllegalArgumentException if {@code type} is an unacceptable
     * data type for the supplied {@code TIFFTag}.
     * @throws IllegalArgumentException if {@code count&nbsp;&lt;&nbsp;0}.
     * @throws IllegalArgumentException if {@code count&nbsp;&lt;&nbsp;1}
     * and {@code type} is {@code TIFF_RATIONAL} or
     * {@code TIFF_SRATIONAL}.
     * @throws IllegalArgumentException if {@code count&nbsp;&ne;&nbsp;1}
     * and {@code type} is {@code TIFF_IFD_POINTER}.
     * @throws NullPointerException if {@code data&nbsp;==&nbsp;null}.
     * @throws IllegalArgumentException if {@code data} is an instance of
     * a class incompatible with the specified type.
     * @throws IllegalArgumentException if the size of the data array is wrong.
     */
    public TIFFField(TIFFTag tag, int type, int count, Object data) {
        if(tag == null) {
            throw new NullPointerException("tag == null!");
        } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
            throw new IllegalArgumentException("Unknown data type "+type);
        } else if(!tag.isDataTypeOK(type)) {
            throw new IllegalArgumentException("Illegal data type " + type
                + " for " + tag.getName() + " tag");
        } else if(count < 0) {
            throw new IllegalArgumentException("count < 0!");
        } else if((type == TIFFTag.TIFF_RATIONAL
                   || type == TIFFTag.TIFF_SRATIONAL)
                  && count < 1) {
            throw new IllegalArgumentException
                ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
        } else if (type == TIFFTag.TIFF_IFD_POINTER && count != 1) {
            throw new IllegalArgumentException
                ("Type is TIFF_IFD_POINTER count != 1");
        } else if(data == null) {
            throw new NullPointerException("data == null!");
        }

        boolean isDataArrayCorrect = false;

        switch (type) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_SBYTE:
        case TIFFTag.TIFF_UNDEFINED:
            isDataArrayCorrect = data instanceof byte[]
                && ((byte[])data).length == count;
            break;
        case TIFFTag.TIFF_ASCII:
            isDataArrayCorrect = data instanceof String[]
                && ((String[])data).length == count;
            break;
        case TIFFTag.TIFF_SHORT:
            isDataArrayCorrect = data instanceof char[]
                && ((char[])data).length == count;
            break;
        case TIFFTag.TIFF_LONG:
            isDataArrayCorrect = data instanceof long[]
                && ((long[])data).length == count;
            break;
        case TIFFTag.TIFF_IFD_POINTER:
            isDataArrayCorrect = data instanceof long[]
                && ((long[])data).length == 1;
            break;
        case TIFFTag.TIFF_RATIONAL:
            isDataArrayCorrect = data instanceof long[][]
                && ((long[][])data).length == count
                && ((long[][])data)[0].length == 2;
            break;
        case TIFFTag.TIFF_SSHORT:
            isDataArrayCorrect = data instanceof short[]
                && ((short[])data).length == count;
            break;
        case TIFFTag.TIFF_SLONG:
            isDataArrayCorrect = data instanceof int[]
                && ((int[])data).length == count;
            break;
        case TIFFTag.TIFF_SRATIONAL:
            isDataArrayCorrect = data instanceof int[][]
                && ((int[][])data).length == count
                && ((int[][])data)[0].length == 2;
            break;
        case TIFFTag.TIFF_FLOAT:
            isDataArrayCorrect = data instanceof float[]
                && ((float[])data).length == count;
            break;
        case TIFFTag.TIFF_DOUBLE:
            isDataArrayCorrect = data instanceof double[]
                && ((double[])data).length == count;
            break;
        default:
            throw new IllegalArgumentException("Unknown data type "+type);
        }

        if (!isDataArrayCorrect) {
            throw new IllegalArgumentException
                ("Illegal class or length for data array");
        }

        this.tag = tag;
        this.tagNumber = tag.getNumber();
        this.type = type;
        this.count = count;
        this.data = data;
    }

    /**
     * Constructs a data array using {@link #createArrayForType
     * createArrayForType()} and invokes
     * {@link #TIFFField(TIFFTag,int,int,Object)} with the supplied
     * parameters and the created array.
     *
     * @param tag The tag to associated with this field.
     * @param type One of the {@code TIFFTag.TIFF_*} constants
     * indicating the data type of the field as written to the TIFF stream.
     * @param count The number of data values.
     * @throws NullPointerException if {@code tag&nbsp;==&nbsp;null}.
     * @throws IllegalArgumentException if {@code type} is not
     * one of the {@code TIFFTag.TIFF_*} data type constants.
     * @throws IllegalArgumentException if {@code type} is an unacceptable
     * data type for the supplied {@code TIFFTag}.
     * @throws IllegalArgumentException if {@code count&nbsp;&lt;&nbsp;0}.
     * @see #TIFFField(TIFFTag,int,int,Object)
     */
    public TIFFField(TIFFTag tag, int type, int count) {
        this(tag, type, count, createArrayForType(type, count));
    }

    /**
     * Constructs a {@code TIFFField} with a single non-negative integral
     * value.
     * The field will have type
     * {@link TIFFTag#TIFF_SHORT  TIFF_SHORT} if
     * {@code val&nbsp;&lt;&nbsp;65536} and type
     * {@link TIFFTag#TIFF_LONG TIFF_LONG} otherwise.  The count
     * of the field will be unity.
     *
     * @param tag The tag to associate with this field.
     * @param value The value to associate with this field.
     * @throws NullPointerException if {@code tag&nbsp;==&nbsp;null}.
     * @throws IllegalArgumentException if the derived type is unacceptable
     * for the supplied {@code TIFFTag}.
     * @throws IllegalArgumentException if {@code value&nbsp;&lt;&nbsp;0}.
     */
    public TIFFField(TIFFTag tag, int value) {
        if(tag == null) {
            throw new NullPointerException("tag == null!");
        }
        if (value < 0) {
            throw new IllegalArgumentException("value < 0!");
        }

        this.tag = tag;
        this.tagNumber = tag.getNumber();
        this.count = 1;

        if (value < 65536) {
            if (!tag.isDataTypeOK(TIFFTag.TIFF_SHORT)) {
                throw new IllegalArgumentException("Illegal data type "
                    + TIFFTag.TIFF_SHORT + " for " + tag.getName() + " tag");
            }
            this.type = TIFFTag.TIFF_SHORT;
            char[] cdata = new char[1];
            cdata[0] = (char)value;
            this.data = cdata;
        } else {
            if (!tag.isDataTypeOK(TIFFTag.TIFF_LONG)) {
                throw new IllegalArgumentException("Illegal data type "
                    + TIFFTag.TIFF_LONG + " for " + tag.getName() + " tag");
            }
            this.type = TIFFTag.TIFF_LONG;
            long[] ldata = new long[1];
            ldata[0] = value;
            this.data = ldata;
        }
    }

    /**
     * Constructs a {@code TIFFField} with an IFD offset and contents.
     * The offset will be stored as the data of this field as
     * {@code long[] {offset}}. The directory will not be cloned. The count
     * of the field will be unity.
     *
     * @param tag The tag to associated with this field.
     * @param type One of the constants {@code TIFFTag.TIFF_LONG} or
     * {@code TIFFTag.TIFF_IFD_POINTER}.
     * @param offset The IFD offset.
     * @param dir The directory.
     *
     * @throws NullPointerException if {@code tag&nbsp;==&nbsp;null}.
     * @throws IllegalArgumentException if {@code type} is neither
     * {@code TIFFTag.TIFF_LONG} nor {@code TIFFTag.TIFF_IFD_POINTER}.
     * @throws IllegalArgumentException if {@code type} is an unacceptable
     * data type for the supplied {@code TIFFTag}.
     * @throws IllegalArgumentException if {@code offset} is non-positive.
     * @throws NullPointerException if {@code dir&nbsp;==&nbsp;null}.
     *
     * @see #TIFFField(TIFFTag,int,int,Object)
     */
    public TIFFField(TIFFTag tag, int type, long offset, TIFFDirectory dir) {
        this(tag, type, 1, new long[] {offset});
        if (type != TIFFTag.TIFF_LONG && type != TIFFTag.TIFF_IFD_POINTER) {
            throw new IllegalArgumentException("type " + type
                + " is neither TIFFTag.TIFF_LONG nor TIFFTag.TIFF_IFD_POINTER");
        } else if (offset <= 0) {
            throw new IllegalArgumentException("offset " + offset
                + " is non-positive");
        } else if (dir == null) {
            throw new NullPointerException("dir == null");
        }
        this.dir = dir;
    }

    /**
     * Retrieves the tag associated with this field.
     *
     * @return The associated {@code TIFFTag}.
     */
    public TIFFTag getTag() {
        return tag;
    }

    /**
     * Retrieves the tag number in the range {@code [0,&nbsp;65535]}.
     *
     * @return The tag number.
     */
    public int getTagNumber() {
        return tagNumber;
    }

    /**
     * Returns the type of the data stored in the field.  For a TIFF 6.0
     * stream, the value will equal one of the {@code TIFFTag.TIFF_*}
     * constants. For future revisions of TIFF, higher values are possible.
     *
     * @return The data type of the field value.
     */
    public int getType() {
        return type;
    }

    /**
     * Returns the name of the supplied data type constant.
     *
     * @param dataType One of the {@code TIFFTag.TIFF_*} constants
     * indicating the data type of the field as written to the TIFF stream.
     * @return The type name corresponding to the supplied type constant.
     * @throws IllegalArgumentException if {@code dataType} is not
     * one of the {@code TIFFTag.TIFF_*} data type constants.
     */
    public static String getTypeName(int dataType) {
        if (dataType < TIFFTag.MIN_DATATYPE ||
            dataType > TIFFTag.MAX_DATATYPE) {
            throw new IllegalArgumentException("Unknown data type "+dataType);
        }

        return typeNames[dataType];
    }

    /**
     * Returns the data type constant corresponding to the supplied data
     * type name. If the name is unknown {@code -1} will be returned.
     *
     * @param typeName The type name.
     * @return One of the {@code TIFFTag.TIFF_*} constants or
     * {@code -1} if the name is not recognized.
     */
    public static int getTypeByName(String typeName) {
        for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
            if (typeName.equals(typeNames[i])) {
                return i;
            }
        }

        return -1;
    }

    /**
     * Creates an array appropriate for the indicated data type.
     *
     * @param dataType One of the {@code TIFFTag.TIFF_*} data type
     * constants.
     * @param count The number of values in the array.
     * @return An array appropriate for the specified data type.
     *
     * @throws IllegalArgumentException if {@code dataType} is not
     * one of the {@code TIFFTag.TIFF_*} data type constants.
     * @throws IllegalArgumentException if {@code count&nbsp;&lt;&nbsp;0}.
     */
    public static Object createArrayForType(int dataType, int count) {
        if(count < 0) {
            throw new IllegalArgumentException("count < 0!");
        }
        switch (dataType) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_SBYTE:
        case TIFFTag.TIFF_UNDEFINED:
            return new byte[count];
        case TIFFTag.TIFF_ASCII:
            return new String[count];
        case TIFFTag.TIFF_SHORT:
            return new char[count];
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            return new long[count];
        case TIFFTag.TIFF_RATIONAL:
            return new long[count][2];
        case TIFFTag.TIFF_SSHORT:
            return new short[count];
        case TIFFTag.TIFF_SLONG:
            return new int[count];
        case TIFFTag.TIFF_SRATIONAL:
            return new int[count][2];
        case TIFFTag.TIFF_FLOAT:
            return new float[count];
        case TIFFTag.TIFF_DOUBLE:
            return new double[count];
        default:
            throw new IllegalArgumentException("Unknown data type "+dataType);
        }
    }

    /**
     * Returns the {@code TIFFField} as a node named either
     * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
     * TIFF native image metadata specification. The node will be named
     * <tt>"TIFFIFD"</tt> if and only if the field's data object is an
     * instance of {@link TIFFDirectory} or equivalently
     * {@link TIFFTag#isIFDPointer getTag.isIFDPointer()} returns
     * {@code true}.
     *
     * @return a {@code Node} named <tt>"TIFFField"</tt> or
     * <tt>"TIFFIFD"</tt>.
     */
    public Node getAsNativeNode() {
        return new TIFFFieldNode(this);
    }

    /**
     * Indicates whether the value associated with the field is of
     * integral data type.
     *
     * @return Whether the field type is integral.
     */
    public boolean isIntegral() {
        return isIntegral[type];
    }

    /**
     * Returns the number of data items present in the field.  For
     * {@code TIFFTag.TIFF_ASCII} fields, the value returned is the
     * number of {@code String}s, not the total length of the
     * data as in the file representation.
     *
     * @return The number of data items present in the field.
     */
    public int getCount() {
        return count;
    }

    /**
     * Returns a reference to the data object associated with the field.
     *
     * @return The data object of the field.
     */
    public Object getData() {
        return data;
    }

    /**
     * Returns the data as an uninterpreted array of
     * {@code byte}s.  The type of the field must be one of
     * {@code TIFFTag.TIFF_BYTE}, {@code TIFF_SBYTE}, or
     * {@code TIFF_UNDEFINED}.
     *
     * <p> For data in {@code TIFFTag.TIFF_BYTE} format, the application
     * must take care when promoting the data to longer integral types
     * to avoid sign extension.
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_BYTE}, {@code TIFF_SBYTE}, or
     * {@code TIFF_UNDEFINED}.
     * @return The data as an uninterpreted array of bytes.
     */
    public byte[] getAsBytes() {
        return (byte[])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_SHORT} data as an array of
     * {@code char}s (unsigned 16-bit integers).
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_SHORT}.
     * @return The data as an array of {@code char}s.
     */
    public char[] getAsChars() {
        return (char[])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_SSHORT} data as an array of
     * {@code short}s (signed 16-bit integers).
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_SSHORT}.
     * @return The data as an array of {@code short}s.
     */
    public short[] getAsShorts() {
        return (short[])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_SLONG} data as an array of
     * {@code int}s (signed 32-bit integers).
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_SHORT}, {@code TIFF_SSHORT}, or
     * {@code TIFF_SLONG}.
     * @return The data as an array of {@code int}s.
     */
    public int[] getAsInts() {
        if (data instanceof int[]) {
            return (int[])data;
        } else if (data instanceof char[]){
            char[] cdata = (char[])data;
            int[] idata = new int[cdata.length];
            for (int i = 0; i < cdata.length; i++) {
                idata[i] = cdata[i] & 0xffff;
            }
            return idata;
        } else if (data instanceof short[]){
            short[] sdata = (short[])data;
            int[] idata = new int[sdata.length];
            for (int i = 0; i < sdata.length; i++) {
                idata[i] = (int)sdata[i];
            }
            return idata;
        } else {
            throw new ClassCastException("Data not char[], short[], or int[]!");
        }
    }

    /**
     * Returns {@code TIFFTag.TIFF_LONG} or
     * {@code TIFF_IFD_POINTER} data as an array of
     * {@code long}s (signed 64-bit integers).
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_LONG} or {@code TIFF_IFD_POINTER}.
     * @return The data as an array of {@code long}s.
     */
    public long[] getAsLongs() {
        return (long[])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_FLOAT} data as an array of
     * {@code float}s (32-bit floating-point values).
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_FLOAT}.
     * @return The data as an array of {@code float}s.
     */
    public float[] getAsFloats() {
        return (float[])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_DOUBLE} data as an array of
     * {@code double}s (64-bit floating-point values).
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_DOUBLE}.
     * @return The data as an array of {@code double}s.
     */
    public double[] getAsDoubles() {
        return (double[])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_SRATIONAL} data as an array of
     * 2-element arrays of {@code int}s.
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_SRATIONAL}.
     * @return The data as an array of signed rationals.
     */
    public int[][] getAsSRationals() {
        return (int[][])data;
    }

    /**
     * Returns {@code TIFFTag.TIFF_RATIONAL} data as an array of
     * 2-element arrays of {@code long}s.
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_RATIONAL}.
     * @return The data as an array of unsigned rationals.
     */
    public long[][] getAsRationals() {
        return (long[][])data;
    }

    /**
     * Returns data in any format as an {@code int}.
     *
     * <p> {@code TIFFTag.TIFF_BYTE} values are treated as unsigned; that
     * is, no sign extension will take place and the returned value
     * will be in the range [0, 255].  {@code TIFF_SBYTE} data
     * will be returned in the range [-128, 127].
     *
     * <p> A {@code TIFF_UNDEFINED} value is treated as though
     * it were a {@code TIFF_BYTE}.
     *
     * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
     * {@code TIFF_FLOAT}, {@code TIFF_DOUBLE} or
     * {@code TIFF_IFD_POINTER} format are simply cast to
     * {@code int} and may suffer from truncation.
     *
     * <p> Data in {@code TIFF_SRATIONAL} or
     * {@code TIFF_RATIONAL} format are evaluated by dividing the
     * numerator into the denominator using double-precision
     * arithmetic and then casting to {@code int}.  Loss of
     * precision and truncation may occur.
     *
     * <p> Data in {@code TIFF_ASCII} format will be parsed as by
     * the {@code Double.parseDouble} method, with the result
     * case to {@code int}.
     *
     * @param index The index of the data.
     * @return The data at the given index as an {@code int}.
     */
    public int getAsInt(int index) {
        switch (type) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_UNDEFINED:
            return ((byte[])data)[index] & 0xff;
        case TIFFTag.TIFF_SBYTE:
            return ((byte[])data)[index];
        case TIFFTag.TIFF_SHORT:
            return ((char[])data)[index] & 0xffff;
        case TIFFTag.TIFF_SSHORT:
            return ((short[])data)[index];
        case TIFFTag.TIFF_SLONG:
            return ((int[])data)[index];
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            return (int)((long[])data)[index];
        case TIFFTag.TIFF_FLOAT:
            return (int)((float[])data)[index];
        case TIFFTag.TIFF_DOUBLE:
            return (int)((double[])data)[index];
        case TIFFTag.TIFF_SRATIONAL:
            int[] ivalue = getAsSRational(index);
            return (int)((double)ivalue[0]/ivalue[1]);
        case TIFFTag.TIFF_RATIONAL:
            long[] lvalue = getAsRational(index);
            return (int)((double)lvalue[0]/lvalue[1]);
        case TIFFTag.TIFF_ASCII:
             String s = ((String[])data)[index];
             return (int)Double.parseDouble(s);
        default:
            throw new ClassCastException(); // should never happen
        }
    }

    /**
     * Returns data in any format as a {@code long}.
     *
     * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
     * are treated as unsigned; that is, no sign extension will take
     * place and the returned value will be in the range [0, 255].
     * {@code TIFF_SBYTE} data will be returned in the range
     * [-128, 127].
     *
     * <p> Data in {@code TIFF_FLOAT} and {@code TIFF_DOUBLE} are
     * simply cast to {@code long} and may suffer from truncation.
     *
     * <p> Data in {@code TIFF_SRATIONAL} or
     * {@code TIFF_RATIONAL} format are evaluated by dividing the
     * numerator into the denominator using double-precision
     * arithmetic and then casting to {@code long}.  Loss of
     * precision and truncation may occur.
     *
     * <p> Data in {@code TIFF_ASCII} format will be parsed as by
     * the {@code Double.parseDouble} method, with the result
     * cast to {@code long}.
     *
     * @param index The index of the data.
     * @return The data at the given index as a {@code long}.
     */
    public long getAsLong(int index) {
        switch (type) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_UNDEFINED:
            return ((byte[])data)[index] & 0xff;
        case TIFFTag.TIFF_SBYTE:
            return ((byte[])data)[index];
        case TIFFTag.TIFF_SHORT:
            return ((char[])data)[index] & 0xffff;
        case TIFFTag.TIFF_SSHORT:
            return ((short[])data)[index];
        case TIFFTag.TIFF_SLONG:
            return ((int[])data)[index];
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            return ((long[])data)[index];
        case TIFFTag.TIFF_FLOAT:
            return (long)((float[])data)[index];
        case TIFFTag.TIFF_DOUBLE:
            return (long)((double[])data)[index];
        case TIFFTag.TIFF_SRATIONAL:
            int[] ivalue = getAsSRational(index);
            return (long)((double)ivalue[0]/ivalue[1]);
        case TIFFTag.TIFF_RATIONAL:
            long[] lvalue = getAsRational(index);
            return (long)((double)lvalue[0]/lvalue[1]);
        case TIFFTag.TIFF_ASCII:
             String s = ((String[])data)[index];
             return (long)Double.parseDouble(s);
        default:
            throw new ClassCastException(); // should never happen
        }
    }

    /**
     * Returns data in any format as a {@code float}.
     *
     * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
     * are treated as unsigned; that is, no sign extension will take
     * place and the returned value will be in the range [0, 255].
     * {@code TIFF_SBYTE} data will be returned in the range
     * [-128, 127].
     *
     * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
     * {@code TIFF_DOUBLE}, or {@code TIFF_IFD_POINTER} format are
     * simply cast to {@code float} and may suffer from
     * truncation.
     *
     * <p> Data in {@code TIFF_SRATIONAL} or
     * {@code TIFF_RATIONAL} format are evaluated by dividing the
     * numerator into the denominator using double-precision
     * arithmetic and then casting to {@code float}.
     *
     * <p> Data in {@code TIFF_ASCII} format will be parsed as by
     * the {@code Double.parseDouble} method, with the result
     * cast to {@code float}.
     *
     * @param index The index of the data.
     * @return The data at the given index as a {@code float}.
     */
    public float getAsFloat(int index) {
        switch (type) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_UNDEFINED:
            return ((byte[])data)[index] & 0xff;
        case TIFFTag.TIFF_SBYTE:
            return ((byte[])data)[index];
        case TIFFTag.TIFF_SHORT:
            return ((char[])data)[index] & 0xffff;
        case TIFFTag.TIFF_SSHORT:
            return ((short[])data)[index];
        case TIFFTag.TIFF_SLONG:
            return ((int[])data)[index];
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            return ((long[])data)[index];
        case TIFFTag.TIFF_FLOAT:
            return ((float[])data)[index];
        case TIFFTag.TIFF_DOUBLE:
            return (float)((double[])data)[index];
        case TIFFTag.TIFF_SRATIONAL:
            int[] ivalue = getAsSRational(index);
            return (float)((double)ivalue[0]/ivalue[1]);
        case TIFFTag.TIFF_RATIONAL:
            long[] lvalue = getAsRational(index);
            return (float)((double)lvalue[0]/lvalue[1]);
        case TIFFTag.TIFF_ASCII:
             String s = ((String[])data)[index];
             return (float)Double.parseDouble(s);
        default:
            throw new ClassCastException(); // should never happen
        }
    }

    /**
     * Returns data in any format as a {@code double}.
     *
     * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
     * are treated as unsigned; that is, no sign extension will take
     * place and the returned value will be in the range [0, 255].
     * {@code TIFF_SBYTE} data will be returned in the range
     * [-128, 127].
     *
     * <p> Data in {@code TIFF_SRATIONAL} or
     * {@code TIFF_RATIONAL} format are evaluated by dividing the
     * numerator into the denominator using double-precision
     * arithmetic.
     *
     * <p> Data in {@code TIFF_ASCII} format will be parsed as by
     * the {@code Double.parseDouble} method.
     *
     * @param index The index of the data.
     * @return The data at the given index as a {@code double}.
     */
    public double getAsDouble(int index) {
        switch (type) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_UNDEFINED:
            return ((byte[])data)[index] & 0xff;
        case TIFFTag.TIFF_SBYTE:
            return ((byte[])data)[index];
        case TIFFTag.TIFF_SHORT:
            return ((char[])data)[index] & 0xffff;
        case TIFFTag.TIFF_SSHORT:
            return ((short[])data)[index];
        case TIFFTag.TIFF_SLONG:
            return ((int[])data)[index];
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            return ((long[])data)[index];
        case TIFFTag.TIFF_FLOAT:
            return ((float[])data)[index];
        case TIFFTag.TIFF_DOUBLE:
            return ((double[])data)[index];
        case TIFFTag.TIFF_SRATIONAL:
            int[] ivalue = getAsSRational(index);
            return (double)ivalue[0]/ivalue[1];
        case TIFFTag.TIFF_RATIONAL:
            long[] lvalue = getAsRational(index);
            return (double)lvalue[0]/lvalue[1];
        case TIFFTag.TIFF_ASCII:
             String s = ((String[])data)[index];
             return Double.parseDouble(s);
        default:
            throw new ClassCastException(); // should never happen
        }
    }

    /**
     * Returns a {@code TIFFTag.TIFF_ASCII} value as a
     * {@code String}.
     *
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_ASCII}.
     *
     * @param index The index of the data.
     * @return The data at the given index as a {@code String}.
     */
    public String getAsString(int index) {
        return ((String[])data)[index];
    }

    /**
     * Returns a {@code TIFFTag.TIFF_SRATIONAL} data item as a
     * two-element array of {@code int}s.
     *
     * @param index The index of the data.
     * @return The data at the given index as a signed rational.
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_SRATIONAL}.
     */
    public int[] getAsSRational(int index) {
        return ((int[][])data)[index];
    }

    /**
     * Returns a TIFFTag.TIFF_RATIONAL data item as a two-element array
     * of ints.
     *
     * @param index The index of the data.
     * @return The data at the given index as an unsigned rational.
     * @throws ClassCastException if the field is not of type
     * {@code TIFF_RATIONAL}.
     */
    public long[] getAsRational(int index) {
        return ((long[][])data)[index];
    }


    /**
     * Returns a {@code String} containing a human-readable
     * version of the data item.  Data of type
     * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} are
     * represented as a pair of integers separated by a
     * {@code '/'} character.  If the numerator of a
     * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} is an integral
     * multiple of the denominator, then the value is represented as
     * {@code "q/1"} where {@code q} is the quotient of the numerator and
     * denominator.
     *
     * @param index The index of the data.
     * @return The data at the given index as a {@code String}.
     * @throws ClassCastException if the field is not of one of the
     * legal field types.
     */
    public String getValueAsString(int index) {
        switch (type) {
        case TIFFTag.TIFF_ASCII:
            return ((String[])data)[index];
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_UNDEFINED:
            return Integer.toString(((byte[])data)[index] & 0xff);
        case TIFFTag.TIFF_SBYTE:
            return Integer.toString(((byte[])data)[index]);
        case TIFFTag.TIFF_SHORT:
            return Integer.toString(((char[])data)[index] & 0xffff);
        case TIFFTag.TIFF_SSHORT:
            return Integer.toString(((short[])data)[index]);
        case TIFFTag.TIFF_SLONG:
            return Integer.toString(((int[])data)[index]);
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            return Long.toString(((long[])data)[index]);
        case TIFFTag.TIFF_FLOAT:
            return Float.toString(((float[])data)[index]);
        case TIFFTag.TIFF_DOUBLE:
            return Double.toString(((double[])data)[index]);
        case TIFFTag.TIFF_SRATIONAL:
            int[] ivalue = getAsSRational(index);
            String srationalString;
            if(ivalue[1] != 0 && ivalue[0] % ivalue[1] == 0) {
                // If the denominator is a non-zero integral divisor
                // of the numerator then convert the fraction to be
                // with respect to a unity denominator.
                srationalString =
                    Integer.toString(ivalue[0] / ivalue[1]) + "/1";
            } else {
                // Use the values directly.
                srationalString =
                    Integer.toString(ivalue[0]) +
                    "/" +
                    Integer.toString(ivalue[1]);
            }
            return srationalString;
        case TIFFTag.TIFF_RATIONAL:
            long[] lvalue = getAsRational(index);
            String rationalString;
            if(lvalue[1] != 0L && lvalue[0] % lvalue[1] == 0) {
                // If the denominator is a non-zero integral divisor
                // of the numerator then convert the fraction to be
                // with respect to a unity denominator.
                rationalString =
                    Long.toString(lvalue[0] / lvalue[1]) + "/1";
            } else {
                // Use the values directly.
                rationalString =
                    Long.toString(lvalue[0]) +
                    "/" +
                    Long.toString(lvalue[1]);
            }
            return rationalString;
        default:
            throw new ClassCastException(); // should never happen
        }
    }

    /**
     * Returns whether the field has a {@code TIFFDirectory}.
     *
     * @return true if and only if getDirectory() returns non-null.
     */
    public boolean hasDirectory() {
        return getDirectory() != null;
    }

    /**
     * Returns the associated {@code TIFFDirectory}, if available. If no
     * directory is set, then {@code null} will be returned.
     *
     * @return the TIFFDirectory instance or null.
     */
    public TIFFDirectory getDirectory() {
        return dir;
    }

    /**
     * Clones the field and all the information contained therein.
     *
     * @return A clone of this {@code TIFFField}.
     * @throws CloneNotSupportedException if the instance cannot be cloned.
     */
    @Override
    public TIFFField clone() throws CloneNotSupportedException {
        TIFFField field = (TIFFField)super.clone();

        Object fieldData;
        switch (type) {
        case TIFFTag.TIFF_BYTE:
        case TIFFTag.TIFF_UNDEFINED:
        case TIFFTag.TIFF_SBYTE:
            fieldData = ((byte[])data).clone();
            break;
        case TIFFTag.TIFF_SHORT:
            fieldData = ((char[])data).clone();
            break;
        case TIFFTag.TIFF_SSHORT:
            fieldData = ((short[])data).clone();
            break;
        case TIFFTag.TIFF_SLONG:
            fieldData = ((int[])data).clone();
            break;
        case TIFFTag.TIFF_LONG:
        case TIFFTag.TIFF_IFD_POINTER:
            fieldData = ((long[])data).clone();
            break;
        case TIFFTag.TIFF_FLOAT:
            fieldData = ((float[])data).clone();
            break;
        case TIFFTag.TIFF_DOUBLE:
            fieldData = ((double[])data).clone();
            break;
        case TIFFTag.TIFF_SRATIONAL:
            fieldData = ((int[][])data).clone();
            break;
        case TIFFTag.TIFF_RATIONAL:
            fieldData = ((long[][])data).clone();
            break;
        case TIFFTag.TIFF_ASCII:
            fieldData = ((String[])data).clone();
            break;
        default:
            throw new ClassCastException(); // should never happen
        }

        field.tag = tag;
        field.tagNumber = tagNumber;
        field.type = type;
        field.count = count;
        field.data = fieldData;
        field.dir = dir != null ? dir.clone() : null;

        return field;
    }
}
