From 915b707fa4fe980cbb8160eb37f41f4102b0b19b Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Fri, 23 Mar 2018 10:23:08 -0700 Subject: [PATCH] Express readonly intent in Span parameters --- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 33 ++++++++++---------- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 17 ++++------ 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 2c7396f3ec..ffa3875057 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -349,13 +349,12 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// Converts a byte array to a new array where each value in the original array is represented by the specified number of bits. /// - /// The bytes to convert from. Cannot be null. + /// The bytes to convert from. Cannot be empty. /// The number of bytes per scanline /// The number of bits per value. - /// The resulting array. Is never null. - /// is null. + /// The resulting array. /// is less than or equals than zero. - private static Span ToArrayByBitsLength(Span source, int bytesPerScanline, int bits) + private static ReadOnlySpan ToArrayByBitsLength(ReadOnlySpan source, int bytesPerScanline, int bits) { Guard.MustBeGreaterThan(source.Length, 0, nameof(source)); Guard.MustBeGreaterThan(bits, 0, nameof(bits)); @@ -669,7 +668,7 @@ namespace SixLabors.ImageSharp.Formats.Png } Span rowSpan = image.GetPixelRowSpan(this.currentRow); - this.ProcessInterlacedDefilteredScanline(this.scanline.Array, rowSpan, Adam7FirstColumn[this.pass], Adam7ColumnIncrement[this.pass]); + this.ProcessInterlacedDefilteredScanline(this.scanline.Span, rowSpan, Adam7FirstColumn[this.pass], Adam7ColumnIncrement[this.pass]); this.SwapBuffers(); @@ -697,20 +696,20 @@ namespace SixLabors.ImageSharp.Formats.Png /// The pixel format. /// The de-filtered scanline /// The image - private void ProcessDefilteredScanline(Span defilteredScanline, ImageFrame pixels) + private void ProcessDefilteredScanline(ReadOnlySpan defilteredScanline, ImageFrame pixels) where TPixel : struct, IPixel { var color = default(TPixel); Span rowSpan = pixels.GetPixelRowSpan(this.currentRow); // Trim the first marker byte from the buffer - Span scanlineBuffer = defilteredScanline.Slice(1, defilteredScanline.Length - 1); + ReadOnlySpan scanlineBuffer = defilteredScanline.Slice(1, defilteredScanline.Length - 1); switch (this.pngColorType) { case PngColorType.Grayscale: int factor = 255 / ((int)Math.Pow(2, this.header.BitDepth) - 1); - Span newScanline1 = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth); + ReadOnlySpan newScanline1 = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth); for (int x = 0; x < this.header.Width; x++) { @@ -794,10 +793,10 @@ namespace SixLabors.ImageSharp.Formats.Png } else { - Span rgb24Span = scanlineBuffer.NonPortableCast(); + ReadOnlySpan rgb24Span = scanlineBuffer.NonPortableCast(); for (int x = 0; x < this.header.Width; x++) { - ref Rgb24 rgb24 = ref rgb24Span[x]; + ref readonly Rgb24 rgb24 = ref rgb24Span[x]; var rgba32 = default(Rgba32); rgba32.Rgb = rgb24; rgba32.A = (byte)(rgb24.Equals(this.rgb24Trans) ? 0 : 255); @@ -838,7 +837,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// The target buffer /// The target length [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void From16BitTo8Bit(Span source, Span target, int length) + private void From16BitTo8Bit(ReadOnlySpan source, Span target, int length) { for (int i = 0, j = 0; i < length; i++, j += 2) { @@ -879,10 +878,10 @@ namespace SixLabors.ImageSharp.Formats.Png /// The type of pixel we are expanding to /// The scanline /// Thecurrent output image row - private void ProcessScanlineFromPalette(Span defilteredScanline, Span row) + private void ProcessScanlineFromPalette(ReadOnlySpan defilteredScanline, Span row) where TPixel : struct, IPixel { - Span newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth); + ReadOnlySpan newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth); byte[] pal = this.palette; var color = default(TPixel); @@ -929,19 +928,19 @@ namespace SixLabors.ImageSharp.Formats.Png /// The current image row. /// The column start index. Always 0 for none interlaced images. /// The column increment. Always 1 for none interlaced images. - private void ProcessInterlacedDefilteredScanline(byte[] defilteredScanline, Span rowSpan, int pixelOffset = 0, int increment = 1) + private void ProcessInterlacedDefilteredScanline(ReadOnlySpan defilteredScanline, Span rowSpan, int pixelOffset = 0, int increment = 1) where TPixel : struct, IPixel { var color = default(TPixel); // Trim the first marker byte from the buffer - var scanlineBuffer = new Span(defilteredScanline, 1, defilteredScanline.Length - 1); + ReadOnlySpan scanlineBuffer = defilteredScanline.Slice(1, defilteredScanline.Length - 1); switch (this.pngColorType) { case PngColorType.Grayscale: int factor = 255 / ((int)Math.Pow(2, this.header.BitDepth) - 1); - Span newScanline1 = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth); + ReadOnlySpan newScanline1 = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth); for (int x = pixelOffset, o = 0; x < this.header.Width; x += increment, o++) { @@ -974,7 +973,7 @@ namespace SixLabors.ImageSharp.Formats.Png case PngColorType.Palette: - Span newScanline = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth); + ReadOnlySpan newScanline = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth); var rgba = default(Rgba32); if (this.paletteAlpha != null && this.paletteAlpha.Length > 0) diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index a0e09e911e..0cded1d80c 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -255,7 +255,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// The pixel format. /// The image row span. - private void CollectGrayscaleBytes(Span rowSpan) + private void CollectGrayscaleBytes(ReadOnlySpan rowSpan) where TPixel : struct, IPixel { byte[] rawScanlineArray = this.rawScanline.Array; @@ -290,7 +290,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// The pixel format. /// The row span. - private void CollecTPixelBytes(Span rowSpan) + private void CollecTPixelBytes(ReadOnlySpan rowSpan) where TPixel : struct, IPixel { if (this.bytesPerPixel == 4) @@ -311,7 +311,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// The row span. /// The row. /// The - private IManagedByteBuffer EncodePixelRow(Span rowSpan, int row) + private IManagedByteBuffer EncodePixelRow(ReadOnlySpan rowSpan, int row) where TPixel : struct, IPixel { switch (this.pngColorType) @@ -554,15 +554,14 @@ namespace SixLabors.ImageSharp.Formats.Png byte[] buffer; int bufferLength; - MemoryStream memoryStream = null; - try + + using (var memoryStream = new MemoryStream()) { - memoryStream = new MemoryStream(); using (var deflateStream = new ZlibDeflateStream(memoryStream, this.compressionLevel)) { for (int y = 0; y < this.height; y++) { - IManagedByteBuffer r = this.EncodePixelRow(pixels.GetPixelRowSpan(y), y); + IManagedByteBuffer r = this.EncodePixelRow(pixels.GetPixelRowSpan(y).AsReadOnlySpan(), y); deflateStream.Write(r.Array, 0, resultLength); IManagedByteBuffer temp = this.rawScanline; @@ -574,10 +573,6 @@ namespace SixLabors.ImageSharp.Formats.Png buffer = memoryStream.ToArray(); bufferLength = buffer.Length; } - finally - { - memoryStream?.Dispose(); - } // Store the chunks in repeated 64k blocks. // This reduces the memory load for decoding the image for many decoders.