diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 5a2e11266d..d9e0f1e08f 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -25,7 +25,7 @@ jobs:
sdk-preview: true
runtime: -x64
codecov: false
- - os: macos-latest
+ - os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
framework: net7.0
sdk: 7.0.x
sdk-preview: true
@@ -48,7 +48,7 @@ jobs:
sdk: 6.0.x
runtime: -x64
codecov: false
- - os: macos-latest
+ - os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
framework: net6.0
sdk: 6.0.x
runtime: -x64
@@ -67,7 +67,7 @@ jobs:
steps:
- name: Install libgdi+, which is required for tests running on ubuntu
- if: ${{ matrix.options.os == 'buildjet-4vcpu-ubuntu-2204-arm' }}
+ if: ${{ contains(matrix.options.os, 'ubuntu') }}
run: sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
- name: Git Config
@@ -108,18 +108,12 @@ jobs:
restore-keys: ${{ runner.os }}-nuget-
- name: DotNet Setup
- if: ${{ matrix.options.sdk-preview != true }}
- uses: actions/setup-dotnet@v3
- with:
- dotnet-version: |
- 6.0.x
-
- - name: DotNet Setup Preview
- if: ${{ matrix.options.sdk-preview == true }}
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: |
+ 8.0.x
7.0.x
+ 6.0.x
- name: DotNet Build
if: ${{ matrix.options.sdk-preview != true }}
@@ -152,7 +146,7 @@ jobs:
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit
- name: Export Failed Output
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: failure()
with:
name: actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip
diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml
index e551afbd6d..db9aca0b08 100644
--- a/.github/workflows/code-coverage.yml
+++ b/.github/workflows/code-coverage.yml
@@ -17,6 +17,9 @@ jobs:
runs-on: ${{matrix.options.os}}
steps:
+ - name: Install libgdi+, which is required for tests running on ubuntu
+ run: sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
+
- name: Git Config
shell: bash
run: |
@@ -55,9 +58,11 @@ jobs:
restore-keys: ${{ runner.os }}-nuget-
- name: DotNet Setup
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: |
+ 8.0.x
+ 7.0.x
6.0.x
- name: DotNet Build
diff --git a/Directory.Build.props b/Directory.Build.props
index 26b3cc5afc..c94d9cbc9c 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -21,9 +21,9 @@
-
+
- preview
+ 12.0
-
+
diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
index 6399e1193e..bc6eeedcbe 100644
--- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs
@@ -204,6 +204,17 @@ public void Issue1530_BadDescriptorDimensions(TestImageProvider
image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact);
}
+ // https://github.com/SixLabors/ImageSharp/issues/2758
+ [Theory]
+ [WithFile(TestImages.Gif.Issues.Issue2758, PixelTypes.Rgba32)]
+ public void Issue2758_BadDescriptorDimensions(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage();
+ image.DebugSaveMultiFrame(provider);
+ image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact);
+ }
+
// https://github.com/SixLabors/ImageSharp/issues/405
[Theory]
[WithFile(TestImages.Gif.Issues.BadAppExtLength, PixelTypes.Rgba32)]
@@ -296,15 +307,9 @@ public void Issue2012EmptyXmp(TestImageProvider provider)
public void Issue2012BadMinCode(TestImageProvider provider)
where TPixel : unmanaged, IPixel
{
- Exception ex = Record.Exception(
- () =>
- {
- using Image image = provider.GetImage();
- image.DebugSave(provider);
- });
-
- Assert.NotNull(ex);
- Assert.Contains("Gif Image does not contain a valid LZW minimum code.", ex.Message);
+ using Image image = provider.GetImage();
+ image.DebugSave(provider);
+ image.CompareToReferenceOutput(provider);
}
// https://bugzilla.mozilla.org/show_bug.cgi?id=55918
@@ -318,4 +323,27 @@ public void IssueDeferredClearCode(TestImageProvider provider)
image.DebugSave(provider);
image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider);
}
+
+ // https://github.com/SixLabors/ImageSharp/issues/2743
+ [Theory]
+ [WithFile(TestImages.Gif.Issues.BadMaxLzwBits, PixelTypes.Rgba32)]
+ public void IssueTooLargeLzwBits(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage();
+ image.DebugSaveMultiFrame(provider);
+ image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact);
+ }
+
+ // https://github.com/SixLabors/ImageSharp/issues/2859
+ [Theory]
+ [WithFile(TestImages.Gif.Issues.Issue2859_A, PixelTypes.Rgba32)]
+ [WithFile(TestImages.Gif.Issues.Issue2859_B, PixelTypes.Rgba32)]
+ public void Issue2859_LZWPixelStackOverflow(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage();
+ image.DebugSaveMultiFrame(provider);
+ image.CompareToReferenceOutputMultiFrame(provider, ImageComparer.Exact);
+ }
}
diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs
index fb4445cdac..b4fd87755c 100644
--- a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs
@@ -214,4 +214,24 @@ public void Identify_Frames(
Assert.Equal(frameDelay, gifFrameMetadata.FrameDelay);
Assert.Equal(disposalMethod, gifFrameMetadata.DisposalMethod);
}
+
+ [Theory]
+ [InlineData(TestImages.Gif.Issues.BadMaxLzwBits, 8)]
+ [InlineData(TestImages.Gif.Issues.Issue2012BadMinCode, 1)]
+ public void Identify_Frames_Bad_Lzw(string imagePath, int framesCount)
+ {
+ TestFile testFile = TestFile.Create(imagePath);
+ using MemoryStream stream = new(testFile.Bytes, false);
+
+ ImageInfo imageInfo = Image.Identify(stream);
+
+ Assert.NotNull(imageInfo);
+ GifMetadata gifMetadata = imageInfo.Metadata.GetGifMetadata();
+ Assert.NotNull(gifMetadata);
+
+ Assert.Equal(framesCount, imageInfo.FrameMetadataCollection.Count);
+ GifFrameMetadata gifFrameMetadata = imageInfo.FrameMetadataCollection[imageInfo.FrameMetadataCollection.Count - 1].GetGifMetadata();
+
+ Assert.NotNull(gifFrameMetadata);
+ }
}
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
index 1c203e7342..e68dd1f879 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
@@ -8,6 +8,7 @@
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.TestUtilities;
// ReSharper disable InconsistentNaming
@@ -425,6 +426,32 @@ public void EncodedStringTags_Read()
VerifyEncodedStrings(exif);
}
+ // https://github.com/SixLabors/ImageSharp/issues/2758
+ [Theory]
+ [WithFile(TestImages.Jpeg.Issues.Issue2758, PixelTypes.L8)]
+ public void Issue2758_DecodeWorks(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage(JpegDecoder.Instance);
+
+ Assert.Equal(59787, image.Width);
+ Assert.Equal(511, image.Height);
+
+ JpegMetadata meta = image.Metadata.GetJpegMetadata();
+
+ // Quality determination should be between 1-100.
+ Assert.Equal(15, meta.LuminanceQuality);
+ Assert.Equal(1, meta.ChrominanceQuality);
+
+ // We want to test the encoder to ensure the determined values can be encoded but not by encoding
+ // the full size image as it would be too slow.
+ // We will crop the image to a smaller size and then encode it.
+ image.Mutate(x => x.Crop(new(0, 0, 100, 100)));
+
+ using MemoryStream ms = new();
+ image.Save(ms, new JpegEncoder());
+ }
+
private static void VerifyEncodedStrings(ExifProfile exif)
{
Assert.NotNull(exif);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
index 2fe4282607..97be5d8383 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
@@ -67,11 +67,11 @@ private static bool SkipTest(ITestImageProvider provider)
public void ParseStream_BasicPropertiesAreCorrect()
{
JpegDecoderOptions options = new();
+ Configuration configuration = options.GeneralOptions.Configuration;
byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes;
using MemoryStream ms = new(bytes);
- using BufferedReadStream bufferedStream = new(Configuration.Default, ms);
using JpegDecoderCore decoder = new(options);
- using Image image = decoder.Decode(bufferedStream, cancellationToken: default);
+ using Image image = decoder.Decode(configuration, ms, cancellationToken: default);
// I don't know why these numbers are different. All I know is that the decoder works
// and spectral data is exactly correct also.
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
index 978978989e..a3fbe4018e 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
@@ -5,7 +5,6 @@
using System.Text;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
-using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
@@ -216,18 +215,17 @@ internal static bool CompareBlocks(Span a, Span b, float tolerance
internal static JpegDecoderCore ParseJpegStream(string testFileName, bool metaDataOnly = false)
{
byte[] bytes = TestFile.Create(testFileName).Bytes;
- using var ms = new MemoryStream(bytes);
- using var bufferedStream = new BufferedReadStream(Configuration.Default, ms);
-
- JpegDecoderOptions options = new();
- var decoder = new JpegDecoderCore(options);
+ using MemoryStream ms = new(bytes);
+ JpegDecoderOptions decoderOptions = new();
+ Configuration configuration = decoderOptions.GeneralOptions.Configuration;
+ JpegDecoderCore decoder = new(decoderOptions);
if (metaDataOnly)
{
- decoder.Identify(bufferedStream, cancellationToken: default);
+ decoder.Identify(configuration, ms, default);
}
else
{
- using Image image = decoder.Decode(bufferedStream, cancellationToken: default);
+ using Image image = decoder.Decode(configuration, ms, default);
}
return decoder;
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
index 8d4bc3f461..11af57e39f 100644
--- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
@@ -701,4 +701,14 @@ public void Decode_BadPalette(string file)
string path = Path.GetFullPath(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, file));
using Image image = Image.Load(path);
}
+
+ [Theory]
+ [WithFile(TestImages.Png.Issue2752, PixelTypes.Rgba32)]
+ public void CanDecodeJustOneFrame(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ DecoderOptions options = new() { MaxFrames = 1 };
+ using Image image = provider.GetImage(PngDecoder.Instance, options);
+ Assert.Equal(1, image.Frames.Count);
+ }
}
diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs
index acca49dcf4..c6751e2a66 100644
--- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs
@@ -497,6 +497,38 @@ public void Encode_Lossy_WorksWithTestPattern(TestImageProvider
image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f));
}
+ // https://github.com/SixLabors/ImageSharp/issues/2763
+ [Theory]
+ [WithFile(Lossy.Issue2763, PixelTypes.Rgba32)]
+ public void WebpDecoder_CanDecode_Issue2763(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ WebpEncoder encoder = new()
+ {
+ Quality = 84,
+ FileFormat = WebpFileFormatType.Lossless
+ };
+
+ using Image image = provider.GetImage(PngDecoder.Instance);
+ image.DebugSave(provider);
+ image.VerifyEncoder(provider, "webp", string.Empty, encoder);
+ }
+
+ // https://github.com/SixLabors/ImageSharp/issues/2801
+ [Theory]
+ [WithFile(Lossy.Issue2801, PixelTypes.Rgba32)]
+ public void WebpDecoder_CanDecode_Issue2801(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ WebpEncoder encoder = new()
+ {
+ Quality = 100
+ };
+
+ using Image image = provider.GetImage();
+ image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.TolerantPercentage(0.0994F));
+ }
+
public static void RunEncodeLossy_WithPeakImage()
{
TestImageProvider provider = TestImageProvider.File(TestImageLossyFullPath);
@@ -512,6 +544,44 @@ public static void RunEncodeLossy_WithPeakImage()
[Fact]
public void RunEncodeLossy_WithPeakImage_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.DisableHWIntrinsic);
+ [Theory]
+ [WithFile(TestPatternOpaque, PixelTypes.Rgba32)]
+ public void CanSave_NonSeekableStream(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage();
+ WebpEncoder encoder = new();
+
+ using MemoryStream seekable = new();
+ image.Save(seekable, encoder);
+
+ using MemoryStream memoryStream = new();
+ using NonSeekableStream nonSeekable = new(memoryStream);
+
+ image.Save(nonSeekable, encoder);
+
+ Assert.True(seekable.ToArray().SequenceEqual(memoryStream.ToArray()));
+ }
+
+ [Theory]
+ [WithFile(TestPatternOpaque, PixelTypes.Rgba32)]
+ public async Task CanSave_NonSeekableStream_Async(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using Image image = provider.GetImage();
+ WebpEncoder encoder = new();
+
+ await using MemoryStream seekable = new();
+ image.Save(seekable, encoder);
+
+ await using MemoryStream memoryStream = new();
+ await using NonSeekableStream nonSeekable = new(memoryStream);
+
+ await image.SaveAsync(nonSeekable, encoder);
+
+ Assert.True(seekable.ToArray().SequenceEqual(memoryStream.ToArray()));
+ }
+
private static ImageComparer GetComparer(int quality)
{
float tolerance = 0.01f; // ~1.0%
diff --git a/tests/ImageSharp.Tests/IO/ChunkedMemoryStreamTests.cs b/tests/ImageSharp.Tests/IO/ChunkedMemoryStreamTests.cs
index 1803cfddb9..390170cfef 100644
--- a/tests/ImageSharp.Tests/IO/ChunkedMemoryStreamTests.cs
+++ b/tests/ImageSharp.Tests/IO/ChunkedMemoryStreamTests.cs
@@ -13,6 +13,8 @@ namespace SixLabors.ImageSharp.Tests.IO;
///
public class ChunkedMemoryStreamTests
{
+ private readonly Random bufferFiller = new(123);
+
///
/// The default length in bytes of each buffer chunk when allocating large buffers.
///
@@ -30,7 +32,7 @@ public class ChunkedMemoryStreamTests
[Fact]
public void MemoryStream_GetPositionTest_Negative()
{
- using var ms = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream ms = new(this.allocator);
long iCurrentPos = ms.Position;
for (int i = -1; i > -6; i--)
{
@@ -42,7 +44,7 @@ public void MemoryStream_GetPositionTest_Negative()
[Fact]
public void MemoryStream_ReadTest_Negative()
{
- var ms2 = new ChunkedMemoryStream(this.allocator);
+ ChunkedMemoryStream ms2 = new(this.allocator);
Assert.Throws(() => ms2.Read(null, 0, 0));
Assert.Throws(() => ms2.Read(new byte[] { 1 }, -1, 0));
@@ -64,7 +66,7 @@ public void MemoryStream_ReadTest_Negative()
public void MemoryStream_ReadByteTest(int length)
{
using MemoryStream ms = this.CreateTestStream(length);
- using var cms = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream cms = new(this.allocator);
ms.CopyTo(cms);
cms.Position = 0;
@@ -85,7 +87,7 @@ public void MemoryStream_ReadByteTest(int length)
public void MemoryStream_ReadByteBufferTest(int length)
{
using MemoryStream ms = this.CreateTestStream(length);
- using var cms = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream cms = new(this.allocator);
ms.CopyTo(cms);
cms.Position = 0;
@@ -105,10 +107,11 @@ public void MemoryStream_ReadByteBufferTest(int length)
[InlineData(DefaultSmallChunkSize * 4)]
[InlineData((int)(DefaultSmallChunkSize * 5.5))]
[InlineData(DefaultSmallChunkSize * 16)]
+ [InlineData(DefaultSmallChunkSize * 32)]
public void MemoryStream_ReadByteBufferSpanTest(int length)
{
using MemoryStream ms = this.CreateTestStream(length);
- using var cms = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream cms = new(this.allocator);
ms.CopyTo(cms);
cms.Position = 0;
@@ -122,18 +125,24 @@ public void MemoryStream_ReadByteBufferSpanTest(int length)
}
}
- [Fact]
- public void MemoryStream_WriteToTests()
+ [Theory]
+ [InlineData(DefaultSmallChunkSize)]
+ [InlineData((int)(DefaultSmallChunkSize * 1.5))]
+ [InlineData(DefaultSmallChunkSize * 4)]
+ [InlineData((int)(DefaultSmallChunkSize * 5.5))]
+ [InlineData(DefaultSmallChunkSize * 16)]
+ [InlineData(DefaultSmallChunkSize * 32)]
+ public void MemoryStream_WriteToTests(int length)
{
- using (var ms2 = new ChunkedMemoryStream(this.allocator))
+ using (ChunkedMemoryStream ms2 = new(this.allocator))
{
byte[] bytArrRet;
- byte[] bytArr = new byte[] { byte.MinValue, byte.MaxValue, 1, 2, 3, 4, 5, 6, 128, 250 };
+ byte[] bytArr = this.CreateTestBuffer(length);
// [] Write to memoryStream, check the memoryStream
ms2.Write(bytArr, 0, bytArr.Length);
- using var readonlyStream = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream readonlyStream = new(this.allocator);
ms2.WriteTo(readonlyStream);
readonlyStream.Flush();
readonlyStream.Position = 0;
@@ -146,11 +155,11 @@ public void MemoryStream_WriteToTests()
}
// [] Write to memoryStream, check the memoryStream
- using (var ms2 = new ChunkedMemoryStream(this.allocator))
- using (var ms3 = new ChunkedMemoryStream(this.allocator))
+ using (ChunkedMemoryStream ms2 = new(this.allocator))
+ using (ChunkedMemoryStream ms3 = new(this.allocator))
{
byte[] bytArrRet;
- byte[] bytArr = new byte[] { byte.MinValue, byte.MaxValue, 1, 2, 3, 4, 5, 6, 128, 250 };
+ byte[] bytArr = this.CreateTestBuffer(length);
ms2.Write(bytArr, 0, bytArr.Length);
ms2.WriteTo(ms3);
@@ -164,21 +173,29 @@ public void MemoryStream_WriteToTests()
}
}
- [Fact]
- public void MemoryStream_WriteToSpanTests()
+ [Theory]
+ [InlineData(DefaultSmallChunkSize)]
+ [InlineData((int)(DefaultSmallChunkSize * 1.5))]
+ [InlineData(DefaultSmallChunkSize * 4)]
+ [InlineData((int)(DefaultSmallChunkSize * 5.5))]
+ [InlineData(DefaultSmallChunkSize * 16)]
+ [InlineData(DefaultSmallChunkSize * 32)]
+ public void MemoryStream_WriteToSpanTests(int length)
{
- using (var ms2 = new ChunkedMemoryStream(this.allocator))
+ using (ChunkedMemoryStream ms2 = new(this.allocator))
{
Span bytArrRet;
- Span bytArr = new byte[] { byte.MinValue, byte.MaxValue, 1, 2, 3, 4, 5, 6, 128, 250 };
+ Span bytArr = this.CreateTestBuffer(length);
// [] Write to memoryStream, check the memoryStream
ms2.Write(bytArr, 0, bytArr.Length);
- using var readonlyStream = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream readonlyStream = new(this.allocator);
ms2.WriteTo(readonlyStream);
+
readonlyStream.Flush();
readonlyStream.Position = 0;
+
bytArrRet = new byte[(int)readonlyStream.Length];
readonlyStream.Read(bytArrRet, 0, (int)readonlyStream.Length);
for (int i = 0; i < bytArr.Length; i++)
@@ -188,13 +205,14 @@ public void MemoryStream_WriteToSpanTests()
}
// [] Write to memoryStream, check the memoryStream
- using (var ms2 = new ChunkedMemoryStream(this.allocator))
- using (var ms3 = new ChunkedMemoryStream(this.allocator))
+ using (ChunkedMemoryStream ms2 = new(this.allocator))
+ using (ChunkedMemoryStream ms3 = new(this.allocator))
{
Span bytArrRet;
- Span bytArr = new byte[] { byte.MinValue, byte.MaxValue, 1, 2, 3, 4, 5, 6, 128, 250 };
+ Span bytArr = this.CreateTestBuffer(length);
ms2.Write(bytArr, 0, bytArr.Length);
+
ms2.WriteTo(ms3);
ms3.Position = 0;
bytArrRet = new byte[(int)ms3.Length];
@@ -209,37 +227,35 @@ public void MemoryStream_WriteToSpanTests()
[Fact]
public void MemoryStream_WriteByteTests()
{
- using (var ms2 = new ChunkedMemoryStream(this.allocator))
- {
- byte[] bytArrRet;
- byte[] bytArr = new byte[] { byte.MinValue, byte.MaxValue, 1, 2, 3, 4, 5, 6, 128, 250 };
+ using ChunkedMemoryStream ms2 = new(this.allocator);
+ byte[] bytArrRet;
+ byte[] bytArr = new byte[] { byte.MinValue, byte.MaxValue, 1, 2, 3, 4, 5, 6, 128, 250 };
- for (int i = 0; i < bytArr.Length; i++)
- {
- ms2.WriteByte(bytArr[i]);
- }
+ for (int i = 0; i < bytArr.Length; i++)
+ {
+ ms2.WriteByte(bytArr[i]);
+ }
- using var readonlyStream = new ChunkedMemoryStream(this.allocator);
- ms2.WriteTo(readonlyStream);
- readonlyStream.Flush();
- readonlyStream.Position = 0;
- bytArrRet = new byte[(int)readonlyStream.Length];
- readonlyStream.Read(bytArrRet, 0, (int)readonlyStream.Length);
- for (int i = 0; i < bytArr.Length; i++)
- {
- Assert.Equal(bytArr[i], bytArrRet[i]);
- }
+ using ChunkedMemoryStream readonlyStream = new(this.allocator);
+ ms2.WriteTo(readonlyStream);
+ readonlyStream.Flush();
+ readonlyStream.Position = 0;
+ bytArrRet = new byte[(int)readonlyStream.Length];
+ readonlyStream.Read(bytArrRet, 0, (int)readonlyStream.Length);
+ for (int i = 0; i < bytArr.Length; i++)
+ {
+ Assert.Equal(bytArr[i], bytArrRet[i]);
}
}
[Fact]
public void MemoryStream_WriteToTests_Negative()
{
- using var ms2 = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream ms2 = new(this.allocator);
Assert.Throws(() => ms2.WriteTo(null));
ms2.Write(new byte[] { 1 }, 0, 1);
- var readonlyStream = new MemoryStream(new byte[1028], false);
+ MemoryStream readonlyStream = new(new byte[1028], false);
Assert.Throws(() => ms2.WriteTo(readonlyStream));
readonlyStream.Dispose();
@@ -286,7 +302,7 @@ public void MemoryStream_CopyTo_Invalid()
[MemberData(nameof(CopyToData))]
public void CopyTo(Stream source, byte[] expected)
{
- using var destination = new ChunkedMemoryStream(this.allocator);
+ using ChunkedMemoryStream destination = new(this.allocator);
source.CopyTo(destination);
Assert.InRange(source.Position, source.Length, int.MaxValue); // Copying the data should have read to the end of the stream or stayed past the end.
Assert.Equal(expected, destination.ToArray());
@@ -297,16 +313,16 @@ public static IEnumerable GetAllTestImages()
IEnumerable allImageFiles = Directory.EnumerateFiles(TestEnvironment.InputImagesDirectoryFullPath, "*.*", SearchOption.AllDirectories)
.Where(s => !s.EndsWith("txt", StringComparison.OrdinalIgnoreCase));
- var result = new List();
+ List result = new();
foreach (string path in allImageFiles)
{
- result.Add(path.Substring(TestEnvironment.InputImagesDirectoryFullPath.Length));
+ result.Add(path[TestEnvironment.InputImagesDirectoryFullPath.Length..]);
}
return result;
}
- public static IEnumerable AllTestImages = GetAllTestImages();
+ public static IEnumerable AllTestImages { get; } = GetAllTestImages();
[Theory]
[WithFileCollection(nameof(AllTestImages), PixelTypes.Rgba32)]
@@ -334,40 +350,77 @@ public void DecoderIntegrationTest(TestImageProvider provider)
((TestImageProvider.FileProvider)provider).FilePath);
using FileStream fs = File.OpenRead(fullPath);
- using var nonSeekableStream = new NonSeekableStream(fs);
+ using NonSeekableStream nonSeekableStream = new(fs);
+
+ using Image actual = Image.Load(nonSeekableStream);
+
+ ImageComparer.Exact.VerifySimilarity(expected, actual);
+ expected.Dispose();
+ }
+
+ [Theory]
+ [WithFileCollection(nameof(AllTestImages), PixelTypes.Rgba32)]
+ public void EncoderIntegrationTest(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ if (!TestEnvironment.Is64BitProcess)
+ {
+ return;
+ }
+
+ Image expected;
+ try
+ {
+ expected = provider.GetImage();
+ }
+ catch
+ {
+ // The image is invalid
+ return;
+ }
- var actual = Image.Load(nonSeekableStream);
+ string fullPath = Path.Combine(
+ TestEnvironment.InputImagesDirectoryFullPath,
+ ((TestImageProvider.FileProvider)provider).FilePath);
+
+ using MemoryStream ms = new();
+ using NonSeekableStream nonSeekableStream = new(ms);
+ expected.SaveAsWebp(nonSeekableStream);
+
+ using Image actual = Image.Load(nonSeekableStream);
ImageComparer.Exact.VerifySimilarity(expected, actual);
+ expected.Dispose();
}
public static IEnumerable