/********************************************************************** * TDump - JSTOR/Harvard Object Validation Environment * Copyright 2003-2004 by JSTOR and the President and Fellows of Harvard College * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA **********************************************************************/ import edu.harvard.hul.ois.jhove.*; import edu.harvard.hul.ois.jhove.module.tiff.*; import java.io.*; import java.util.*; /** * Dump contents of TIFF file in human-readable format. */ public class TDump extends Dump { /****************************************************************** * PRIVATE CLASS FIELDS. ******************************************************************/ /** Count of IFDs. */ private static int _nIFDs; /** Sorted associative map of tags. */ private static Map _tags; /****************************************************************** * MAIN ENTRY POINT. ******************************************************************/ /** * Main entry point. * @param args Command line arguments */ public static void main (String [] args) { if (args.length < 1) { System.err.println ("usage: java TDump [-bs] file"); System.exit (-1); } String tiff = null; boolean nobyte = false; boolean nosub = false; for (int i=0; i 0) { } file.close (); } catch (Exception e) { e.printStackTrace (System.out); err = -2; } finally { /* Display all tags in offset-sorted order. */ Iterator iter = _tags.keySet ().iterator (); while (iter.hasNext ()) { String os = (String) iter.next (); System.out.println (os + ": " + (String) _tags.get (os)); } if (err != 0) { System.exit (err); } } } /** * Read IFDs. * @param file Open TIFF file * @param bigEndian True if big-endian * @param offset Byte offset of IFD * @param nobyte If true, only display the first 8 bytes of data of * type BYTE * @param nosub If true, do not parse subIFDs */ private static long readIFD (RandomAccessFile file, boolean bigEndian, long offset, boolean nobyte, boolean nosub) throws Exception { int nIFD = ++_nIFDs; List subIFDs = new ArrayList (); List stripByteCounts = new ArrayList (); List stripOffsets = new ArrayList (); file.seek (offset); int nEntries = ModuleBase.readUnsignedShort (file, bigEndian); _tags.put (leading (offset, 8) + offset, "IFD " + nIFD + " with " + nEntries + " entries"); String name = null; for (int i=0; i 4) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } StringBuffer ascii = new StringBuffer (); for (int j=0; j 4) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } buffer.append (" ="); long ct = count; if (nobyte && count > 8) { ct = 8; } for (int j=0; j 8) { buffer.append (" ..."); } } else if (type == IFD.DOUBLE) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo + " ="); for (int j=0; j 1) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } buffer.append (" ="); for (int j=0; j 1) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo + " = "); } else if (tag == 330 || /* Sub IFD */ tag == 34665 || /* EXIF IFD */ tag == 34853 || /* EXIF GPS IFD */ tag == 40965) { /* EXIF Interoperability IFD */ buffer.append (" @"); } else { buffer.append (" = "); } for (int j=0; j 0) { buffer.append (" "); } buffer.append (in); if (tag == 330 || /* Sub IFD */ tag == 34665 || /* EXIF IFD */ tag == 34853 || /* EXIF GPS IFD */ tag == 40965) { /* EXIF Interoperability IFD */ subIFDs.add (new Long (in)); } else if (tag == 273) { stripOffsets.add (new Long (in)); } else if (tag == 279) { stripByteCounts.add (new Long (in)); } } } else if (type == IFD.RATIONAL) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo + " ="); for (int j=0; j 4) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } buffer.append (" ="); for (int j=0; j 2) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } buffer.append (" ="); for (int j=0; j 1) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } buffer.append (" ="); for (int j=0; j 2) { long vo = ModuleBase.readUnsignedInt (file, bigEndian); file.seek (vo); buffer.append (" @" + vo); } buffer.append (" ="); for (int j=0; j 0) { } } } long os = offset + 2 + nEntries*12; file.seek (os); long next = ModuleBase.readUnsignedInt (file, bigEndian); _tags.put (leading (os, 8) + os, "NextIFDOffset LONG @" + next); int len = stripOffsets.size (); if (len > 0) { for (int j=0; j