001package algs55; // section 5.5 002import stdlib.*; 003/* *********************************************************************** 004 * Compilation: javac RunLength.java 005 * Execution: java RunLength - < input.txt (compress) 006 * Execution: java RunLength + < input.txt (expand) 007 * Dependencies: BinaryIn.java BinaryOut.java 008 * 009 * Compress or expand binary input from standard input using 010 * run-length encoding. 011 * 012 * % java BinaryDump 40 < 4runs.bin 013 * 0000000000000001111111000000011111111111 014 * 40 bits 015 * 016 * This has runs of 15 0s, 7 1s, 7 0s, and 11 1s. 017 * 018 * % java RunLength - < 4runs.bin | java HexDump 019 * 0f 07 07 0b 020 * 4 bytes 021 * 022 *************************************************************************/ 023 024public class RunLength { 025 private static BinaryIn binaryIn; 026 private static BinaryOut binaryOut; 027 private static final int R = 256; 028 private static final int lgR = 8; 029 030 public static void expand() { 031 boolean b = false; 032 while (!binaryIn.isEmpty()) { 033 int run = binaryIn.readInt(lgR); 034 for (int i = 0; i < run; i++) 035 binaryOut.write(b); 036 b = !b; 037 } 038 binaryOut.close(); 039 } 040 041 public static void compress() { 042 char run = 0; 043 boolean old = false; 044 while (!binaryIn.isEmpty()) { 045 boolean b = binaryIn.readBoolean(); 046 if (b != old) { 047 binaryOut.write(run, lgR); 048 run = 1; 049 old = !old; 050 } 051 else { 052 if (run == R-1) { 053 binaryOut.write(run, lgR); 054 run = 0; 055 binaryOut.write(run, lgR); 056 } 057 run++; 058 } 059 } 060 binaryOut.write(run, lgR); 061 binaryOut.close(); 062 } 063 064 065 public static void main(String[] args) { 066 String txtFile = "data/4runs.bin"; 067 String binFile = "4runsOut.bin"; 068 //args = new String[] { "+" }; binaryIn = new BinaryIn(binFile); binaryOut = new BinaryOut(); 069 args = new String[] { "-" }; binaryIn = new BinaryIn(txtFile); binaryOut = new BinaryOut(binFile); 070 if (args[0].equals("-")) compress(); 071 else if (args[0].equals("+")) expand(); 072 else throw new Error("Illegal command line argument"); 073 } 074 075}