FreakySources.Code.AsciimationDataGenerator.Decompress_v_1_3 C# (CSharp) Method

Decompress_v_1_3() public static method

public static Decompress_v_1_3 ( string str, int currentFrame ) : string
str string
currentFrame int
return string
        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();
            }
        }