Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**********************************************************************
* 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 JPEG2000 file in human-readable format.
*/
public class J2Dump extends Dump {
/* Fixed value for first 12 bytes */
private static final int[] sigByte =
{
0X00,
0X00,
0X00,
0X0C,
0X6A,
0X50,
0X20,
0X20,
0X0D,
0X0A,
0X87,
0X0A };
private static final boolean ENDIAN = true; /* bigEndian */
/******************************************************************
* 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 J2Dump file");
System.exit (-1);
}
try {
FileInputStream file = new FileInputStream (args[0]);
BufferedInputStream buffer = new BufferedInputStream (file);
DataInputStream stream = new DataInputStream (buffer);
J2Dump dump = new J2Dump (); // Just to access contained classes
long os = 0;
boolean bigEndian = true;
int i;
for (i = 0; i < 12; i++) {
int ch;
ch = stream.readUnsignedByte();
if (ch != sigByte[i]) {
System.out.println ("No JPEG 2000 header");
System.exit (-2);
}
}
os += 12;
boolean endOfFile = false;
Stack boxStack = new Stack ();
while (!endOfFile) {
//If there are boxes on the stack, see if there's space
//left in the top one.
Box boxtop;
for (;;) {
boxtop = null;
if (boxStack.isEmpty ()) {
break;
}
boxtop = (Box) boxStack.peek ();
if (boxtop.bytesLeft > 0) {
break;
}
boxStack.pop ();
}
// Read the header of a JP2 box
Box box = dump.new Box (stream);
try {
box.read ();
}
catch (EOFException e) {
endOfFile = true;
break;
}
os += box.length - box.bytesLeft;
// If it's contained in a superbox, subtract
// this box from its remaining length
if (boxtop != null) {
boxtop.bytesLeft -= box.length;
}
System.out.println (leading (os, 8) + os + ": " +
stackPrefix (boxStack) + box.type + " " + box.length);
if (box.isSuperbox ()) {
boxStack.push (box);
}
else {
os += box.bytesLeft;
stream.skipBytes((int) box.bytesLeft);
}
// A "length" of 0 means the box occupies the rest of the file.
if (box.length == 0) {
endOfFile = true;
}
}
}
catch (Exception e) {
e.printStackTrace (System.err);
System.exit (-2);
}
}
/* Constructs a qualifying prefix to indicate nested boxes. */
private static String stackPrefix (Stack boxStack)
{
StringBuffer retval = new StringBuffer ();
// In defiance of gravity, we rummage through the stack
// of boxes starting at the bottom.
for (int i = 0; i < boxStack.size(); i++) {
Box box = (Box) boxStack.elementAt (i);
// Remove trailing spaces from types for better readability
retval.append (box.type.trim() + "/");
}
return retval.toString ();
}
/** Local class for defining JPEG2000 boxes. */
class Box {
public String type;
public long length;
public long bytesLeft;
public boolean hasBoxes;
DataInputStream dstream;
public Box (DataInputStream stream)
{
this.dstream = stream;
}
/** Reads a box header and sets up for reading contents. */
public void read () throws IOException
{
length = ModuleBase.readUnsignedInt (dstream, ENDIAN, null);
long headerLength = 8;
type = read4Chars ();
// If the length field is 1, there is an 8-byte extended
// length field.
if (length == 1) {
length = ModuleBase.readSignedLong(dstream, true, null);
headerLength = 16;
}
bytesLeft = length - headerLength;
}
/* Reads a 4-character name */
private String read4Chars() throws IOException {
StringBuffer sbuf = new StringBuffer(4);
for (int i = 0; i < 4; i++) {
int ch = ModuleBase.readUnsignedByte(dstream, null);
sbuf.append((char) ch);
}
return sbuf.toString();
}
/** Returns true if this box contains other boxes.
* At present, we don't deal with the insides of boxes
* that contain both data and boxes (e.g., cref). */
public boolean isSuperbox ()
{
// If it's a known superbox type, we return true.
// If we've left any out, that will merely make us
// lose the subboxes of that type.
String [] supertypes = { "asoc", "cgrp", "comp", "drep",
"ftbl", "jp2h", "jpch",
"jplh", "res ", "uuid" };
for (int i = 0; i < supertypes.length; i++) {
if (supertypes[i].equals (type)) {
return true;
}
}
return false;
}
}
}