|
1 package SevenZip; |
|
2 |
|
3 public class LzmaAlone |
|
4 { |
|
5 static public class CommandLine |
|
6 { |
|
7 public static final int kEncode = 0; |
|
8 public static final int kDecode = 1; |
|
9 public static final int kBenchmak = 2; |
|
10 |
|
11 public int Command = -1; |
|
12 public int NumBenchmarkPasses = 10; |
|
13 |
|
14 public int DictionarySize = 1 << 23; |
|
15 public boolean DictionarySizeIsDefined = false; |
|
16 |
|
17 public int Lc = 3; |
|
18 public int Lp = 0; |
|
19 public int Pb = 2; |
|
20 |
|
21 public int Fb = 128; |
|
22 public boolean FbIsDefined = false; |
|
23 |
|
24 public boolean Eos = false; |
|
25 |
|
26 public int Algorithm = 2; |
|
27 public int MatchFinder = 1; |
|
28 |
|
29 public String InFile; |
|
30 public String OutFile; |
|
31 |
|
32 boolean ParseSwitch(String s) |
|
33 { |
|
34 if (s.startsWith("d")) |
|
35 { |
|
36 DictionarySize = 1 << Integer.parseInt(s.substring(1)); |
|
37 DictionarySizeIsDefined = true; |
|
38 } |
|
39 else if (s.startsWith("fb")) |
|
40 { |
|
41 Fb = Integer.parseInt(s.substring(2)); |
|
42 FbIsDefined = true; |
|
43 } |
|
44 else if (s.startsWith("a")) |
|
45 Algorithm = Integer.parseInt(s.substring(1)); |
|
46 else if (s.startsWith("lc")) |
|
47 Lc = Integer.parseInt(s.substring(2)); |
|
48 else if (s.startsWith("lp")) |
|
49 Lp = Integer.parseInt(s.substring(2)); |
|
50 else if (s.startsWith("pb")) |
|
51 Pb = Integer.parseInt(s.substring(2)); |
|
52 else if (s.startsWith("eos")) |
|
53 Eos = true; |
|
54 else if (s.startsWith("mf")) |
|
55 { |
|
56 String mfs = s.substring(2); |
|
57 if (mfs.equals("bt2")) |
|
58 MatchFinder = 0; |
|
59 else if (mfs.equals("bt4")) |
|
60 MatchFinder = 1; |
|
61 else if (mfs.equals("bt4b")) |
|
62 MatchFinder = 2; |
|
63 else |
|
64 return false; |
|
65 } |
|
66 else |
|
67 return false; |
|
68 return true; |
|
69 } |
|
70 |
|
71 public boolean Parse(String[] args) throws Exception |
|
72 { |
|
73 int pos = 0; |
|
74 boolean switchMode = true; |
|
75 for (int i = 0; i < args.length; i++) |
|
76 { |
|
77 String s = args[i]; |
|
78 if (s.length() == 0) |
|
79 return false; |
|
80 if (switchMode) |
|
81 { |
|
82 if (s.compareTo("--") == 0) |
|
83 { |
|
84 switchMode = false; |
|
85 continue; |
|
86 } |
|
87 if (s.charAt(0) == '-') |
|
88 { |
|
89 String sw = s.substring(1).toLowerCase(); |
|
90 if (sw.length() == 0) |
|
91 return false; |
|
92 try |
|
93 { |
|
94 if (!ParseSwitch(sw)) |
|
95 return false; |
|
96 } |
|
97 catch (NumberFormatException e) |
|
98 { |
|
99 return false; |
|
100 } |
|
101 continue; |
|
102 } |
|
103 } |
|
104 if (pos == 0) |
|
105 { |
|
106 if (s.equalsIgnoreCase("e")) |
|
107 Command = kEncode; |
|
108 else if (s.equalsIgnoreCase("d")) |
|
109 Command = kDecode; |
|
110 else if (s.equalsIgnoreCase("b")) |
|
111 Command = kBenchmak; |
|
112 else |
|
113 return false; |
|
114 } |
|
115 else if(pos == 1) |
|
116 { |
|
117 if (Command == kBenchmak) |
|
118 { |
|
119 try |
|
120 { |
|
121 NumBenchmarkPasses = Integer.parseInt(s); |
|
122 if (NumBenchmarkPasses < 1) |
|
123 return false; |
|
124 } |
|
125 catch (NumberFormatException e) |
|
126 { |
|
127 return false; |
|
128 } |
|
129 } |
|
130 else |
|
131 InFile = s; |
|
132 } |
|
133 else if(pos == 2) |
|
134 OutFile = s; |
|
135 else |
|
136 return false; |
|
137 pos++; |
|
138 continue; |
|
139 } |
|
140 return true; |
|
141 } |
|
142 } |
|
143 |
|
144 |
|
145 static void PrintHelp() |
|
146 { |
|
147 System.out.println( |
|
148 "\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" + |
|
149 " e: encode file\n" + |
|
150 " d: decode file\n" + |
|
151 " b: Benchmark\n" + |
|
152 "<Switches>\n" + |
|
153 // " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" + |
|
154 " -d{N}: set dictionary - [0,28], default: 23 (8MB)\n" + |
|
155 " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" + |
|
156 " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + |
|
157 " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + |
|
158 " -pb{N}: set number of pos bits - [0, 4], default: 2\n" + |
|
159 " -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" + |
|
160 " -eos: write End Of Stream marker\n" |
|
161 ); |
|
162 } |
|
163 |
|
164 public static void main(String[] args) throws Exception |
|
165 { |
|
166 System.out.println("\nLZMA (Java) 4.42 Copyright (c) 1999-2006 Igor Pavlov 2006-05-15\n"); |
|
167 |
|
168 if (args.length < 1) |
|
169 { |
|
170 PrintHelp(); |
|
171 return; |
|
172 } |
|
173 |
|
174 CommandLine params = new CommandLine(); |
|
175 if (!params.Parse(args)) |
|
176 { |
|
177 System.out.println("\nIncorrect command"); |
|
178 return; |
|
179 } |
|
180 |
|
181 if (params.Command == CommandLine.kBenchmak) |
|
182 { |
|
183 int dictionary = (1 << 21); |
|
184 if (params.DictionarySizeIsDefined) |
|
185 dictionary = params.DictionarySize; |
|
186 if (params.MatchFinder > 1) |
|
187 throw new Exception("Unsupported match finder"); |
|
188 SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary); |
|
189 } |
|
190 else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode) |
|
191 { |
|
192 java.io.File inFile = new java.io.File(params.InFile); |
|
193 java.io.File outFile = new java.io.File(params.OutFile); |
|
194 |
|
195 java.io.BufferedInputStream inStream = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile)); |
|
196 java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile)); |
|
197 |
|
198 boolean eos = false; |
|
199 if (params.Eos) |
|
200 eos = true; |
|
201 if (params.Command == CommandLine.kEncode) |
|
202 { |
|
203 SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); |
|
204 if (!encoder.SetAlgorithm(params.Algorithm)) |
|
205 throw new Exception("Incorrect compression mode"); |
|
206 if (!encoder.SetDictionarySize(params.DictionarySize)) |
|
207 throw new Exception("Incorrect dictionary size"); |
|
208 if (!encoder.SeNumFastBytes(params.Fb)) |
|
209 throw new Exception("Incorrect -fb value"); |
|
210 if (!encoder.SetMatchFinder(params.MatchFinder)) |
|
211 throw new Exception("Incorrect -mf value"); |
|
212 if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb)) |
|
213 throw new Exception("Incorrect -lc or -lp or -pb value"); |
|
214 encoder.SetEndMarkerMode(eos); |
|
215 encoder.WriteCoderProperties(outStream); |
|
216 long fileSize; |
|
217 if (eos) |
|
218 fileSize = -1; |
|
219 else |
|
220 fileSize = inFile.length(); |
|
221 for (int i = 0; i < 8; i++) |
|
222 outStream.write((int)(fileSize >>> (8 * i)) & 0xFF); |
|
223 encoder.Code(inStream, outStream, -1, -1, null); |
|
224 } |
|
225 else |
|
226 { |
|
227 int propertiesSize = 5; |
|
228 byte[] properties = new byte[propertiesSize]; |
|
229 if (inStream.read(properties, 0, propertiesSize) != propertiesSize) |
|
230 throw new Exception("input .lzma file is too short"); |
|
231 SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); |
|
232 if (!decoder.SetDecoderProperties(properties)) |
|
233 throw new Exception("Incorrect stream properties"); |
|
234 long outSize = 0; |
|
235 for (int i = 0; i < 8; i++) |
|
236 { |
|
237 int v = inStream.read(); |
|
238 if (v < 0) |
|
239 throw new Exception("Can't read stream size"); |
|
240 outSize |= ((long)v) << (8 * i); |
|
241 } |
|
242 if (!decoder.Code(inStream, outStream, outSize)) |
|
243 throw new Exception("Error in data stream"); |
|
244 } |
|
245 outStream.flush(); |
|
246 outStream.close(); |
|
247 inStream.close(); |
|
248 } |
|
249 else |
|
250 throw new Exception("Incorrect command"); |
|
251 return; |
|
252 } |
|
253 } |