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 }
private void DecodeZPlaneStrip(ZPlaneStripData strip) { _bitStreamManager = new BitStreamManager(strip.ImageData); bool finishDecode = false; while (!finishDecode) { byte count = _bitStreamManager.ReadByte(); if (count > 0) { if (BinaryHelper.CheckBitState(count, 7)) { // write the same byte count times count = BinaryHelper.GetBitsFromByte(count, 7); // &= 0x7F; byte b = _bitStreamManager.ReadByte(); for (int i = 0; i < count; i++) { if (!CheckEndOfGraphics()) { DrawLine(b); } } } else { // write count bytes as is from the input for (int i = 0; i < count; i++) { if (!CheckEndOfGraphics()) { DrawLine(_bitStreamManager.ReadByte()); } } } } //else //{ // Debugger.Break(); //} if (CheckEndOfGraphics() || _bitStreamManager.EndOfStream) { finishDecode = true; } } }
private void DecodeUncompressed(StripData strip) { _bitStreamManager = new BitStreamManager(strip.ImageData); bool finishDecode = false; _paletteIndex = _bitStreamManager.ReadByte(); SetCurrentColor(); _resultBitmap.SetPixel(_currentOffset, 0, _currentColor); while (!finishDecode) { _paletteIndex = _bitStreamManager.ReadByte(); SetCurrentColor(); DrawNextPixel(); if ((_currentColumn == 7 && _currentLine == (_height - 1)) || _bitStreamManager.EndOfStream) { finishDecode = true; } } }
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(); }
private void DecodeCode2Specifics() { // Decoder specific actions. If we are here, is because the previous read bit by DecodeCompressed was True (1). /* * 10: Read a new palette index from the bitstream (i.e., the number of bits specified by the parameter), and draw the next pixel. * 11: Read the next 3 bit value, and perform an action, depending on the value: * 000 (0): Decrease current palette index by 4. * 001 (1): Decrease current palette index by 3. * 010 (2): Decrease current palette index by 2. * 011 (3): Decrease current palette index by 1. * 100 (4): Read next 8 bits. Draw the number of pixels specified by these 8 bits with the current palette index (somewhat similar to RLE). * 101 (5): Increase current palette index by 1. * 110 (6): Increase current palette index by 2. * 111 (7): Increase current palette index by 3. */ var nextBitCode = _bitStreamManager.ReadBit(); if (!nextBitCode) // last bit is false (0). { //last read bit is 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); SetCurrentColor(); } else // last bit is true (1). { //11: Read the next 3 bit value, and perform an action, depending on the value: byte nextValue = _bitStreamManager.ReadValue(3); switch (nextValue) { case 0: //000: Decrease current palette index by 4. _paletteIndex -= 4; SetCurrentColor(); break; case 1: //001: Decrease current palette index by 3. _paletteIndex -= 3; SetCurrentColor(); break; case 2: //010: Decrease current palette index by 2. _paletteIndex -= 2; SetCurrentColor(); break; case 3: //011: Decrease current palette index by 1. _paletteIndex -= 1; SetCurrentColor(); break; case 4: //100: Read next 8 bits. //Draw the number of pixels specified by these 8 bits with the current palette index (somewhat similar to RLE). var numPixels = _bitStreamManager.ReadByte(); for (int i = 0; i < numPixels; i++) { //if (!((_currentColumn == 7 && _currentLine == (_height - 1)))) { DrawNextPixel(); } } return; case 5: //101: Increase current palette index by 1. _paletteIndex += 1; SetCurrentColor(); break; case 6: //110: Increase current palette index by 2. _paletteIndex += 2; SetCurrentColor(); break; case 7: //111: Increase current palette index by 3. _paletteIndex += 3; SetCurrentColor(); break; default: Debugger.Break(); break; } } DrawNextPixel(); }
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; } } }