예제 #1
0
        /// <summary>
        /// This method searches through the slidingWindow
        /// dictionary for the longest sequence matching the MAX_CODED
        /// long string stored in the uncodedLookahead
        /// </summary>
        /// <param name="uncodedHead">Index of the character from which the coding begins</param>
        private static EncodedString FindMatch(int uncodedHead)
        {
            var matchData = new EncodedString();

            var i = HashTable[GetHashKey(uncodedHead, true)];
            var j = 0;

            while (i != Constants.NullIndex)
            {
                // We've matched the first symbol
                if (SlidingWindow[i] == UncodedLookahead[uncodedHead])
                {
                    j = 1;

                    while (SlidingWindow[(i + j) % Constants.WindowSize] ==
                           UncodedLookahead[(uncodedHead + j) % Constants.MaxCoded])
                    {
                        if (j >= Constants.MaxCoded)
                        {
                            break;
                        }

                        j++;
                    }

                    if (j > matchData.Length)
                    {
                        matchData.Length = j;
                        matchData.Offset = i;
                    }
                }

                if (j >= Constants.MaxCoded)
                {
                    matchData.Length = Constants.MaxCoded;
                    break;
                }

                i = Next[i];
            }

            return(matchData);
        }
예제 #2
0
        /// <summary>
        /// Performs LZSS algorithm decoding
        /// </summary>
        /// <param name="inputStream">Input file</param>
        /// <param name="outputStream">Output file</param>
        public static void Decode(Stream inputStream, Stream outputStream)
        {
            var reader = new BinaryReader(inputStream);
            var writer = new BinaryWriter(outputStream);

            InitializeDataStructures();

            var flags     = 0;                             // Encoded flag
            var flagsUsed = 8;                             // Not encoded flag
            var nextChar  = Constants.WindowSize - 16 - 2; // Next char in sliding window
            var code      = new EncodedString();

            while (true)
            {
                // Shifted out all the flag bits -> read a new flag
                byte readChar = 0;
                if (flagsUsed >= 8)
                {
                    if (reader.BaseStream.Position >= reader.BaseStream.Length)
                    {
                        break;
                    }
                    readChar = reader.ReadByte();

                    flags     = readChar;
                    flagsUsed = 0;
                }

                // Uncoded character
                if ((flags & 1) != 0)
                {
                    if (reader.BaseStream.Position >= reader.BaseStream.Length)
                    {
                        break;
                    }
                    readChar = reader.ReadByte();

                    // Write out byte and put it in sliding window
                    writer.Write(readChar);
                    SlidingWindow[nextChar] = readChar;
                    nextChar = (nextChar + 1) % Constants.WindowSize;
                }
                else
                {
                    if (reader.BaseStream.Position >= reader.BaseStream.Length)
                    {
                        break;
                    }
                    code.Offset = reader.ReadByte();
                    if (reader.BaseStream.Position >= reader.BaseStream.Length)
                    {
                        break;
                    }
                    code.Length = reader.ReadByte();

                    // Unpack offset and length
                    code.Offset |= ((code.Length & 0x00F0) << 4);
                    code.Length  = (code.Length & 0x000F) + Constants.MaxUncoded + 1;

                    // Write out decoded string to file and lookahead
                    for (var i = 0; i < code.Length; i++)
                    {
                        readChar = SlidingWindow[(code.Offset + i) % Constants.WindowSize];
                        writer.Write(readChar);
                        SlidingWindow[(nextChar + i) % Constants.WindowSize] = readChar;
                    }

                    nextChar = (nextChar + code.Length) % Constants.WindowSize;

                    // PrintSlidingWindow();
                    // PrintUncodedLookahead();
                    // Console.WriteLine();
                }

                flags >>= 1;
                flagsUsed++;
            }
        }
예제 #3
0
        /// <summary>
        /// Performs LZSS algorithm decoding
        /// </summary>
        /// <param name="inputFileNameForDecode">Input file</param>
        /// <param name="outputFileNameForDecode">Output file</param>
        public static void Decode(string inputFileNameForDecode, string outputFileNameForDecode)
        {
            using (var reader = new StreamReader(inputFileNameForDecode))
            {
                using (var writer = new StreamWriter(outputFileNameForDecode))
                {
                    InitializeDataStructures();

                    var flags     = 0; // Encoded flag
                    var flagsUsed = 7; // Not encoded flag
                    var nextChar  = 0; // Next char in sliding window
                    var code      = new EncodedString();

                    while (true)
                    {
                        flags >>= 1;
                        flagsUsed++;

                        // Shifted out all the flag bits -> read a new flag
                        var readChar = 0;
                        if (flagsUsed == 8)
                        {
                            if ((readChar = reader.Read()) == -1)
                            {
                                break;
                            }

                            flags     = readChar & 0xFF;
                            flagsUsed = 0;
                        }

                        // Uncoded character
                        if ((flags & 1) != 0)
                        {
                            if ((readChar = reader.Read()) == -1)
                            {
                                break;
                            }

                            // Write out byte and put it in sliding window
                            writer.Write((char)readChar);
                            SlidingWindow[nextChar] = (char)readChar;
                            nextChar = (nextChar + 1) % Constants.WindowSize;
                        }
                        else
                        {
                            if ((code.Offset = reader.Read()) == -1)
                            {
                                break;
                            }

                            if ((code.Length = reader.Read()) == -1)
                            {
                                break;
                            }

                            // Unpack offset and length
                            code.Offset <<= 4;
                            code.Offset  |= (code.Length & 0x00F0) >> 4;
                            code.Length   = (code.Length & 0x000F) + Constants.MaxUncoded + 1;

                            // Write out decoded string to file and lookahead
                            for (var i = 0; i < code.Length; i++)
                            {
                                readChar = SlidingWindow[(code.Offset + i) % Constants.WindowSize];
                                writer.Write((char)readChar);
                                UncodedLookahead[i] = (char)readChar;
                            }

                            // Write out decoded string to sliding window
                            for (var i = 0; i < code.Length; i++)
                            {
                                SlidingWindow[(nextChar + i) % Constants.WindowSize] = UncodedLookahead[i];
                            }

                            nextChar = (nextChar + code.Length) % Constants.WindowSize;

                            // PrintSlidingWindow();
                            // PrintUncodedLookahead();
                            // Console.WriteLine();
                        }
                    }
                }
            }
        }