Beispiel #1
0
        public void TestReadBitAndAdvanceStream()
        {
            var sourceBytes = new byte[1];

            sourceBytes[0] = 130; //1000 0010

            var bitStreamManager = new BitStreamManager(sourceBytes);

            Assert.AreEqual(0, bitStreamManager.Position);

            //Le um bit e verifica se ele é off;
            //o Stream resultante ficou assim: 1000 001
            Assert.IsFalse(bitStreamManager.ReadBit());


            Assert.AreEqual(1, bitStreamManager.Position);

            //Verifica que o stream não terminou
            Assert.IsFalse(bitStreamManager.EndOfStream);

            //Le mais 7 bits
            byte result = bitStreamManager.ReadValue(7);

            //65 = 0100 0001 porque o bit mais significante foi completado em branco.
            Assert.AreEqual(65, result);
        }
Beispiel #2
0
        private void DecodeCode1Specifics()
        {
            // Decoder specific actions. If we are here, is because the previous read bit by DecodeCompressed was True (1).

            var nextBitCode = _bitStreamManager.ReadBit();

            if (!nextBitCode) // next bit is false (0).
            {
                //previous bit was false (0). So now we have a code 10 (1 previous bit and 0 from this one).
                //10: Read a new palette index from the bit stream, i.e., read the number of bits that the parameter
                //    specifies as a value (see the Tiny Bits of Decompression chapter).
                //    Set the subtraction variable to 1.
                //    Draw the next pixel.
                _paletteIndex        = _bitStreamManager.ReadValue(_numBitPerPaletteEntry);
                _substrationVariable = 1;
                SetCurrentColor();
            }
            else
            {
                //previous bit was true (1). So now we have a code 11 (1 previous bit and 1 from this one).
                //11 alone is not enough. We will need the next bit to know what to do.
                nextBitCode = _bitStreamManager.ReadBit();
                if (!nextBitCode)
                {
                    //previous bit was false. Now we have a code 110 (1 from first bit, 1 from second and 0 from the last read.)
                    //110: Subtract the subtraction variable from the palette index.
                    //     Draw the next pixel.
                    _paletteIndex -= _substrationVariable;
                    SetCurrentColor();
                }
                else
                {
                    //previous bit was true. Now we have a code 111 (1 from first bit, 1 from second and 1 from the last read.)
                    //111: Negate the subtraction variable (i.e., if it's 1, change it to -1, if it's -1, change it to 1).
                    //     Subtract it from the palette index.
                    //     Draw the next pixel.
                    _substrationVariable = _substrationVariable * -1;
                    _paletteIndex       -= _substrationVariable;
                    SetCurrentColor();
                }
            }

            DrawNextPixel();
        }
Beispiel #3
0
        public void TestC()
        {
            //            else if (highestPaletteIndex >= 16 && highestPaletteIndex <= 31)
            //{
            //     paletteBitSize = 5;//max 31 values;

            BitStreamManager bs = new BitStreamManager();

            bs.AddBit(true);
            bs.AddBit(false);
            bs.AddByte(28, 5);

            byte[] values = bs.ToByteArray();
            bs = new BitStreamManager(values);

            Assert.IsTrue(bs.ReadBit());
            Assert.IsFalse(bs.ReadBit());
            Assert.AreEqual(28, bs.ReadValue(6));
            //Assert.IsFalse(bs.ReadBit());
        }
Beispiel #4
0
        public void TestB()
        {
            //0x11 (17)  - 0000 1011
            //0x05 (5)   - 0000 0101
            //0x80 (128) - 1000 0000
            //0xFC (252) - 1111 1100

            var bs = new BitStreamManager(new byte[] { 0x11, 0x05, 0x80, 0xFC });
            //int pSize = 7;

            var compression = bs.ReadByte();

            Assert.AreEqual(0x11, compression);

            Assert.AreEqual(0x05, bs.ReadByte()); //le o numero da palheta;

            //0x80

            //Desenha tudo na mesma paletta.
            Assert.AreEqual(false, bs.ReadBit()); //0
            Assert.AreEqual(false, bs.ReadBit()); //0
            Assert.AreEqual(false, bs.ReadBit()); //0
            Assert.AreEqual(false, bs.ReadBit()); //0

            Assert.AreEqual(false, bs.ReadBit()); //0
            Assert.AreEqual(false, bs.ReadBit()); //0
            Assert.AreEqual(false, bs.ReadBit()); //0

            //Encontrou bit de controle.
            Assert.AreEqual(true, bs.ReadBit());  //1

            //0xFC

            //Bit 0 - le o próximo indice da palheta (7 bits)
            Assert.AreEqual(false, bs.ReadBit()); //0

            Assert.AreEqual(0x7E, bs.ReadValue(7));
            //Assert.AreEqual(false, bs.ReadBit()); //0
            //Assert.AreEqual(true, bs.ReadBit());  //1
            //Assert.AreEqual(true, bs.ReadBit());  //1

            //Assert.AreEqual(true, bs.ReadBit());  //1
            //Assert.AreEqual(true, bs.ReadBit());  //1
            //Assert.AreEqual(true, bs.ReadBit());  //1
            //Assert.AreEqual(true, bs.ReadBit());  //1
        }
Beispiel #5
0
        private void DecodeCompressed(StripData strip)
        {
            _numBitPerPaletteEntry = strip.CodecId - strip.ParamSubtraction;
            _substrationVariable   = 1;
            _bitStreamManager      = new BitStreamManager(strip.ImageData);

            _currentLine   = 0;
            _currentColumn = 0;
            bool finishDecode = false;

            //if (strip.CodecId >= 0x54 && strip.CodecId <= 0x58) Debugger.Break();
            //if (strip.CodecId >= 0x40 && strip.CodecId <= 0x44) Debugger.Break();

            //Read palette and Draw the first pixel.
            _paletteIndex = _bitStreamManager.ReadByte();

            SetCurrentColor();

            _resultBitmap.SetPixel(_currentOffset + _currentColumn, _currentLine, _currentColor);

            while (!finishDecode)
            {
                var changeAction = _bitStreamManager.ReadBit();
                //changeAction = false (0): Draw next pixel with current palette index.
                //                          Otherwise changeAction is true and we need the next bit to decide what to do.

                //changeAction = true (1): We need the next bit to discover what to do.
                if (changeAction)
                {
                    if (strip.CompressionType == CompressionTypes.Method1)
                    {
                        DecodeCode1Specifics();
                    }
                    else if (strip.CompressionType == CompressionTypes.Method2)
                    {
                        DecodeCode2Specifics();
                    }
                }
                else
                {
                    DrawNextPixel();
                }


                if ((_currentColumn == 7 && _currentLine == (_height - 1)) || _bitStreamManager.EndOfStream)
                {
                    finishDecode = true;
                }
            }

            UsedIndexes.Sort();
        }
        public void Decode()
        {
            UsedIndexes = new List <int>();

            _currentLine   = 0;
            _currentColumn = 0;

            var bitStreamManager = new BitStreamManager(_imageData.Data);

            _resultBitmap = new Bitmap(_width, _height);

            //if (_pictureData.ImageData.Length == 0
            //    || (_pictureData.ImageData.Length == 1 && _pictureData.ImageData[0] == 0)) return; //Algumas imagens são vazias!!

            /*
             * Each line start with a 16le storing the size of the encoded line (without the size header itself) followed by the RLE data.
             * lines
             *  encoded size : 16le
             *  line data    : size bytes
             */
            bool finishDecode = false;

            while (!finishDecode)
            {
                uint lineSize       = bitStreamManager.ReadUInt16();
                int  streamPosition = bitStreamManager.Position;

                while ((bitStreamManager.Position - streamPosition) < (lineSize * 8))
                {
                    bool repeatSameColor = bitStreamManager.ReadBit();
                    int  count           = bitStreamManager.ReadValue(7) + 1;

                    if (count > _width)
                    {
                        count = _width;
                    }

                    if (repeatSameColor)
                    {
                        byte colorIndex = bitStreamManager.ReadByte();
                        var  color      = GetColor(colorIndex);
                        for (int j = 0; j < count; j++)
                        {
                            DrawNextPixel(color);
                        }
                    }
                    else
                    {
                        for (int j = 0; j < count; j++)
                        {
                            byte colorIndex = bitStreamManager.ReadByte();
                            var  color      = GetColor(colorIndex);
                            DrawNextPixel(color);
                        }
                    }

                    if ((_currentColumn == 0 && _currentLine == _imageData.Height) || bitStreamManager.EndOfStream)
                    {
                        finishDecode = true;
                    }
                }
            }

            UsedIndexes.Sort();
        }