All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.monte.media.tiff.IFDEntry Maven / Gradle / Ivy

The newest version!

package org.monte.media.tiff;

import java.io.IOException;
import java.nio.ByteOrder;


public class IFDEntry {


    private int tagNumber;

    private int typeNumber;

    private long count;

    private long valueOffset;

    private long entryOffset;

    private long ifdOffset;

    private Object data;

    public IFDEntry(int tagNumber, int typeNumber, long count, long valueOffset, long entryOffset) {
        this.tagNumber = tagNumber;
        this.typeNumber = typeNumber;
        this.count = count;
        this.valueOffset = valueOffset;
        this.entryOffset = entryOffset;
    }

    public long getCount() {
        return count;
    }

    public int getTagNumber() {
        return tagNumber;
    }

    public int getTypeNumber() {
        return typeNumber;
    }


    public long getValueOffset() {
        return valueOffset;
    }


    public long getDataOffset() {
        return isDataInValueOffset() ? entryOffset + 8 : valueOffset+ifdOffset;
    }

    public void setIFDOffset(long newValue) {
        ifdOffset = newValue;
    }

    public long getEntryOffset() {
        return entryOffset;
    }
    public long getIFDOffset() {
        return ifdOffset;
    }

    public boolean isDataInValueOffset() {
        switch (IFDDataType.valueOf(typeNumber)) {
            case ASCII:

                return false;
            case BYTE:
                return count <= 4;
            case SHORT:
                return count <= 2;
            case LONG:
                return count <= 1;
            case RATIONAL:
                return false;
            case SBYTE:
                return count <= 4;
            case UNDEFINED:
                return count <= 4;
            case SSHORT:
                return count <= 2;
            case SLONG:
                return count <= 1;
            case SRATIONAL:
                return false;
            case FLOAT:
                return count <= 1;
            case DOUBLE:
                return false;
            default:
                return true;
        }
    }

    public long getLength() {
        switch (IFDDataType.valueOf(typeNumber)) {
            case ASCII:
                return count;
            case BYTE:
                return count;
            case SHORT:
                return count * 2;
            case LONG:
                return count * 4;
            case RATIONAL:
                return count * 8;
            case SBYTE:
                return count;
            case UNDEFINED:
                return count;
            case SSHORT:
                return count * 2;
            case SLONG:
                return count * 4;
            case SRATIONAL:
                return count * 8;
            case FLOAT:
                return count * 4;
            case DOUBLE:
                return count * 8;
            default:
                return 0;
        }
    }


    public Object readData(TIFFInputStream in) throws IOException {
        return readData(in, ifdOffset);
    }


    public Object readData(TIFFInputStream in, long ifdDataOffset) throws IOException {
        Object d = null;
        IFDDataType tt = IFDDataType.valueOf(typeNumber);
        if (tt != null) {
            switch (tt) {
                case ASCII:

                    if (count <= 4) {
                        StringBuilder buf = new StringBuilder();
                        int data = (int) valueOffset;
                        if (in.getByteOrder() == ByteOrder.LITTLE_ENDIAN) {
                            for (int i = 0; i < count - 1; i++) {
                                buf.append((char) (data & 0xff));
                                data >>= 8;
                            }
                        } else {
                            for (int i = 0; i < count - 1; i++) {
                                buf.append((char) (data >>> 24));
                                data <<= 8;
                            }
                        }
                        return buf.toString();
                    } else {
                        return in.readASCII(valueOffset + ifdDataOffset, count);
                    }
                case SHORT:
                    if (count == 1) {
                        if (in.getByteOrder() == ByteOrder.LITTLE_ENDIAN) {
                            d = (int) (valueOffset & 0xffff);
                        } else {
                            d = (int) ((valueOffset >> 16) & 0xffff);
                        }
                    } else if (count == 2) {
                        d = new int[]{(int) (valueOffset & 0xffff), (int) ((valueOffset & 0xffff0000) >> 16)};
                    } else {
                        d = in.readSHORT(valueOffset + ifdDataOffset, count);
                    }
                    break;
                case LONG:
                    if (count == 1) {
                        d = valueOffset;
                    } else {
                        d = in.readLONG(valueOffset + ifdDataOffset, count);
                    }
                    break;
                case RATIONAL:
                    if (count == 1) {
                        d = in.readRATIONAL(valueOffset + ifdDataOffset);
                    } else {
                        d = in.readRATIONAL(valueOffset + ifdDataOffset, count);
                    }
                    break;
                case BYTE:
                    if (count == 1) {
                        d = (short) (valueOffset & 0xff);
                    } else if (count == 2) {
                        d = new short[]{(short) ((valueOffset & 0xff00) >> 8), (short) (valueOffset & 0xff)};
                    } else if (count == 3) {
                        d = new short[]{(short) ((valueOffset & 0xff0000) >> 16), (short) ((valueOffset & 0xff00) >> 8), (short) (valueOffset & 0xff)};
                    } else if (count == 4) {
                        d = new short[]{(short) ((valueOffset & 0xff000000) >> 24), (short) ((valueOffset & 0xff0000) >> 16), (short) ((valueOffset & 0xff00) >> 8), (short) (valueOffset & 0xff)};
                    } else {
                        byte[] b = new byte[(int) count];
                        in.read(valueOffset + ifdDataOffset, b, 0, b.length);
                        short[] s = new short[(int) count];
                        for (int i = 0; i < b.length; i++) {
                            s[i] = (short) (b[i] & 0xff);
                        }
                        d = s;
                    }
                    break;
                case SBYTE:
                case UNDEFINED:
                    if (count == 1) {
                        d = (byte) valueOffset;
                    } else if (count == 2) {
                        d = new byte[]{(byte) ((valueOffset & 0xff00) >> 8), (byte) (valueOffset & 0xff)};
                    } else if (count == 3) {
                        d = new byte[]{(byte) ((valueOffset & 0xff0000) >> 16), (byte) ((valueOffset & 0xff00) >> 8), (byte) (valueOffset & 0xff)};
                    } else if (count == 4) {
                        d = new byte[]{(byte) ((valueOffset & 0xff000000) >> 24), (byte) ((valueOffset & 0xff0000) >> 16), (byte) ((valueOffset & 0xff00) >> 8), (byte) (valueOffset & 0xff)};
                    } else {
                        byte[] b = new byte[(int) count];
                        in.read(valueOffset + ifdDataOffset, b, 0, b.length);
                        d = b;
                    }
                    break;
                case SSHORT:
                    if (count == 1) {
                        if (in.getByteOrder() == ByteOrder.LITTLE_ENDIAN) {
                            d = (short) (valueOffset & 0xffff);
                        } else {
                            d = (short) ((valueOffset >> 16) & 0xffff);
                        }
                    } else if (count == 2) {
                        d = new int[]{(short) (valueOffset & 0xffff), (short) ((valueOffset & 0xffff0000) >> 16)};
                    } else {
                        d = in.readSSHORT(valueOffset + ifdDataOffset, count);
                    }
                    break;
                case SLONG:
                    throw new IOException("Format " + typeNumber + " not implemented");
                case SRATIONAL:
                    if (count == 1) {
                        d = in.readSRATIONAL(valueOffset + ifdDataOffset);
                    } else {
                        d = in.readSRATIONAL(valueOffset + ifdDataOffset, count);
                    }
                    break;
                case FLOAT:
                case DOUBLE:
                default:
                    throw new IOException("Format " + typeNumber + " not implemented");
            }
        }
        return d;
    }

    public void loadData(TIFFInputStream in) throws IOException {
        data = readData(in);
    }

    public Object getData() {
        return data;
    }


    @Override
    public String toString() {
        return "IFD Entry: tag:0x" + Integer.toHexString(tagNumber) + " type:0x" + Integer.toHexString(typeNumber) + " count:0x" + Long.toHexString(count) + " valueOffset:0x" + Long.toHexString(valueOffset);
    }

    public String toString(Enum tagName) {
        StringBuilder buf = new StringBuilder();
        buf.append(
                "Entry tag:" + tagName + "(" + Integer.toHexString(tagNumber) + "), type:" + IFDDataType.valueOf(typeNumber) + "(" + typeNumber + "), count:" + count + ", valueOffset:" + valueOffset);
        if (data != null) {
            buf.append(", data:");
            if (data instanceof byte[]) {
                byte[] d = (byte[]) data;
                for (int i = 0; i < d.length; i++) {
                    if (i != 0) {
                        buf.append(',');
                    }
                    buf.append(d[i]);
                }
            } else if (data instanceof short[]) {
                short[] d = (short[]) data;
                for (int i = 0; i < d.length; i++) {
                    if (i != 0) {
                        buf.append(',');
                    }
                    buf.append(d[i]);
                }
            } else if (data instanceof int[]) {
                int[] d = (int[]) data;
                for (int i = 0; i < d.length; i++) {
                    if (i != 0) {
                        buf.append(',');
                    }
                    buf.append(d[i]);
                }
            } else if (data instanceof long[]) {
                long[] d = (long[]) data;
                for (int i = 0; i < d.length; i++) {
                    if (i != 0) {
                        buf.append(',');
                    }
                    buf.append(d[i]);
                }
            } else if (data instanceof Object[]) {
                Object[] d = (Object[]) data;
                for (int i = 0; i < d.length; i++) {
                    if (i != 0) {
                        buf.append(',');
                    }
                    buf.append(d[i]);
                }
            } else {
                buf.append(data);
            }
        }
        return buf.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy