예제 #1
0
        static void Main(string[] args)
        {
            List <string> infiles    = new List <string>();
            Prefilter     filter     = Prefilter.None;
            Exhaustion    exhaustion = Exhaustion.Standard;

            for (int i = 0; i < args.Length; ++i)
            {
                if (args[i] == "--filter")
                {
                    ++i;
                    filter = (Prefilter)Enum.Parse(typeof(Prefilter), args[i], true);
                }
                else if (args[i] == "--exhaustion")
                {
                    ++i;
                    exhaustion = (Exhaustion)Enum.Parse(typeof(Exhaustion), args[i], true);
                }
                else
                {
                    infiles.Add(args[i]);
                }
            }

            if (infiles.Count == 0)
            {
                Console.WriteLine("Usage: FileCompressor [options] files");
                Console.WriteLine("Options:");
                Console.WriteLine("  --filter");
                foreach (object e in Enum.GetValues(typeof(Prefilter)))
                {
                    Console.WriteLine("      " + e.ToString());
                }
                Console.WriteLine("  --exhaustion");
                foreach (object e in Enum.GetValues(typeof(Exhaustion)))
                {
                    Console.WriteLine("      " + e.ToString());
                }
            }

            foreach (string infile in infiles)
            {
                string outfile = infile + "_" + filter.ToString() + "_" + exhaustion.ToString() + ".bin";
                Console.WriteLine("Generating: " + outfile);

                Stream ms;
                using (var fs = new FileStream(infile, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    ms = fs.CopyToMemory();
                    fs.Close();
                }

                using (var compressed = Compress(ms, filter, exhaustion)) {
                    using (FileStream os = new FileStream(outfile, FileMode.Create)) {
                        compressed.Position = 0;
                        StreamUtils.CopyStream(compressed, os);
                    }
                }
            }
        }
예제 #2
0
        public static Stream Compress(Stream instream, Prefilter filter, Exhaustion exhaustion)
        {
            MemoryStream outstream = new MemoryStream((int)instream.Length);
            uint         crc       = CRC.CalculateDigest(instream.CopyToByteArray(), 0, (uint)instream.Length);

            if (filter == Prefilter.None)
            {
                MemoryStream memorystream = new MemoryStream((int)instream.Length);
                instream.Position = 0;
                StreamUtils.CopyStream(instream, memorystream);

                outstream.WriteUInt8(0);                 // filter ID
                outstream.WriteUInt32(crc, EndianUtils.Endianness.LittleEndian);
                CompressInternalLzmaSemiOptimized(memorystream, outstream, exhaustion);
                return(outstream);
            }

            if (filter == Prefilter.Delta2LE_0x30Lead)
            {
                if ((instream.Length % 2) != 0 || instream.Length < 0x30)
                {
                    throw new Exception("unsupported length for " + filter.ToString());
                }
                MemoryStream filteredstream = new MemoryStream((int)instream.Length);
                instream.Position = 0;
                StreamUtils.CopyStream(instream, filteredstream, 0x30);

                ushort last = 0;
                while (instream.Position < instream.Length)
                {
                    ushort curr = instream.ReadUInt16(EndianUtils.Endianness.LittleEndian);
                    ushort diff = (ushort)(last - curr);
                    filteredstream.WriteUInt16(diff, EndianUtils.Endianness.LittleEndian);
                    last = curr;
                }

                outstream.WriteUInt8(1);                 // filter ID
                outstream.WriteUInt32(crc, EndianUtils.Endianness.LittleEndian);
                filteredstream.Position = 0;
                CompressInternalLzmaSemiOptimized(filteredstream, outstream, exhaustion);
                return(outstream);
            }

            if (filter == Prefilter.Delta4LE_0x30Lead)
            {
                if ((instream.Length % 4) != 0 || instream.Length < 0x30)
                {
                    throw new Exception("unsupported length for " + filter.ToString());
                }
                MemoryStream filteredstream = new MemoryStream((int)instream.Length);
                instream.Position = 0;
                StreamUtils.CopyStream(instream, filteredstream, 0x30);

                uint last = 0;
                while (instream.Position < instream.Length)
                {
                    uint curr = instream.ReadUInt32(EndianUtils.Endianness.LittleEndian);
                    uint diff = (uint)(last - curr);
                    filteredstream.WriteUInt32(diff, EndianUtils.Endianness.LittleEndian);
                    last = curr;
                }

                outstream.WriteUInt8(2);                 // filter ID
                outstream.WriteUInt32(crc, EndianUtils.Endianness.LittleEndian);
                filteredstream.Position = 0;
                CompressInternalLzmaSemiOptimized(filteredstream, outstream, exhaustion);
                return(outstream);
            }

            if (filter == Prefilter.Delta2LE_Deinterleaved_0x30Lead)
            {
                if ((instream.Length % 4) != 0 || instream.Length < 0x30)
                {
                    throw new Exception("unsupported length for " + filter.ToString());
                }
                MemoryStream filteredstream = new MemoryStream((int)instream.Length);
                instream.Position = 0;
                StreamUtils.CopyStream(instream, filteredstream, 0x30);

                long   pos  = instream.Position;
                ushort last = 0;
                while (instream.Position < instream.Length)
                {
                    ushort curr = instream.ReadUInt16(EndianUtils.Endianness.LittleEndian);
                    ushort diff = (ushort)(last - curr);
                    filteredstream.WriteUInt16(diff, EndianUtils.Endianness.LittleEndian);
                    last = curr;
                    instream.ReadUInt16(EndianUtils.Endianness.LittleEndian);
                }
                instream.Position = pos;
                last = 0;
                while (instream.Position < instream.Length)
                {
                    instream.ReadUInt16(EndianUtils.Endianness.LittleEndian);
                    ushort curr = instream.ReadUInt16(EndianUtils.Endianness.LittleEndian);
                    ushort diff = (ushort)(last - curr);
                    filteredstream.WriteUInt16(diff, EndianUtils.Endianness.LittleEndian);
                    last = curr;
                }

                outstream.WriteUInt8(3);                 // filter ID
                outstream.WriteUInt32(crc, EndianUtils.Endianness.LittleEndian);
                filteredstream.Position = 0;
                CompressInternalLzmaSemiOptimized(filteredstream, outstream, exhaustion);
                return(outstream);
            }

            throw new Exception("unexpected filter");
        }