Esempio n. 1
0
        /// <summary>
        /// Decodes the data in the stream with the LZW decoder
        /// </summary>
        /// <param name="compressedInput">Stream of compressed data</param>
        /// <param name="output">Stream of decompressed data</param>
        public static void Decode(Stream compressedInput, Stream output)
        {
            NBitStream input = new NBitStream(compressedInput);
            //int bitsInChunk = MIN_CHUNK_SIZE; // Min size
            byte firstByte   = 0;
            long nextCommand = 0;

            input.BitsInChunk = MIN_CHUNK_SIZE;

            var dic = new LzwDictionary(DICTIONARY_SIZE);

            while ((nextCommand = input.Read()) != EOD)
            {
                if (nextCommand < 0)
                {
                    break;
                }

                // Do our reset
                if (nextCommand == CLEAR_TABLE)
                {
                    input.BitsInChunk = MIN_CHUNK_SIZE;
                    dic = new LzwDictionary(DICTIONARY_SIZE);
                }
                else
                {
                    byte[] data = dic.GetData(nextCommand);
                    if (data == null)
                    {
                        dic.Visit(firstByte);
                        data = dic.GetData(nextCommand);
                        dic.Clearbuffer(); // clear buffer
                    }
                    if (data != null)
                    {
                        dic.Visit(data);

                        if (dic.GetNextCode() >= 2047)
                        {
                            input.BitsInChunk = 12;
                        }
                        else if (dic.GetNextCode() >= 1023)
                        {
                            input.BitsInChunk = 11;
                        }
                        else if (dic.GetNextCode() >= 511)
                        {
                            input.BitsInChunk = 10;
                        }
                        else
                        {
                            input.BitsInChunk = 9;
                        }

                        firstByte = data[0];
                        output.Write(data, 0, data.Length);
                    }
                    else
                    {
                        //throw new Exception("Error: data is null");
                    }
                }
                output.Flush();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Decodes the data in the stream with the LZW decoder
        /// </summary>
        /// <param name="compressedInput">Stream of compressed data</param>
        /// <param name="output">Stream of decompressed data</param>
        public static void Decode(Stream compressedInput, Stream output)
        {
            NBitStream input = new NBitStream(compressedInput);

            //byte firstByte = 0;
            long nextCommand = 0;

            long lastCommand = -1; // CLEAR_TABLE;

            int earlyChange = 1;

            LzwTable table = new LzwTable(TABLE_SIZE);

            // The input needs the bits in chunk set properly to read the data
            input.BitsInChunk = MIN_CHUNK_SIZE;


            while ((nextCommand = input.Read()) != EOD)
            {
                if (nextCommand < 0)
                {
                    break; // EOF?
                }
                // Do our reset
                if (nextCommand == CLEAR_TABLE)
                {
                    input.BitsInChunk = MIN_CHUNK_SIZE;
                    table             = new LzwTable(TABLE_SIZE);
                    lastCommand       = -1;
                }
                else
                {
                    //if (table[lastCommand] == null)
                    //{
                    //    throw new Exception(String.Format("Corrupted LZW: code {0} (table size: {1})", lastCommand, table.Length));
                    //}

                    // Check if the command is already in the table
                    // We could use a dictionary here, but I don't think we need the extra overhead of a hash
                    if (nextCommand < table.Count)
                    {
                        table[(int)nextCommand].writeTo(output);

                        if (lastCommand != -1)
                        {
                            table.Add(table[(int)lastCommand].concatenate(table[(int)nextCommand].firstChar));
                        }
                    }
                    else
                    {
                        LZWString outString = table[(int)lastCommand].concatenate(table[(int)lastCommand].firstChar);

                        outString.writeTo(output);
                        table.Add(outString);
                    }



                    // The input needs the bits in chunk set properly to read the data
                    if (table.GetNextCode() >= 4096 - earlyChange)
                    {
                        input.BitsInChunk = 13;
                    }
                    else
                    if (table.GetNextCode() >= 2048 - earlyChange)
                    {
                        input.BitsInChunk = 12;
                    }
                    else if (table.GetNextCode() >= 1024 - earlyChange)
                    {
                        input.BitsInChunk = 11;
                    }
                    else if (table.GetNextCode() >= 512 - earlyChange)
                    {
                        input.BitsInChunk = 10;
                    }
                    else
                    {
                        input.BitsInChunk = 9;
                    }

                    lastCommand = nextCommand;
                }
            } // while end


            output.Flush();
        }