Browse Source

Remove usage of GetSingleSpan() in tga encoder

af/octree-no-pixelmap
Brian Popow 6 years ago
parent
commit
ce385e8687
  1. 46
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

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

@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
if (this.compression is TgaCompression.RunLength) if (this.compression is TgaCompression.RunLength)
{ {
this.WriteRunLengthEndcodedImage(stream, image.Frames.RootFrame); this.WriteRunLengthEncodedImage(stream, image.Frames.RootFrame);
} }
else else
{ {
@ -150,19 +150,20 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// <typeparam name="TPixel">The pixel type.</typeparam> /// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="stream">The stream to write the image to.</param> /// <param name="stream">The stream to write the image to.</param>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
private void WriteRunLengthEndcodedImage<TPixel>(Stream stream, ImageFrame<TPixel> image) private void WriteRunLengthEncodedImage<TPixel>(Stream stream, ImageFrame<TPixel> image)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
Rgba32 color = default; Rgba32 color = default;
Buffer2D<TPixel> pixels = image.PixelBuffer; Buffer2D<TPixel> pixels = image.PixelBuffer;
Span<TPixel> pixelSpan = pixels.GetSingleSpan();
int totalPixels = image.Width * image.Height; int totalPixels = image.Width * image.Height;
int encodedPixels = 0; int encodedPixels = 0;
while (encodedPixels < totalPixels) 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); 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. // 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));
@ -203,27 +204,34 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// Finds consecutive pixels, which have the same value starting from the pixel span offset 0. /// Finds consecutive pixels, which have the same value starting from the pixel span offset 0.
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam> /// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="pixelSpan">The pixel span to search in.</param> /// <param name="pixels">The pixels of the image.</param>
/// <param name="xStart">X coordinate to start searching for the same pixels.</param>
/// <param name="yStart">Y coordinate to start searching for the same pixels.</param>
/// <returns>The number of equal pixels.</returns> /// <returns>The number of equal pixels.</returns>
private byte FindEqualPixels<TPixel>(Span<TPixel> pixelSpan) private byte FindEqualPixels<TPixel>(Buffer2D<TPixel> pixels, int xStart, int yStart)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
int idx = 0;
byte equalPixelCount = 0; byte equalPixelCount = 0;
while (equalPixelCount < 127 && idx < pixelSpan.Length - 1) for (int y = yStart; y < pixels.Height; y++)
{ {
TPixel currentPixel = pixelSpan[idx]; for (int x = xStart; x < pixels.Width - 1; x++)
TPixel nextPixel = pixelSpan[idx + 1];
if (currentPixel.Equals(nextPixel))
{ {
equalPixelCount++; TPixel currentPixel = pixels[x, y];
} TPixel nextPixel = pixels[x + 1, y];
else if (currentPixel.Equals(nextPixel))
{ {
return equalPixelCount; equalPixelCount++;
}
else
{
return equalPixelCount;
}
if (equalPixelCount >= 127)
{
break;
}
} }
idx++;
} }
return equalPixelCount; return equalPixelCount;

Loading…
Cancel
Save