Esempio n. 1
0
        public byte[] Decompress()
        {
            if (_compressed[0] != HALC.RedundancyMagicSignature[0] || _compressed[1] != HALC.RedundancyMagicSignature[1])
            {
                throw new InvalidImageException("Missing signature");
            }
            _decompressionPointer += HALC.RedundancyMagicSignature.Length;

            while (HasMoreBytes())
            {
                switch (GetCommand())
                {
                case HALC.Command.Literal:
                    UseLiteral();
                    break;

                case HALC.Command.RLE:
                    UseRLE();
                    break;

                case HALC.Command.ShortPointer:
                    UseShortPointer();
                    break;

                case HALC.Command.LongPointer:
                    UseLongPointer();
                    break;
                }
            }

            return(_builder.GetBytes());
        }
Esempio n. 2
0
        public byte[] Compress()
        {
            _builder.Append(HALC.RedundancyMagicSignature);

            var literalBuffer = new ByteArrayBuilder();

            while (HasMoreBytes())
            {
                var repeatCount = GetRepeatCount();

                // try RLE first
                if (repeatCount > HALC.RLECommandLength)
                {
                    if (literalBuffer.Length > 0)
                    {
                        UseLiteral(literalBuffer.GetBytes());
                        literalBuffer = new ByteArrayBuilder();
                    }
                    UseRLE(repeatCount);
                }
                else
                {
                    var previousOccurance = GetPreviousOccurance();
                    if (previousOccurance.BestMatchLength > HALC.ShortPointerCommandLength &&
                        previousOccurance.BestMatchOffset <= HALC.MaxShortPointerOffset &&
                        previousOccurance.BestMatchLength <= HALC.MaxShortPointerLength)
                    {
                        if (literalBuffer.Length > 0)
                        {
                            UseLiteral(literalBuffer.GetBytes());
                            literalBuffer = new ByteArrayBuilder();
                        }
                        UseShortPointer(previousOccurance);
                    }
                    else if (previousOccurance.BestMatchLength > HALC.LongPointerCommandLength)
                    {
                        if (literalBuffer.Length > 0)
                        {
                            UseLiteral(literalBuffer.GetBytes());
                            literalBuffer = new ByteArrayBuilder();
                        }
                        UseLongPointer(previousOccurance);
                    }
                    else
                    {
                        literalBuffer.Append(_uncompressed[_compressionPointer]);
                        _compressionPointer++;
                    }
                }
            }

            if (literalBuffer.Length > 0)
            {
                UseLiteral(literalBuffer.GetBytes());
            }

            return(_builder.GetBytes());
        }
Esempio n. 3
0
        public byte[] Compress()
        {
            _builder.Append(HALC.ProbabilityMagicSignature);

            // build huffman tree
            var histogram    = GetHistogram();
            var nodes        = histogram.Select(kvp => new Frequency(kvp.Key, kvp.Value)).OrderBy(f => f.Count).ToList();
            var indexedNodes = nodes.ToDictionary(f => f.B, f => f);

            while (nodes.Count() > 1)
            {
                var left    = nodes[0];
                var right   = nodes[1];
                var newNode = new Frequency(left, right);
                nodes.Remove(left);
                nodes.Remove(right);
                nodes.Add(newNode);
                nodes = nodes.OrderBy(f => f.Count).ToList();
            }

            // output tree
            var bitBuilder = new BitArrayBuilder();

            nodes[0].OutputAndBuildPaths(bitBuilder, new List <bool>());
            _builder.Append(bitBuilder.GetBytes());

            // output huffman codes for each byte
            bitBuilder = new BitArrayBuilder();
            foreach (var b in _data)
            {
                var node = indexedNodes[b];
                foreach (var p in node.Path)
                {
                    bitBuilder.Append(p);
                }
            }
            _builder.Append(bitBuilder.GetBytes());

            return(_builder.GetBytes());
        }