Пример #1
0
        public void DecodeFile(IFileReader fileReader, IFileWriter fileWriter)
        {
            if (fileReader == null)
            {
                throw new ArgumentNullException(nameof(fileReader));
            }

            if (fileWriter == null)
            {
                throw new ArgumentNullException(nameof(fileWriter));
            }

            InterpretHeader(fileReader);

            var firstIndex  = fileReader.ReadBits(numberOfBitsForIndex);
            var firstString = lzWDictionary.GetStringByIndex(firstIndex);

            firstString.WriteToFile(fileWriter);

            var lastString = firstString;

            while (!fileReader.ReachedEndOfFile && fileReader.BitsLeft >= numberOfBitsForIndex)
            {
                var    currentIndex = fileReader.ReadBits(numberOfBitsForIndex);
                string currentString;

                if (lzWDictionary.ContainsIndex(currentIndex))
                {
                    currentString = lzWDictionary.GetStringByIndex(currentIndex);

                    var dictionaryNewString = lastString + currentString[0];
                    lzWDictionary.Add(dictionaryNewString);
                }
                else
                {
                    var dictionaryNewString = lastString + lastString[0];
                    lzWDictionary.Add(dictionaryNewString);

                    currentString = lzWDictionary.GetStringByIndex(currentIndex);
                }

                currentString.WriteToFile(fileWriter);
                lastString = currentString;
            }
        }
Пример #2
0
        public void EncodeFile(IFileReader fileReader, IFileWriter fileWriter, OnFullDictionaryOption onFullDictionaryOption, int numberOfBitsIndex)
        {
            if (fileReader == null)
            {
                throw new ArgumentNullException(nameof(fileReader));
            }

            if (fileWriter == null)
            {
                throw new ArgumentNullException(nameof(fileWriter));
            }

            if (numberOfBitsIndex < 9 || numberOfBitsIndex > 15)
            {
                throw new ArgumentException($"{nameof(numberOfBitsIndex)} must be at least 9, and at most 15");
            }

            WriteHeader(fileWriter, onFullDictionaryOption, numberOfBitsIndex);
            IndexesFromLastRun.Clear();

            LzWDictionary = new LzWDictionary((int)Math.Pow(2, numberOfBitsIndex) - 1, onFullDictionaryOption);

            var lastCharacter = (char)fileReader.ReadBits(8);
            var shouldStop = false;

            while (true)
            {
                var currentString = lastCharacter.ToString();
                uint lastIndex = 0;

                if (shouldStop)
                {
                    break;
                }

                while (true)
                {
                    if (LzWDictionary.ContainsString(currentString))
                    {
                        lastIndex = LzWDictionary.GetIndexByString(currentString);

                        if (shouldStop)
                        {
                            fileWriter.WriteValueOnBits(lastIndex, (byte)numberOfBitsIndex);
                            IndexesFromLastRun.Add(lastIndex);

                            break;
                        }
                    }
                    else
                    {
                        LzWDictionary.Add(currentString);

                        fileWriter.WriteValueOnBits(lastIndex, (byte)numberOfBitsIndex);
                        IndexesFromLastRun.Add(lastIndex);

                        break;
                    }

                    if (!fileReader.ReachedEndOfFile)
                    {
                        var readByte = (byte)fileReader.ReadBits(8);
                        currentString += (char)readByte;
                        lastCharacter = (char)readByte;
                    }
                    else
                    {
                        shouldStop = true;
                    }
                }
            }

            fileWriter.Flush();
        }