public AddonReader(IColorReader colorReader, List <DataFrame> frames, ILogger logger) { this.frames = frames; this.logger = logger; this.colorReader = colorReader; this.width = frames.Last().point.X + 1; this.height = frames.Max(f => f.point.Y) + 1; this.squareReader = new SquareReader(this); var items = JsonConvert.DeserializeObject <List <Item> >(File.ReadAllText("../json/data/items.json")); var creatures = JsonConvert.DeserializeObject <List <Creature> >(File.ReadAllText("../json/data/creatures.json")); this.BagReader = new BagReader(squareReader, 20, items, ReadAHPrices()); this.equipmentReader = new EquipmentReader(squareReader, 30); this.PlayerReader = new PlayerReader(squareReader, creatures); this.LevelTracker = new LevelTracker(PlayerReader); }
public Image Decode(Stream stream) { _stream = stream; _stream.Seek(8, SeekOrigin.Current); bool isEndChunckReached = false; PngChunk currentChunk = null; byte[] palette = null; byte[] paletteAlpha = null; using (MemoryStream dataStream = new MemoryStream()) { while ((currentChunk = ReadChunk()) != null) { if (isEndChunckReached) { throw new ImageFormatException("Image does not end with end chunk."); } if (currentChunk.Type == PngChunkTypes.Header) { ReadHeaderChunk(currentChunk.Data); ValidateHeader(); } else if (currentChunk.Type == PngChunkTypes.Data) { dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length); } else if (currentChunk.Type == PngChunkTypes.Palette) { palette = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.PaletteAlpha) { paletteAlpha = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.End) { isEndChunckReached = true; } } if (_header.Width > Image.MaxWidth || _header.Height > Image.MaxHeight) { throw new ArgumentOutOfRangeException( $"The input png '{ _header.Width }x{ _header.Height }' is bigger then the max allowed size '{ Image.MaxWidth }x{ Image.MaxHeight }'"); } byte[] pixels = new byte[_header.Width * _header.Height * 4]; PngColorTypeInformation colorTypeInformation = _colorTypes[_header.ColorType]; if (colorTypeInformation != null) { IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha); ReadScanlines(dataStream, pixels, colorReader, colorTypeInformation); } return(new Image(_header.Width, _header.Height, pixels)); } }
private void ReadScanlines(MemoryStream dataStream, byte[] pixels, IColorReader colorReader, PngColorTypeInformation colorTypeInformation) { dataStream.Position = 0; int scanlineLength = CalculateScanlineLength(colorTypeInformation); int scanlineStep = CalculateScanlineStep(colorTypeInformation); byte[] lastScanline = new byte[scanlineLength]; byte[] currScanline = new byte[scanlineLength]; byte a = 0; byte b = 0; byte c = 0; int row = 0, filter = 0, column = -1; using (var compressedStream = new ZlibInflateStream(dataStream)) { int readByte = 0; while ((readByte = compressedStream.ReadByte()) >= 0) { if (column == -1) { filter = readByte; column++; } else { currScanline[column] = (byte)readByte; if (column >= scanlineStep) { a = currScanline[column - scanlineStep]; c = lastScanline[column - scanlineStep]; } else { a = 0; c = 0; } b = lastScanline[column]; if (filter == 1) { currScanline[column] = (byte)(currScanline[column] + a); } else if (filter == 2) { currScanline[column] = (byte)(currScanline[column] + b); } else if (filter == 3) { currScanline[column] = (byte)(currScanline[column] + (byte)((a + b) / 2)); } else if (filter == 4) { currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c)); } column++; if (column == scanlineLength) { colorReader.ReadScanline(currScanline, pixels, _header); column = -1; row++; var tmp = currScanline; currScanline = lastScanline; lastScanline = tmp; } } } } }
private void ReadScanlines(MemoryStream dataStream, byte[] pixels, IColorReader colorReader, PngColorTypeInformation colorTypeInformation) { // Read the zlib header : http://tools.ietf.org/html/rfc1950 // CMF(Compression Method and flags) // This byte is divided into a 4 - bit compression method and a // 4-bit information field depending on the compression method. // bits 0 to 3 CM Compression method // bits 4 to 7 CINFO Compression info // // 0 1 // +---+---+ // |CMF|FLG| // +---+---+ int cmf = dataStream.ReadByte(); int flag = dataStream.ReadByte(); //please note that position=2 int scanlineLength = CalculateScanlineLength(colorTypeInformation); int scanlineStep = CalculateScanlineStep(colorTypeInformation); byte[] lastScanline = new byte[scanlineLength]; byte[] currScanline = new byte[scanlineLength]; byte a = 0; byte b = 0; byte c = 0; int row = 0, filter = 0, column = -1; //using (InflaterInputStream compressedStream = new InflaterInputStream(dataStream)) //{ // int readByte = 0; // while ((readByte = compressedStream.ReadByte()) >= 0) // { // if (column == -1) // { // filter = readByte; // column++; // } // else // { // currScanline[column] = (byte)readByte; // if (column >= scanlineStep) // { // a = currScanline[column - scanlineStep]; // c = lastScanline[column - scanlineStep]; // } // else // { // a = 0; // c = 0; // } // b = lastScanline[column]; // if (filter == 1) // { // currScanline[column] = (byte)(currScanline[column] + a); // } // else if (filter == 2) // { // currScanline[column] = (byte)(currScanline[column] + b); // } // else if (filter == 3) // { // currScanline[column] = (byte)(currScanline[column] + (byte)Math.Floor((double)(a + b) / 2)); // } // else if (filter == 4) // { // currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c)); // } // column++; // if (column == scanlineLength) // { // colorReader.ReadScanline(currScanline, pixels, _header); // column = -1; // row++; // Extensions.Swap(ref currScanline, ref lastScanline); // } // } // } //} //using (Ionic.Zlib.DeflateStream compressedStream = new Ionic.Zlib.DeflateStream(dataStream, Ionic.Zlib.CompressionMode.Decompress)) using (System.IO.Compression.DeflateStream compressedStream = new System.IO.Compression.DeflateStream( dataStream, System.IO.Compression.CompressionMode.Decompress, true)) { int readByte = 0; //byte[] singleByte = new byte[1]; //compressedStream.Read(singleByte, 0, 1); while ((readByte = compressedStream.ReadByte()) >= 0) { if (column == -1) { filter = readByte; column++; } else { currScanline[column] = (byte)readByte; if (column >= scanlineStep) { a = currScanline[column - scanlineStep]; c = lastScanline[column - scanlineStep]; } else { a = 0; c = 0; } b = lastScanline[column]; if (filter == 1) { currScanline[column] = (byte)(currScanline[column] + a); } else if (filter == 2) { currScanline[column] = (byte)(currScanline[column] + b); } else if (filter == 3) { currScanline[column] = (byte)(currScanline[column] + (byte)Math.Floor((double)(a + b) / 2)); } else if (filter == 4) { currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c)); } column++; if (column == scanlineLength) { colorReader.ReadScanline(currScanline, pixels, _header); column = -1; row++; // //Extensions.Swap(ref currScanline, ref lastScanline); var tmpA = currScanline; var tmpB = lastScanline; lastScanline = tmpA; currScanline = tmpB; } } } } }
/// <summary> /// Decodes the image from the specified stream and sets /// the data to image. /// </summary> /// <param name="image">The image, where the data should be set to. /// Cannot be null (Nothing in Visual Basic).</param> /// <param name="stream">The stream, where the image should be /// decoded from. Cannot be null (Nothing in Visual Basic).</param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="image"/> is null (Nothing in Visual Basic).</para> /// <para>- or -</para> /// <para><paramref name="stream"/> is null (Nothing in Visual Basic).</para> /// </exception> public void Decode(ExtendedImage image, Stream stream) { _image = image; _stream = stream; _stream.Seek(8, SeekOrigin.Current); bool isEndChunckReached = false; PngChunk currentChunk = null; byte[] palette = null; byte[] paletteAlpha = null; using (MemoryStream dataStream = new MemoryStream()) { while ((currentChunk = ReadChunk()) != null) { if (isEndChunckReached) { throw new ImageFormatException("Image does not end with end chunk."); } if (currentChunk.Type == PngChunkTypes.Header) { ReadHeaderChunk(currentChunk.Data); ValidateHeader(); } else if (currentChunk.Type == PngChunkTypes.Physical) { ReadPhysicalChunk(currentChunk.Data); } else if (currentChunk.Type == PngChunkTypes.Data) { dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length); } else if (currentChunk.Type == PngChunkTypes.Palette) { palette = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.PaletteAlpha) { paletteAlpha = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.Text) { ReadTextChunk(currentChunk.Data); } else if (currentChunk.Type == PngChunkTypes.End) { isEndChunckReached = true; } } byte[] pixels = new byte[_header.Width * _header.Height * 4]; PngColorTypeInformation colorTypeInformation = _colorTypes[_header.ColorType]; if (colorTypeInformation != null) { IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha); ReadScanlines(dataStream, pixels, colorReader, colorTypeInformation); } image.SetPixels(_header.Width, _header.Height, pixels); } }
private void ReadScanlines(MemoryStream dataStream, byte[] pixels, IColorReader colorReader, PngColorTypeInformation colorTypeInformation) { dataStream.Position = 0; int scanlineLength = CalculateScanlineLength(colorTypeInformation); int scanlineStep = CalculateScanlineStep(colorTypeInformation); byte[] lastScanline = new byte[scanlineLength]; byte[] currScanline = new byte[scanlineLength]; byte a = 0; byte b = 0; byte c = 0; int row = 0, filter = 0, column = -1; using (InflaterInputStream compressedStream = new InflaterInputStream(dataStream)) { int readByte = 0; while ((readByte = compressedStream.ReadByte()) >= 0) { if (column == -1) { filter = readByte; column++; } else { currScanline[column] = (byte)readByte; if (column >= scanlineStep) { a = currScanline[column - scanlineStep]; c = lastScanline[column - scanlineStep]; } else { a = 0; c = 0; } b = lastScanline[column]; if (filter == 1) { currScanline[column] = (byte)(currScanline[column] + a); } else if (filter == 2) { currScanline[column] = (byte)(currScanline[column] + b); } else if (filter == 3) { currScanline[column] = (byte)(currScanline[column] + (byte)Math.Floor((a + b) / 2d)); } else if (filter == 4) { currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c)); } column++; if (column == scanlineLength) { colorReader.ReadScanline(currScanline, pixels, _header); column = -1; row++; Extensions.Swap(ref currScanline, ref lastScanline); } } } } }
public DataFrameConfiguration(IColorReader colorReader) { this.colorReader = colorReader; }
private static void ParseInterlaced(byte[] data, PngFileHeader fileHeader, int bytesPerPixel, IColorReader reader, byte[] pixels) { const int passes = 7; var readOffset = 0; var done = false; var r = new Span <byte>(data); for (var i = 0; i < passes; i++) { int columns = Adam7.ComputeColumns(fileHeader.Width, i); if (columns == 0) { continue; } int rowSize = GetScanlineLength(columns, fileHeader) + 1; // Read rows. Span <byte> prevRowData = null; for (int row = Adam7.FirstRow[i]; row < fileHeader.Height; row += Adam7.RowIncrement[i]) { // Early out if invalid pass. if (r.Length - readOffset < rowSize) { done = true; break; } var rowData = new Span <byte>(new byte[rowSize]); r.Slice(readOffset, rowSize).CopyTo(rowData); int filter = rowData[0]; rowData = rowData.Slice(1); readOffset += rowSize; // Apply filter to the whole row. for (var column = 0; column < rowData.Length; column++) { rowData[column] = ApplyFilter(rowData, prevRowData, filter, column, bytesPerPixel); } reader.ReadScanlineInterlaced(rowData, pixels, fileHeader, row, i); prevRowData = rowData; } if (done) { break; } } }
private static void Parse(byte[] data, PngFileHeader fileHeader, int bytesPerPixel, IColorReader reader, byte[] pixels) { // Find the scan line length. int scanlineLength = GetScanlineLength(fileHeader.Width, fileHeader) + 1; int scanLineCount = data.Length / scanlineLength; // Run through all scanlines. var cannotParallel = new List <int>(); ParallelWork.FastLoops(scanLineCount, (start, end) => { int readOffset = start * scanlineLength; for (int i = start; i < end; i++) { // Early out for invalid data. if (data.Length - readOffset < scanlineLength) { break; } // Get the current scanline. var rowData = new Span <byte>(data, readOffset + 1, scanlineLength - 1); int filter = data[readOffset]; readOffset += scanlineLength; // Check if it has a filter. // PNG filters require the previous row. // We can't do those in parallel. if (filter != 0) { lock (cannotParallel) { cannotParallel.Add(i); } continue; } reader.ReadScanline(rowData, pixels, fileHeader, i); } }).Wait(); if (cannotParallel.Count == 0) { return; } PerfProfiler.ProfilerEventStart("PNG Parse Sequential", "Loading"); // Run scanlines which couldn't be parallel processed. if (scanLineCount >= 2000) { Engine.Log.Trace("Loaded a big PNG with scanlines which require filtering. If you re-export it without that, it will load faster.", MessageSource.ImagePng); } cannotParallel.Sort(); for (var i = 0; i < cannotParallel.Count; i++) { int idx = cannotParallel[i]; int rowStart = idx * scanlineLength; Span <byte> prevRowData = idx == 0 ? null : new Span <byte>(data, (idx - 1) * scanlineLength + 1, scanlineLength - 1); var rowData = new Span <byte>(data, rowStart + 1, scanlineLength - 1); // Apply filter to the whole row. int filter = data[rowStart]; for (var column = 0; column < rowData.Length; column++) { rowData[column] = ApplyFilter(rowData, prevRowData, filter, column, bytesPerPixel); } reader.ReadScanline(rowData, pixels, fileHeader, idx); } PerfProfiler.ProfilerEventEnd("PNG Parse Sequential", "Loading"); }
/// <summary> /// Decode the provided png file to a BGRA pixel array, Y flipped. /// </summary> /// <param name="pngData">The png file as bytes.</param> /// <param name="fileHeader">The png file's header.</param> /// <returns>The RGBA pixel data from the png.</returns> public static byte[] Decode(byte[] pngData, out PngFileHeader fileHeader) { fileHeader = new PngFileHeader(); if (!IsPng(pngData)) { Engine.Log.Warning("Tried to decode a non-png image!", MessageSource.ImagePng); return(null); } using var stream = new MemoryStream(pngData); stream.Seek(8, SeekOrigin.Current); var endChunkReached = false; byte[] palette = null; byte[] paletteAlpha = null; using var dataStream = new MemoryStream(); // Read chunks while there are valid chunks. PngChunk currentChunk; while ((currentChunk = new PngChunk(stream)).Valid) { if (endChunkReached) { Engine.Log.Warning("Image did not end with an end chunk...", MessageSource.ImagePng); continue; } switch (currentChunk.Type) { case PngChunkTypes.HEADER: { Array.Reverse(currentChunk.Data, 0, 4); Array.Reverse(currentChunk.Data, 4, 4); fileHeader.Width = BitConverter.ToInt32(currentChunk.Data, 0); fileHeader.Height = BitConverter.ToInt32(currentChunk.Data, 4); fileHeader.BitDepth = currentChunk.Data[8]; fileHeader.ColorType = currentChunk.Data[9]; fileHeader.FilterMethod = currentChunk.Data[11]; fileHeader.InterlaceMethod = currentChunk.Data[12]; fileHeader.CompressionMethod = currentChunk.Data[10]; // Validate header. if (fileHeader.ColorType >= ColorTypes.Length || ColorTypes[fileHeader.ColorType] == null) { Engine.Log.Warning($"Color type '{fileHeader.ColorType}' is not supported or not valid.", MessageSource.ImagePng); return(null); } if (!ColorTypes[fileHeader.ColorType].SupportedBitDepths.Contains(fileHeader.BitDepth)) { Engine.Log.Warning($"Bit depth '{fileHeader.BitDepth}' is not supported or not valid for color type {fileHeader.ColorType}.", MessageSource.ImagePng); } if (fileHeader.FilterMethod != 0) { Engine.Log.Warning("The png specification only defines 0 as filter method.", MessageSource.ImagePng); } break; } case PngChunkTypes.DATA: dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length); break; case PngChunkTypes.PALETTE: palette = currentChunk.Data; break; case PngChunkTypes.PALETTE_ALPHA: paletteAlpha = currentChunk.Data; break; case PngChunkTypes.END: endChunkReached = true; break; } } stream.Dispose(); // Determine color reader to use. PngColorTypeInformation colorTypeInformation = ColorTypes[fileHeader.ColorType]; if (colorTypeInformation == null) { return(null); } IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha); // Calculate the bytes per pixel. var bytesPerPixel = 1; if (fileHeader.BitDepth >= 8) { bytesPerPixel = colorTypeInformation.ChannelsPerColor * fileHeader.BitDepth / 8; } // Decompress data. dataStream.Position = 0; PerfProfiler.ProfilerEventStart("PNG Decompression", "Loading"); byte[] data = ZlibStreamUtility.Decompress(dataStream); PerfProfiler.ProfilerEventEnd("PNG Decompression", "Loading"); // Parse into pixels. var pixels = new byte[fileHeader.Width * fileHeader.Height * 4]; if (fileHeader.InterlaceMethod == 1) { ParseInterlaced(data, fileHeader, bytesPerPixel, colorReader, pixels); } else { Parse(data, fileHeader, bytesPerPixel, colorReader, pixels); } return(pixels); }
public void Decode(Image2 image, Stream stream) { Image2 currentImage = image; currentStream = stream; currentStream.Seek(8, SeekOrigin.Current); bool isEndChunkReached = false; byte[] palette = null; byte[] paletteAlpha = null; using (MemoryStream dataStream = new MemoryStream()){ PngChunk currentChunk; while ((currentChunk = ReadChunk()) != null) { if (isEndChunkReached) { throw new Exception("Image does not end with end chunk."); } if (currentChunk.Type == PngChunkTypes.Header) { ReadHeaderChunk(currentChunk.Data); ValidateHeader(); } else if (currentChunk.Type == PngChunkTypes.Physical) { ReadPhysicalChunk(currentImage, currentChunk.Data); } else if (currentChunk.Type == PngChunkTypes.Data) { dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length); } else if (currentChunk.Type == PngChunkTypes.Palette) { palette = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.PaletteAlpha) { paletteAlpha = currentChunk.Data; } else if (currentChunk.Type == PngChunkTypes.Text) { ReadTextChunk(currentImage, currentChunk.Data); } else if (currentChunk.Type == PngChunkTypes.End) { isEndChunkReached = true; } } if (header.Width > image.MaxWidth || header.Height > image.MaxHeight) { throw new ArgumentOutOfRangeException($"The input png '{header.Width}x{header.Height}' is bigger than the " + $"max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); } Color2[] pixels = new Color2[header.Width * header.Height]; PngColorTypeInformation colorTypeInformation = colorTypes[header.ColorType]; if (colorTypeInformation != null) { IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha); ReadScanlines(dataStream, pixels, colorReader, colorTypeInformation); } image.SetPixels(header.Width, header.Height, pixels); } }
/// <summary> /// Reads the scanlines. /// </summary> /// <param name="dataStream">The data stream.</param> /// <param name="pixels">The pixels.</param> /// <param name="colorReader">The color reader.</param> /// <param name="colorTypeInformation">The color type information.</param> /// <param name="header">The header.</param> private void ReadScanlines(MemoryStream dataStream, Color[] pixels, IColorReader colorReader, ColorTypeInformation colorTypeInformation, Header header) { dataStream.Seek(0, SeekOrigin.Begin); var ScanlineLength = CalculateScanlineLength(colorTypeInformation, header); var ScanlineStep = CalculateScanlineStep(colorTypeInformation, header); byte[] LastScanline = new byte[ScanlineLength]; byte[] CurrentScanline = new byte[ScanlineLength]; int Filter = 0, Column = -1, Row = 0; using (InflateStream CompressedStream = new InflateStream(dataStream)) { int ReadByte; while ((ReadByte = CompressedStream.ReadByte()) >= 0) { if (Column == -1) { Filter = ReadByte; ++Column; } else { CurrentScanline[Column] = (byte)ReadByte; byte a; byte b; byte c; if (Column >= ScanlineStep) { a = CurrentScanline[Column - ScanlineStep]; c = LastScanline[Column - ScanlineStep]; } else { a = 0; c = 0; } b = LastScanline[Column]; switch (Filter) { case 1: CurrentScanline[Column] = (byte)(CurrentScanline[Column] + a); break; case 2: CurrentScanline[Column] = (byte)(CurrentScanline[Column] + b); break; case 3: CurrentScanline[Column] = (byte)(CurrentScanline[Column] + (byte)((a + b) / 2)); break; case 4: CurrentScanline[Column] = (byte)(CurrentScanline[Column] + PaethPredicator(a, b, c)); break; } ++Column; if (Column == ScanlineLength) { colorReader.ReadScanline(CurrentScanline, pixels, header, Row); ++Row; Column = -1; var Holder = CurrentScanline; CurrentScanline = LastScanline; LastScanline = Holder; } } } } //dataStream.Seek(0, SeekOrigin.Begin); //var ScanlineLength = CalculateScanlineLength(colorTypeInformation, header); //var ScanlineStep = CalculateScanlineStep(colorTypeInformation, header); //byte[] LastScanline = new byte[ScanlineLength]; //byte[] CurrentScanline = new byte[ScanlineLength]; //using (InflateStream CompressedStream = new InflateStream(dataStream)) //{ // using (MemoryStream DecompressedStream = new MemoryStream()) // { // CompressedStream.CopyTo(DecompressedStream); // DecompressedStream.Flush(); // byte[] DecompressedArray = DecompressedStream.ToArray(); // for (int y = 0, Column = 0; y < header.Height; ++y, Column += (ScanlineLength + 1)) // { // Array.Copy(DecompressedArray, Column + 1, CurrentScanline, 0, ScanlineLength); // if (DecompressedArray[Column] < 0) // break; // byte[] Result = Filters[(FilterType)DecompressedArray[Column]].Decode(CurrentScanline, LastScanline, ScanlineStep); // colorReader.ReadScanline(Result, pixels, header, y); // Array.Copy(CurrentScanline, LastScanline, ScanlineLength); // } // } //} }
private void ReadScanlines(MemoryStream dataStream, byte[] pixels, IColorReader colorReader, PngColorTypeInformation colorTypeInformation) { // Read the zlib header : http://tools.ietf.org/html/rfc1950 // CMF(Compression Method and flags) // This byte is divided into a 4 - bit compression method and a // 4-bit information field depending on the compression method. // bits 0 to 3 CM Compression method // bits 4 to 7 CINFO Compression info // // 0 1 // +---+---+ // |CMF|FLG| // +---+---+ int cmf = dataStream.ReadByte(); int flag = dataStream.ReadByte(); //please note that position=2 int scanlineLength = CalculateScanlineLength(colorTypeInformation); int scanlineStep = CalculateScanlineStep(colorTypeInformation); byte[] lastScanline = new byte[scanlineLength]; byte[] currScanline = new byte[scanlineLength]; byte a = 0; byte b = 0; byte c = 0; int row = 0, filter = 0, column = -1; //using (InflaterInputStream compressedStream = new InflaterInputStream(dataStream)) //{ // int readByte = 0; // while ((readByte = compressedStream.ReadByte()) >= 0) // { // if (column == -1) // { // filter = readByte; // column++; // } // else // { // currScanline[column] = (byte)readByte; // if (column >= scanlineStep) // { // a = currScanline[column - scanlineStep]; // c = lastScanline[column - scanlineStep]; // } // else // { // a = 0; // c = 0; // } // b = lastScanline[column]; // if (filter == 1) // { // currScanline[column] = (byte)(currScanline[column] + a); // } // else if (filter == 2) // { // currScanline[column] = (byte)(currScanline[column] + b); // } // else if (filter == 3) // { // currScanline[column] = (byte)(currScanline[column] + (byte)Math.Floor((double)(a + b) / 2)); // } // else if (filter == 4) // { // currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c)); // } // column++; // if (column == scanlineLength) // { // colorReader.ReadScanline(currScanline, pixels, _header); // column = -1; // row++; // Extensions.Swap(ref currScanline, ref lastScanline); // } // } // } //} using (System.IO.Compression.DeflateStream compressedStream = new System.IO.Compression.DeflateStream( dataStream, System.IO.Compression.CompressionMode.Decompress, true)) //using (Ionic.Zlib.DeflateStream compressedStream = new Ionic.Zlib.DeflateStream(dataStream, Ionic.Zlib.CompressionMode.Decompress)) { int readByte = 0; //byte[] singleByte = new byte[1]; //compressedStream.Read(singleByte, 0, 1); while ((readByte = compressedStream.ReadByte()) >= 0) { if (column == -1) { filter = readByte; column++; } else { currScanline[column] = (byte)readByte; if (column >= scanlineStep) { a = currScanline[column - scanlineStep]; c = lastScanline[column - scanlineStep]; } else { a = 0; c = 0; } b = lastScanline[column]; if (filter == 1) { currScanline[column] = (byte)(currScanline[column] + a); } else if (filter == 2) { currScanline[column] = (byte)(currScanline[column] + b); } else if (filter == 3) { currScanline[column] = (byte)(currScanline[column] + (byte)Math.Floor((double)(a + b) / 2)); } else if (filter == 4) { currScanline[column] = (byte)(currScanline[column] + PaethPredicator(a, b, c)); } column++; if (column == scanlineLength) { colorReader.ReadScanline(currScanline, pixels, _header); column = -1; row++; // //Extensions.Swap(ref currScanline, ref lastScanline); var tmpA = currScanline; var tmpB = lastScanline; lastScanline = tmpA; currScanline = tmpB; } } } } }