Browse Source

Use DangerousGetRowSpan when run length encode image

pull/2197/head
Brian Popow 4 years ago
parent
commit
95ae124adb
  1. 28
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

28
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -117,7 +117,6 @@ namespace SixLabors.ImageSharp.Formats.Tga
fileHeader.WriteTo(buffer); fileHeader.WriteTo(buffer);
stream.Write(buffer, 0, TgaFileHeader.Size); stream.Write(buffer, 0, TgaFileHeader.Size);
if (this.compression is TgaCompression.RunLength) if (this.compression is TgaCompression.RunLength)
{ {
this.WriteRunLengthEncodedImage(stream, image.Frames.RootFrame); this.WriteRunLengthEncodedImage(stream, image.Frames.RootFrame);
@ -175,15 +174,14 @@ namespace SixLabors.ImageSharp.Formats.Tga
{ {
Rgba32 color = default; Rgba32 color = default;
Buffer2D<TPixel> pixels = image.PixelBuffer; Buffer2D<TPixel> pixels = image.PixelBuffer;
int totalPixels = image.Width * image.Height; for (int y = 0; y < image.Height; y++)
int encodedPixels = 0; {
while (encodedPixels < totalPixels) Span<TPixel> pixelRow = pixels.DangerousGetRowSpan(y);
for (int x = 0; x < image.Width;)
{ {
int x = encodedPixels % pixels.Width; TPixel currentPixel = pixelRow[x];
int y = encodedPixels / pixels.Width;
TPixel currentPixel = pixels[x, y];
currentPixel.ToRgba32(ref color); currentPixel.ToRgba32(ref color);
byte equalPixelCount = this.FindEqualPixels(pixels, x, y); byte equalPixelCount = this.FindEqualPixels(pixelRow, x);
// Write the number of equal pixels, with the high bit set, indicating ist a compressed pixel run. // Write the number of equal pixels, with the high bit set, indicating ist a compressed pixel run.
stream.WriteByte((byte)(equalPixelCount | 128)); stream.WriteByte((byte)(equalPixelCount | 128));
@ -218,7 +216,8 @@ namespace SixLabors.ImageSharp.Formats.Tga
break; break;
} }
encodedPixels += equalPixelCount + 1; x += equalPixelCount + 1;
}
} }
} }
@ -226,18 +225,17 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// Finds consecutive pixels which have the same value. /// Finds consecutive pixels which have the same value.
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam> /// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="pixels">The pixels of the image.</param> /// <param name="pixelRow">A pixel row of the image to encode.</param>
/// <param name="xStart">X coordinate to start searching for the same pixels.</param> /// <param name="xStart">X coordinate to start searching for the same pixels.</param>
/// <param name="yPos">Y coordinate to searching for the same pixels in only one scan line.</param>
/// <returns>The number of equal pixels.</returns> /// <returns>The number of equal pixels.</returns>
private byte FindEqualPixels<TPixel>(Buffer2D<TPixel> pixels, int xStart, int yPos) private byte FindEqualPixels<TPixel>(Span<TPixel> pixelRow, int xStart)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
byte equalPixelCount = 0; byte equalPixelCount = 0;
TPixel startPixel = pixels[xStart, yPos]; TPixel startPixel = pixelRow[xStart];
for (int x = xStart + 1; x < pixels.Width; x++) for (int x = xStart + 1; x < pixelRow.Length; x++)
{ {
TPixel nextPixel = pixels[x, yPos]; TPixel nextPixel = pixelRow[x];
if (startPixel.Equals(nextPixel)) if (startPixel.Equals(nextPixel))
{ {
equalPixelCount++; equalPixelCount++;

Loading…
Cancel
Save