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); }
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(); }
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 }
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()); }
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(); }
public void Decode() { /* The compression used for the costume data is a simple byte based RLE compression. * However, it works by columns, not by lines. * Each byte contains the color in the high bits and the repetition count in the low bits. * If the repetition count is 0, then the next byte contains the actual repetition count. * How many bits are used for the color depends on the palette size: for a 16 color palette, 4 bits are used for the color; for 32 colors, 5 bits are used. */ var bitStreamManager = new BitStreamManager(_pictureData.ImageData); int colorSize = 0; int repetitionCountSize = 0; if (_costume.PaletteSize == 16) { colorSize = 4; repetitionCountSize = 4; } else { colorSize = 5; repetitionCountSize = 3; } if (_pictureData.Width == 0 || _pictureData.Height == 0) { _resultBitmap = null; return; } _resultBitmap = new Bitmap(_pictureData.Width, _pictureData.Height); if (_pictureData.ImageData.Length == 0 || (_pictureData.ImageData.Length == 1 && _pictureData.ImageData[0] == 0)) { return; //Algumas imagens são vazias!! } /* * while(1) * { * rep = read_byte(); * color = rep >> shift; * rep &= mask; * if(!rep) * rep = read_byte(); * while(rep > 0) { * set_pixel(x,y,color); * rep--; * y++; * if(y >= height) { * y = 0; * x++; * if(x >= width) break; * } * } * } * */ bool finishDecode = false; int currentLine = 0; int currentColumn = 0; while (!finishDecode) { //if (currentColumn == _pictureData.Width -1 && currentLine == _pictureData.Height -1) Debugger.Break(); int repetitionCount = bitStreamManager.ReadValue(repetitionCountSize); byte paletteIndex = bitStreamManager.ReadValue(colorSize); //The second conditiong wad added because of a bug when decoding DOTT, ROOM 65, Costume 001, Frame 7. This tweak solves. if (repetitionCount == 0 && bitStreamManager.Position != bitStreamManager.Lenght) { repetitionCount = bitStreamManager.ReadByte(); } SetCurrentColor(paletteIndex); for (int i = 0; i < repetitionCount; i++) { _resultBitmap.SetPixel(currentColumn, currentLine, _currentColor); currentLine++; if (currentLine == _pictureData.Height) { currentLine = 0; currentColumn++; } } if ((currentColumn == _pictureData.Width && currentLine == 0) || bitStreamManager.EndOfStream) { finishDecode = true; } } }