Beispiel #1
0
 protected void DecompressTokenSequence(DecompressedBuffer buffer, DecompressionState state, IEnumerable <TokenSequence> tokenSequence)
 {
     foreach (var t in tokenSequence)
     {
         t.Decompress(buffer, state);
     }
 }
Beispiel #2
0
        // Section 2.4.1.3.6
        // page 62
        /// <summary>
        /// Compresses the data given in UncompressedData.
        /// </summary>
        /// <param name="UncompressedData">Uncompressed raw data</param>
        /// <returns>A byte array containing the compressed data</returns>
        public static Byte[] Compress(byte[] UncompressedData)
        {
            if (UncompressedData == null)
            {
                throw new ArgumentNullException("UncompressedData");
            }

            var resultBuffer = new CompressedBuffer(UncompressedData.Length);

            DecompressedBuffer uncompressedDataBuffer = new DecompressedBuffer(UncompressedData);
            var state = new DecompressionState(uncompressedDataBuffer);

            // 2.4.1.3.6 Compression algorithm
            resultBuffer.SetByte(state.CompressedCurrent, 0x01);
            ++state.CompressedCurrent;

            while (state.DecompressedCurrent < state.DecompressedBufferEnd)
            {
                state.CompressedChunkStart   = state.CompressedCurrent;
                state.DecompressedChunkStart = state.DecompressedCurrent;
                CompressDecompressedChunk(UncompressedData, resultBuffer, state);
            }

            return(resultBuffer.GetData());
        }
Beispiel #3
0
        // Section 2.4.1.3.14
        private static void PackCompressedChunkSignature(byte[] Data, DecompressionState state, CompressedChunkHeader header)
        {
            UInt16 temp   = (UInt16)(header.AsUInt16() & (ushort)0x8FFF);
            UInt16 result = (UInt16)(temp | (ushort)0x3000);

            header.SetFrom(result);
        }
        public void Decompress(DecompressedBuffer buffer, DecompressionState state)
        {
            state.DecompressedChunkStart = state.DecompressedCurrent;
            //var CompressedEnd = Math.Min(state.CompressionRecordEnd, state.CompressedChunkStart + this.CompressedHeader.CompressedChunkSize);
            state.CompressedCurrent += 2;

            this.CompressedData.Decompress(buffer, state);
        }
Beispiel #5
0
        public override void Decompress(DecompressedBuffer buffer, DecompressionState state)
        {
            var decompressedChunk = new DecompressedChunk(new byte[] { Data });

            buffer.Add(decompressedChunk);

            ++state.DecompressedCurrent;
            ++state.CompressedCurrent;
        }
        /*
         * public Byte[] GetDataInRawBytes()
         * {
         *  IEnumerable<Byte> result = new Byte[] { this.FlagByte };
         *  foreach(var token in _Tokens)
         *  {
         *      result = result.Concat(token.GetDataInRawBytes());
         *  }
         *
         *  return result.ToArray();
         * }*/

        public void Decompress(DecompressedBuffer buffer, DecompressionState state)
        {
            ++state.CompressedCurrent;

            foreach (var token in this._Tokens)
            {
                token.Decompress(buffer, state);
            }
        }
        public override void Decompress(DecompressedBuffer buffer, DecompressionState state)
        {
            var info = UnpackCopyToken(this.Token, state.DecompressedCurrent, state.DecompressedChunkStart);

            var copySource = state.DecompressedCurrent - info.Offset;

            // Call Byte Copy (section 2.4.1.3.11) with CopySource, DecompressedCurrent, and Length
            ByteCopy(buffer, copySource, state.DecompressedCurrent, info.Length);

            state.DecompressedCurrent += info.Length;
            state.CompressedCurrent   += 2;
        }
Beispiel #8
0
        // Section 2.4.1.3.19.3
        // page 69, 70
        private static CopyToken PackCopyToken(byte[] Data, DecompressionState state, UInt16 Offset, UInt16 Length)
        {
            var help = CopyToken.CopyTokenHelp(state.DecompressedCurrent, state.DecompressedChunkStart);

            var temp1 = (ushort)(Offset - 1);
            var temp2 = (ushort)(16 - help.BitCount);
            var temp3 = (ushort)(Length - 3);

            UInt16 TokenAsUInt16 = (UInt16)(((ushort)(temp1 << temp2)) | temp3);
            var    result        = new CopyToken(TokenAsUInt16);

            return(result);
        }
Beispiel #9
0
        // Section 2.4.1.3.16
        private static void PackCompressedChunkFlag(byte[] Data, DecompressionState state, UInt16 CompressedFlag, CompressedChunkHeader header)
        {
            if (CompressedFlag != 0 && CompressedFlag != 1)
            {
                throw new ArgumentOutOfRangeException("CompressedFlag", "CompressedFlag must be 0 or 1");
            }

            UInt16 temp1  = (UInt16)(header.AsUInt16() & (ushort)0x7FFF);
            UInt16 temp2  = (UInt16)(CompressedFlag << 15);
            UInt16 result = (UInt16)(temp1 | temp2);

            header.SetFrom(result);
        }
Beispiel #10
0
        // Section 2.4.1.3.13
        // page 66
        private static void PackCompressedChunkSize(byte[] Data, DecompressionState state, UInt16 size, CompressedChunkHeader header)
        {
            if (size > 4098 || size < 3)
            {
                throw new ArgumentOutOfRangeException("size", "Size must be between 3 - 4098");
            }

            UInt16 temp1  = (UInt16)(header.AsUInt16() & (ushort)(0xF000));
            UInt16 temp2  = (UInt16)(size - 3);
            UInt16 result = (UInt16)(temp1 | temp2);

            header.SetFrom(result);
        }
Beispiel #11
0
        // Section 2.4.1.3.19.4
        // page 70
        private static MatchingResult Matching(byte[] Data, DecompressionState state, int DecompressedEnd)
        {
            int    Candidate  = state.DecompressedCurrent - 1;
            UInt16 BestLength = 0;

            int    BestCandidate = 0;
            UInt16 Offset;
            UInt16 Length;


            while (Candidate >= state.DecompressedChunkStart)
            {
                int    C   = Candidate;
                int    D   = state.DecompressedCurrent;
                UInt16 Len = 0;

                while (D < DecompressedEnd && Data[D] == Data[C])
                {
                    ++Len;
                    ++C;
                    ++D;
                }

                if (Len > BestLength)
                {
                    BestLength    = Len;
                    BestCandidate = Candidate;
                }

                --Candidate;
            }

            if (BestLength >= 3)
            {
                ushort MaximumLength = CopyToken.CopyTokenHelp(state.DecompressedCurrent, state.DecompressedChunkStart).MaximumLength;
                Length = Math.Min(BestLength, MaximumLength);
                Offset = (UInt16)(state.DecompressedCurrent - BestCandidate);
            }
            else
            {
                Length = 0;
                Offset = 0;
            }

            return(new MatchingResult(Offset, Length));
        }
Beispiel #12
0
        public void DecompressRawChunk(DecompressedBuffer buffer, DecompressionState state, Byte[] Data)
        {
            throw new NotImplementedException();

            Byte[] append = new Byte[4096];
            //Array.Copy(state.OriginalData, state.CompressedCurrent, append, 0, header.CompressedChunkSize);

            //int nCopy = Math.Min(4096, state.OriginalData.Length-state.CompressedCurrent);
            //Array.Copy(state.OriginalData, state.CompressedCurrent, append, 0, nCopy);
            Array.Copy(this.Data, 0, append, 0, 4096); // todo: maybe copy from original data?
            state.DecompressedCurrent += 4096;
            state.CompressedCurrent   += 4096;

            var x = new DecompressedChunk(append);

            buffer.Add(x);
        }
        public void Decompress(DecompressedBuffer buffer)
        {
            var state = new DecompressionState();

            if (this.SignatureByte == (Byte)0x01)
            {
                ++state.CompressedCurrent;

                foreach (var chunk in _Chunks)
                {
                    state.CompressedChunkStart = state.CompressedCurrent;
                    chunk.Decompress(buffer, state);
                }
            }
            else
            {
                throw new FormatException("Signature byte was not 0x01");
            }
        }
Beispiel #14
0
        // Section 2.4.1.3.8
        // page 63
        private static void CompressTokenSequence(byte[] Data, CompressedBuffer resultBuffer, DecompressionState state, int CompressedEnd, int DecompressedEnd)
        {
            var  FlagByteIndex = state.CompressedCurrent;
            Byte TokenFlags    = 0x0; // 0b00000000

            ++state.CompressedCurrent;

            for (int index = 0; index <= 7; index++)
            {
                if (state.DecompressedCurrent < DecompressedEnd && state.CompressedCurrent < CompressedEnd)
                {
                    TokenFlags = CompressToken(Data, resultBuffer, state, CompressedEnd, DecompressedEnd, index, TokenFlags);
                }
            }

            resultBuffer.SetByte(FlagByteIndex, TokenFlags);
        }
Beispiel #15
0
        // Section 2.4.1.3.9
        // page 64
        private static Byte CompressToken(byte[] Data, CompressedBuffer resultBuffer, DecompressionState state, int CompressedEnd, int DecompressedEnd, int index, Byte Flags)
        {
            UInt16 Offset = 0;

            var match = Matching(Data, state, DecompressedEnd);

            Offset = match.Offset;
            UInt16 Length = match.Length;

            if (Offset != 0)
            {
                if ((state.CompressedCurrent + 1) < CompressedEnd)
                {
                    var Token = PackCopyToken(Data, state, Offset, Length);

                    var bytes = BitConverter.GetBytes(Token.AsUInt16());

                    // Convert to little endian order, if necessary
                    if (!BitConverter.IsLittleEndian)
                    {
                        bytes = bytes.Reverse().ToArray();
                    }

                    Byte byte1 = bytes.First();
                    Byte byte2 = bytes.Skip(1).Single();

                    /*
                     * ////////////////// DEBUG ////////////////////////////////////
                     *
                     * byte[] _debug_all_expected_bytes = .... get expected output e.g. from unit test data ...
                     * byte[] _debug_expected_bytes = new byte[] { _debug_all_expected_bytes.ElementAt(state.CompressedCurrent), _debug_all_expected_bytes.ElementAt(state.CompressedCurrent + 1) };
                     *
                     * var TokenValue_Expected = BitConverter.ToUInt16(_debug_expected_bytes, 0);
                     * var Token_Expected = new CopyToken(TokenValue_Expected);
                     *
                     * CopyToken.UnpackedInfo Actual_Infos = Token.UnpackCopyToken(state.DecompressedCurrent, state.DecompressedChunkStart);
                     * CopyToken.UnpackedInfo Expected_Infos = Token_Expected.UnpackCopyToken(state.DecompressedCurrent, state.DecompressedChunkStart);
                     *
                     * string _debug_bitStr = BitHelper.ToBitString(bytes);
                     * string _debug_str_found = String.Format("ACTUAL:  Token at index {0}: {1} (Bits {2}). Length = {3}, Offset = {4} (-> copy bytes: {5}).", state.CompressedCurrent, BitConverter.ToString(bytes), BitHelper.ToBitString(bytes), Actual_Infos.Length, Actual_Infos.Offset, BitConverter.ToString(Data.Skip(state.DecompressedCurrent - Actual_Infos.Offset).Take(Actual_Infos.Length).ToArray()));
                     * string _debug_str_expected = String.Format("EXPECTED: Token at index {0}: {1} (Bits {2}). Length = {3}, Offset = {4} (-> copy bytes: {5})", state.CompressedCurrent, BitConverter.ToString(_debug_expected_bytes), BitHelper.ToBitString(_debug_expected_bytes), Expected_Infos.Length, Expected_Infos.Offset, BitConverter.ToString(Data.Skip(state.DecompressedCurrent - Expected_Infos.Offset).Take(Expected_Infos.Length).ToArray()));
                     *
                     * Trace.WriteLine(_debug_str_found);
                     * Trace.WriteLine(_debug_str_expected);
                     *
                     *
                     * ////////////////// DEBUG ////////////////////////////////////
                     * */

                    resultBuffer.SetByte(state.CompressedCurrent, byte1);
                    resultBuffer.SetByte(state.CompressedCurrent + 1, byte2);

                    Flags = SetFlagBit(index, 1, Flags);

                    state.CompressedCurrent   += 2;
                    state.DecompressedCurrent += Length;
                }
                else
                {
                    state.CompressedCurrent = CompressedEnd;
                }
            }
            else
            {
                if (state.CompressedCurrent < CompressedEnd)
                {
                    byte LiteralToken = Data[state.DecompressedCurrent];
                    resultBuffer.SetByte(state.CompressedCurrent, LiteralToken);
                    ++state.CompressedCurrent;
                    ++state.DecompressedCurrent;
                }
                else
                {
                    state.CompressedCurrent = CompressedEnd;
                }
            }

            return(Flags);
        }
 public abstract void Decompress(DecompressedBuffer buffer, DecompressionState state);
Beispiel #17
0
        // section 2.4.1.3.10
        // page 65
        private static void CompressRawChunk(byte[] Data, CompressedBuffer resultBuffer, DecompressionState state, int LastByte)
        {
            state.CompressedCurrent   = state.CompressedChunkStart + 2;
            state.DecompressedCurrent = state.DecompressedChunkStart;
            int PadCount = 4096;

            for (int i = state.DecompressedChunkStart; i <= LastByte; i++)
            {
                Byte B = Data[i]; // issue: do they really mean from Data?
                resultBuffer.SetByte(state.CompressedCurrent, B);

                ++state.CompressedCurrent;
                ++state.DecompressedCurrent;
                --PadCount;
            }

            for (int counter = 1; counter <= PadCount; counter++)
            {
                resultBuffer.SetByte(state.CompressedCurrent, 0x00);
                ++state.CompressedCurrent;
            }
        }
Beispiel #18
0
        // 2.4.1.3.7 Compressing a DecompressedChunk
        // page 62
        private static void CompressDecompressedChunk(byte[] Data, CompressedBuffer resultBuffer, DecompressionState state)
        {
            var CompressedEnd = state.CompressedChunkStart + 4098;

            state.CompressedCurrent = state.CompressedChunkStart + 2;
            var DecompressedEnd = Math.Min(state.DecompressedChunkStart + 4096, state.DecompressedBufferEnd);

            while (state.DecompressedCurrent < DecompressedEnd && state.CompressedCurrent < CompressedEnd)
            {
                CompressTokenSequence(Data, resultBuffer, state, CompressedEnd, DecompressedEnd);
            }

            UInt16 CompressedFlag;

            if (state.DecompressedCurrent < DecompressedEnd)
            {
                CompressRawChunk(Data, resultBuffer, state, DecompressedEnd - 1);
                CompressedFlag = 0;
            }
            else
            {
                CompressedFlag = 1;
            }


            UInt16 size   = Convert.ToUInt16(state.CompressedCurrent - state.CompressedChunkStart);
            var    header = new CompressedChunkHeader(0x0000);

            PackCompressedChunkSize(Data, state, size, header);
            PackCompressedChunkFlag(Data, state, CompressedFlag, header);
            PackCompressedChunkSignature(Data, state, header);

            // SET the CompressedChunkHeader (section 2.4.1.1.5) located at CompressedChunkStart TO Header
            var bytes = BitConverter.GetBytes(header.AsUInt16());

            resultBuffer.SetByte(state.CompressedChunkStart, bytes.First());
            resultBuffer.SetByte(state.CompressedChunkStart + 1, bytes.Skip(1).Single());
        }