Skip to content

Commit 61da705

Browse files
Merge pull request #567 from carbon/memory-rc1
Expose Span methods on LoadPixelData and SavePixelData
2 parents 5012861 + 05aa089 commit 61da705

File tree

15 files changed

+177
-216
lines changed

15 files changed

+177
-216
lines changed

src/ImageSharp/Common/Extensions/ByteExtensions.cs

Lines changed: 0 additions & 55 deletions
This file was deleted.

src/ImageSharp/Common/Helpers/Guard.cs

Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Diagnostics;
7-
using System.Linq;
87

98
namespace SixLabors.ImageSharp
109
{
@@ -15,78 +14,62 @@ namespace SixLabors.ImageSharp
1514
internal static class Guard
1615
{
1716
/// <summary>
18-
/// Verifies, that the method parameter with specified object value is not null
19-
/// and throws an exception if it is found to be so.
17+
/// Ensures that the value is not null.
2018
/// </summary>
21-
/// <param name="target">The target object, which cannot be null.</param>
19+
/// <param name="value">The target object, which cannot be null.</param>
2220
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
23-
/// <param name="message">The error message, if any to add to the exception.</param>
24-
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception>
25-
public static void NotNull(object target, string parameterName, string message = "")
21+
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null</exception>
22+
public static void NotNull(object value, string parameterName)
2623
{
27-
if (target == null)
24+
if (value == null)
2825
{
29-
if (!string.IsNullOrWhiteSpace(message))
30-
{
31-
throw new ArgumentNullException(parameterName, message);
32-
}
33-
3426
throw new ArgumentNullException(parameterName);
3527
}
3628
}
3729

3830
/// <summary>
39-
/// Verifies, that the string method parameter with specified object value and message
40-
/// is not null, not empty and does not contain only blanks and throws an exception
41-
/// if the object is null.
31+
/// Ensures that the target value is not null, empty, or whitespace.
4232
/// </summary>
43-
/// <param name="target">The target string, which should be checked against being null or empty.</param>
33+
/// <param name="value">The target string, which should be checked against being null or empty.</param>
4434
/// <param name="parameterName">Name of the parameter.</param>
45-
/// <param name="message">The error message, if any to add to the exception.</param>
46-
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null.</exception>
47-
/// <exception cref="ArgumentException"><paramref name="target"/> is empty or contains only blanks.</exception>
48-
public static void NotNullOrEmpty(string target, string parameterName, string message = "")
35+
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
36+
/// <exception cref="ArgumentException"><paramref name="value"/> is empty or contains only blanks.</exception>
37+
public static void NotNullOrWhiteSpace(string value, string parameterName)
4938
{
50-
NotNull(target, parameterName, message);
51-
52-
if (string.IsNullOrWhiteSpace(target))
39+
if (value == null)
5340
{
54-
if (!string.IsNullOrWhiteSpace(message))
55-
{
56-
throw new ArgumentException(message, parameterName);
57-
}
41+
throw new ArgumentNullException(parameterName);
42+
}
5843

59-
throw new ArgumentException("Value cannot be null or empty and cannot contain only blanks.", parameterName);
44+
if (string.IsNullOrWhiteSpace(value))
45+
{
46+
throw new ArgumentException("Must not be empty or whitespace.", parameterName);
6047
}
6148
}
6249

6350
/// <summary>
64-
/// Verifies, that the enumeration is not null and not empty.
51+
/// Ensures that the enumeration is not null or empty.
6552
/// </summary>
66-
/// <typeparam name="T">The type of objects in the <paramref name="target"/></typeparam>
67-
/// <param name="target">The target enumeration, which should be checked against being null or empty.</param>
53+
/// <typeparam name="T">The type of objects in the <paramref name="value"/></typeparam>
54+
/// <param name="value">The target enumeration, which should be checked against being null or empty.</param>
6855
/// <param name="parameterName">Name of the parameter.</param>
69-
/// <param name="message">The error message, if any to add to the exception.</param>
70-
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null.</exception>
71-
/// <exception cref="ArgumentException"><paramref name="target"/> is empty.</exception>
72-
public static void NotNullOrEmpty<T>(IEnumerable<T> target, string parameterName, string message = "")
56+
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
57+
/// <exception cref="ArgumentException"><paramref name="value"/> is empty.</exception>
58+
public static void NotNullOrEmpty<T>(ICollection<T> value, string parameterName)
7359
{
74-
NotNull(target, parameterName, message);
75-
76-
if (!target.Any())
60+
if (value == null)
7761
{
78-
if (!string.IsNullOrWhiteSpace(message))
79-
{
80-
throw new ArgumentException(message, parameterName);
81-
}
62+
throw new ArgumentNullException(parameterName);
63+
}
8264

83-
throw new ArgumentException("Value cannot be empty.", parameterName);
65+
if (value.Count == 0)
66+
{
67+
throw new ArgumentException("Must not be empty.", parameterName);
8468
}
8569
}
8670

8771
/// <summary>
88-
/// Verifies that the specified value is less than a maximum value
89-
/// and throws an exception if it is not.
72+
/// Ensures that the specified value is less than a maximum value.
9073
/// </summary>
9174
/// <param name="value">The target value, which should be validated.</param>
9275
/// <param name="max">The maximum value.</param>
@@ -191,15 +174,9 @@ public static void MustBeBetweenOrEqualTo<TValue>(TValue value, TValue min, TVal
191174
/// Verifies, that the method parameter with specified target value is true
192175
/// and throws an exception if it is found to be so.
193176
/// </summary>
194-
/// <param name="target">
195-
/// The target value, which cannot be false.
196-
/// </param>
197-
/// <param name="parameterName">
198-
/// The name of the parameter that is to be checked.
199-
/// </param>
200-
/// <param name="message">
201-
/// The error message, if any to add to the exception.
202-
/// </param>
177+
/// <param name="target">The target value, which cannot be false.</param>
178+
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
179+
/// <param name="message">The error message, if any to add to the exception.</param>
203180
/// <exception cref="ArgumentException">
204181
/// <paramref name="target"/> is false
205182
/// </exception>

src/ImageSharp/Formats/Gif/GifDecoderCore.cs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ internal sealed class GifDecoderCore
3939
/// </summary>
4040
private IManagedByteBuffer globalColorTable;
4141

42-
/// <summary>
43-
/// The global color table length
44-
/// </summary>
45-
private int globalColorTableLength;
46-
4742
/// <summary>
4843
/// The area to restore.
4944
/// </summary>
@@ -333,8 +328,8 @@ private void ReadFrame<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPixel> p
333328
indices = this.configuration.MemoryManager.AllocateManagedByteBuffer(imageDescriptor.Width * imageDescriptor.Height, true);
334329

335330
this.ReadFrameIndices(imageDescriptor, indices.Span);
336-
IManagedByteBuffer colorTable = localColorTable ?? this.globalColorTable;
337-
this.ReadFrameColors(ref image, ref previousFrame, indices.Span, colorTable.Span, imageDescriptor);
331+
ReadOnlySpan<Rgb24> colorTable = MemoryMarshal.Cast<byte, Rgb24>((localColorTable ?? this.globalColorTable).Span);
332+
this.ReadFrameColors(ref image, ref previousFrame, indices.Span, colorTable, imageDescriptor);
338333

339334
// Skip any remaining blocks
340335
this.Skip(0);
@@ -370,7 +365,7 @@ private void ReadFrameIndices(in GifImageDescriptor imageDescriptor, Span<byte>
370365
/// <param name="indices">The indexed pixels.</param>
371366
/// <param name="colorTable">The color table containing the available colors.</param>
372367
/// <param name="descriptor">The <see cref="GifImageDescriptor"/></param>
373-
private void ReadFrameColors<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPixel> previousFrame, Span<byte> indices, Span<byte> colorTable, in GifImageDescriptor descriptor)
368+
private void ReadFrameColors<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPixel> previousFrame, Span<byte> indices, ReadOnlySpan<Rgb24> colorTable, in GifImageDescriptor descriptor)
374369
where TPixel : struct, IPixel<TPixel>
375370
{
376371
ref byte indicesRef = ref MemoryMarshal.GetReference(indices);
@@ -458,11 +453,8 @@ private void ReadFrameColors<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPi
458453
if (this.graphicsControlExtension.TransparencyFlag == false ||
459454
this.graphicsControlExtension.TransparencyIndex != index)
460455
{
461-
int indexOffset = index * 3;
462-
463456
ref TPixel pixel = ref Unsafe.Add(ref rowRef, x);
464-
rgba.Rgb = colorTable.GetRgb24(indexOffset);
465-
457+
rgba.Rgb = colorTable[index];
466458
pixel.PackFromRgba32(rgba);
467459
}
468460

@@ -534,12 +526,12 @@ private void ReadLogicalScreenDescriptorAndGlobalColorTable(Stream stream)
534526

535527
if (this.logicalScreenDescriptor.GlobalColorTableFlag)
536528
{
537-
this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
529+
int globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
538530

539-
this.globalColorTable = this.MemoryManager.AllocateManagedByteBuffer(this.globalColorTableLength, true);
531+
this.globalColorTable = this.MemoryManager.AllocateManagedByteBuffer(globalColorTableLength, true);
540532

541-
// Read the global color table from the stream
542-
stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength);
533+
// Read the global color table data from the stream
534+
stream.Read(this.globalColorTable.Array, 0, globalColorTableLength);
543535
}
544536
}
545537
}

src/ImageSharp/Formats/ImageFormatManager.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ public void AddImageFormat(IImageFormat format)
8585
/// <returns>The <see cref="IImageFormat"/> if found otherwise null</returns>
8686
public IImageFormat FindFormatByFileExtension(string extension)
8787
{
88+
Guard.NotNullOrWhiteSpace(extension, nameof(extension));
89+
90+
if (extension[0] == '.')
91+
{
92+
extension = extension.Substring(1);
93+
}
94+
8895
return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase));
8996
}
9097

src/ImageSharp/Formats/Png/Filters/NoneFilter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal static class NoneFilter
2020
/// <param name="scanline">The scanline to encode</param>
2121
/// <param name="result">The filtered scanline result.</param>
2222
[MethodImpl(MethodImplOptions.AggressiveInlining)]
23-
public static void Encode(Span<byte> scanline, Span<byte> result)
23+
public static void Encode(ReadOnlySpan<byte> scanline, Span<byte> result)
2424
{
2525
// Insert a byte before the data.
2626
result[0] = 0;

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ private void ProcessScanlineFromPalette<TPixel>(ReadOnlySpan<byte> defilteredSca
853853
where TPixel : struct, IPixel<TPixel>
854854
{
855855
ReadOnlySpan<byte> newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth);
856-
byte[] pal = this.palette;
856+
ReadOnlySpan<Rgb24> pal = MemoryMarshal.Cast<byte, Rgb24>(this.palette);
857857
var color = default(TPixel);
858858

859859
var rgba = default(Rgba32);
@@ -865,10 +865,9 @@ private void ProcessScanlineFromPalette<TPixel>(ReadOnlySpan<byte> defilteredSca
865865
for (int x = 0; x < this.header.Width; x++)
866866
{
867867
int index = newScanline[x];
868-
int pixelOffset = index * 3;
869868

870869
rgba.A = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
871-
rgba.Rgb = pal.GetRgb24(pixelOffset);
870+
rgba.Rgb = pal[index];
872871

873872
color.PackFromRgba32(rgba);
874873
row[x] = color;
@@ -881,9 +880,8 @@ private void ProcessScanlineFromPalette<TPixel>(ReadOnlySpan<byte> defilteredSca
881880
for (int x = 0; x < this.header.Width; x++)
882881
{
883882
int index = newScanline[x];
884-
int pixelOffset = index * 3;
885883

886-
rgba.Rgb = pal.GetRgb24(pixelOffset);
884+
rgba.Rgb = pal[index];
887885

888886
color.PackFromRgba32(rgba);
889887
row[x] = color;
@@ -946,6 +944,7 @@ private void ProcessInterlacedDefilteredScanline<TPixel>(ReadOnlySpan<byte> defi
946944

947945
ReadOnlySpan<byte> newScanline = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth);
948946
var rgba = default(Rgba32);
947+
Span<Rgb24> pal = MemoryMarshal.Cast<byte, Rgb24>(this.palette);
949948

950949
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
951950
{
@@ -954,10 +953,9 @@ private void ProcessInterlacedDefilteredScanline<TPixel>(ReadOnlySpan<byte> defi
954953
for (int x = pixelOffset, o = 0; x < this.header.Width; x += increment, o++)
955954
{
956955
int index = newScanline[o];
957-
int offset = index * 3;
958956

959957
rgba.A = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
960-
rgba.Rgb = this.palette.GetRgb24(offset);
958+
rgba.Rgb = pal[index];
961959

962960
color.PackFromRgba32(rgba);
963961
rowSpan[x] = color;
@@ -970,10 +968,8 @@ private void ProcessInterlacedDefilteredScanline<TPixel>(ReadOnlySpan<byte> defi
970968
for (int x = pixelOffset, o = 0; x < this.header.Width; x += increment, o++)
971969
{
972970
int index = newScanline[o];
973-
int offset = index * 3;
974-
975-
rgba.Rgb = this.palette.GetRgb24(offset);
976971

972+
rgba.Rgb = pal[index];
977973
color.PackFromRgba32(rgba);
978974
rowSpan[x] = color;
979975
}

0 commit comments

Comments
 (0)