package SevenZip; | |
public class LzmaAlone | |
{ | |
static public class CommandLine | |
{ | |
public static final int kEncode = 0; | |
public static final int kDecode = 1; | |
public static final int kBenchmak = 2; | |
public int Command = -1; | |
public int NumBenchmarkPasses = 10; | |
public int DictionarySize = 1 << 23; | |
public boolean DictionarySizeIsDefined = false; | |
public int Lc = 3; | |
public int Lp = 0; | |
public int Pb = 2; | |
public int Fb = 128; | |
public boolean FbIsDefined = false; | |
public boolean Eos = false; | |
public int Algorithm = 2; | |
public int MatchFinder = 1; | |
public String InFile; | |
public String OutFile; | |
boolean ParseSwitch(String s) | |
{ | |
if (s.startsWith("d")) | |
{ | |
DictionarySize = 1 << Integer.parseInt(s.substring(1)); | |
DictionarySizeIsDefined = true; | |
} | |
else if (s.startsWith("fb")) | |
{ | |
Fb = Integer.parseInt(s.substring(2)); | |
FbIsDefined = true; | |
} | |
else if (s.startsWith("a")) | |
Algorithm = Integer.parseInt(s.substring(1)); | |
else if (s.startsWith("lc")) | |
Lc = Integer.parseInt(s.substring(2)); | |
else if (s.startsWith("lp")) | |
Lp = Integer.parseInt(s.substring(2)); | |
else if (s.startsWith("pb")) | |
Pb = Integer.parseInt(s.substring(2)); | |
else if (s.startsWith("eos")) | |
Eos = true; | |
else if (s.startsWith("mf")) | |
{ | |
String mfs = s.substring(2); | |
if (mfs.equals("bt2")) | |
MatchFinder = 0; | |
else if (mfs.equals("bt4")) | |
MatchFinder = 1; | |
else if (mfs.equals("bt4b")) | |
MatchFinder = 2; | |
else | |
return false; | |
} | |
else | |
return false; | |
return true; | |
} | |
public boolean Parse(String[] args) throws Exception | |
{ | |
int pos = 0; | |
boolean switchMode = true; | |
for (int i = 0; i < args.length; i++) | |
{ | |
String s = args[i]; | |
if (s.length() == 0) | |
return false; | |
if (switchMode) | |
{ | |
if (s.compareTo("--") == 0) | |
{ | |
switchMode = false; | |
continue; | |
} | |
if (s.charAt(0) == '-') | |
{ | |
String sw = s.substring(1).toLowerCase(); | |
if (sw.length() == 0) | |
return false; | |
try | |
{ | |
if (!ParseSwitch(sw)) | |
return false; | |
} | |
catch (NumberFormatException e) | |
{ | |
return false; | |
} | |
continue; | |
} | |
} | |
if (pos == 0) | |
{ | |
if (s.equalsIgnoreCase("e")) | |
Command = kEncode; | |
else if (s.equalsIgnoreCase("d")) | |
Command = kDecode; | |
else if (s.equalsIgnoreCase("b")) | |
Command = kBenchmak; | |
else | |
return false; | |
} | |
else if(pos == 1) | |
{ | |
if (Command == kBenchmak) | |
{ | |
try | |
{ | |
NumBenchmarkPasses = Integer.parseInt(s); | |
if (NumBenchmarkPasses < 1) | |
return false; | |
} | |
catch (NumberFormatException e) | |
{ | |
return false; | |
} | |
} | |
else | |
InFile = s; | |
} | |
else if(pos == 2) | |
OutFile = s; | |
else | |
return false; | |
pos++; | |
continue; | |
} | |
return true; | |
} | |
} | |
static void PrintHelp() | |
{ | |
System.out.println( | |
"\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" + | |
" e: encode file\n" + | |
" d: decode file\n" + | |
" b: Benchmark\n" + | |
"<Switches>\n" + | |
// " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" + | |
" -d{N}: set dictionary - [0,28], default: 23 (8MB)\n" + | |
" -fb{N}: set number of fast bytes - [5, 273], default: 128\n" + | |
" -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + | |
" -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + | |
" -pb{N}: set number of pos bits - [0, 4], default: 2\n" + | |
" -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" + | |
" -eos: write End Of Stream marker\n" | |
); | |
} | |
public static void main(String[] args) throws Exception | |
{ | |
System.out.println("\nLZMA (Java) 4.61 2008-11-23\n"); | |
if (args.length < 1) | |
{ | |
PrintHelp(); | |
return; | |
} | |
CommandLine params = new CommandLine(); | |
if (!params.Parse(args)) | |
{ | |
System.out.println("\nIncorrect command"); | |
return; | |
} | |
if (params.Command == CommandLine.kBenchmak) | |
{ | |
int dictionary = (1 << 21); | |
if (params.DictionarySizeIsDefined) | |
dictionary = params.DictionarySize; | |
if (params.MatchFinder > 1) | |
throw new Exception("Unsupported match finder"); | |
SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary); | |
} | |
else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode) | |
{ | |
java.io.File inFile = new java.io.File(params.InFile); | |
java.io.File outFile = new java.io.File(params.OutFile); | |
java.io.BufferedInputStream inStream = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile)); | |
java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile)); | |
boolean eos = false; | |
if (params.Eos) | |
eos = true; | |
if (params.Command == CommandLine.kEncode) | |
{ | |
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); | |
if (!encoder.SetAlgorithm(params.Algorithm)) | |
throw new Exception("Incorrect compression mode"); | |
if (!encoder.SetDictionarySize(params.DictionarySize)) | |
throw new Exception("Incorrect dictionary size"); | |
if (!encoder.SetNumFastBytes(params.Fb)) | |
throw new Exception("Incorrect -fb value"); | |
if (!encoder.SetMatchFinder(params.MatchFinder)) | |
throw new Exception("Incorrect -mf value"); | |
if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb)) | |
throw new Exception("Incorrect -lc or -lp or -pb value"); | |
encoder.SetEndMarkerMode(eos); | |
encoder.WriteCoderProperties(outStream); | |
long fileSize; | |
if (eos) | |
fileSize = -1; | |
else | |
fileSize = inFile.length(); | |
for (int i = 0; i < 8; i++) | |
outStream.write((int)(fileSize >>> (8 * i)) & 0xFF); | |
encoder.Code(inStream, outStream, -1, -1, null); | |
} | |
else | |
{ | |
int propertiesSize = 5; | |
byte[] properties = new byte[propertiesSize]; | |
if (inStream.read(properties, 0, propertiesSize) != propertiesSize) | |
throw new Exception("input .lzma file is too short"); | |
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); | |
if (!decoder.SetDecoderProperties(properties)) | |
throw new Exception("Incorrect stream properties"); | |
long outSize = 0; | |
for (int i = 0; i < 8; i++) | |
{ | |
int v = inStream.read(); | |
if (v < 0) | |
throw new Exception("Can't read stream size"); | |
outSize |= ((long)v) << (8 * i); | |
} | |
if (!decoder.Code(inStream, outStream, outSize)) | |
throw new Exception("Error in data stream"); | |
} | |
outStream.flush(); | |
outStream.close(); | |
inStream.close(); | |
} | |
else | |
throw new Exception("Incorrect command"); | |
return; | |
} | |
} |