From 28f3938de2c5845d88e05d516a216a0dd04baad9 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 9 Apr 2020 23:45:23 +0100 Subject: [PATCH 1/2] Improve accessability of Span methods. Fixes #1164 --- .../Advanced/AdvancedImageExtensions.cs | 78 ------------------- src/ImageSharp/ImageFrame{TPixel}.cs | 34 ++++++++ src/ImageSharp/Image{TPixel}.cs | 33 ++++++++ .../Advanced/AdvancedImageExtensionsTests.cs | 5 +- .../Drawing/DrawImageTests.cs | 3 +- .../Formats/Gif/GifDecoderTests.cs | 5 +- .../Formats/Tga/TgaTestUtils.cs | 4 +- .../ImageFrameCollectionTests.Generic.cs | 22 ++++-- .../ImageFrameCollectionTests.NonGeneric.cs | 6 +- .../Image/ImageTests.WrapMemory.cs | 10 ++- tests/ImageSharp.Tests/Image/ImageTests.cs | 9 ++- .../Transforms/AffineTransformTests.cs | 2 +- .../Processors/Transforms/ResizeTests.cs | 3 +- .../TestUtilities/TestImageExtensions.cs | 11 +-- .../TestUtilities/TestUtils.cs | 6 +- 15 files changed, 122 insertions(+), 109 deletions(-) diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 0273f02f5..a79733fec 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -78,84 +78,6 @@ namespace SixLabors.ImageSharp.Advanced where TPixel : unmanaged, IPixel => source?.Frames.RootFrame.GetPixelMemoryGroup() ?? throw new ArgumentNullException(nameof(source)); - /// - /// Gets the representation of the pixels as a in the source image's pixel format - /// stored in row major order, if the backing buffer is contiguous. - /// - /// The type of the pixel. - /// The source image. - /// The - /// Thrown when the backing buffer is discontiguous. - [Obsolete( - @"GetPixelSpan might fail, because the backing buffer could be discontiguous for large images. Use GetPixelMemoryGroup or GetPixelRowSpan instead!")] - public static Span GetPixelSpan(this ImageFrame source) - where TPixel : unmanaged, IPixel - { - Guard.NotNull(source, nameof(source)); - - IMemoryGroup mg = source.GetPixelMemoryGroup(); - if (mg.Count > 1) - { - throw new InvalidOperationException($"GetPixelSpan is invalid, since the backing buffer of this {source.Width}x{source.Height} sized image is discontiguous!"); - } - - return mg.Single().Span; - } - - /// - /// Gets the representation of the pixels as a of contiguous memory in the source image's pixel format - /// stored in row major order. - /// - /// The type of the pixel. - /// The source. - /// The - /// Thrown when the backing buffer is discontiguous. - [Obsolete( - @"GetPixelSpan might fail, because the backing buffer could be discontiguous for large images. Use GetPixelMemoryGroup or GetPixelRowSpan instead!")] - public static Span GetPixelSpan(this Image source) - where TPixel : unmanaged, IPixel - { - Guard.NotNull(source, nameof(source)); - - return source.Frames.RootFrame.GetPixelSpan(); - } - - /// - /// Gets the representation of the pixels as a of contiguous memory - /// at row beginning from the the first pixel on that row. - /// - /// The type of the pixel. - /// The source. - /// The row. - /// The - public static Span GetPixelRowSpan(this ImageFrame source, int rowIndex) - where TPixel : unmanaged, IPixel - { - Guard.NotNull(source, nameof(source)); - Guard.MustBeGreaterThanOrEqualTo(rowIndex, 0, nameof(rowIndex)); - Guard.MustBeLessThan(rowIndex, source.Height, nameof(rowIndex)); - - return source.PixelBuffer.GetRowSpan(rowIndex); - } - - /// - /// Gets the representation of the pixels as of of contiguous memory - /// at row beginning from the the first pixel on that row. - /// - /// The type of the pixel. - /// The source. - /// The row. - /// The - public static Span GetPixelRowSpan(this Image source, int rowIndex) - where TPixel : unmanaged, IPixel - { - Guard.NotNull(source, nameof(source)); - Guard.MustBeGreaterThanOrEqualTo(rowIndex, 0, nameof(rowIndex)); - Guard.MustBeLessThan(rowIndex, source.Height, nameof(rowIndex)); - - return source.Frames.RootFrame.PixelBuffer.GetRowSpan(rowIndex); - } - /// /// Gets the representation of the pixels as a of contiguous memory /// at row beginning from the the first pixel on that row. diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index a35443ec9..0c00349f2 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; @@ -166,6 +167,39 @@ namespace SixLabors.ImageSharp } } + /// + /// Gets the representation of the pixels as a of contiguous memory + /// at row beginning from the first pixel on that row. + /// + /// The row. + /// The + public Span GetPixelRowSpan(int rowIndex) + { + Guard.MustBeGreaterThanOrEqualTo(rowIndex, 0, nameof(rowIndex)); + Guard.MustBeLessThan(rowIndex, this.Height, nameof(rowIndex)); + + return this.PixelBuffer.GetRowSpan(rowIndex); + } + + /// + /// Gets the representation of the pixels as a in the source image's pixel format + /// stored in row major order, if the backing buffer is contiguous. + /// + /// The . + /// The . + public bool TryGetSinglePixelSpan(out Span span) + { + IMemoryGroup mg = this.GetPixelMemoryGroup(); + if (mg.Count > 1) + { + span = default; + return false; + } + + span = mg.Single().Span; + return true; + } + /// /// Gets a reference to the pixel at the specified position. /// diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 56f1f6b7b..20be772e2 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -163,6 +163,39 @@ namespace SixLabors.ImageSharp } } + /// + /// Gets the representation of the pixels as a of contiguous memory + /// at row beginning from the first pixel on that row. + /// + /// The row. + /// The + public Span GetPixelRowSpan(int rowIndex) + { + Guard.MustBeGreaterThanOrEqualTo(rowIndex, 0, nameof(rowIndex)); + Guard.MustBeLessThan(rowIndex, this.Height, nameof(rowIndex)); + + return this.PixelSource.PixelBuffer.GetRowSpan(rowIndex); + } + + /// + /// Gets the representation of the pixels as a in the source image's pixel format + /// stored in row major order, if the backing buffer is contiguous. + /// + /// The . + /// The . + public bool TryGetSinglePixelSpan(out Span span) + { + IMemoryGroup mg = this.GetPixelMemoryGroup(); + if (mg.Count > 1) + { + span = default; + return false; + } + + span = mg.Single().Span; + return true; + } + /// /// Clones the current image /// diff --git a/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs b/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs index dca124849..97731be94 100644 --- a/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs @@ -61,7 +61,10 @@ namespace SixLabors.ImageSharp.Tests.Advanced { using Image image0 = provider.GetImage(); var targetBuffer = new TPixel[image0.Width * image0.Height]; - image0.GetPixelSpan().CopyTo(targetBuffer); + + Assert.True(image0.TryGetSinglePixelSpan(out Span sourceBuffer)); + + sourceBuffer.CopyTo(targetBuffer); var managerOfExternalMemory = new TestMemoryManager(targetBuffer); diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs index c3bc2f2ae..d08d81899 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs @@ -128,7 +128,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing using (Image background = provider.GetImage()) using (var overlay = new Image(50, 50)) { - overlay.GetPixelSpan().Fill(Color.Black); + Assert.True(overlay.TryGetSinglePixelSpan(out Span overlaySpan)); + overlaySpan.Fill(Color.Black); background.Mutate(c => c.DrawImage(overlay, new Point(x, y), PixelColorBlendingMode.Normal, 1F)); diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index fa2899372..b3a99aa1c 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -164,7 +164,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif { ImageFrame first = kumin1.Frames[i]; ImageFrame second = kumin2.Frames[i]; - first.ComparePixelBufferTo(second.GetPixelSpan()); + + Assert.True(second.TryGetSinglePixelSpan(out Span secondSpan)); + + first.ComparePixelBufferTo(secondSpan); } } } diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs index c69cf2f20..48171a77d 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs @@ -9,6 +9,7 @@ using ImageMagick; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; +using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Tga { @@ -46,7 +47,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga { magickImage.AutoOrient(); var result = new Image(configuration, magickImage.Width, magickImage.Height); - Span resultPixels = result.GetPixelSpan(); + + Assert.True(result.TryGetSinglePixelSpan(out Span resultPixels)); using (IPixelCollection pixels = magickImage.GetPixelsUnsafe()) { diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs index 9ea6a305c..2b7c1e2c6 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs @@ -198,7 +198,9 @@ namespace SixLabors.ImageSharp.Tests using (Image cloned = img.Frames.CloneFrame(0)) { Assert.Equal(2, img.Frames.Count); - cloned.ComparePixelBufferTo(img.GetPixelSpan()); + Assert.True(img.TryGetSinglePixelSpan(out Span imgSpan)); + + cloned.ComparePixelBufferTo(imgSpan); } } } @@ -210,7 +212,8 @@ namespace SixLabors.ImageSharp.Tests { using (Image img = provider.GetImage()) { - var sourcePixelData = img.GetPixelSpan().ToArray(); + Assert.True(img.TryGetSinglePixelSpan(out Span imgSpan)); + TPixel[] sourcePixelData = imgSpan.ToArray(); img.Frames.AddFrame(new ImageFrame(Configuration.Default, 10, 10)); using (Image cloned = img.Frames.ExportFrame(0)) @@ -242,7 +245,8 @@ namespace SixLabors.ImageSharp.Tests [Fact] public void AddFrameFromPixelData() { - var pixelData = this.Image.Frames.RootFrame.GetPixelSpan().ToArray(); + Assert.True(this.Image.Frames.RootFrame.TryGetSinglePixelSpan(out Span imgSpan)); + var pixelData = imgSpan.ToArray(); this.Image.Frames.AddFrame(pixelData); Assert.Equal(2, this.Image.Frames.Count); } @@ -251,8 +255,10 @@ namespace SixLabors.ImageSharp.Tests public void AddFrame_clones_sourceFrame() { var otherFrame = new ImageFrame(Configuration.Default, 10, 10); - var addedFrame = this.Image.Frames.AddFrame(otherFrame); - addedFrame.ComparePixelBufferTo(otherFrame.GetPixelSpan()); + ImageFrame addedFrame = this.Image.Frames.AddFrame(otherFrame); + + Assert.True(otherFrame.TryGetSinglePixelSpan(out Span otherFrameSpan)); + addedFrame.ComparePixelBufferTo(otherFrameSpan); Assert.NotEqual(otherFrame, addedFrame); } @@ -260,8 +266,10 @@ namespace SixLabors.ImageSharp.Tests public void InsertFrame_clones_sourceFrame() { var otherFrame = new ImageFrame(Configuration.Default, 10, 10); - var addedFrame = this.Image.Frames.InsertFrame(0, otherFrame); - addedFrame.ComparePixelBufferTo(otherFrame.GetPixelSpan()); + ImageFrame addedFrame = this.Image.Frames.InsertFrame(0, otherFrame); + + Assert.True(otherFrame.TryGetSinglePixelSpan(out Span otherFrameSpan)); + addedFrame.ComparePixelBufferTo(otherFrameSpan); Assert.NotEqual(otherFrame, addedFrame); } diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs index 08e6f8e1f..a05b428e1 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs @@ -159,7 +159,8 @@ namespace SixLabors.ImageSharp.Tests var expectedClone = (Image)cloned; - expectedClone.ComparePixelBufferTo(img.GetPixelSpan()); + Assert.True(img.TryGetSinglePixelSpan(out Span imgSpan)); + expectedClone.ComparePixelBufferTo(imgSpan); } } } @@ -171,7 +172,8 @@ namespace SixLabors.ImageSharp.Tests { using (Image img = provider.GetImage()) { - var sourcePixelData = img.GetPixelSpan().ToArray(); + Assert.True(img.TryGetSinglePixelSpan(out Span imgSpan)); + var sourcePixelData = imgSpan.ToArray(); ImageFrameCollection nonGenericFrameCollection = img.Frames; diff --git a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs index 423309dfb..e0152558b 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs @@ -91,7 +91,8 @@ namespace SixLabors.ImageSharp.Tests using (var image = Image.WrapMemory(cfg, memory, 5, 5, metaData)) { - ref Rgba32 pixel0 = ref image.GetPixelSpan()[0]; + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + ref Rgba32 pixel0 = ref imageSpan[0]; Assert.True(Unsafe.AreSame(ref array[0], ref pixel0)); Assert.Equal(cfg, image.GetConfiguration()); @@ -118,7 +119,8 @@ namespace SixLabors.ImageSharp.Tests using (var image = Image.WrapMemory(memory, bmp.Width, bmp.Height)) { Assert.Equal(memory, image.GetRootFramePixelBuffer().GetSingleMemory()); - image.GetPixelSpan().Fill(bg); + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + imageSpan.Fill(bg); for (var i = 10; i < 20; i++) { image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg); @@ -153,8 +155,8 @@ namespace SixLabors.ImageSharp.Tests using (var image = Image.WrapMemory(memoryManager, bmp.Width, bmp.Height)) { Assert.Equal(memoryManager.Memory, image.GetRootFramePixelBuffer().GetSingleMemory()); - - image.GetPixelSpan().Fill(bg); + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + imageSpan.Fill(bg); for (var i = 10; i < 20; i++) { image.GetPixelRowSpan(i).Slice(10, 10).Fill(fg); diff --git a/tests/ImageSharp.Tests/Image/ImageTests.cs b/tests/ImageSharp.Tests/Image/ImageTests.cs index c99b75733..6bba8b15c 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.cs @@ -27,7 +27,8 @@ namespace SixLabors.ImageSharp.Tests { Assert.Equal(11, image.Width); Assert.Equal(23, image.Height); - Assert.Equal(11 * 23, image.GetPixelSpan().Length); + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + Assert.Equal(11 * 23, imageSpan.Length); image.ComparePixelBufferTo(default(Rgba32)); Assert.Equal(Configuration.Default, image.GetConfiguration()); @@ -43,7 +44,8 @@ namespace SixLabors.ImageSharp.Tests { Assert.Equal(11, image.Width); Assert.Equal(23, image.Height); - Assert.Equal(11 * 23, image.GetPixelSpan().Length); + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + Assert.Equal(11 * 23, imageSpan.Length); image.ComparePixelBufferTo(default(Rgba32)); Assert.Equal(configuration, image.GetConfiguration()); @@ -60,7 +62,8 @@ namespace SixLabors.ImageSharp.Tests { Assert.Equal(11, image.Width); Assert.Equal(23, image.Height); - Assert.Equal(11 * 23, image.GetPixelSpan().Length); + Assert.True(image.TryGetSinglePixelSpan(out Span imageSpan)); + Assert.Equal(11 * 23, imageSpan.Length); image.ComparePixelBufferTo(color); Assert.Equal(configuration, image.GetConfiguration()); diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs index cdc77d321..2de903d66 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs @@ -241,7 +241,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms private static void VerifyAllPixelsAreWhiteOrTransparent(Image image) where TPixel : unmanaged, IPixel { - Span data = image.Frames.RootFrame.GetPixelSpan(); + Assert.True(image.Frames.RootFrame.TryGetSinglePixelSpan(out Span data)); var white = new Rgb24(255, 255, 255); foreach (TPixel pixel in data) { diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 655bcfea4..3f323000a 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -244,7 +244,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { using (Image image0 = provider.GetImage()) { - var mmg = TestMemoryManager.CreateAsCopyOf(image0.GetPixelSpan()); + Assert.True(image0.TryGetSinglePixelSpan(out Span imageSpan)); + var mmg = TestMemoryManager.CreateAsCopyOf(imageSpan); using (var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height)) { diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 8ecb2ee6c..fbdb512de 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -417,8 +417,7 @@ namespace SixLabors.ImageSharp.Tests Span expectedPixels) where TPixel : unmanaged, IPixel { - Span actualPixels = image.GetPixelSpan(); - + Assert.True(image.TryGetSinglePixelSpan(out Span actualPixels)); CompareBuffers(expectedPixels, actualPixels); return image; @@ -478,7 +477,7 @@ namespace SixLabors.ImageSharp.Tests public static ImageFrame ComparePixelBufferTo(this ImageFrame imageFrame, TPixel expectedPixel) where TPixel : unmanaged, IPixel { - Span actualPixels = imageFrame.GetPixelSpan(); + Assert.True(imageFrame.TryGetSinglePixelSpan(out Span actualPixels)); for (int i = 0; i < actualPixels.Length; i++) { @@ -493,8 +492,7 @@ namespace SixLabors.ImageSharp.Tests Span expectedPixels) where TPixel : unmanaged, IPixel { - Span actual = image.GetPixelSpan(); - + Assert.True(image.TryGetSinglePixelSpan(out Span actual)); Assert.True(expectedPixels.Length == actual.Length, "Buffer sizes are not equal!"); for (int i = 0; i < expectedPixels.Length; i++) @@ -677,8 +675,7 @@ namespace SixLabors.ImageSharp.Tests { var image = new Image(buffer.Width, buffer.Height); - Span pixels = image.Frames.RootFrame.GetPixelSpan(); - + Assert.True(image.Frames.RootFrame.TryGetSinglePixelSpan(out Span pixels)); Span bufferSpan = buffer.GetSingleSpan(); for (int i = 0; i < bufferSpan.Length; i++) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs index 3a1fbd195..8af20a94f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs @@ -14,6 +14,7 @@ using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; +using Xunit; namespace SixLabors.ImageSharp.Tests { @@ -160,7 +161,7 @@ namespace SixLabors.ImageSharp.Tests ImageComparer comparer = null) where TPixel : unmanaged, IPixel { - comparer??= ImageComparer.Exact; + comparer ??= ImageComparer.Exact; using Image expected = provider.GetImage(); int width = expected.Width; expected.Mutate(process); @@ -277,7 +278,8 @@ namespace SixLabors.ImageSharp.Tests using (Image image0 = provider.GetImage()) { - var mmg = TestMemoryManager.CreateAsCopyOf(image0.GetPixelSpan()); + Assert.True(image0.TryGetSinglePixelSpan(out Span imageSpan)); + var mmg = TestMemoryManager.CreateAsCopyOf(imageSpan); using (var image1 = Image.WrapMemory(mmg.Memory, image0.Width, image0.Height)) { From 2ec776812f739f62c77384f008486b3d927ceab1 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 13 Apr 2020 14:54:45 +0100 Subject: [PATCH 2/2] Add argument docs and negative tests --- src/ImageSharp/ImageFrame{TPixel}.cs | 1 + src/ImageSharp/Image{TPixel}.cs | 1 + .../Image/LargeImageIntegrationTests.cs | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index 0c00349f2..0171f3d07 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -173,6 +173,7 @@ namespace SixLabors.ImageSharp /// /// The row. /// The + /// Thrown when row index is out of range. public Span GetPixelRowSpan(int rowIndex) { Guard.MustBeGreaterThanOrEqualTo(rowIndex, 0, nameof(rowIndex)); diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 20be772e2..f6173db97 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -169,6 +169,7 @@ namespace SixLabors.ImageSharp /// /// The row. /// The + /// Thrown when row index is out of range. public Span GetPixelRowSpan(int rowIndex) { Guard.MustBeGreaterThanOrEqualTo(rowIndex, 0, nameof(rowIndex)); diff --git a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs index c8a8baf1d..7352ddd7d 100644 --- a/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs +++ b/tests/ImageSharp.Tests/Image/LargeImageIntegrationTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using Xunit; @@ -17,5 +18,15 @@ namespace SixLabors.ImageSharp.Tests image.Mutate(c => c.Resize(1000, 1000)); image.DebugSave(provider); } + + [Theory] + [WithBasicTestPatternImages(width: 10, height: 10, PixelTypes.Rgba32)] + public void GetSingleSpan(TestImageProvider provider) + { + provider.LimitAllocatorBufferCapacity().InPixels(10); + using Image image = provider.GetImage(); + Assert.False(image.TryGetSinglePixelSpan(out Span imageSpan)); + Assert.False(image.Frames.RootFrame.TryGetSinglePixelSpan(out Span imageFrameSpan)); + } } }