Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CI/job_templates/test_drawing_libraries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ jobs:
inputs:
packageType: 'sdk'
version: '5.x'
# .NET 7.0 need to install only on x86
- ${{ if and(eq(parameters.framework, 'net70'), eq(parameters.architecture, '.x86')) }}:
- task: UseDotNet@2
displayName: 'Install .NET7 sdk'
inputs:
packageType: 'sdk'
version: '7.x'
env:
PROCESSOR_ARCHITECTURE: x86
- ${{ if ne(parameters.framework, 'net60') }}:
- task: DotNetCoreCLI@2
displayName: Execute ${{ parameters.OSPlatform }} ${{ parameters.framework}} ${{ parameters.architecture }} Tests
Expand Down
64 changes: 44 additions & 20 deletions CI/stage_templates/run_tests_on_pool.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,71 @@ stages:
- script: echo "Skip Unit tests"
- ${{ if eq(parameters.runUnitTests, true) }}:
- ${{ if eq(parameters.OSPlatform, 'Windows') }}:
# Windows .NET 472 x86 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net472x86
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'net472'
architecture: '.x86'
buildConfiguration: $(Configuration)
# Windows .NET 472 x64 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net472
name: UnitTest${{ parameters.OSPlatform }}net472x64
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'net472'
architecture: ''
buildConfiguration: $(Configuration)
# Windows .NET Core x64 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}netcore
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'netcoreapp3.1'
architecture: ''
buildConfiguration: $(Configuration)
# Windows .NET Core x86 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}netcorex86
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'netcoreapp3.1'
architecture: '.x86'
buildConfiguration: $(Configuration)
# Windows .NET 5.0 Tests
# Windows .NET Core x64 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}netcore
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'netcoreapp3.1'
architecture: ''
buildConfiguration: $(Configuration)
# Windows .NET Core x86 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}netcorex86
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'netcoreapp3.1'
architecture: '.x86'
buildConfiguration: $(Configuration)
# Windows .NET 6.0 x86 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net60x86
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'net60'
architecture: '.x86'
buildConfiguration: $(Configuration)
# Windows .NET 7.0 x86 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net70x86
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'net70'
architecture: '.x86'
buildConfiguration: $(Configuration)
# .NET 5.0 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net50
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'net50'
architecture: ''
buildConfiguration: $(Configuration)
# Windows .NET 6.0 Tests
# .NET 6.0 x64 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net60
OSPlatform: ${{ parameters.OSPlatform }}
framework: 'net60'
architecture: ''
buildConfiguration: $(Configuration)
# Windows .NET 7.0 Tests
# .NET 7.0 x64 Tests
- template: ../job_templates/test_drawing_libraries.yml
parameters:
name: UnitTest${{ parameters.OSPlatform }}net70
Expand Down
1 change: 1 addition & 0 deletions IronSoftware.Drawing/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
IronSoftware.Drawing.Common.Tests/Data/RenderedFromChrome.bmp filter=lfs diff=lfs merge=lfs -text
Git LFS file not shown
Original file line number Diff line number Diff line change
Expand Up @@ -866,5 +866,21 @@ public void LoadImage_TiffImage_ShouldLoadWithoutThumbnail()
bitmap.FrameCount.Should().Be(1);
}


[FactWithAutomaticDisplayName]
public void CastAnyBitmap_from_SixLabors()
{
//This test throw System.OutOfMemoryException in x86

var image = Image.Load(GetRelativeFilePath("RenderedFromChrome.bmp"));

var anyBitmap = (AnyBitmap)image;

image.Save("expected.bmp");
anyBitmap.SaveAs("result.bmp");

AssertLargeImageAreEqual("expected.bmp", "result.bmp", true);
}

}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.IO;
using System.Linq;
Expand All @@ -14,43 +15,74 @@ protected Compare(ITestOutputHelper output) : base(output)
{
}

protected static void AssertImageAreEqual(string expectedImagePath, string resultImagePath, bool isCleanAll = false)
protected static void AssertLargeImageAreEqual(string expectedImagePath, string resultImagePath, bool isCleanAll = false)
{
string assertName = "AssertImage.AreEqual";
using SixLabors.ImageSharp.Image<Rgba32> expectedImageSharp = SixLabors.ImageSharp.Image.Load<Rgba32>(expectedImagePath);
using SixLabors.ImageSharp.Image<Rgba32> actualImageSharp = SixLabors.ImageSharp.Image.Load<Rgba32>(resultImagePath);

var expected = AnyBitmap.FromFile(expectedImagePath);
var actual = AnyBitmap.FromFile(resultImagePath);
CleanCompareResultFile(expectedImagePath, resultImagePath, isCleanAll);

if (isCleanAll)
{
CleanResultFile(expectedImagePath);
}
expectedImageSharp.Mutate(x => x.Resize(100, 100));
actualImageSharp.Mutate(x => x.Resize(100, 100));

CleanResultFile(resultImagePath);
AssertImageAreEqual(expectedImageSharp, actualImageSharp);
}

//Test to see if we have the same size of image
if (expected.Width != actual.Width || expected.Height != actual.Height)
{
throw new AssertActualExpectedException($"Expected:<Height {expected.Height}, Width {expected.Width}>.", $"Actual:<Height {actual.Height},Width {actual.Width}>.", $"{assertName} failed.");
}
protected static void AssertImageAreEqual(string expectedImagePath, string resultImagePath, bool isCleanAll = false)
{
using var expected = AnyBitmap.FromFile(expectedImagePath);
using var actual = AnyBitmap.FromFile(resultImagePath);

//Convert each image to a byte array
byte[] btImageExpected = expected.ExportBytes();
byte[] btImageActual = expected.ExportBytes();
CleanCompareResultFile(expectedImagePath, resultImagePath, isCleanAll);

//Compute a hash for each image
var shaM = SHA256.Create();
byte[] hash1 = shaM.ComputeHash(btImageExpected);
byte[] hash2 = shaM.ComputeHash(btImageActual);
AssertImageAreEqual(expected, actual);
}

//Compare the hash values
for (int i = 0; i < hash1.Length && i < hash2.Length; i++)
protected static void AssertImageAreEqual(AnyBitmap expected, AnyBitmap actual)
{
try
{
if (hash1[i] != hash2[i])
string assertName = "AssertImage.AreEqual";

//Test to see if we have the same size of image
if (expected.Width != actual.Width || expected.Height != actual.Height)
{
throw new AssertActualExpectedException($"Expected:<hash value {hash1[i]}>.", $"Actual:<hash value {hash2[i]}>.", $"{assertName} failed.");
throw new AssertActualExpectedException($"Expected:<Height {expected.Height}, Width {expected.Width}>.", $"Actual:<Height {actual.Height},Width {actual.Width}>.", $"{assertName} failed.");
}

//Convert each image to a byte array
byte[] btImageExpected = expected.ExportBytes();
byte[] btImageActual = expected.ExportBytes();

//Compute a hash for each image
var shaM = SHA256.Create();
byte[] hash1 = shaM.ComputeHash(btImageExpected);
byte[] hash2 = shaM.ComputeHash(btImageActual);

//Compare the hash values
for (int i = 0; i < hash1.Length && i < hash2.Length; i++)
{
if (hash1[i] != hash2[i])
{
throw new AssertActualExpectedException($"Expected:<hash value {hash1[i]}>.", $"Actual:<hash value {hash2[i]}>.", $"{assertName} failed.");
}
}
}
finally
{
expected?.Dispose();
actual?.Dispose();
}
}

private static void CleanCompareResultFile(string expectedImagePath, string resultImagePath, bool isCleanAll)
{
if (isCleanAll)
{
CleanResultFile(expectedImagePath);
}

CleanResultFile(resultImagePath);
}

protected static void CleanResultFile(string filename)
Expand All @@ -60,6 +92,7 @@ protected static void CleanResultFile(string filename)
File.Delete(filename);
}
}

protected static void AssertStreamAreEqual(MemoryStream expected, MemoryStream actual)
{
string assertName = "AssertStream.AreEqual";
Expand Down
13 changes: 4 additions & 9 deletions IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public AnyBitmap Clone(Rectangle rectangle)
public byte[] ExportBytes(
ImageFormat format = ImageFormat.Default, int lossy = 100)
{
MemoryStream mem = new();
using MemoryStream mem = new();
ExportStream(mem, format, lossy);
byte[] byteArray = mem.ToArray();

Expand Down Expand Up @@ -202,13 +202,7 @@ public void ExportFile(
ImageFormat format = ImageFormat.Default,
int lossy = 100)
{
using (MemoryStream mem = new())
{
ExportStream(mem, format, lossy);
byte[] byteArray = mem.ToArray();

File.WriteAllBytes(file, byteArray);
}
SaveAs(file, format, lossy);
}

/// <summary>
Expand Down Expand Up @@ -346,7 +340,8 @@ public void SaveAs(string file)
/// <seealso cref="TrySaveAs(string)"/>
public void SaveAs(string file, ImageFormat format, int lossy = 100)
{
File.WriteAllBytes(file, ExportBytes(format, lossy));
using var fileStream = new FileStream(file, FileMode.Create);
ExportStream(fileStream, format, lossy);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion NuGet/IronSoftware.Drawing.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Supports:

For general support and technical inquiries, please email us at: support@ironsoftware.com</description>
<summary>IronSoftware.System.Drawing is an open-source solution for .NET developers to replace System.Drawing.Common with a universal and flexible library.</summary>
<releaseNotes>- Update SixLabors.ImageSharp &amp; SixLabors.ImageSharp.Drawing to address known vulnerabilities.</releaseNotes>
<releaseNotes>- Improves memory management when loading large image input</releaseNotes>
<copyright>Copyright © Iron Software 2022-2024</copyright>
<tags>Images, Bitmap, SkiaSharp, SixLabors, BitMiracle, Maui, SVG, TIFF, TIF, GIF, JPEG, PNG, Color, Rectangle, Drawing, C#, VB.NET, ASPX, create, render, generate, standard, netstandard2.0, core, netcore</tags>
<repository type="git" url="https://github.com/iron-software/IronSoftware.Drawing.Common" commit="$commit$" />
Expand Down