misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
branchui-scaling
changeset 15283 c4fd2813b127
parent 13390 0135e64c6c66
parent 15279 7ab5cf405686
child 15663 d92eeb468dad
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
     1 using System;
       
     2 using System.IO;
       
     3 namespace SevenZip
       
     4 {
       
     5 	using CommandLineParser;
       
     6 	
       
     7 	public class CDoubleStream: Stream
       
     8 	{
       
     9 		public System.IO.Stream s1;
       
    10 		public System.IO.Stream s2;
       
    11 		public int fileIndex;
       
    12 		public long skipSize;
       
    13 		
       
    14 		public override bool CanRead { get { return true; }}
       
    15 		public override bool CanWrite { get { return false; }}
       
    16 		public override bool CanSeek { get { return false; }}
       
    17 		public override long Length { get { return s1.Length + s2.Length - skipSize; } }
       
    18 		public override long Position
       
    19 		{
       
    20 			get { return 0;	}
       
    21 			set { }
       
    22 		}
       
    23 		public override void Flush() { }
       
    24 		public override int Read(byte[] buffer, int offset, int count) 
       
    25 		{
       
    26 			int numTotal = 0;
       
    27 			while (count > 0)
       
    28 			{
       
    29 				if (fileIndex == 0)
       
    30 				{
       
    31 					int num = s1.Read(buffer, offset, count);
       
    32 					offset += num;
       
    33 					count -= num;
       
    34 					numTotal += num;
       
    35 					if (num == 0)
       
    36 						fileIndex++;
       
    37 				}
       
    38 				if (fileIndex == 1)
       
    39 				{
       
    40 					numTotal += s2.Read(buffer, offset, count);
       
    41 					return numTotal;
       
    42 				}
       
    43 			}
       
    44 			return numTotal;
       
    45 		}
       
    46 		public override void Write(byte[] buffer, int offset, int count)
       
    47 		{
       
    48 			throw (new Exception("can't Write"));
       
    49 		}
       
    50 		public override long Seek(long offset, System.IO.SeekOrigin origin)
       
    51 		{
       
    52 			throw (new Exception("can't Seek"));
       
    53 		}
       
    54 		public override void SetLength(long value)
       
    55 		{
       
    56 			throw (new Exception("can't SetLength"));
       
    57 		}
       
    58 	}
       
    59 	
       
    60 	class LzmaAlone
       
    61 	{
       
    62 		enum Key
       
    63 		{
       
    64 			Help1 = 0,
       
    65 			Help2,
       
    66 			Mode,
       
    67 			Dictionary,
       
    68 			FastBytes,
       
    69 			LitContext,
       
    70 			LitPos,
       
    71 			PosBits,
       
    72 			MatchFinder,
       
    73 			EOS,
       
    74 			StdIn,
       
    75 			StdOut,
       
    76 			Train
       
    77 		};
       
    78 
       
    79 		static void PrintHelp()
       
    80 		{
       
    81 			System.Console.WriteLine("\nUsage:  LZMA <e|d> [<switches>...] inputFile outputFile\n" +
       
    82 				"  e: encode file\n" +
       
    83 				"  d: decode file\n" +
       
    84 				"  b: Benchmark\n" +
       
    85 				"<Switches>\n" +
       
    86 				// "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n" +
       
    87 				"  -d{N}:  set dictionary - [0, 29], default: 23 (8MB)\n" +
       
    88 				"  -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
       
    89 				"  -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
       
    90 				"  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
       
    91 				"  -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
       
    92 				"  -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
       
    93 				"  -eos:   write End Of Stream marker\n"
       
    94 				// + "  -si:    read data from stdin\n"
       
    95 				// + "  -so:    write data to stdout\n"
       
    96 				);
       
    97 		}
       
    98 
       
    99 		static bool GetNumber(string s, out Int32 v)
       
   100 		{
       
   101 			v = 0;
       
   102 			for (int i = 0; i < s.Length; i++)
       
   103 			{
       
   104 				char c = s[i];
       
   105 				if (c < '0' || c > '9')
       
   106 					return false;
       
   107 				v *= 10;
       
   108 				v += (Int32)(c - '0');
       
   109 			}
       
   110 			return true;
       
   111 		}
       
   112 
       
   113 		static int IncorrectCommand()
       
   114 		{
       
   115 			throw (new Exception("Command line error"));
       
   116 			// System.Console.WriteLine("\nCommand line error\n");
       
   117 			// return 1;
       
   118 		}
       
   119 		static int Main2(string[] args)
       
   120 		{
       
   121 			System.Console.WriteLine("\nLZMA# 4.49 Copyright (c) 1999-2007 Igor Pavlov  2006-07-05\n");
       
   122 
       
   123 			if (args.Length == 0)
       
   124 			{
       
   125 				PrintHelp();
       
   126 				return 0;
       
   127 			}
       
   128 
       
   129 			SwitchForm[] kSwitchForms = new SwitchForm[13];
       
   130 			int sw = 0;
       
   131 			kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false);
       
   132 			kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false);
       
   133 			kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1);
       
   134 			kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1);
       
   135 			kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1);
       
   136 			kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1);
       
   137 			kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1);
       
   138 			kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1);
       
   139 			kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1);
       
   140 			kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false);
       
   141 			kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false);
       
   142 			kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false);
       
   143 			kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1);
       
   144 
       
   145 
       
   146 			Parser parser = new Parser(sw);
       
   147 			try
       
   148 			{
       
   149 				parser.ParseStrings(kSwitchForms, args);
       
   150 			}
       
   151 			catch
       
   152 			{
       
   153 				return IncorrectCommand();
       
   154 			}
       
   155 
       
   156 			if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs)
       
   157 			{
       
   158 				PrintHelp();
       
   159 				return 0;
       
   160 			}
       
   161 
       
   162 			System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings;
       
   163 
       
   164 			int paramIndex = 0;
       
   165 			if (paramIndex >= nonSwitchStrings.Count)
       
   166 				return IncorrectCommand();
       
   167 			string command = (string)nonSwitchStrings[paramIndex++];
       
   168 			command = command.ToLower();
       
   169 
       
   170 			bool dictionaryIsDefined = false;
       
   171 			Int32 dictionary = 1 << 21;
       
   172 			if (parser[(int)Key.Dictionary].ThereIs)
       
   173 			{
       
   174 				Int32 dicLog;
       
   175 				if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog))
       
   176 					IncorrectCommand();
       
   177 				dictionary = (Int32)1 << dicLog;
       
   178 				dictionaryIsDefined = true;
       
   179 			}
       
   180 			string mf = "bt4";
       
   181 			if (parser[(int)Key.MatchFinder].ThereIs)
       
   182 				mf = (string)parser[(int)Key.MatchFinder].PostStrings[0];
       
   183 			mf = mf.ToLower();
       
   184 
       
   185 			if (command == "b")
       
   186 			{
       
   187 				const Int32 kNumDefaultItereations = 10;
       
   188 				Int32 numIterations = kNumDefaultItereations;
       
   189 				if (paramIndex < nonSwitchStrings.Count)
       
   190 					if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations))
       
   191 						numIterations = kNumDefaultItereations;
       
   192 				return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary);
       
   193 			}
       
   194 
       
   195 			string train = "";
       
   196 			if (parser[(int)Key.Train].ThereIs)
       
   197 				train = (string)parser[(int)Key.Train].PostStrings[0];
       
   198 
       
   199 			bool encodeMode = false;
       
   200 			if (command == "e")
       
   201 				encodeMode = true;
       
   202 			else if (command == "d")
       
   203 				encodeMode = false;
       
   204 			else
       
   205 				IncorrectCommand();
       
   206 
       
   207 			bool stdInMode = parser[(int)Key.StdIn].ThereIs;
       
   208 			bool stdOutMode = parser[(int)Key.StdOut].ThereIs;
       
   209 
       
   210 			Stream inStream = null;
       
   211 			if (stdInMode)
       
   212 			{
       
   213 				throw (new Exception("Not implemeted"));
       
   214 			}
       
   215 			else
       
   216 			{
       
   217 				if (paramIndex >= nonSwitchStrings.Count)
       
   218 					IncorrectCommand();
       
   219 				string inputName = (string)nonSwitchStrings[paramIndex++];
       
   220 				inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);
       
   221 			}
       
   222 
       
   223 			FileStream outStream = null;
       
   224 			if (stdOutMode)
       
   225 			{
       
   226 				throw (new Exception("Not implemeted"));
       
   227 			}
       
   228 			else
       
   229 			{
       
   230 				if (paramIndex >= nonSwitchStrings.Count)
       
   231 					IncorrectCommand();
       
   232 				string outputName = (string)nonSwitchStrings[paramIndex++];
       
   233 				outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);
       
   234 			}
       
   235 
       
   236 			FileStream trainStream = null;
       
   237 			if (train.Length != 0)
       
   238 				trainStream = new FileStream(train, FileMode.Open, FileAccess.Read);
       
   239 
       
   240 			if (encodeMode)
       
   241 			{
       
   242 				if (!dictionaryIsDefined)
       
   243 					dictionary = 1 << 23;
       
   244 
       
   245 				Int32 posStateBits = 2;
       
   246 				Int32 litContextBits = 3; // for normal files
       
   247 				// UInt32 litContextBits = 0; // for 32-bit data
       
   248 				Int32 litPosBits = 0;
       
   249 				// UInt32 litPosBits = 2; // for 32-bit data
       
   250 				Int32 algorithm = 2;
       
   251 				Int32 numFastBytes = 128;
       
   252 
       
   253 				bool eos = parser[(int)Key.EOS].ThereIs || stdInMode;
       
   254 
       
   255 				if (parser[(int)Key.Mode].ThereIs)
       
   256 					if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm))
       
   257 						IncorrectCommand();
       
   258 
       
   259 				if (parser[(int)Key.FastBytes].ThereIs)
       
   260 					if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes))
       
   261 						IncorrectCommand();
       
   262 				if (parser[(int)Key.LitContext].ThereIs)
       
   263 					if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits))
       
   264 						IncorrectCommand();
       
   265 				if (parser[(int)Key.LitPos].ThereIs)
       
   266 					if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits))
       
   267 						IncorrectCommand();
       
   268 				if (parser[(int)Key.PosBits].ThereIs)
       
   269 					if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits))
       
   270 						IncorrectCommand();
       
   271 
       
   272 				CoderPropID[] propIDs = 
       
   273 				{
       
   274 					CoderPropID.DictionarySize,
       
   275 					CoderPropID.PosStateBits,
       
   276 					CoderPropID.LitContextBits,
       
   277 					CoderPropID.LitPosBits,
       
   278 					CoderPropID.Algorithm,
       
   279 					CoderPropID.NumFastBytes,
       
   280 					CoderPropID.MatchFinder,
       
   281 					CoderPropID.EndMarker
       
   282 				};
       
   283 				object[] properties = 
       
   284 				{
       
   285 					(Int32)(dictionary),
       
   286 					(Int32)(posStateBits),
       
   287 					(Int32)(litContextBits),
       
   288 					(Int32)(litPosBits),
       
   289 					(Int32)(algorithm),
       
   290 					(Int32)(numFastBytes),
       
   291 					mf,
       
   292 					eos
       
   293 				};
       
   294 
       
   295 				Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
       
   296 				encoder.SetCoderProperties(propIDs, properties);
       
   297 				encoder.WriteCoderProperties(outStream);
       
   298 				Int64 fileSize;
       
   299 				if (eos || stdInMode)
       
   300 					fileSize = -1;
       
   301 				else
       
   302 					fileSize = inStream.Length;
       
   303 				for (int i = 0; i < 8; i++)
       
   304 					outStream.WriteByte((Byte)(fileSize >> (8 * i)));
       
   305 				if (trainStream != null)
       
   306 				{
       
   307 					CDoubleStream doubleStream = new CDoubleStream();
       
   308 					doubleStream.s1 = trainStream;
       
   309 					doubleStream.s2 = inStream;
       
   310 					doubleStream.fileIndex = 0;
       
   311 					inStream = doubleStream;
       
   312 					long trainFileSize = trainStream.Length;
       
   313 					doubleStream.skipSize = 0;
       
   314 					if (trainFileSize > dictionary)
       
   315 						doubleStream.skipSize = trainFileSize - dictionary;
       
   316 					trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);
       
   317 					encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));
       
   318 				}
       
   319 				encoder.Code(inStream, outStream, -1, -1, null);
       
   320 			}
       
   321 			else if (command == "d")
       
   322 			{
       
   323 				byte[] properties = new byte[5];
       
   324 				if (inStream.Read(properties, 0, 5) != 5)
       
   325 					throw (new Exception("input .lzma is too short"));
       
   326 				Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
       
   327 				decoder.SetDecoderProperties(properties);
       
   328 				if (trainStream != null)
       
   329 				{
       
   330 					if (!decoder.Train(trainStream))
       
   331 						throw (new Exception("can't train"));
       
   332 				}
       
   333 				long outSize = 0;
       
   334 				for (int i = 0; i < 8; i++)
       
   335 				{
       
   336 					int v = inStream.ReadByte();
       
   337 					if (v < 0)
       
   338 						throw (new Exception("Can't Read 1"));
       
   339 					outSize |= ((long)(byte)v) << (8 * i);
       
   340 				}
       
   341 				long compressedSize = inStream.Length - inStream.Position;
       
   342 				decoder.Code(inStream, outStream, compressedSize, outSize, null);
       
   343 			}
       
   344 			else
       
   345 				throw (new Exception("Command Error"));
       
   346 			return 0;
       
   347 		}
       
   348 
       
   349 		[STAThread]
       
   350 		static int Main(string[] args)
       
   351 		{
       
   352 			try
       
   353 			{
       
   354 				return Main2(args);
       
   355 			}
       
   356 			catch (Exception e)
       
   357 			{
       
   358 				Console.WriteLine("{0} Caught exception #1.", e);
       
   359 				// throw e;
       
   360 				return 1;
       
   361 			}
       
   362 		}
       
   363 	}
       
   364 }