LzmaAlone.java 6.6 KB

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