Ejemplo n.º 1
0
        static void ApplyParameters(CodecBase codec, string parameterText)
        {
            var type  = codec.GetType();
            var props = Utility.GetPropertiesWith <CodecParameterAttribute>(type).ToList();

            parameterText = parameterText.Trim(new char[] { ':' });
            var phrases = parameterText.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var phrase in phrases)
            {
                var  tokens = phrase.Split(new[] { '=' });
                uint value;
                if (tokens.Length != 2 || !UInt32.TryParse(tokens[1], out value))
                {
                    Console.WriteLine($"Error! unknown parameter {phrase}");
                    continue;
                }
                var property = props.FirstOrDefault(p =>
                {
                    var attr = p.GetCustomAttribute(typeof(CodecParameterAttribute)) as CodecParameterAttribute;
                    return(attr != null && attr.SymbolName == tokens[0]);
                }
                                                    );
                if (property == null)
                {
                    Console.WriteLine($"Error! unknown parameter {phrase}");
                    continue;
                }
                property.SetValue(codec, value);
                Console.WriteLine($"Codec {codec.GetType().Name.Replace("Codec","")} parameter {property.Name} set to {value}");
            }
        }
Ejemplo n.º 2
0
        public static void Optimize(byte [] data)
        {
            var entropy = CodecBase.ComputeShannonEntropy(data);
            var ratio   = entropy / 8.0;

            Console.WriteLine($"Shannon entropy {entropy:F3} -> ratio {ratio:F3}");

            //var codec = new LZCLCodec();
            //codec.Options |= LZCLCodec.OptionFlags.DumpOptimize;
            //codec.OutputWriter = Console.Out;
            //codec.Optimize(data);
        }
Ejemplo n.º 3
0
        // items to show (when relevant):
        // codec, success, uncompressed size, compressed size, compression ratio, compression ticks, decompression ticks, filesize, filename
        private void DumpResult(Result result, CodecBase codec, string filename)
        {
            var length = 0L;

            if (File.Exists(filename))
            {
                var fi = new FileInfo(filename);
                length = fi.Length;
            }
            var codecName = codec.CodecName;//GetType().Name;

            Write($"{codecName,10}, {result.Success, 5}, {result.UncompressedLength,8}, {result.CompressedLength,8}, {result.Ratio:F3}, ");
            Write($"{result.CompressionTicks,10}, {result.DecompressionTicks,10}, ");
            Write($"{length,10}, {filename}, ");
            WriteLine();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Test data round-trip.
        /// Gather info about it and return in result
        /// </summary>
        /// <param name="request"></param>
        /// <param name="codec"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        Result TestDataRoundtrip(Request request, CodecBase codec, byte [] data)
        {
            var result = new Result();
            var timer  = new Stopwatch();

            timer.Start();
            var compressed = codec.Compress(data);

            timer.Stop();
            result.CompressionTicks   = timer.ElapsedTicks;
            result.CompressedLength   = compressed?.Length ?? 0;
            result.UncompressedLength = data.Length;

            result.Success = true; // assume succeeded
            if (request.Decompress)
            {
                timer.Reset();

                byte[] decompressed;
                if (request.UseExternalDecompressor)
                {
                    byte canary             = (byte)(data.Length ^ 0x5A); // check survives
                    var  decompressedCanary = new byte[data.Length + 1];
                    decompressedCanary[decompressedCanary.Length - 1] = canary;
                    if (codec.GetType() == typeof(HuffmanCodec) && compressed != null)
                    {
                        timer.Start();
                        NativeMethods.DecompressHuffman(compressed, compressed.Length, decompressedCanary,
                                                        decompressedCanary.Length - 1);
                        timer.Stop();
                    }
                    else if (codec.GetType() == typeof(Lz77Codec) && compressed != null)
                    {
                        timer.Start();
                        NativeMethods.DecompressLZ77(compressed, compressed.Length, decompressedCanary,
                                                     decompressedCanary.Length - 1);
                        timer.Stop();
                    }
                    else if (codec.GetType() == typeof(ArithmeticCodec) && compressed != null)
                    {
                        timer.Start();
                        NativeMethods.DecompressArithmetic(compressed, compressed.Length, decompressedCanary,
                                                           decompressedCanary.Length - 1);
                        timer.Stop();
                    }
                    else if (codec.GetType() == typeof(LzclCodec) && compressed != null)
                    {
                        timer.Start();
                        NativeMethods.DecompressLZCL(compressed, compressed.Length, decompressedCanary,
                                                     decompressedCanary.Length - 1);
                        timer.Stop();
                    }
                    if (decompressedCanary[decompressedCanary.Length - 1] != canary)
                    {
                        throw new Exception("Decompression canary overwritten!");
                    }
                    // must shrink decompressed to proper size for compare
                    decompressed = new byte[data.Length];
                    Array.Copy(decompressedCanary, decompressed, decompressed.Length);
                }
                else
                {
                    timer.Start();
                    decompressed = codec.Decompress(compressed);
                    timer.Stop();
                }
                result.DecompressionTicks = timer.ElapsedTicks;
                result.Success            = CodecBase.CompareBytes(data, decompressed);
            }
            return(result);
        }
Ejemplo n.º 5
0
        static int PerformCommand(Options opts)
        {
            if (opts.Testing)
            {
                DoTesting();
                return(1);
            }
            // create list of codecs
            var codecs = new List <CodecBase>();

            for (var i = 0; i < opts.CodecIndices.Count; ++i)
            {
                var       ci    = opts.CodecIndices[i];
                CodecBase codec = null;
                switch (CodecNames[ci])
                {
                case "Arithmetic":
                    codec = new ArithmeticCodec();
                    break;

                case "Huffman":
                    codec = new HuffmanCodec();
                    break;

                case "Lz77":
                    codec = new Lz77Codec();
                    break;

                case "Lzcl":
                    codec = new LzclCodec();
                    break;

                default:
                    Console.Error.WriteLine($"Unknown codec {CodecNames[ci]}");
                    break;
                }
                ApplyParameters(codec, opts.CodecParameters[i]);
                if (codec != null)
                {
                    codecs.Add(codec);
                }
            }
            if (!codecs.Any())
            {
                Console.Error.WriteLine("No codec(s) specified");
                return(-2);
            }
            if (opts.Verbose)
            {
                foreach (var c in codecs)
                {
                    c.OutputWriter = Console.Out;
                    // todo - flags?
                }
            }


            // if has input file and output file then do that
            if (!String.IsNullOrEmpty(opts.Inputfile) && !String.IsNullOrEmpty(opts.Outputfile))
            {
                if (!File.Exists(opts.Inputfile))
                {
                    Console.Error.WriteLine($"File {opts.Inputfile} does not exist");
                    Environment.Exit(-3);
                }
                // do first codec only
                var data = File.ReadAllBytes(opts.Inputfile);

                var watch = System.Diagnostics.Stopwatch.StartNew();

                var output    = opts.Decompress ? codecs[0].Decompress(data) : codecs[0].Compress(data);
                var headerMsg = $"File {opts.Inputfile} compressed from {data.Length} to {output.Length} for {(double)output.Length/data.Length:F3} ratio";
                if (codecs[0] is Lz77Codec)
                {
                    var lz77    = codecs[0] as Lz77Codec;
                    var bufSize = Math.Max(lz77.MaximumDistance, lz77.MaximumLength) + 1;
                    headerMsg += $" LZ77 bufsize {bufSize}";
                }
                if (codecs[0] is LzclCodec)
                {
                    var lzcl    = codecs[0] as LzclCodec;
                    var bufSize = Math.Max(lzcl.MaximumDistance, lzcl.MaximumLength) + 1;
                    headerMsg += $" LZCL bufsize {bufSize}";
                }
                OutputData(opts.Outputfile, output, OutputFormats[opts.OutputFormatIndex], headerMsg);

                watch.Stop();
                var elapsedMs  = watch.ElapsedMilliseconds;
                var actionText = opts.Decompress ? "decompressed" : "compressed";
                Console.WriteLine(
                    $"{Path.GetFileName(opts.Inputfile)} ({data.Length} bytes) {actionText} to {opts.Outputfile} ({output.Length} bytes).");
                if (!opts.Decompress)
                {
                    Console.WriteLine($"Compression ratio {100 - (100.0 * output.Length / data.Length):F1}%");
                }
                Console.WriteLine($"Elapsed time: {elapsedMs}ms");
                return(1);
            }
            // if has only input file - do some testing
            if (!String.IsNullOrEmpty(opts.Inputfile))
            {
                //public string Inputfile { get; set; } = "";
                //public bool RecurseDirectories { get; set; } = false;
                //public int OutputFormatIndex { get; set; } = -1;
                //public bool Decompress { get; set; } = false;

                var test    = new Testing();
                var request = new Testing.Request
                {
                    Codecs       = codecs,
                    Filename     = "*.*",
                    Path         = opts.Inputfile,
                    RecurseFiles = opts.RecurseDirectories,

                    // Decompress = false,
                    // UseExternalDecompressor = true,
                    ShowOnlyErrors = false,
                    TrapErrors     = true
                };
                test.DoTest(request);
                return(1);
            }
            Console.Error.WriteLine("Nothing to do");
            return(-4);
        }