/********************************************************************** * JDump - JSTOR/Harvard Object Validation Environment * Copyright 2004 by 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 java.io.*; //import java.util.*; /** * Dump contents of JPEG file in human-readable format. */ public class JDump extends Dump { /****************************************************************** * 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 JDump file"); System.exit (-1); } try { FileInputStream file = new FileInputStream (args[0]); BufferedInputStream buffer = new BufferedInputStream (file); DataInputStream stream = new DataInputStream (buffer); boolean bigEndian = true; long os = 0; boolean endOfImage = false; boolean readingECS = false; boolean haveCode = false;; int nECS = 0; int code = 0; while (!endOfImage) { if (!readingECS) { if (!haveCode) { code = stream.readUnsignedByte (); for (int i=0; (code = stream.readUnsignedByte ()) == 0xff; i++) { System.out.println (leading (os, 8) + os + ": fill 0xff"); os++; } } } else { boolean ff = false; int length = 0; while (true) { code = stream.readUnsignedByte (); length++; if (code == 0xff) { ff = true; } else if (ff) { if (code != 0x00) { length -= 2; break; } else { ff = false; } } } System.out.println (leading (os, 8) + os + ": ECS" + nECS + " " + length + " ..."); os += length; nECS++; readingECS = false; haveCode = true; continue; } if (code == 0x01) { System.out.println (leading (os, 8) + os + ": TEM"); } else if ((code >= 0xc0 && code <= 0xc3) || (code >= 0xc5 && code <= 0xc7) || (code >= 0xc9 && code <= 0xcb) || (code >= 0xcd && code <= 0xcf)) { int n = code - 0xc0; /****************** int length = markerSegment (stream, bigEndian); */ int length = ModuleBase.readUnsignedShort (stream, bigEndian, null); int P = stream.readUnsignedByte (); int Y = ModuleBase.readUnsignedShort (stream, bigEndian, null); int X = ModuleBase.readUnsignedShort (stream, bigEndian, null); int Nf = stream.readUnsignedByte (); int [] Ci = new int [Nf]; int [] Hi = new int [Nf]; int [] Vi = new int [Nf]; int [] Tqi = new int [Nf]; for (int i=0; i= 0xd0 && code <= 0xd7) { int m = code - 0xd0; System.out.println (leading (os, 8) + os + ": RST" + m); readingECS = true; } else if (code == 0xd8) { System.out.println (leading (os, 8) + os + ": SOI"); } else if (code == 0xd9) { System.out.println (leading (os, 8) + os + ": EOI"); endOfImage = true; break; } else if (code == 0xda) { int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": SOS" + " " + length + " ..."); os += length; readingECS = true; } else if (code == 0xdb) { int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": DQT" + " " + length + " ..."); os += length; } else if (code == 0xdc) { int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": DNL" + " " + length + " ..."); os += length; } else if (code == 0xdd) { int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": DRI" + " " + length + " ..."); os += length; } else if (code == 0xde) { int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": DHP" + " " + length + " ..."); os += length; } else if (code == 0xdf) { int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": EXP" + " " + length + " ..."); os += length; } else if (code == 0xe0) { int length = ModuleBase.readUnsignedShort (stream, bigEndian, null); String id = readChars (stream, 5); if (id.equals ("JFIF\0")) { int major = stream.readUnsignedByte (); int minor = stream.readUnsignedByte (); int units = stream.readUnsignedByte (); int xDensity = ModuleBase.readUnsignedShort (stream, bigEndian, null); int yDensity = ModuleBase.readUnsignedShort (stream, bigEndian, null); int xThumbnail = stream.readUnsignedByte (); int yThumbnail = stream.readUnsignedByte (); System.out.print (leading (os, 8) + os + ": APP0 " + "\"" + id + "\" " + major + "." + minor + " " + units + " " + xDensity + "x" + yDensity + " " + xThumbnail + "x" + yThumbnail); int n = length - 16; if (n > 0) { for (int i=0; i 0) { for (int i=0; i= 0xe1 && code <= 0xef) { int n = code - 0xe0; /* int length = markerSegment (stream, bigEndian); */ int length = ModuleBase.readUnsignedShort (stream, bigEndian, null); if ((n == 1 || n == 2) && length >= 8) { String id = readChars (stream, 4); int NULL = stream.readUnsignedByte (); int padding = stream.readUnsignedByte (); if (id.equals ("Exif") || id.equals ("FPXR")) { System.out.println (leading (os, 8) + os + ": APP" + n + " \"" + id + "\" " + NULL + " " + padding + " " + (length-8) + ": ..."); } else { System.out.println (leading (os, 8) + os + ": APP" + n + " " + length + " ..."); } for (int i=8; i 0) { int [] cap = new int [n]; for (int i=0; i= 0xf7 && code <= 0xfd) { int n = code - 0xf0; int length = markerSegment (stream, bigEndian); System.out.println (leading (os, 8) + os + ": JPG" + n + " " + length + " ..."); os += length; } else if (code == 0xfe) { int length = ModuleBase.readUnsignedShort (stream, bigEndian, null); String comment = readChars (stream, length-2); System.out.println (leading (os, 8) + os + ": COM \"" + comment + "\""); os += length; } else { int length = markerSegment (stream, bigEndian); String hex = Integer.toHexString (code); System.out.println (leading (os, 8) + os + ": RES (0x" + leading (hex, 2) + hex + ") " + length + " ..."); } os += 2; } stream.close (); } catch (Exception e) { e.printStackTrace (System.err); System.exit (-2); } } /** * Read marker segment data * @param stream Data input stream * @param bigEndian True if big-endian * @return Length of marker segment */ private static int markerSegment (DataInputStream stream, boolean bigEndian) throws IOException { int length = ModuleBase.readUnsignedShort (stream, bigEndian, null); for (int i=2; i