Script started on Wed 19 Mar 2008 03:38:21 PM EDT destroyer:~/workspace/651_Project2/script> cat AmerRLE_Encode.java import java.io.*; import java.util.*; // the encoder object which gets a file to be encoded and encodes the file // using run length encoding and writes the encoded file to a file with .ARLE // extension. public class AmerRLE_Encode { public static void main(String[] args) { int inputFileLength = 0; // the length of the file to be encoded int MAX_ALPHABET_SIZE = 128; // valid alphabet size int alphabetSize = 0; // the alphabet size of the file to be encoded /* array to keep track of which chars are in the alphabet during the pass */ int alphabet[] = new int[MAX_ALPHABET_SIZE]; // the string which keeps alphabet of the encoded file String strAlphabet = ""; // check if user provided the file name for the file to be encoded if (args.length != 1) { System.err.println("Usage: java AmerRLE_Encode [inputfile]"); } File inFile = new File(args[0]); // file to be encoded File outFile = new File(args[0] + ".ARLE"); // encoded file // check if the file exists - ask user what to do: overwrite or abort if (outFile.exists() == true) { System.out.println("File exists! To overwrite the existing file " + "type \'o\', to abort type \'a\'!"); try { int readByte = System.in.read(); // read users choice if (readByte == 'o') { // choice: overwrite the file System.out.println("File will be overwritten!"); } else if (readByte == 'a') { // choice: abort the process System.out.println("The process is aborting!"); System.exit(1); } else { // choice: wrong input // abort the process System.out.println("Invalid character is entered, aborting!"); System.exit(1); } } catch (IOException ioe) { ioe.printStackTrace(); } } // get the length of the file to be encoded inputFileLength = (int) inFile.length(); // the byte array that will keep the file to be encoded byte inputFile[] = new byte[inputFileLength]; try { // read the file to be encoded into the byte array inputFile = getBytesFromFile(inFile); } catch (IOException ioe) { ioe.printStackTrace(); } // initialize the alphabet array for (int i = 0; i < MAX_ALPHABET_SIZE; i++) { alphabet[i] = 0; } // integer values of the currently read ASCII char and the next char Integer currentTempInt, nextTempInt; int runLength = 1; // length of the current (inspected) run int numberOfRuns = 1; // total number of runs in the file to be encoded /* compression object which keeps all the information to encode the file to be encoded such as signature, version, alphabet, alphabet length and data pairs */ AmerRLE compressionObject = new AmerRLE(); /* Check if the file has any invalid characters (byte value in range [128-255]). If the file has any invalid characters then abort. At the same time scan the file and grab the chars for the alphabet and runs of chars and add them to the compression object. */ for (int i = 0; i < inputFileLength; i++) { // integer value of the current ASCII char of the file to be encoded currentTempInt = new Integer(inputFile[i]); // integer value of the next ASCII char of the file to be encoded if (i == inputFileLength - 1) nextTempInt = new Integer(-1); else nextTempInt = new Integer(inputFile[i+1]); /* check if the read ASCII char is a valid char - abort the process if an invalid char is detected. */ if (currentTempInt.intValue() >= 128 || currentTempInt.intValue() < 0) { System.out.println("Error: file cannot be compressed because" + "file has one or more invalid characters (byte value" + "is not in range [0-127])."); System.exit(1); } /* Check if the read ASCII char is already in the alphabet array. If not in the array append the ASCII char to the alphabet array and increase the alphabet size. If alphabet size greater than MAX_ALPHABET_SIZE return an error and abort the application. */ if (alphabet[currentTempInt.intValue()] == 0) { alphabet[currentTempInt.intValue()] = 1; alphabetSize++; // add new ASCII char to the alphabet string strAlphabet += (char)currentTempInt.intValue(); /* check the size of the alphabet- if bigger than maximum available abort the process */ if (alphabetSize > MAX_ALPHABET_SIZE) { System.err.println("Error: alphabet size greater than " + "specified maximum."); System.exit(1); } } /* a new run inspected - create a data pair object for the prev. run and append it to the compression object. */ if (currentTempInt.intValue() != nextTempInt.intValue()) { DataPair currentRun = new DataPair((char)currentTempInt.intValue(), runLength); compressionObject.addDataPair(currentRun); numberOfRuns++; // increase the number of total runs runLength = 1; // since the new run starts set length of run to 1 } else { runLength++; // same chars (same run) - increase runLength } // nextTempInt = currentTempInt; // remove } // set the alphabet size and alphabet of the compression object compressionObject.setAlphabetLength(alphabetSize); compressionObject.setAlphabet(strAlphabet); try { // write the encoded file writeBytesToFile(compressionObject.getCompressedFile(), outFile); } catch (IOException ioe) { ioe.printStackTrace(); } } /*************************************************************************** * Function getBytesFromFile * * ************************************************************************* * 1. Purpose: This function simply returns the contents of a specified file * in a byte array. 2. http://jug.org.ua/wiki/display/JavaAlmanac/Reading+a+File+into+a+Byte+Array * 3. Inputs: A File object which the content of this file will be stored in * a byte array and returned. 4. Outputs: A byte array with the contents of * the specified file. 5. Procedures/Functions called: none 6. * Procedures/Functions calling: none 7. Local Variables: is -- * FileInputStream object which is used to read the contents of the file in * a byte array. length -- The length of the specified file. bytes[] -- a * byte array which is returned with the contents of the file 8. Global * Variables: none 9. Global Constants: none 10. Bugs: none **************************************************************************/ public static byte[] getBytesFromFile(File file) throws IOException { InputStream is = new FileInputStream(file); // Get the size of the file long length = file.length(); /* You cannot create an array using a long type. It needs to be an int type. Before converting to an int type, check to ensure that file is not larger than Integer.MAX_VALUE. */ if (length > Integer.MAX_VALUE) { // File is too large throw new IOException("The file is too large: " + file.getName()); } // Create the byte array to hold the data byte[] bytes = new byte[(int) length]; // Read in the bytes int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read in if (offset < bytes.length) { throw new IOException("Could not completely read file " + file.getName()); } // Close the input stream and return bytes is.close(); return bytes; } /*************************************************************************** * Function writeBytesToFile * * ************************************************************************* * 1. Purpose: This function simply writes a byte array to the specified * output file. 2. Bryan Youse, Nasif Ekiz, March 2008 3. Inputs: A byte * array and a File object. 4. Outputs: none 5. Procedures/Functions called: * none 6. Procedures/Functions calling: none 7. Local Variables: fos -- * FileOutputStream object which is used to write byte array to the file 8. * Global Variables: none 9. Global Constants: none 10. Bugs: none **************************************************************************/ public static void writeBytesToFile(byte[] bytes, File outFile) throws IOException { FileOutputStream fos = new FileOutputStream(outFile); fos.write(bytes); } } /* Data compression object which is used to create the encoded file. */ class AmerRLE { byte signature[]; /* header signature (always ASCII "amerRLE") */ byte version; /* amerRLE format version (initially ASCII "1") */ byte alphabetLength[]; /* size alphabet (ASCII "001" to "128") */ int ALPHABET_LENGTH; /* number of digits of alphabet size */ int alphabetSize; /* input alphabet size */ byte alphabet[]; /* input alphabet */ Vector dataPairs; /* variable number of pairs; different for */ /* each file being compressed */ int totalDataPairEncodedInBytes;// total number of bytes of the encoded data // pairs - variable public AmerRLE() { // constructor of data compression object signature = new byte[7]; // declare signature setSignature(); // assign "amerRLE" to signature setVersion(1); // assign the version: [1-9] is possible ALPHABET_LENGTH = 3; // set number of digits for alphabet length alphabetLength = new byte[ALPHABET_LENGTH]; dataPairs = new Vector();// initialize data pair vector totalDataPairEncodedInBytes = 0; // set 0 to total bytes of data pairs // encoded } // returns the signature public byte[] getSignature() { return signature; } // sets the signature to the constant value "amerRLE" public void setSignature() { String strSignature = new String("amerRLE"); // convert string signature to byte array and assign byte array to sign. this.signature = convertStringToByteArray(strSignature); } // returns the version of the data compression object public byte getVersion() { return version; } // sets the version of the data compression object to any single digit int public void setVersion(int version) { String tempStr = "" + version; Integer tempInt = new Integer(tempStr.charAt(0)); this.version = tempInt.byteValue(); } // returns the length of the alphabet of the encoded file public byte[] getAlphabetLength() { return alphabetLength; } // sets the length of the alphabet public void setAlphabetLength(int alphabetLength) { String tempStr = "" + alphabetLength; this.alphabet = new byte[alphabetLength];// array to hold alphabet length this.alphabetSize = alphabetLength; // set size of the alphabet // generate the alphabet length field with 3 digits representation if (tempStr.length() == 1) tempStr = "00" + tempStr; else if (tempStr.length() == 2) tempStr = "0" + tempStr; // get the byte array of alphabet length this.alphabetLength = convertStringToByteArray(tempStr); } // returns the byte array of the encoded file's alphabet public byte[] getAlphabet() { return alphabet; } // sets the encoded file's alphabet public void setAlphabet(String alphabet) { this.alphabet = convertStringToByteArray(alphabet); } // converts any passed String object to a byte array public byte[] convertStringToByteArray (String strToConvert) { byte tempByteArray[] = new byte[strToConvert.length()]; for (int i = 0; i < strToConvert.length(); i++) { Integer tempInt = new Integer(strToConvert.charAt(i)); tempByteArray[i] = tempInt.byteValue(); } return tempByteArray; } // returns the encoded file as a byte array - data compression object's // data fields are used to generate the final encoded file public byte[] getCompressedFile() { int compressedFileLength = 0;// total length in bytes of the encoded file int currentWritePosition = 0;// cursor to hold write position in byte a. int encodedDataPairLength = 0; // the length of the data pair to be // encoded - variable for each data pair compressedFileLength += signature.length; // add signature length: 7 compressedFileLength += 1; // add version length: 1 compressedFileLength += ALPHABET_LENGTH; // add version length: 3 compressedFileLength += alphabetSize; // add alphabet size: variable compressedFileLength += totalDataPairEncodedInBytes; // add DataPairs:var byte compressedFile[] = new byte[compressedFileLength]; // write signature field to byte array for (int i = 0; i < signature.length; i++, currentWritePosition++) { compressedFile[currentWritePosition] = signature[i]; } // write version field to byte array compressedFile[currentWritePosition++] = version; // write alphabet length field to byte array for (int i = 0; i < ALPHABET_LENGTH; i++, currentWritePosition++) { compressedFile[currentWritePosition] = alphabetLength[i]; } // write alphabet field to byte array for (int i = 0; i < alphabetSize; i++, currentWritePosition++) { compressedFile[currentWritePosition] = alphabet[i]; } // write each data pair to byte array while (!dataPairs.isEmpty()) { // get the first data pair from the head DataPair tempDataPair = dataPairs.remove(0); // get the length of the encoded data pair encodedDataPairLength = tempDataPair.getEncodedLength(); // create a temp byte array to hold encoded data pair byte tempByteArray[] = new byte[encodedDataPairLength]; tempByteArray = tempDataPair.getEncodedByteArrayofDataPair(); // write encoded data pair into the byte array of the encoded file for (int i = 0; i < encodedDataPairLength; i++, currentWritePosition++) { compressedFile[currentWritePosition] = tempByteArray[i]; } } return compressedFile; // return encoded file as a byte array } // adds a new data pair object to the vector storing data pair objects public void addDataPair(DataPair newPair) { // increase the total bytes of encoded data pair objects totalDataPairEncodedInBytes += newPair.getEncodedLength(); // add the data pair object to the vector if ( ! dataPairs.add(newPair)) { System.err.println("Error: An error occured when adding DataPair " + "to the DataPair Vector!"); System.exit(1); } } } // data pair object which is used to store information for each run and return // encoded run class DataPair { char character; /* character repeated RunLength times */ int runLength; /* # of times Character repeats */ int encodedLength; /* total number of bytes of encoded data pair */ // constructor of the data pair object public DataPair(char character, int runLength) { this.character = character; this.runLength = runLength; } // returns the total length of the run public int getRunLength() { return this.runLength; } // sets the total length of the run public void setRunLength(int runLength) { this.runLength = runLength; } // returns the ASCII char of the run public char getCharacter() { return character; } // sets the ASCII char of the run public void setCharacter(char character) { this.character = character; } // returns an integer which gives the total length of the encoded run public int getEncodedLength() { int numberOfRuns; // number of 9 char divided smaller runs if (this.runLength % 9 == 0) numberOfRuns = this.runLength / 9; else numberOfRuns = this.runLength / 9 + 1; return numberOfRuns*2;// for each run: 1byte for [1-9], 1 byte ASCII char } // returns encoded run as a byte array public byte[] getEncodedByteArrayofDataPair () { int encodedChars = 0; // total number of chars encoded at the time byte tempByteArray[] = new byte[getEncodedLength()]; String tempString = ""; // holds the encoded run as a string while (encodedChars != runLength) { if (runLength - encodedChars <= 9) { // add the integer part of the smaller run tempString += Integer.toString(runLength-encodedChars); tempString += character; // add ASCII char of the smaller run encodedChars = runLength; // all chars are encoded } else { tempString += Integer.toString(9); // add integer part of the run tempString += character; // add ASCII char to the run encodedChars += 9; // increase encodedChars by 9 } } // convert the string holding encoded run to byte array for (int i = 0; i < tempString.length(); i++) { Integer tempInt = new Integer(tempString.charAt(i)); tempByteArray[i] = tempInt.byteValue(); } return tempByteArray; } } destroyer:~/workspace/651_Project2/script> cat amerRLE_decode.java /** * File: amerRLE_decode.java - class containing the main method * for the run length decoder */ import java.io.*; /** * @author Bryan Youse */ public class amerRLE_decode { /** * @param args - command line arguments */ public static void main(String[] args) { // check for validity of current program's parameter(s) if(args.length != 1 || (!(args[0].endsWith(".ARLE")))){ System.err.println("Usage: java amerRLE_decode .ARLE"); System.exit(1); } String inFile = args[0]; // determine the prefix of the input file (everything but the .ARLE) // then concatenate this with the required extension int fileNameEnd = inFile.lastIndexOf("."); String outFile = inFile.substring(0, fileNameEnd) + ".RECONSTRUCTED"; System.out.println("Writing to file: " + outFile); // create File objects File inputFile = new File(inFile); File outputFile = new File(outFile); // check for existence of inputfile if(!inputFile.exists()){ System.err.println("File [" + inputFile.toString() + "] does not" + " exist.\nQuitting..."); System.exit(1); } // check against existence of outputfile if(outputFile.exists()){ System.out.println("File [" + outputFile.toString() + "] exists.\n" + "Quitting..."); System.exit(0); } // do all the work in the Decoder class! Decoder d = new Decoder(inputFile, outputFile); try{ d.decode(); } catch(Exception e){ e.printStackTrace(); } } } destroyer:~/workspace/651_Project2/script> cat Decoder.java /** * File: Decoder.java - class definition for Decoder class, * which decodes a file compressed with the amerRLE compression * technique */ import java.io.*; import java.util.ArrayList; /** * @author Bryan Youse */ public class Decoder { private static final String Signature = "amerRLE"; private static final int Version = 1; private File inputFile; private File outputFile; private ArrayList fileData; private char[] alphabet; private int alphabetLength; private int pairCount; /** * Class constructor * @param inFile - the file to read the amerRLE-encoded text from * @param outFile - the file to write the reconstructed text to */ public Decoder(File inFile, File outFile){ inputFile = inFile; outputFile = outFile; pairCount = 0; fileData = new ArrayList(); } /** * Main work function of Decoder class. All relevant decoding work * is done within this function or sourced out to other functions. * This is the only method an outside class needs to call to decode * an amerRLE-encoded text * @throws Exception */ public void decode() throws Exception{ // set up a buffered reader to get information from the input file BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(inputFile))); // ensure the signature, version, number of characters, and // amount of characters specified by the input file are all valid ensureInitialValidity(br); // create buffer to store a data pair char[] dataPair = new char[2]; // read the first data pair int dataRead = br.read(dataPair, 0, 2); // run loop until all data pairs are read in while(dataRead == 2){ // create a data pair from the next two characters in input file // this method also checks for validity of data pairs createDataPair(dataPair[0], dataPair[1]); // read in the next data pair dataRead = br.read(dataPair, 0, 2); } // check to make sure there wasn't a half-pair dangling at end if(dataRead == 1){ error("Incomplete pair at end of input beginning with " + dataPair[0]); } // call a method to expand our data pairs and write to the output file int totalChars = writeOutFile(); // summarize the decoding process with statistics summarize(totalChars); } /** * Small method to summarize information about the data decompression * @param totalChars - the total number of characters in * the RECONSTRUCTED file */ private void summarize(int totalChars){ // encoded file size = 11 (amerRLE####) + // size of the alphabet + (2 * number of pairs) int noMetaSize = 2*pairCount; int encodedSize = 11 + alphabetLength + noMetaSize; System.out.println("With/without metadata [" + encodedSize + "/" + noMetaSize + "] encoded characters decoded into " + totalChars + " characters."); } /** * Method to write collected data pairs to the final output file * @return - total number of written bits * @throws Exception */ private int writeOutFile() throws Exception{ BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(outputFile))); int runLength; char character; int totalWrittenChars = 0; // for each data pair we encountered from the input file for(DataPair datapair : fileData){ // get the runlength and the character itself runLength = datapair.getLength(); character = datapair.getChar(); //System.out.println("Lenght: " + runLength + //" Character: " + character); for(int i=0; i 9){ error("Invalid runlength (" + runLengthChar + ")" + " Must be a number in range [1,9]."); } // check to make sure character was in the alphabet from metadata if(!isCharInAlphabet(whichChar)){ error("Invalid character (" + whichChar + "). Not in stated alphabet."); } // if we've reached this point, the data pair is valid. // create it and add to list fileData.add(pairCount, new DataPair(runLength, whichChar)); pairCount++; } /** * Simple method that runs through previously build character array * consisting of the metadata's stated alphabet. It determines if * a given character is present in that alphabet * @param c character in question * @return true if the character is in the metadata's alphabet */ private boolean isCharInAlphabet(char c){ for(int i=0; i 128){ error("Invalid alphabet length " + alphabetLength + ". Should be in range [001,128]."); } alphabet = new char[alphabetLength]; // make sure there are at least n alphabet left, // where n = alphabet length charsRead = br.read(alphabet, 0, alphabetLength); if(charsRead != alphabetLength){ error("Invalid codefile.\nNumber of alphabet specified (" + charsRead + ") does not match stated alphabet length (" + alphabetLength + ")."); } // DEBUG output block /* System.out.print("alphabet encountered ["); for(int i = 0; i < alphabetLength; i++){ System.out.print(alphabet[i]); if(i == alphabetLength - 1){ System.out.println("]"); } } */ } /** * Method to print an inputted string to standard error and exit * @param err - the error message to print */ private void error(String err){ System.err.println(err); System.err.println("Quitting..."); System.exit(1); } /** * Subclass DataPair to store RLE-ecoded pairs consisting of * an integer representing the subsequent character's run length * @author Bryan Youse */ private class DataPair{ private int runLength; private char character; // Constructor public DataPair(int i, char c){ runLength = i; character = c; } // Debugging output function public void printPair(){ System.out.println("[" + runLength + "," + character + "]"); } // Get method for runlength public int getLength(){ return runLength; } // Get method for character public char getChar(){ return character; } } }destroyer:~/workspace/651_Project2/script> javac AmerRLE_Encode.java destroyer:~/workspace/651_Project2/script> javac amerRLE_decode.java Decoder.java destroyer:~/workspace/651_Project2/script> cat paul.banner ###### # # ## # # # # # # # # # # ###### # # # # # # ###### # # # # # # # # # # # # #### ###### # # # # # ###### ##### # # ## ## # # # # # # ## # ##### # # ####### # # # ##### # # # # # # # # # # # ###### # # destroyer:~/workspace/651_Project2/script> java AmerRLE_Encode paul.banner destroyer:~/workspace/651_Project2/script> cat paul.banner.ARLE amerRLE1003# 6#1 1#5 1#4 2#4 1#4 1#2 1#1 1#5 1#3 1#2 1#3 1#4 1#2 1#1 6#3 1#4 1#2 1#4 1#2 1#1 1#8 6#2 1#4 1#2 1#1 1#8 1#4 1#2 1#4 1#2 1#1 1#8 1#4 1#3 4#3 6#2 3 1#1 2 1#1 1#4 1#4 1#2 6#2 5#1 1 1#3 1#3 2#2 2#2 1#7 1#4 1#1 1#5 1#2 1#1 2#1 1#2 5#3 1#4 1#1 7#2 1#4 1#2 1#7 5#1 1#5 1#2 1#4 1#2 1#7 1#3 1#1 1#5 1#2 1#4 1#2 6#2 1#4 1#2 destroyer:~/workspace/651_Project2/script> java amerRLE_decode paul.pabanner.ARLE Writing to file: paul.banner.RECONSTRUCTED With/without metadata [328/314] encoded characters decoded into 370 characters. destroyer:~/workspace/651_Project2/script> cat paul.banner.RECONSTRUCTED ###### # # ## # # # # # # # # # # ###### # # # # # # ###### # # # # # # # # # # # # #### ###### # # # # # ###### ##### # # ## ## # # # # # # ## # ##### # # ####### # # # ##### # # # # # # # # # # # ###### # # destroyer:~/workspace/651_Project2/script> diff paul.banner paul.banner.RECONSTRUCTED destroyer:~/workspace/651_Project2/script> ls -l paul.banner* -rw-r--r-- 1 youse youse 370 2008-03-19 15:33 paul.banner -rw-r--r-- 1 youse youse 328 2008-03-19 15:39 paul.banner.ARLE -rw-r--r-- 1 youse youse 370 2008-03-19 15:40 paul.banner.RECONSTRUCTED destroyer:~/workspace/651_Project2/script> cat christmas .,ueeeeeu, e$$$$$P?$$$$$b :$$$$" '$$$$c $$$$ $$$$c $$$6 $$$$$ $$$F $$$$" $$$F $$$F $$$$ $$$F $$$$ J$$F .ccCCCCCCCCc,. ?$$$ $$$$$$e ,CCCCCCCCCCCCCCCCCCc :$$$ `$$$$$" CCCCCCCCCCCCCC" CCCCCC. `$$$. CCCCCCCCCCC" .,d.`CCCCCC. $$$t .,uuuuu,. ::: d$$$$$ :::: ::` .::::: HHHHF ,!!' !!!!!! 9$$P""""?$$$$$$$$" ! ; `:: $$$$$$ : ::: .::::::::: ?HH" ,!!! !!!!!!! 3$$$.``''$$$F - ; ! ! `: $$$$$$`:: :: .::::::::::: H" ,!!!'$L; !' ; , """"""" ; \ `! !!!,?$$$$$ ` $$$$$$$$d$$$$$$$$$P""""` . . ' !!!!!!!!! . `; ` ` !, !!i"$$$$ ` $$$$$$$$$$$$$$$$$F i!!' ,' .. .. ``!!! ! `; \ ` `\`!!.$$$L >>>"""""""??$$$$k ==" !!' ' , , d$$" u":". !! ! \ `; ` i!i,`!!, ?$F $$$$UUU$$$$u,"?$$$ =" r ' $F4 ".$$LJ 3$L !!,` ', \ !!i,.`!i.`!.$ $$$$$$$$$$$ec. d$$$ f '" $$F4.$"zP"$$b."b !!,` '! . :!!!!!!i.`!i """```"=??he, ?$$$b ,i'! ! d$$$$$d$b$$$$$$F?$ `!='' ..... `!,!i ,,,, ,,, ::: $$$$ `!i 'i" $$$$$$$$$$$$$$$c`" d$$$$$$bc, "?$$$$$$$.!,`!i $$$' $$$ '::::: '$$$> !!!!! `?$$$$$$$$$$$$F d$$$$$$$$$$F,u.'$$$$$$c!i`! : .$$$"x ::::: $$$ i!!!!!, $. ``"""""" .,z$$$P"?$$$",ed$$$b $$$$$$i!!! $e $$$" $R ::::: 3$$ !!!!!!!,`$$bd"uer .dP"""?$$. ?y, "4$$$$$$,`$$$$Fi!!! " d$$$ :::::::: )$$ !!!!!!i `$$bc . "?bey,. `d$$e `$$$$F $PP"i!!!! d$$F $r :::::: $$$ )!!!!!! `$$$L".W. "?$by,`"d$$$$$$c $$$" .eeeeu '! J$$" : .:::: . """ !!!!!!!i. `??$ .,._ `"3$$$$$$$$$b,,,d$$$$$$$$c "$" ::::::' : !!!!!!!!!!!!i;;i! ueee. `"?$$$$$$$$$$$$$$$$$$$$$$$$$$$F :.::::::: `:: :: z$$$$$$$$$$$be..`'<<:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ...\..>\\.\\.\\\\ ,/ |, ''```''`<<''<'<<<<<</`\\\>\%`%%"./'%..\=///,%//,,/', ,/'' ,/ , `'''''''''''''''''!!!!!!! //>;>;\.""./';./>.`\- |`/./'','./|'"/`\\>>`,`/'. '. ,` ,/',/',|%//<'/%.////;.//>>,/,;,.-.`\`,..\`<.\\=\\-^//=/<<\\%'- ' .,::` ..:' '`.::: '/'/''/'/>.''(\<|/%<%///>\`\%>\\%\\\>/\'\\\\< `.,'' ..::'`.:.::::'` /',/"><|,/','/'>,/,/'>/|/>\\`|"\|<``\`\"" \<```.,,'`` ..::::..:::: ::: ::::::::::::::::::::::...::::::::::::::::::::''` ...::::::::::::::: ::: ............................................. .:::::::::::::::::::: ::: ::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::: . destroyer:~/workspace/651_Project2/script> java AmerRLE_Encode christmas destroyer:~/workspace/651_Project2/script> cat christmas.ARLE amerRLE1056 .,ue $P?b:"'c6FJC`dtzhj/)\;l%fm_i!93a^7kUxRyW|(5 1.1,1u5e1u1,1 3 1e5$1P1?5$1b1 1 1:4$1"6 1'4$1c1 1 4$9 1 4$1c1 1 3$169 1 5$1 1 3$1F9 1 4$1"1 1 3$1F9 1 3$1F1 1 4$9 3$1F1 1 4$8 1J2$1F9 9 9 8 1.2c8C1c1,1.1 1 1?3$8 6$1e9 9 9 2 1,9C9C1c1 1 1:3$8 1`5$1"9 9 9 1 9C5C1"1 6C1.1 1 1`3$1.9 9 9 9 5 9C2C1"1 1.1,1d1.1`6C1.1 2 3$1t9 4 1.1,5u1,1.9 9 1<3C2 1.1 1`2"1,6$1L1 6C1 2 1?3$9 1 1,9H4H1b1,9 6 3C1 9$1P4"1 1`5C1 2 1`3$8 141F2"1 1.1,7u4,1.9 5 1`2C1 1'1=1-2 1"3$1=3"2$1r1 1C1>1<1C1 2 1`3$1,6 1z1u1H1F2"1`1.6,1.1 2"2?2H9 4 1`2C1 1b1u1e1$1:4$1b1d3$1 1C1 1?1 1C1 3 4$6 1-2=1'1.2e3?1$4e1c3,1.1`1=1.9 4 1`1C1 4$1 2$1P3?3$1 1C2 1c1C1 3 1?3$5 1,1H2"2 1.1e1$1P3"1?1h4e2,1.2"9 6 1.1'1P1 1.2c1-1=1<1C1c1,2 1c1C1'2C1'1 3 1`3$4 2H1 1j1F1 3$1b1,1/3"1c1d2$2.2,1)9 8 1\1 1d1P1"1.2 1.1,1c3C1P1 1u1 3 1`3$1.1 1.3H1 1H1'1:1F1 3$1d1u1,4$1 1'1 1"1;1l9 9 9C4C1'1.2$1 4 3$1h1 3H1F1 1H1 1H2 1"5$1F1 1d1$1 142$1 1H9 7 1,1z1 1"1?8C1P1 1J2$1 2:1 1$1 4 1?3$1 3H1'1j1F1.1H1 1%1 1$1P1"1 3.1'1"1 1u1$1 1J1'9 3 1.1d4$1F1 1.3 4.1z1d1$1P1"1 3:1d1$1 4 1:3$1 3H1 1H1 1H1F1 2%1,2%1"5 1%1'1 1d1H9 2 1j8$1 3:8 5:1 2$1 9 4 1?1 1H1F1 5%1.1%1.1 1"1 1%1 1J1H1f8 2:1 9$1.1 9:6:1d2$1 1 1.9:4:3 1'9%1%1/1 1H1"6 5:1 9$1$1 9:5:1d3$1 3:1'9`1`1'3:1 1`9%1 1J1H1 1d1H3 6:1 1?9$1 1`9:3:1 4$1 2.9:6:1.2 6%1/1'1,1 1H1"1 1H1"1,2"2 1`3:1 1?9$1"1 9:2:1`5$1 3 3.1 1.1 3:1 1:1 1.1 1`1:1 1`5e1;1"1.1F1 1-1.1H1 1d4H1c1.4 5$1F1"1`1.1=1"1 1`7:1`1 1'1?4$1 5:3 1.1z1e1$1e1u2 1.1 1`1:2 1=4u1/1"1z1"1.1H1"1 9H1H1e1.1 2"1 1e6$1b2 4:1 2e1,1.1 1'2$1 1'3 1z9$4$2 1`1.1z2e1d1?2"1.1d1H1F1 9H5H2 5$1b3e1m1 1'1:1 1e1c1,1"4$1 1'1 1 1:1 143$1 1.3 4$2?2 1b6e1d1H1F2"1.5H1F2"1 1_2,2.4 1`4$1c1z1e1=1 1'1:2,1`1"7$1 1:2 5$1b2,1d1$1F2 1,2 1.2H1F3"1.1,1z1e4H1F1"1 1,1i1!1"1`1 1.1,1;1i3!1i1;1.1 1?1$1b2e1`1 2:1`2"197$1 1:1 9$2$1L1.1,2 1c2,2e8H1F1 1,1i1!1'1 1.1;9!5!1.2 1.1 4:2"2?7$1 1 1J5$2?1$1,1`1'1"1.1 1.9H3H1"1 1,2!1'1.1i9!9!2 1\1 5:1 1d1$1b1c1.1"2?1$1 1 1"6$1h2 1.1;1 1.9H2H1F1"1 1,2!1'1,1!1 6!4'1`2 3'1<2!1i2 1?1 4:1 1d5$1 1:1$1 1"7$1F1 1u9H2H1"1 1,2!1 1,2!1 3!1"9 7 1!1i4 3:2 5$1 3$4 3"4 1"9H1 1,2!1'1,4!1 1!1"1 1.1d4$1e1z1e1c1e3$1,3 1!4 3:1 1d5$1'1 3.1:2 8:2 135H1"1 1,2!1'1,5!3 1d9$6$1t3 1>3 3:1 1d5$1 4:1 2:1`1 1.5:2 4H1F1 1,2!1'1 6!2 192$1P4"1?8$1"3 1!1 1;1 1`2:1 6$1 1:1 3:3 1.9:1 1?2H1"1 1,3!1 7!2 133$1.2`2'3$1F1 1-1 1;4 1!1 1!1 1`1:2 6$1`2:1 2:2 1.9:2:2 1H1"1 1,3!1'1<7!1i2 9$1$1 1t2e1J1'1 1.2 1!1 1!2 1:1 1d6$1`2:1 1`1 1.9:5:1 1"1 1,4!1 1<8!3 6$1P2?1'1?2$6 1!1 1!1i1 1`1 1d6$1L2:1 1 9:2:8 1`1<3!1 8!1'3 1'2$1u1,4"1 1,1'1 1.2 1;2 1!1 1`1!1.2 1d7$2:1 1.7:2 1a4e6$1e3 1<7!1'3 1'1.1^6$1F1'2 1;6 2!1 2!1,1 8$1`1:1 9:1:1`2"371d6$1u2 6!3 1'2 2$2e3.1e1%2 1<2 1,4 2!1 1`2!1i7$1L1 1:1 1 6`2:2`1 1d5$2 1?3$1b1 1`3!1'2 1,1 1.2 8$4 1.5 1.1 2!1 3!1,7$1 1:1 1e2c1e1c1,1.2 1,1z1d9$1$1>1$1L1;1 1!1'3 1;1 1,3 7"7 1;4 1\1 1`1!1 3!1,1?5$1 1`1 8$1d9$1P4"1`1 1.2 1.2 1'5 9!1 1.4 1`1;2 1`1 1`2 1!1,1 2!1i1"4$1 1`1 9$8$1F4 1i2!1'4 1,1'3 2.1 2.1 2`3!1 1!5 1`1;2 1\1 1`3 1`1\1`2!1.3$1L1 3>7"2?4$1k1 2=1"1 2!1'2 1'1 1,2 1,1 1d2$1"1 1u1"1:1"1.1 2!1 1!2 1\2 1`1;2 1`3 1i1!1i1,1`2!1,1 1?1$1F1 4$3U4$1u1,1"1?3$1 1=1"1 1r3 1'4 1$1F141 1"1.2$1L1J1 131$1L1 2!1,1`2 1'1,4 1\1 2!1i1,1.1`1!1i1.1`1!1.1$1 9$2$1e1c1.1 1d3$2 1f5 1'1"1 2$1F141.1$1"1z1P1"2$1b1.1"1b2 2!1,1`1 1'1!2 1.1 1:6!1i1.1`1!1i1 3"3`1"1=2?1h1e1,2 1?3$1b1 1,1i1'1!2 1!1 1d5$1d1$1b6$1F1?1$7 1`1!1=2'2 5.1 1`1!1,1!1i1 4,2 3,3 3:1 4$1 1`1!1i1 1'1i1"1 9$6$1c1`1"1 1d6$1b1c1,1 1"1?7$1.1!1,1`1!1i1 3$1'1 3$1 1'5:1 1'3$1>1 5!3 1`1?9$3$1F2 1d9$1$1F1,1u1.1'6$1c1!1i1`1!1 1 1:1 1.3$1"1x1 5:2 3$1 1i5!1,1 1$1.3 2`6"1 1.1,1z3$1P1"1?3$1"1,1e1d3$1b1 6$1i3!1 1$1e1 3$1"1 1$1R1 5:1 132$1 7!1,1`2$1b1d1"1u1e1r2 1.1d1P3"1?2$1.1 1?1y1,1 1"146$1,1`4$1F1i3!1 1"1 1d3$2 8:1 1)2$1 6!1i3 1`2$1b1c6 1.1 1"1?1b1e1y1,1.1 1`1d2$1e1 1`4$1F1 1$2P1"1i4!1 1 1d2$1F1 1$1r1 6:2 3$1 1)6!5 1`3$1L1"1.1W1.1 1"1?1$1b1y1,1`1"1d6$1c1 3$1"1 1.4e1u1 1'1!1 1J2$1"1 1:2 1.4:2 1.1 3"1 7!1i1.5 1`2?1$2 1.1,1.1_1 1`1"139$1b3,1d8$1c1 1"1$1"1 6:1'4 1:2 9!3!1i2;1i1!1 1u3e1.1 1`1"1?9$9$9$1F1 1:1.7:2 1`2:1 2:1 1<9!3!1>1 1z9$2$1b1e2.1`1'3<2?9$6$1F1.1i1 8:2 1:1 2:1 2:2 9!2!1'1:9$9$1b7e1,1.4 3`1"1`1,1i3!1 6:2 3:1 3:1 1:2 9!1'1 1.1 2"2?9$5$1P1F3"1'1`2 1.2,2;2i8!1 5:3 3:1 1`2:1 2:1 1`7!2 5!1i4,3.2 5.3,3;2i9!8!1 3:2 2:1 4:1 2:1 2:2 5!1'1 1,9!3!1"1,9!8!1,1`9!4!1 1:1`2 1'2:1 4:1 2:1 2:2 4!1'1 9!4!1 1,9!9!1!1i9!4!1 1 1.2:1 2:1 4:1 2:1 2:2 3!1'1 9!3!1'1.9!9!9!8!1 4:1 2:1 4:1 2:1 2:2 2!1'1 9!3!1'1,4!2'1.1,5;1,1.1`7'1`9!3!1 4:1 1:1'1 4:1 1`1:1 1`1:2 1!1'1.9!9!9!9!1!1i1;2,2.1`1'1<5!1 3:1 1:1'1 5:1 2:1 2:3 1.4!1 1.7!1i9!9!9!4!1i2;2,1 1'1 2:1`1.1:1 1.1:2'1`1 2.2 1.1 2`1 1.2 1'2 1,1 1'4!1i4!1>1:9!9!9!6!1 7 3.1\2.1>2\1.2\1.4\1 1,1/1 1|1,3 2'3`2'1`2<2'1<1'7<9!9!2!1 1`1\1>1/1`3\1>1\1%1`2%1"1.1/1'1%2.1\1=3/1,1%2/2,1/1'1,1 1,1/2'1 1,1/3 1,2 1`9'8'7!1 2/1>1;1>1;1\1.2"1.1/1'1;1.1/1>1.1`1\1-1 1|1`1/1.1/2'1,1'1.1/1|1'1"1/1`2\1<1/1%1/1'2/1%1'1,1'9:7:6!1'1 1\1.1:1\1'1.1'3/1'1"3>1`1,1`1/1'1.2 1'1.1 1,1`1 1,1/1'1,1/1'1,1|1%2/2<1/1,1'1<1^1<1 1-1=1-1<1'2\1'1-2:2`1,2:1'1.3!1'1`1 1.1 1/2=1>1'1/1%1.4/1;1.2/2>1,1/1,1;1,1.1-1.1`1\1`1,2.1\1`1<1.2\1=2\1-1^2/1=1/2<2\1%1'1-1 1'1 1.1,2:1`1 2.1:1'1 1'1`1.3:1 1'1/1'1/2'1/1'1/1>1.2'1<1/1>1(1\1<1|1/1%1<1%3/1>1\1`1\1%1<1/2>2\1%3\1>1/1\1'4\1<1 1`1.1,2'2 2.2:1'1`1.1:1.4:1'1`1 1/1'1,1/1"1>1<1|1,1/1'1,1'1/1'1>1,1/1,1/1'1>1/1|1/1>2\1`1|1"1\1|1<2`1\1`1\2"1 1\1<3`1.2,1'2`2 2.4:2.4:1 3:1 9:9:4:3.9:9:2:2'1`1 3.9:6:1 3:1 9.9.9.9.9.1 1.9:9:2:1 3:1 9:9:9:9:9:1 9:9:6:3 1.2 destroyer:~/workspace/651_Project2/script> java amerRLE_decode christmas.ARLE Writing to file: christmas.RECONSTRUCTED With/without metadata [5311/5244] encoded characters decoded into 5637 characters. destroyer:~/workspace/651_Project2/script> cat christmas.RECONSTRUCTED .,ueeeeeu, e$$$$$P?$$$$$b :$$$$" '$$$$c $$$$ $$$$c $$$6 $$$$$ $$$F $$$$" $$$F $$$F $$$$ $$$F $$$$ J$$F .ccCCCCCCCCc,. ?$$$ $$$$$$e ,CCCCCCCCCCCCCCCCCCc :$$$ `$$$$$" CCCCCCCCCCCCCC" CCCCCC. `$$$. CCCCCCCCCCC" .,d.`CCCCCC. $$$t .,uuuuu,. ::: d$$$$$ :::: ::` .::::: HHHHF ,!!' !!!!!! 9$$P""""?$$$$$$$$" ! ; `:: $$$$$$ : ::: .::::::::: ?HH" ,!!! !!!!!!! 3$$$.``''$$$F - ; ! ! `: $$$$$$`:: :: .::::::::::: H" ,!!!'$L; !' ; , """"""" ; \ `! !!!,?$$$$$ ` $$$$$$$$d$$$$$$$$$P""""` . . ' !!!!!!!!! . `; ` ` !, !!i"$$$$ ` $$$$$$$$$$$$$$$$$F i!!' ,' .. .. ``!!! ! `; \ ` `\`!!.$$$L >>>"""""""??$$$$k ==" !!' ' , , d$$" u":". !! ! \ `; ` i!i,`!!, ?$F $$$$UUU$$$$u,"?$$$ =" r ' $F4 ".$$LJ 3$L !!,` ', \ !!i,.`!i.`!.$ $$$$$$$$$$$ec. d$$$ f '" $$F4.$"zP"$$b."b !!,` '! . :!!!!!!i.`!i """```"=??he, ?$$$b ,i'! ! d$$$$$d$b$$$$$$F?$ `!='' ..... `!,!i ,,,, ,,, ::: $$$$ `!i 'i" $$$$$$$$$$$$$$$c`" d$$$$$$bc, "?$$$$$$$.!,`!i $$$' $$$ '::::: '$$$> !!!!! `?$$$$$$$$$$$$F d$$$$$$$$$$F,u.'$$$$$$c!i`! : .$$$"x ::::: $$$ i!!!!!, $. ``"""""" .,z$$$P"?$$$",ed$$$b $$$$$$i!!! $e $$$" $R ::::: 3$$ !!!!!!!,`$$bd"uer .dP"""?$$. ?y, "4$$$$$$,`$$$$Fi!!! " d$$$ :::::::: )$$ !!!!!!i `$$bc . "?bey,. `d$$e `$$$$F $PP"i!!!! d$$F $r :::::: $$$ )!!!!!! `$$$L".W. "?$by,`"d$$$$$$c $$$" .eeeeu '! J$$" : .:::: . """ !!!!!!!i. `??$ .,._ `"3$$$$$$$$$b,,,d$$$$$$$$c "$" ::::::' : !!!!!!!!!!!!i;;i! ueee. `"?$$$$$$$$$$$$$$$$$$$$$$$$$$$F :.::::::: `:: :: z$$$$$$$$$$$be..`'<<:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ...\..>\\.\\.\\\\ ,/ |, ''```''`<<''<'<<<<<</`\\\>\%`%%"./'%..\=///,%//,,/', ,/'' ,/ , `'''''''''''''''''!!!!!!! //>;>;\.""./';./>.`\- |`/./'','./|'"/`\\>>`,`/'. '. ,` ,/',/',|%//<'/%.////;.//>>,/,;,.-.`\`,..\`<.\\=\\-^//=/<<\\%'- ' .,::` ..:' '`.::: '/'/''/'/>.''(\<|/%<%///>\`\%>\\%\\\>/\'\\\\< `.,'' ..::'`.:.::::'` /',/"><|,/','/'>,/,/'>/|/>\\`|"\|<``\`\"" \<```.,,'`` ..::::..:::: ::: ::::::::::::::::::::::...::::::::::::::::::::''` ...::::::::::::::: ::: ............................................. .:::::::::::::::::::: ::: ::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::: . destroyer:~/workspace/651_Project2/script> diff christmas christmas.RECONSTRUCTED destroyer:~/workspace/651_Project2/script> ls -l christmas* -rw-r--r-- 1 youse youse 5637 2008-03-19 15:33 mchristmas -rw-r--r-- 1 youse youse 5311 2008-03-19 15:41 mchristmas.ARLE -rw-r--r-- 1 youse youse 5637 2008-03-19 15:41 mchristmas.RECONSTRUCTED destroyer:~/workspace/651_Project2/script> cat pelican.txt `.---...__ /```.__ ``. Pelecanus occidentalis |```/ `'--.._`. |``| (o).) \`` \ _,-' `. \```\ ( ( ` . `. `.```. `.` . ` `. `.``\ `.__ `. `. ___\``), )\ `-. `. `. __ _,-' \,' / \ `-. `. `. ,-' '`,-' ' ''| ' ' | `-. `. `. ,-''_,-' ' ' ' ' | ' '| `-. `.`. ,-'_,-' ' ' '' | ' ' | `-.`.`. ,-',-' '' ,' | | |' ' / `-..`. ,' ,' ' ' | ,' | ,' / ' '| `-.) // / ' | ,' ,' / ' '/ | || ,' ,' | ,' | ,' ' '| |||| | ,' ,' ,' ,' ' ' / | | |,' ' |' ,' ' ' '/ | ||,' ,' | ,' ,' ' \ '/ |||| | , ,' ,-' / ' '| ',' | / ,' ' ,-' ' |' |,' | | ' ,' ,-' ' ' ' | '| |||,' ,-' ' ' '_|' '/ |,|,-' /'___,..--'' \ ' | / // ,'-' |' | \ | ///,-' \ | \'| '--' \'\ | | __ ) \___ __| |_ ____,...----'' ||`-- <_.--._ -`--. __ jrei '' `-` `'''''''-----......_____ destroyer:~/workspace/651_Project2/script> java AmerRLE_Encode pelican.txt destroyer:~/workspace/651_Project2/script> cat pelican.txt.ARLE amerRLE1028 `.-_/Pelcanusoidt|'()\, java amerRLE_decode pelican.txt.ARLE Writing to file: pelican.txt.RECONSTRUCTED With/without metadata [1447/1408] encoded characters decoded into 1391 characters. destroyer:~/workspace/651_Project2/script> cat pelican.txt.RECONSTRUCTED `.---...__ /```.__ ``. Pelecanus occidentalis |```/ `'--.._`. |``| (o).) \`` \ _,-' `. \```\ ( ( ` . `. `.```. `.` . ` `. `.``\ `.__ `. `. ___\``), )\ `-. `. `. __ _,-' \,' / \ `-. `. `. ,-' '`,-' ' ''| ' ' | `-. `. `. ,-''_,-' ' ' ' ' | ' '| `-. `.`. ,-'_,-' ' ' '' | ' ' | `-.`.`. ,-',-' '' ,' | | |' ' / `-..`. ,' ,' ' ' | ,' | ,' / ' '| `-.) // / ' | ,' ,' / ' '/ | || ,' ,' | ,' | ,' ' '| |||| | ,' ,' ,' ,' ' ' / | | |,' ' |' ,' ' ' '/ | ||,' ,' | ,' ,' ' \ '/ |||| | , ,' ,-' / ' '| ',' | / ,' ' ,-' ' |' |,' | | ' ,' ,-' ' ' ' | '| |||,' ,-' ' ' '_|' '/ |,|,-' /'___,..--'' \ ' | / // ,'-' |' | \ | ///,-' \ | \'| '--' \'\ | | __ ) \___ __| |_ ____,...----'' ||`-- <_.--._ -`--. __ jrei '' `-` `'''''''-----......_____ destroyer:~/workspace/651_Project2/script> diff pelican.txt pelican.txt.RECONSTRUCTED destroyer:~/workspace/651_Project2/script> ls -l pelican.txt* -rw-r--r-- 1 youse youse 1391 2008-03-19 15:33 mpelican.txt -rw-r--r-- 1 youse youse 1447 2008-03-19 15:43 mpelican.txt.ARLE -rw-r--r-- 1 youse youse 1391 2008-03-19 15:44 mpelican.txt.RECONSTRUCTED destroyer:~/workspace/651_Project2/script> exit exit Script done on Wed 19 Mar 2008 03:44:47 PM EDT