private static byte[] ParseInterlaced(byte[] pureData, PngFileHeader fileHeader, int bytesPerPixel, int channelsPerColor, ColorReader reader) { PerfProfiler.ProfilerEventStart("PNG Parse Interlaced", "Loading"); // Combine interlaced pixels into one image here. var width = (int)fileHeader.Size.X; var height = (int)fileHeader.Size.Y; var combination = new byte[width * height * channelsPerColor]; var pixels = new byte[width * height * 4]; const int passes = 7; var readOffset = 0; var done = false; var data = new Span <byte>(pureData); for (var i = 0; i < passes; i++) { int columns = Adam7.ComputeColumns(width, i); if (columns == 0) { continue; } int scanlineLength = GetScanlineLengthInterlaced(columns, fileHeader, channelsPerColor) + 1; int length = scanlineLength - 1; int pixelsInLine = Adam7.ComputeBlockWidth(width, i); // Read scanlines in this pass. var previousScanline = Span <byte> .Empty; for (int row = Adam7.FirstRow[i]; row < height; row += Adam7.RowIncrement[i]) { // Early out if invalid pass. if (data.Length - readOffset < scanlineLength) { done = true; break; } Span <byte> scanLine = data.Slice(readOffset + 1, length); int filter = data[readOffset]; readOffset += scanlineLength; ApplyFilter(scanLine, previousScanline, filter, bytesPerPixel); // Dump the row into the combined image. Span <byte> convertedLine = ConvertBitArray(scanLine, fileHeader); for (var pixel = 0; pixel < pixelsInLine; pixel++) { int offset = row * bytesPerPixel * width + (Adam7.FirstColumn[i] + pixel * Adam7.ColumnIncrement[i]) * bytesPerPixel; int offsetSrc = pixel * bytesPerPixel; for (var p = 0; p < bytesPerPixel; p++) { combination[offset + p] = convertedLine[offsetSrc + p]; } } previousScanline = scanLine; } if (done) { break; } } // Read the combined image. int stride = width * bytesPerPixel; int scanlineCount = combination.Length / stride; for (var i = 0; i < scanlineCount; i++) { Span <byte> row = new Span <byte>(combination).Slice(stride * i, stride); reader(width, row, pixels, i); } PerfProfiler.ProfilerEventEnd("PNG Parse Interlaced", "Loading"); return(pixels); }