diff --git a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs index f3451a8e2d..5a022e9258 100644 --- a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Formats.Tga if (this.compression is TgaCompression.RunLength) { - this.WriteRunLengthEndcodedImage(stream, image.Frames.RootFrame); + this.WriteRunLengthEncodedImage(stream, image.Frames.RootFrame); } else { @@ -150,19 +150,20 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The pixel type. /// The stream to write the image to. /// The image to encode. - private void WriteRunLengthEndcodedImage(Stream stream, ImageFrame image) + private void WriteRunLengthEncodedImage(Stream stream, ImageFrame image) where TPixel : struct, IPixel { Rgba32 color = default; Buffer2D pixels = image.PixelBuffer; - Span pixelSpan = pixels.GetSingleSpan(); int totalPixels = image.Width * image.Height; int encodedPixels = 0; while (encodedPixels < totalPixels) { - TPixel currentPixel = pixelSpan[encodedPixels]; + int x = encodedPixels % pixels.Width; + int y = encodedPixels / pixels.Width; + TPixel currentPixel = pixels[x, y]; currentPixel.ToRgba32(ref color); - byte equalPixelCount = this.FindEqualPixels(pixelSpan.Slice(encodedPixels)); + byte equalPixelCount = this.FindEqualPixels(pixels, x, y); // Write the number of equal pixels, with the high bit set, indicating ist a compressed pixel run. stream.WriteByte((byte)(equalPixelCount | 128)); @@ -203,27 +204,34 @@ namespace SixLabors.ImageSharp.Formats.Tga /// Finds consecutive pixels, which have the same value starting from the pixel span offset 0. /// /// The pixel type. - /// The pixel span to search in. + /// The pixels of the image. + /// X coordinate to start searching for the same pixels. + /// Y coordinate to start searching for the same pixels. /// The number of equal pixels. - private byte FindEqualPixels(Span pixelSpan) + private byte FindEqualPixels(Buffer2D pixels, int xStart, int yStart) where TPixel : struct, IPixel { - int idx = 0; byte equalPixelCount = 0; - while (equalPixelCount < 127 && idx < pixelSpan.Length - 1) + for (int y = yStart; y < pixels.Height; y++) { - TPixel currentPixel = pixelSpan[idx]; - TPixel nextPixel = pixelSpan[idx + 1]; - if (currentPixel.Equals(nextPixel)) + for (int x = xStart; x < pixels.Width - 1; x++) { - equalPixelCount++; - } - else - { - return equalPixelCount; + TPixel currentPixel = pixels[x, y]; + TPixel nextPixel = pixels[x + 1, y]; + if (currentPixel.Equals(nextPixel)) + { + equalPixelCount++; + } + else + { + return equalPixelCount; + } + + if (equalPixelCount >= 127) + { + break; + } } - - idx++; } return equalPixelCount;