public void Decode() { UsedIndexes = new List <int>(); if (_width == 0 || _height == 0) { _resultBitmap = null; return; } _resultBitmap = new Bitmap(_width, _height); for (int i = 0; i < _strips.Count; i++) { var strip = _strips[i]; _currentLine = 0; _currentColumn = 0; _renderdingDirection = strip.RenderdingDirection; _currentOffset = i * 8;//each strip has 8 pixels width, so with multiply the current strip by 8 to get the proper offset where it should be rendered. if (strip.CompressionType == CompressionTypes.Method1 || strip.CompressionType == CompressionTypes.Method2) { DecodeCompressed(strip); } else if (strip.CompressionType == CompressionTypes.Uncompressed) { DecodeUncompressed(strip); } } }
private StripData EncodeUncompressed() { var strip = new StripData(); var bitStream = new BitStreamManager(); strip.CodecId = 0x01; _renderdingDirection = strip.RenderdingDirection; _currentLocation.X = 0; _currentLocation.Y = 0; int firstPaletteIndex = FindTableIndex(_imageToEncode.GetPixel(_currentOffset + 0, 0)); bitStream.AddByte((byte)firstPaletteIndex); while (!(_currentLocation.X == 7 && _currentLocation.Y == (_height - 1))) { var paletteIndex = FindTableIndex(GetNextPixel()); bitStream.AddByte((byte)paletteIndex); } strip.ImageData = bitStream.ToByteArray(); return(strip); }
private StripData EncodeCompressedMethod2() { var strip = new StripData(); var bitStream = new BitStreamManager(); bool transparent; int paletteSize; VerifyStrip(out transparent, out paletteSize, true); bool alternateCode = EncodeSettings == EncodeTypeSettings.Method2AlternateCode; strip.CodecId = (byte)(GetSubstractionCode(transparent, true, CompressionTypes.Method2, alternateCode) + paletteSize); if (strip.CompressionType == CompressionTypes.Unknow) { strip.CodecId = (byte)(GetSubstractionCode(transparent, true, CompressionTypes.Method2, !alternateCode) + paletteSize); } _renderdingDirection = strip.RenderdingDirection; _currentLocation.X = 0; _currentLocation.Y = 0; //Color currentColor = GetNextPixel(); //pq isso fica menos errado!? Color currentColor = _imageToEncode.GetPixel(_currentOffset + 0, 0); int currentPaletteIndex = FindTableIndex(currentColor); bitStream.AddByte((byte)currentPaletteIndex); byte accumulatedSameColor = 0; while (!(_currentLocation.X == 7 && _currentLocation.Y == (_height - 1))) { var newPaletteIndex = FindTableIndex(GetNextPixel()); if (newPaletteIndex == currentPaletteIndex) { accumulatedSameColor++; //Add one to the count of pixels with the same color. if (accumulatedSameColor == 255) { //If we have pixels with the previous color drawed before the color change //We need to write that information to the data, before process the new color. WriteAccumulatedColor(bitStream, accumulatedSameColor); accumulatedSameColor = 0; } } else { if (accumulatedSameColor > 0) { //If we have pixels with the previous color drawed before the color change //We need to write that information to the data, before process the new color. WriteAccumulatedColor(bitStream, accumulatedSameColor); accumulatedSameColor = 0; } /* * Then discory the new bit code. * * 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. */ bitStream.AddBit(true); //Add the change action bit if ((newPaletteIndex < (currentPaletteIndex - 4)) || (newPaletteIndex > (currentPaletteIndex + 3))) { //reset the negation value, read the next index from the palette, //and draw the pixel. bitStream.AddBit(false); bitStream.AddByte((byte)newPaletteIndex, paletteSize); } else { //Add the read code bit bitStream.AddBit(true); if (newPaletteIndex == (currentPaletteIndex - 4)) //000 (0): Decrease current palette index by 4. { //Add the code 0 bitStream.AddByte(0, 3); } else if (newPaletteIndex == (currentPaletteIndex - 3)) //001 (1): Decrease current palette index by 3. { //Add the code 1 bitStream.AddByte(1, 3); } else if (newPaletteIndex == (currentPaletteIndex - 2)) //010 (2): Decrease current palette index by 2. { //Add the code 2 bitStream.AddByte(2, 3); } else if (newPaletteIndex == (currentPaletteIndex - 1)) //011 (3): Decrease current palette index by 1. { //Add the code 3 bitStream.AddByte(3, 3); } else if (newPaletteIndex == (currentPaletteIndex + 1)) //101 (5): Increase current palette index by 1. { //Add the code 5 bitStream.AddByte(5, 3); } else if (newPaletteIndex == (currentPaletteIndex + 2)) //110 (6): Increase current palette index by 2. { //Add the code 6 bitStream.AddByte(6, 3); } else if (newPaletteIndex == (currentPaletteIndex + 3)) //111 (7): Increase current palette index by 3. { //Add the code 7 bitStream.AddByte(7, 3); } else { throw new ImageEncodeException("nao podia ter caido aqui"); } } currentPaletteIndex = newPaletteIndex; } } //if the loop terminated with accumulated bits pending, add these to the stream. if (accumulatedSameColor > 0) { //If we have pixels with the previous color drawed before the color change //We need to write that information to the data, before process the new color. WriteAccumulatedColor(bitStream, accumulatedSameColor); } strip.ImageData = bitStream.ToByteArray(); return(strip); }
private StripData EncodeCompressedMethod1(bool horizontalDirection) { var strip = new StripData(); var bitStream = new BitStreamManager(); bool transparent; int paletteSize; VerifyStrip(out transparent, out paletteSize, true); strip.CodecId = (byte)(GetSubstractionCode(transparent, horizontalDirection, CompressionTypes.Method1) + paletteSize); _renderdingDirection = strip.RenderdingDirection; _currentLocation.X = 0; _currentLocation.Y = 0; int negationValue = 1; //Color currentColor = GetNextPixel(); //pq isso fica menos errado!? Color currentColor = _imageToEncode.GetPixel(_currentOffset + 0, 0); int currentPaletteIndex = FindTableIndex(currentColor); bitStream.AddByte((byte)currentPaletteIndex); while (!(_currentLocation.X == 7 && _currentLocation.Y == (_height - 1))) { var newPaletteIndex = FindTableIndex(GetNextPixel()); if (newPaletteIndex == currentPaletteIndex) { bitStream.AddBit(false); //continue Drawing the same color. } else { bitStream.AddBit(true); //discover what to do. if (newPaletteIndex == (currentPaletteIndex - negationValue)) { //subtract the negation value from the palette and draw the next pixel; bitStream.AddBit(true); bitStream.AddBit(false); } else if (newPaletteIndex == (currentPaletteIndex - (negationValue * -1))) { //invert the negation value, subtract it from the palette //and draw the next pixel; negationValue *= -1; bitStream.AddBit(true); bitStream.AddBit(true); } else { //reset the negation value, read the next index from the palette, //and draw the pixel. negationValue = 1; bitStream.AddBit(false); bitStream.AddByte((byte)newPaletteIndex, paletteSize); } currentPaletteIndex = newPaletteIndex; } } strip.ImageData = bitStream.ToByteArray(); return(strip); }