Пример #1
0
        /*#HuffmanRleDecode*/
        public static byte[] Decode(HuffmanTree tree, byte[] bytes)
        {
            var root = tree.Root;
            var result = new List<byte>(bytes.Length * 2);
            int bitPos = 0;

            while (bytes.Length * 8 - bitPos > 8)
            {
                var length = Utils.GetInt(bytes, ref bitPos, 8);

                if ((length & 128) == 0)
                {
                    var repeatCount = length + 2;
                    byte value = Utils.GetValue(root, bytes, ref bitPos);
                    for (int j = 0; j < repeatCount; j++)
                        result.Add(value);
                }
                else
                {
                    var notRepeatCount = (127 & length) + 1;
                    for (int j = 0; j < notRepeatCount; j++)
                    {
                        byte value = Utils.GetValue(root, bytes, ref bitPos);
                        result.Add(value);
                    }
                }
            }

            return result.ToArray();
        }
Пример #2
0
 public static byte[] Encode(HuffmanTree tree, byte[] bytes)
 {
     var result = new byte[bytes.Length * 2];
     int curBit = 0;
     Encode(tree, bytes, ref curBit, result);
     result = result.Take((curBit + 7) / 8).ToArray();
     return result;
 }
Пример #3
0
        /*ByteCounts#*/

        #endregion

        #region version 1.3

        public string Compress_v_1_3(out List <CompressedFrame> compressedFrames, bool reducedLines = true)
        {
            var        bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits);
            var        tree       = new HuffmanTree(bytesFreqs);
            List <int> frameDiffs;

            var framesChanges = CalculateFrameChanges();

            compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs);

            bytesFreqs       = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits, compressedFrames);
            tree             = new HuffmanTree(bytesFreqs);
            compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs);

            var result = new byte[1000000];

            int bitPos = 0;

            Utils.AddInt(result, ref bitPos, bytesFreqs.Length, 8);
            foreach (var byteCount in bytesFreqs)
            {
                Utils.AddInt(result, ref bitPos, byteCount.Byte, 8);
                Utils.AddInt(result, ref bitPos, byteCount.Count, 24);
            }

            Utils.AddInt(result, ref bitPos, frameDiffs.Count, 24);
            foreach (var diff in frameDiffs)
            {
                Utils.AddInt(result, ref bitPos, diff, 9);
            }

            foreach (var frame in compressedFrames)
            {
                Utils.AddBytes(result, ref bitPos, frame.CompressedBytes);
            }

            result = result.Take((bitPos + 7) / 8).ToArray();

            return(Convert.ToBase64String(result));
        }
Пример #4
0
        private byte[] GetCompressedFrameBytes(HuffmanTree tree, Frame frame, CompressedFrame compressedFrame)
        {
            int transBitPos   = 0;
            var transZipBytes = new byte[frame.Bytes.Length * 10];

            Utils.AddInt(transZipBytes, ref transBitPos, frame.RepeatCount, 7);
            Utils.AddInt(transZipBytes, ref transBitPos, (int)compressedFrame.FrameType, 3);
            Utils.AddInt(transZipBytes, ref transBitPos, compressedFrame.FrameChanges.Count, 7);
            for (int i = 0; i < compressedFrame.FrameChanges.Count; i++)
            {
                var change = compressedFrame.FrameChanges[i];
                Utils.AddInt(transZipBytes, ref transBitPos, (int)change.Type, 2);
                Utils.AddInt(transZipBytes, ref transBitPos, GetPos(change.X, change.Y), 10);

                if (change.Type == FrameChangeType.One)
                {
                    Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[0]]);
                }
                else
                {
                    Utils.AddInt(transZipBytes, ref transBitPos, change.Length,
                                 change.Type == FrameChangeType.Horizontal ? 7 : 4);
                    //HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4);
                    for (int j = 0; j < change.Chars.Count; j++)
                    {
                        Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]);
                    }

                    /*if (i == 0 && compressedFrame.FrameType != FrameType.Basic && compressedFrame.FrameType != FrameType.Transitional)
                     *      HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4);
                     * else
                     *      for (int j = 0; j < change.Chars.Count; j++)
                     *              Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]);*/
                }
            }
            return(transZipBytes.Take((transBitPos + 7) / 8).ToArray());
        }
Пример #5
0
        public void HuffmanRleFull()
        {
            var generator = new AsciimationDataGenerator(AsciimationData);
            var bytesFreqs = generator.GetBytesFreqs(false);
            var bytes = AsciimationDataGenerator.SerializeByteCount(bytesFreqs);
            var huffmanTable = Convert.ToBase64String(bytes);
            var tree = new HuffmanTree(bytesFreqs);

            var encodedTable = Convert.ToBase64String(bytes);
            var encodedFrames = new List<string>();
            for (int i = 0; i < generator.Frames.Length; i++)
            {
                var frame = generator.Frames[i];
                encodedFrames.Add(Convert.ToBase64String(HuffmanRle.Encode(tree, frame.Bytes)));
            }

            var decodedTree = new HuffmanTree(AsciimationDataGenerator.DeserializeByteCount(Base64.DecodeBase64(encodedTable)));
            var decodedFrames = new List<string>();
            for (int i = 0; i < encodedFrames.Count; i++)
            {
                var frame = HuffmanRle.Decode(decodedTree, Base64.DecodeBase64(encodedFrames[i]));
                CollectionAssert.AreEqual(generator.Frames[i].Bytes, frame);
            }
        }
Пример #6
0
        public static void Encode(HuffmanTree tree, byte[] bytes, ref int curBit, byte[] result, int bitsCountPerRepLength = 8, int bitsCountPerNotRepLength = 8)
        {
            var maxRepeatCount = (1 << (bitsCountPerRepLength - 1)) + 1;
            var maxNotRepeatCount = 1 << (bitsCountPerNotRepLength - 1);

            var compressedBytes = tree.CompressedBytes;
            int i = 0;
            while (i < bytes.Length)
            {
                int j = i;
                do
                    j++;
                while (j != bytes.Length && bytes[j] == bytes[i]);

                int repeatCount = j - i;
                if (repeatCount >= 2)
                {
                    int segmentCount = repeatCount / maxRepeatCount;
                    int rest = repeatCount % maxRepeatCount;

                    for (int k = 0; k < segmentCount; k++)
                    {
                        Utils.AddInt(result, ref curBit, maxRepeatCount - 2, bitsCountPerRepLength);
                        Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]);
                    }
                    if (rest >= 2)
                    {
                        Utils.AddInt(result, ref curBit, (rest - 2), bitsCountPerRepLength);
                        Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]);
                        i = j;
                    }
                    else
                        i = j - rest;
                }
                else
                {
                    while (j != bytes.Length && bytes[j] != bytes[j - 1])
                        j++;

                    int nonrepeatCount = j - i;
                    if (j != bytes.Length)
                        nonrepeatCount--;
                    int segmentCount = nonrepeatCount / maxNotRepeatCount;
                    int rest = nonrepeatCount % maxNotRepeatCount;

                    for (int k = 0; k < segmentCount; k++)
                    {
                        Utils.AddInt(result, ref curBit, (1 << bitsCountPerNotRepLength) - 1, bitsCountPerNotRepLength);
                        for (int l = 0; l < maxNotRepeatCount; l++)
                            Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + k * maxNotRepeatCount + l]]);
                    }

                    if (rest >= 1)
                    {
                        Utils.AddInt(result, ref curBit, (maxNotRepeatCount | (rest - 1)), bitsCountPerNotRepLength);
                        for (int l = 0; l < rest; l++)
                            Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + segmentCount * maxNotRepeatCount + l]]);
                    }
                    i = j;
                    if (j != bytes.Length)
                        i--;
                }
            }
        }
Пример #7
0
        public static byte[] Decode(HuffmanTree tree, byte[] bytes, ref int curBit, int bytesCount, int bitsCountPerRepLength = 8, int bitsCountPerNotRepLength = 8)
        {
            int minLength = Math.Min(bitsCountPerRepLength, bitsCountPerNotRepLength);
            var maxCount = 1 << (minLength - 1);

            var root = tree.Root;
            var result = new List<byte>(bytes.Length * 2);

            int curBytesCount = 0;
            int i = 0;
            while (curBytesCount < bytesCount)
            {
                var length = Utils.GetInt(bytes, ref curBit, minLength);

                if ((length & maxCount) == 0)
                {
                    curBit -= minLength;
                    length = Utils.GetInt(bytes, ref curBit, bitsCountPerRepLength);
                    var repeatCount = length + 2;
                    byte value = Utils.GetValue(root, bytes, ref curBit);
                    for (int j = 0; j < repeatCount; j++)
                    {
                        result.Add(value);
                        curBytesCount++;
                    }
                }
                else
                {
                    curBit -= minLength;
                    length = Utils.GetInt(bytes, ref curBit, bitsCountPerNotRepLength);
                    var notRepeatCount = (((1 << (bitsCountPerNotRepLength - 1)) - 1) & length) + 1;
                    for (int j = 0; j < notRepeatCount; j++)
                    {
                        byte value = Utils.GetValue(root, bytes, ref curBit);
                        result.Add(value);
                        curBytesCount++;
                    }
                }
                i++;
            }

            return result.ToArray();
        }
Пример #8
0
        public static void Encode(HuffmanTree tree, byte[] bytes, ref int curBit, byte[] result, int bitsCountPerRepLength = 8, int bitsCountPerNotRepLength = 8)
        {
            var maxRepeatCount    = (1 << (bitsCountPerRepLength - 1)) + 1;
            var maxNotRepeatCount = 1 << (bitsCountPerNotRepLength - 1);

            var compressedBytes = tree.CompressedBytes;
            int i = 0;

            while (i < bytes.Length)
            {
                int j = i;
                do
                {
                    j++;
                }while (j != bytes.Length && bytes[j] == bytes[i]);

                int repeatCount = j - i;
                if (repeatCount >= 2)
                {
                    int segmentCount = repeatCount / maxRepeatCount;
                    int rest         = repeatCount % maxRepeatCount;

                    for (int k = 0; k < segmentCount; k++)
                    {
                        Utils.AddInt(result, ref curBit, maxRepeatCount - 2, bitsCountPerRepLength);
                        Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]);
                    }
                    if (rest >= 2)
                    {
                        Utils.AddInt(result, ref curBit, (rest - 2), bitsCountPerRepLength);
                        Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i]]);
                        i = j;
                    }
                    else
                    {
                        i = j - rest;
                    }
                }
                else
                {
                    while (j != bytes.Length && bytes[j] != bytes[j - 1])
                    {
                        j++;
                    }

                    int nonrepeatCount = j - i;
                    if (j != bytes.Length)
                    {
                        nonrepeatCount--;
                    }
                    int segmentCount = nonrepeatCount / maxNotRepeatCount;
                    int rest         = nonrepeatCount % maxNotRepeatCount;

                    for (int k = 0; k < segmentCount; k++)
                    {
                        Utils.AddInt(result, ref curBit, (1 << bitsCountPerNotRepLength) - 1, bitsCountPerNotRepLength);
                        for (int l = 0; l < maxNotRepeatCount; l++)
                        {
                            Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + k * maxNotRepeatCount + l]]);
                        }
                    }

                    if (rest >= 1)
                    {
                        Utils.AddInt(result, ref curBit, (maxNotRepeatCount | (rest - 1)), bitsCountPerNotRepLength);
                        for (int l = 0; l < rest; l++)
                        {
                            Utils.AddIntReversed(result, ref curBit, compressedBytes[bytes[i + segmentCount * maxNotRepeatCount + l]]);
                        }
                    }
                    i = j;
                    if (j != bytes.Length)
                    {
                        i--;
                    }
                }
            }
        }
Пример #9
0
        public void RleHuffmanEncodeDecodeWithDifferentLengths()
        {
            var generator = new AsciimationDataGenerator(AsciimationData);
            var bytesFreqs = generator.GetBytesFreqs();
            var tree = new HuffmanTree(bytesFreqs);

            for (int i = 0; i < generator.Frames.Length; i++)
            {
                var frame = generator.Frames[i];
                var orig = frame.Bytes;

                int curBit = 0;
                byte[] bytes = new byte[frame.Bytes.Length * 2];
                HuffmanRle.Encode(tree, orig, ref curBit, bytes, 8, 4);
                bytes = bytes.Take((curBit + 7) / 8).ToArray();

                curBit = 0;
                var decoded = HuffmanRle2.Decode(tree, bytes, ref curBit, frame.Bytes.Length, 8, 4);
                CollectionAssert.AreEqual(orig, decoded);
            }
        }
Пример #10
0
        public void RleHuffmanEncodeDecode()
        {
            var generator = new AsciimationDataGenerator(AsciimationData);
            var bytesFreqs = generator.GetBytesFreqs();
            var tree = new HuffmanTree(bytesFreqs);

            for (int i = 0; i < generator.Frames.Length; i++)
            {
                var frame = generator.Frames[i];
                var orig = frame.Bytes;
                var encoded = HuffmanRle.Encode(tree, orig);
                var decoded = HuffmanRle.Decode(tree, encoded);
                CollectionAssert.AreEqual(orig, decoded);
            }
        }
        public static string Decompress_v_1_3(string str, int currentFrame)
        {
            byte[] bytes = Convert.FromBase64String(str);

            int bitPos = 0;
            byte tableLength = (byte)Utils.GetInt(bytes, ref bitPos, 8);

            var bytesFreqs = new ByteCount[tableLength];
            for (int i = 0; i < tableLength; i++)
            {
                bytesFreqs[i] = new ByteCount
                {
                    Byte = (byte)Utils.GetInt(bytes, ref bitPos, 8),
                    Count = Utils.GetInt(bytes, ref bitPos, 24)
                };
            }
            var tree = new HuffmanTree(bytesFreqs);

            int frameDiffsCount = Utils.GetInt(bytes, ref bitPos, 24);
            var frameNumbers = new List<int>();
            int sum = 0;
            frameNumbers.Add(sum);
            for (int i = 0; i < frameDiffsCount; i++)
            {
                sum += Utils.GetInt(bytes, ref bitPos, 9);
                frameNumbers.Add(sum);
            }

            int beginBitPos = bitPos;
            bitPos = frameNumbers[currentFrame] * 8 + beginBitPos;
            int repeatCount = Utils.GetInt(bytes, ref bitPos, 7);
            var frameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3);
            if (frameType == FrameType.Basic)
            {
                var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits);
                var frameBytes = HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits);
                return CharsToLine(BytesToFrame(frameBytes));
            }
            else
            {
                int prevFrame = currentFrame;
                int prevRepeatCount;
                FrameType prevFrameType;
                do
                {
                    prevFrame--;
                    bitPos = frameNumbers[prevFrame] * 8 + beginBitPos;
                    prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7);
                    prevFrameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3);
                }
                while (prevFrameType != FrameType.Basic);

                var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits);
                var frame = BytesToFrame(HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits));

                do
                {
                    prevFrame++;
                    bitPos = frameNumbers[prevFrame] * 8 + beginBitPos;
                    prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7);
                    prevFrameType = (FrameType)Utils.GetInt(bytes, ref bitPos, 3);

                    switch (prevFrameType)
                    {
                        case FrameType.Transitional:
                            break;
                        case FrameType.TransitionalLeft:
                            for (int y = 0; y < FrameHeight; y++)
                                for (int x = 0; x < FrameWidth - 1; x++)
                                    frame[y, x] = frame[y, x + 1];
                            break;
                        case FrameType.TransitionalRight:
                            for (int y = 0; y < FrameHeight; y++)
                                for (int x = FrameWidth - 1; x >= 1; x--)
                                    frame[y, x] = frame[y, x - 1];
                            break;
                        case FrameType.TransitionalTop:
                            for (int y = 0; y < FrameHeight - 1; y++)
                                for (int x = 0; x < FrameWidth; x++)
                                    frame[y, x] = frame[y + 1, x];
                            break;
                        case FrameType.TransitionalBottom:
                            for (int y = FrameHeight - 1; y >= 1; y--)
                                for (int x = 0; x < FrameWidth; x++)
                                    frame[y, x] = frame[y - 1, x];
                            break;
                    }

                    var frameChangesCount = Utils.GetInt(bytes, ref bitPos, 7);
                    for (int i = 0; i < frameChangesCount; i++)
                    {
                        var frameChangeType = (FrameChangeType)Utils.GetInt(bytes, ref bitPos, 2);
                        var position = Utils.GetInt(bytes, ref bitPos, 10);

                        int length;
                        if (frameChangeType == FrameChangeType.One)
                            length = 1;
                        else
                            length = Utils.GetInt(bytes, ref bitPos, frameChangeType == FrameChangeType.Horizontal ? 7 : 4);
                        for (int j = 0; j < length; j++)
                        {
                            frame[GetY(position), GetX(position)] = (char)Utils.GetValue(tree.Root, bytes, ref bitPos);
                            position += frameChangeType == FrameChangeType.Horizontal ? 1 : FrameWidth;
                        }
                    }
                }
                while (prevFrame != currentFrame);

                return CharsToLine(frame).ToString();
            }
        }
        private List<CompressedFrame> GetCompressedFrames(HuffmanTree tree, bool reducedLines, List<Dictionary<FrameType, CompressedFrame>> framesChanges,
			out List<int> frameDiffs)
        {
            var compressedFrames = new List<CompressedFrame>();
            int currentFrame = 0;
            frameDiffs = new List<int>();
            for (int i = 0; i < Frames.Length; i++)
            {
                var frame = Frames[i];
                var frameChanges = framesChanges[i];

                int basisBitPos = 0;
                byte[] basisBytes = null;
                byte[] transBytes, transLeftBytes, transRightBytes, transTopBytes, transBottomBytes;
                transBytes = transLeftBytes = transRightBytes = transTopBytes = transBottomBytes = null;

                int frameTypeBit;
                basisBytes = new byte[frame.Bytes.Length * 2];
                Utils.AddInt(basisBytes, ref basisBitPos, frame.RepeatCount, 7);
                frameTypeBit = basisBitPos;
                Utils.AddInt(basisBytes, ref basisBitPos, (int)FrameType.Basic, 3);
                Utils.AddInt(basisBytes, ref basisBitPos, frame.ReducedBytes.Length, BasicBytesLengthBits);
                HuffmanRle.Encode(tree, reducedLines ? frame.ReducedBytes : frame.Bytes, ref basisBitPos, basisBytes, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits);
                basisBytes = basisBytes.Take((basisBitPos + 7) / 8).ToArray();

                if (i != 0)
                {
                    transBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.Transitional]);
                    transLeftBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalLeft]);
                    transRightBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalRight]);
                    transTopBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalTop]);
                    transBottomBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalBottom]);
                }

                var typesBytes = new Dictionary<FrameType, byte[]>()
                {
                    { FrameType.Basic, basisBytes },
                    { FrameType.Transitional, transBytes },
                    { FrameType.TransitionalLeft, transLeftBytes },
                    { FrameType.TransitionalRight, transRightBytes },
                    { FrameType.TransitionalTop, transTopBytes },
                    { FrameType.TransitionalBottom, transBottomBytes },
                };

                var minLengthBytesKey = typesBytes.Where(tb => tb.Value != null)
                    .Aggregate((a, b) => a.Value.Length < b.Value.Length ? a : b).Key;

                Utils.AddInt(typesBytes[minLengthBytesKey], ref frameTypeBit, (int)minLengthBytesKey, 3);

                compressedFrames.Add(new CompressedFrame
                {
                    CompressedBytes = typesBytes[minLengthBytesKey],
                    FrameType = minLengthBytesKey,
                    FrameChanges = !frameChanges.ContainsKey(minLengthBytesKey) ? null : frameChanges[minLengthBytesKey].FrameChanges
                });
                currentFrame += typesBytes[minLengthBytesKey].Length;
                frameDiffs.Add(typesBytes[minLengthBytesKey].Length);
            }

            return compressedFrames;
        }
        private byte[] GetCompressedFrameBytes(HuffmanTree tree, Frame frame, CompressedFrame compressedFrame)
        {
            int transBitPos = 0;
            var transZipBytes = new byte[frame.Bytes.Length * 10];
            Utils.AddInt(transZipBytes, ref transBitPos, frame.RepeatCount, 7);
            Utils.AddInt(transZipBytes, ref transBitPos, (int)compressedFrame.FrameType, 3);
            Utils.AddInt(transZipBytes, ref transBitPos, compressedFrame.FrameChanges.Count, 7);
            for (int i = 0; i < compressedFrame.FrameChanges.Count; i++)
            {
                var change = compressedFrame.FrameChanges[i];
                Utils.AddInt(transZipBytes, ref transBitPos, (int)change.Type, 2);
                Utils.AddInt(transZipBytes, ref transBitPos, GetPos(change.X, change.Y), 10);

                if (change.Type == FrameChangeType.One)
                    Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[0]]);
                else
                {
                    Utils.AddInt(transZipBytes, ref transBitPos, change.Length,
                        change.Type == FrameChangeType.Horizontal ? 7 : 4);
                    //HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4);
                    for (int j = 0; j < change.Chars.Count; j++)
                        Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]);
                    /*if (i == 0 && compressedFrame.FrameType != FrameType.Basic && compressedFrame.FrameType != FrameType.Transitional)
                        HuffmanRle.Encode(tree, change.Chars.Select(c => (byte)c).ToArray(), ref transBitPos, transZipBytes, 5, 4);
                    else
                        for (int j = 0; j < change.Chars.Count; j++)
                            Utils.AddIntReversed(transZipBytes, ref transBitPos, tree.CompressedBytes[change.Chars[j]]);*/
                }
            }
            return transZipBytes.Take((transBitPos + 7) / 8).ToArray();
        }
        public string Compress_v_1_3(out List<CompressedFrame> compressedFrames, bool reducedLines = true)
        {
            var bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits);
            var tree = new HuffmanTree(bytesFreqs);
            List<int> frameDiffs;

            var framesChanges = CalculateFrameChanges();
            compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs);

            bytesFreqs = GetBytesFreqs(reducedLines, HuffmanRleRepeatedBits, compressedFrames);
            tree = new HuffmanTree(bytesFreqs);
            compressedFrames = GetCompressedFrames(tree, reducedLines, framesChanges, out frameDiffs);

            var result = new byte[1000000];

            int bitPos = 0;
            Utils.AddInt(result, ref bitPos, bytesFreqs.Length, 8);
            foreach (var byteCount in bytesFreqs)
            {
                Utils.AddInt(result, ref bitPos, byteCount.Byte, 8);
                Utils.AddInt(result, ref bitPos, byteCount.Count, 24);
            }

            Utils.AddInt(result, ref bitPos, frameDiffs.Count, 24);
            foreach (var diff in frameDiffs)
                Utils.AddInt(result, ref bitPos, diff, 9);

            foreach (var frame in compressedFrames)
                Utils.AddBytes(result, ref bitPos, frame.CompressedBytes);

            result = result.Take((bitPos + 7) / 8).ToArray();

            return Convert.ToBase64String(result);
        }
Пример #15
0
        public static string Decompress_v_1_3(string str, int currentFrame)
        {
            byte[] bytes = Convert.FromBase64String(str);

            int  bitPos      = 0;
            byte tableLength = (byte)Utils.GetInt(bytes, ref bitPos, 8);

            var bytesFreqs = new ByteCount[tableLength];

            for (int i = 0; i < tableLength; i++)
            {
                bytesFreqs[i] = new ByteCount
                {
                    Byte  = (byte)Utils.GetInt(bytes, ref bitPos, 8),
                    Count = Utils.GetInt(bytes, ref bitPos, 24)
                };
            }
            var tree = new HuffmanTree(bytesFreqs);

            int frameDiffsCount = Utils.GetInt(bytes, ref bitPos, 24);
            var frameNumbers    = new List <int>();
            int sum             = 0;

            frameNumbers.Add(sum);
            for (int i = 0; i < frameDiffsCount; i++)
            {
                sum += Utils.GetInt(bytes, ref bitPos, 9);
                frameNumbers.Add(sum);
            }

            int beginBitPos = bitPos;

            bitPos = frameNumbers[currentFrame] * 8 + beginBitPos;
            int repeatCount = Utils.GetInt(bytes, ref bitPos, 7);
            var frameType   = (FrameType)Utils.GetInt(bytes, ref bitPos, 3);

            if (frameType == FrameType.Basic)
            {
                var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits);
                var frameBytes  = HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits);
                return(CharsToLine(BytesToFrame(frameBytes)));
            }
            else
            {
                int       prevFrame = currentFrame;
                int       prevRepeatCount;
                FrameType prevFrameType;
                do
                {
                    prevFrame--;
                    bitPos          = frameNumbers[prevFrame] * 8 + beginBitPos;
                    prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7);
                    prevFrameType   = (FrameType)Utils.GetInt(bytes, ref bitPos, 3);
                }while (prevFrameType != FrameType.Basic);

                var frameLength = Utils.GetInt(bytes, ref bitPos, BasicBytesLengthBits);
                var frame       = BytesToFrame(HuffmanRle2.Decode(tree, bytes, ref bitPos, frameLength, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits));

                do
                {
                    prevFrame++;
                    bitPos          = frameNumbers[prevFrame] * 8 + beginBitPos;
                    prevRepeatCount = Utils.GetInt(bytes, ref bitPos, 7);
                    prevFrameType   = (FrameType)Utils.GetInt(bytes, ref bitPos, 3);

                    switch (prevFrameType)
                    {
                    case FrameType.Transitional:
                        break;

                    case FrameType.TransitionalLeft:
                        for (int y = 0; y < FrameHeight; y++)
                        {
                            for (int x = 0; x < FrameWidth - 1; x++)
                            {
                                frame[y, x] = frame[y, x + 1];
                            }
                        }
                        break;

                    case FrameType.TransitionalRight:
                        for (int y = 0; y < FrameHeight; y++)
                        {
                            for (int x = FrameWidth - 1; x >= 1; x--)
                            {
                                frame[y, x] = frame[y, x - 1];
                            }
                        }
                        break;

                    case FrameType.TransitionalTop:
                        for (int y = 0; y < FrameHeight - 1; y++)
                        {
                            for (int x = 0; x < FrameWidth; x++)
                            {
                                frame[y, x] = frame[y + 1, x];
                            }
                        }
                        break;

                    case FrameType.TransitionalBottom:
                        for (int y = FrameHeight - 1; y >= 1; y--)
                        {
                            for (int x = 0; x < FrameWidth; x++)
                            {
                                frame[y, x] = frame[y - 1, x];
                            }
                        }
                        break;
                    }

                    var frameChangesCount = Utils.GetInt(bytes, ref bitPos, 7);
                    for (int i = 0; i < frameChangesCount; i++)
                    {
                        var frameChangeType = (FrameChangeType)Utils.GetInt(bytes, ref bitPos, 2);
                        var position        = Utils.GetInt(bytes, ref bitPos, 10);

                        int length;
                        if (frameChangeType == FrameChangeType.One)
                        {
                            length = 1;
                        }
                        else
                        {
                            length = Utils.GetInt(bytes, ref bitPos, frameChangeType == FrameChangeType.Horizontal ? 7 : 4);
                        }
                        for (int j = 0; j < length; j++)
                        {
                            frame[GetY(position), GetX(position)] = (char)Utils.GetValue(tree.Root, bytes, ref bitPos);
                            position += frameChangeType == FrameChangeType.Horizontal ? 1 : FrameWidth;
                        }
                    }
                }while (prevFrame != currentFrame);

                return(CharsToLine(frame).ToString());
            }
        }
Пример #16
0
        private List <CompressedFrame> GetCompressedFrames(HuffmanTree tree, bool reducedLines, List <Dictionary <FrameType, CompressedFrame> > framesChanges,
                                                           out List <int> frameDiffs)
        {
            var compressedFrames = new List <CompressedFrame>();
            int currentFrame     = 0;

            frameDiffs = new List <int>();
            for (int i = 0; i < Frames.Length; i++)
            {
                var frame        = Frames[i];
                var frameChanges = framesChanges[i];

                int    basisBitPos = 0;
                byte[] basisBytes  = null;
                byte[] transBytes, transLeftBytes, transRightBytes, transTopBytes, transBottomBytes;
                transBytes = transLeftBytes = transRightBytes = transTopBytes = transBottomBytes = null;

                int frameTypeBit;
                basisBytes = new byte[frame.Bytes.Length * 2];
                Utils.AddInt(basisBytes, ref basisBitPos, frame.RepeatCount, 7);
                frameTypeBit = basisBitPos;
                Utils.AddInt(basisBytes, ref basisBitPos, (int)FrameType.Basic, 3);
                Utils.AddInt(basisBytes, ref basisBitPos, frame.ReducedBytes.Length, BasicBytesLengthBits);
                HuffmanRle.Encode(tree, reducedLines ? frame.ReducedBytes : frame.Bytes, ref basisBitPos, basisBytes, HuffmanRleRepeatedBits, HuffmanRleNotRepeatedBits);
                basisBytes = basisBytes.Take((basisBitPos + 7) / 8).ToArray();

                if (i != 0)
                {
                    transBytes       = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.Transitional]);
                    transLeftBytes   = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalLeft]);
                    transRightBytes  = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalRight]);
                    transTopBytes    = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalTop]);
                    transBottomBytes = GetCompressedFrameBytes(tree, frame, frameChanges[FrameType.TransitionalBottom]);
                }

                var typesBytes = new Dictionary <FrameType, byte[]>()
                {
                    { FrameType.Basic, basisBytes },
                    { FrameType.Transitional, transBytes },
                    { FrameType.TransitionalLeft, transLeftBytes },
                    { FrameType.TransitionalRight, transRightBytes },
                    { FrameType.TransitionalTop, transTopBytes },
                    { FrameType.TransitionalBottom, transBottomBytes },
                };

                var minLengthBytesKey = typesBytes.Where(tb => tb.Value != null)
                                        .Aggregate((a, b) => a.Value.Length < b.Value.Length ? a : b).Key;

                Utils.AddInt(typesBytes[minLengthBytesKey], ref frameTypeBit, (int)minLengthBytesKey, 3);

                compressedFrames.Add(new CompressedFrame
                {
                    CompressedBytes = typesBytes[minLengthBytesKey],
                    FrameType       = minLengthBytesKey,
                    FrameChanges    = !frameChanges.ContainsKey(minLengthBytesKey) ? null : frameChanges[minLengthBytesKey].FrameChanges
                });
                currentFrame += typesBytes[minLengthBytesKey].Length;
                frameDiffs.Add(typesBytes[minLengthBytesKey].Length);
            }

            return(compressedFrames);
        }