Browse Source

Merge branch 'sw/github-actions' of https://github.com/SixLabors/ImageSharp into sw/github-actions

af/merge-core
James Jackson-South 6 years ago
parent
commit
a2fff3d35a
  1. 10
      .gitattributes
  2. 34
      Directory.Build.props
  3. 2
      shared-infrastructure
  4. 10
      src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
  5. 16
      src/ImageSharp.Drawing/Processing/BrushApplicator.cs
  6. 68
      src/ImageSharp.Drawing/Processing/PathGradientBrush.cs
  7. 2
      src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor{TPixel}.cs
  8. 6
      src/ImageSharp/Common/Extensions/EncoderExtensions.cs
  9. 47
      src/ImageSharp/Common/Extensions/StreamExtensions.cs
  10. 20
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  11. 4
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  12. 8
      src/ImageSharp/Formats/Gif/LzwDecoder.cs
  13. 11
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs
  14. 2
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  15. 5
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  16. 4
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  17. 18
      src/ImageSharp/ImageSharp.csproj
  18. 16
      tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
  19. 5
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs
  20. 1
      tests/ImageSharp.Tests/TestImages.cs
  21. 2
      tests/Images/External
  22. 3
      tests/Images/Input/Jpg/issues/issue-1076-invalid-subsampling.jpg

10
.gitattributes

@ -64,13 +64,20 @@
# treat as binary
*.bmp binary
*.dll binary
*.eot binary
*.exe binary
*.gif binary
*.jpg binary
*.pdf binary
*.png binary
*.tga binary
*.ppt binary
*.pptx binary
*.ttf binary
*.snk binary
*.woff binary
*.woff2 binary
*.xls binary
*.xlsx binary
# diff as plain text
*.doc diff=astextplain
*.docx diff=astextplain
@ -78,6 +85,7 @@
*.pdf diff=astextplain
*.pptx diff=astextplain
*.rtf diff=astextplain
*.svg diff=astextplain
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text

34
Directory.Build.props

@ -29,10 +29,42 @@
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
</PropertyGroup>
<!--
https://apisof.net/
+===================+================+===================+==============================+======================+==========================+
| Target Framework | SUPPORTS_MATHF | SUPPORTS_HASHCODE | SUPPORTS_EXTENDED_INTRINSICS | SUPPORTS_SPAN_STREAM | SUPPORTS_ENCODING_STRING |
+===================+================+===================+==============================+======================+==========================+
| netcoreapp3.1 | Y | Y | Y | Y | Y |
| netcoreapp2.1 | Y | Y | Y | Y | Y |
| netcoreapp2.0 | Y | N | N | N | N |
| netstandard2.1 | Y | N | N | Y | Y |
| netstandard2.0 | N | N | N | N | N |
| netstandard1.3 | N | N | N | N | N |
| net472 | N | N | Y | N | N |
+===================+================+===================+==============================+======================+==========================+
-->
<!-- TODO: Include additional targets to TargetFrameworks -->
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472'">
<DefineConstants>$(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<!--TODO: Check what this is testing for and why does it fail?-->
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>

2
shared-infrastructure

@ -1 +1 @@
Subproject commit faf84e44ec90e8a42a7271bcd04fea76279efb08
Subproject commit c2e689abe9227209e6d5bc4bf56255d92b4a5d62

10
src/ImageSharp.Drawing/ImageSharp.Drawing.csproj

@ -8,18 +8,10 @@
<PackageId>SixLabors.ImageSharp.Drawing</PackageId>
<PackageTags>Image Draw Shape Path Font</PackageTags>
<RootNamespace>SixLabors.ImageSharp</RootNamespace>
<TargetFrameworks>netcoreapp2.1;netstandard1.3;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<!-- TODO: Include .NETSTANDARD2.1 when released-->
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcoreapp2')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>
<TargetFrameworks>netcoreapp2.1;netstandard2.0;netstandard1.3</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcoreapp2.1')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_HASHCODE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SixLabors.Fonts" />
<PackageReference Include="SixLabors.Shapes" />

16
src/ImageSharp.Drawing/Processing/BrushApplicator.cs

@ -90,19 +90,23 @@ namespace SixLabors.ImageSharp.Processing
{
Span<float> amountSpan = amountBuffer.Memory.Span;
Span<TPixel> overlaySpan = overlay.Memory.Span;
float blendPercentage = this.Options.BlendPercentage;
for (int i = 0; i < scanline.Length; i++)
if (blendPercentage < 1)
{
if (this.Options.BlendPercentage < 1)
for (int i = 0; i < scanline.Length; i++)
{
amountSpan[i] = scanline[i] * this.Options.BlendPercentage;
amountSpan[i] = scanline[i] * blendPercentage;
overlaySpan[i] = this[x + i, y];
}
else
}
else
{
for (int i = 0; i < scanline.Length; i++)
{
amountSpan[i] = scanline[i];
overlaySpan[i] = this[x + i, y];
}
overlaySpan[i] = this[x + i, y];
}
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);

68
src/ImageSharp.Drawing/Processing/PathGradientBrush.cs

@ -2,11 +2,13 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
using SixLabors.Primitives;
using SixLabors.Shapes;
@ -47,7 +49,7 @@ namespace SixLabors.ImageSharp.Processing
throw new ArgumentNullException(nameof(colors));
}
if (!colors.Any())
if (colors.Length == 0)
{
throw new ArgumentOutOfRangeException(
nameof(colors),
@ -99,7 +101,7 @@ namespace SixLabors.ImageSharp.Processing
throw new ArgumentNullException(nameof(colors));
}
if (!colors.Any())
if (colors.Length == 0)
{
throw new ArgumentOutOfRangeException(
nameof(colors),
@ -133,22 +135,19 @@ namespace SixLabors.ImageSharp.Processing
private readonly float length;
private readonly PointF[] buffer;
public Edge(Path path, Color startColor, Color endColor)
{
this.path = path;
Vector2[] points = path.LineSegments.SelectMany(s => s.Flatten()).Select(p => (Vector2)p).ToArray();
this.Start = points.First();
this.Start = points[0];
this.StartColor = (Vector4)startColor;
this.End = points.Last();
this.EndColor = (Vector4)endColor;
this.length = DistanceBetween(this.End, this.Start);
this.buffer = new PointF[this.path.MaxIntersections];
}
public PointF Start { get; }
@ -159,18 +158,38 @@ namespace SixLabors.ImageSharp.Processing
public Vector4 EndColor { get; }
public Intersection? FindIntersection(PointF start, PointF end)
public Intersection? FindIntersection(PointF start, PointF end, MemoryAllocator allocator)
{
int intersections = this.path.FindIntersections(start, end, this.buffer);
if (intersections == 0)
// TODO: The number of max intersections is upper bound to the number of nodes of the path.
// Normally these numbers would be small and could potentially be stackalloc rather than pooled.
// Investigate performance beifit of checking length and choosing approach.
using (IMemoryOwner<PointF> memory = allocator.Allocate<PointF>(this.path.MaxIntersections))
{
return null;
}
Span<PointF> buffer = memory.Memory.Span;
int intersections = this.path.FindIntersections(start, end, buffer);
if (intersections == 0)
{
return null;
}
buffer = buffer.Slice(0, intersections);
PointF minPoint = buffer[0];
var min = new Intersection(minPoint, ((Vector2)(minPoint - start)).LengthSquared());
for (int i = 1; i < buffer.Length; i++)
{
PointF point = buffer[i];
var current = new Intersection(point, ((Vector2)(point - start)).LengthSquared());
return this.buffer.Take(intersections)
.Select(p => new Intersection(point: p, distance: ((Vector2)(p - start)).LengthSquared()))
.Aggregate((min, current) => min.Distance > current.Distance ? current : min);
if (min.Distance > current.Distance)
{
min = current;
}
}
return min;
}
}
public Vector4 ColorAt(float distance)
@ -197,6 +216,10 @@ namespace SixLabors.ImageSharp.Processing
private readonly IList<Edge> edges;
private readonly TPixel centerPixel;
private readonly TPixel transparentPixel;
/// <summary>
/// Initializes a new instance of the <see cref="PathGradientBrushApplicator{TPixel}"/> class.
/// </summary>
@ -214,13 +237,15 @@ namespace SixLabors.ImageSharp.Processing
: base(configuration, options, source)
{
this.edges = edges;
PointF[] points = edges.Select(s => s.Start).ToArray();
this.center = points.Aggregate((p1, p2) => p1 + p2) / edges.Count;
this.centerColor = (Vector4)centerColor;
this.centerPixel = centerColor.ToPixel<TPixel>();
this.maxDistance = points.Select(p => (Vector2)(p - this.center)).Max(d => d.Length());
this.maxDistance = points.Select(p => (Vector2)(p - this.center)).Select(d => d.Length()).Max();
this.transparentPixel = Color.Transparent.ToPixel<TPixel>();
}
/// <inheritdoc />
@ -232,22 +257,20 @@ namespace SixLabors.ImageSharp.Processing
if (point == this.center)
{
return new Color(this.centerColor).ToPixel<TPixel>();
return this.centerPixel;
}
var direction = Vector2.Normalize(point - this.center);
PointF end = point + (PointF)(direction * this.maxDistance);
(Edge edge, Intersection? info) = this.FindIntersection(point, end);
if (!info.HasValue)
{
return Color.Transparent.ToPixel<TPixel>();
return this.transparentPixel;
}
PointF intersection = info.Value.Point;
Vector4 edgeColor = edge.ColorAt(intersection);
float length = DistanceBetween(intersection, this.center);
@ -263,9 +286,10 @@ namespace SixLabors.ImageSharp.Processing
{
(Edge edge, Intersection? info) closest = default;
MemoryAllocator allocator = this.Target.MemoryAllocator;
foreach (Edge edge in this.edges)
{
Intersection? intersection = edge.FindIntersection(start, end);
Intersection? intersection = edge.FindIntersection(start, end, allocator);
if (!intersection.HasValue)
{

2
src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor{TPixel}.cs

@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
source,
sourceRectangle))
{
amount.Memory.Span.Fill(1f);
amount.Memory.Span.Fill(1F);
ParallelHelper.IterateRows(
workingRect,

6
src/ImageSharp/Common/Extensions/EncoderExtensions.cs

@ -1,7 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
#if !NETCOREAPP2_1
#if !SUPPORTS_ENCODING_STRING
using System;
using System.Text;
@ -32,4 +32,4 @@ namespace SixLabors.ImageSharp
}
}
}
#endif
#endif

47
src/ImageSharp/Common/Extensions/StreamExtensions.cs

@ -4,7 +4,6 @@
using System;
using System.Buffers;
using System.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.Memory;
@ -15,7 +14,6 @@ namespace SixLabors.ImageSharp
/// </summary>
internal static class StreamExtensions
{
#if NETCOREAPP2_1
/// <summary>
/// Writes data from a stream into the provided buffer.
/// </summary>
@ -24,23 +22,18 @@ namespace SixLabors.ImageSharp
/// <param name="offset">The offset within the buffer to begin writing.</param>
/// <param name="count">The number of bytes to write to the stream.</param>
public static void Write(this Stream stream, Span<byte> buffer, int offset, int count)
{
stream.Write(buffer.Slice(offset, count));
}
=> stream.Write(buffer.Slice(offset, count));
/// <summary>
/// Reads data from a stream into the provided buffer.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="buffer">The buffer..</param>
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The offset within the buffer where the bytes are read into.</param>
/// <param name="count">The number of bytes, if available, to read.</param>
/// <returns>The actual number of bytes read.</returns>
public static int Read(this Stream stream, Span<byte> buffer, int offset, int count)
{
return stream.Read(buffer.Slice(offset, count));
}
#endif
=> stream.Read(buffer.Slice(offset, count));
/// <summary>
/// Skips the number of bytes in the given stream.
@ -75,17 +68,39 @@ namespace SixLabors.ImageSharp
}
public static void Read(this Stream stream, IManagedByteBuffer buffer)
{
stream.Read(buffer.Array, 0, buffer.Length());
}
=> stream.Read(buffer.Array, 0, buffer.Length());
public static void Write(this Stream stream, IManagedByteBuffer buffer)
=> stream.Write(buffer.Array, 0, buffer.Length());
#if !SUPPORTS_SPAN_STREAM
// This is a port of the CoreFX implementation and is MIT Licensed:
// https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L742
public static int Read(this Stream stream, Span<byte> buffer)
{
stream.Write(buffer.Array, 0, buffer.Length());
// This uses ArrayPool<byte>.Shared, rather than taking a MemoryAllocator,
// in order to match the signature of the framework method that exists in
// .NET Core.
byte[] sharedBuffer = ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
int numRead = stream.Read(sharedBuffer, 0, buffer.Length);
if ((uint)numRead > (uint)buffer.Length)
{
throw new IOException("Stream was too long.");
}
new Span<byte>(sharedBuffer, 0, numRead).CopyTo(buffer);
return numRead;
}
finally
{
ArrayPool<byte>.Shared.Return(sharedBuffer);
}
}
#if NET472 || NETSTANDARD1_3 || NETSTANDARD2_0
// This is a port of the CoreFX implementation and is MIT Licensed: https://github.com/dotnet/coreclr/blob/c4dca1072d15bdda64c754ad1ea474b1580fa554/src/System.Private.CoreLib/shared/System/IO/Stream.cs#L770
// This is a port of the CoreFX implementation and is MIT Licensed:
// https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L775
public static void Write(this Stream stream, ReadOnlySpan<byte> buffer)
{
// This uses ArrayPool<byte>.Shared, rather than taking a MemoryAllocator,

20
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -445,11 +445,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <param name="rowsWithUndefinedPixels">Keeps track of rows, which have undefined pixels.</param>
private void UncompressRle4(int w, Span<byte> buffer, Span<bool> undefinedPixels, Span<bool> rowsWithUndefinedPixels)
{
#if NETCOREAPP2_1
Span<byte> cmd = stackalloc byte[2];
#else
var cmd = new byte[2];
#endif
int count = 0;
while (count < buffer.Length)
@ -556,11 +552,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <param name="rowsWithUndefinedPixels">Keeps track of rows, which have undefined pixels.</param>
private void UncompressRle8(int w, Span<byte> buffer, Span<bool> undefinedPixels, Span<bool> rowsWithUndefinedPixels)
{
#if NETCOREAPP2_1
Span<byte> cmd = stackalloc byte[2];
#else
var cmd = new byte[2];
#endif
int count = 0;
while (count < buffer.Length)
@ -639,11 +631,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <param name="rowsWithUndefinedPixels">Keeps track of rows, which have undefined pixels.</param>
private void UncompressRle24(int w, Span<byte> buffer, Span<bool> undefinedPixels, Span<bool> rowsWithUndefinedPixels)
{
#if NETCOREAPP2_1
Span<byte> cmd = stackalloc byte[2];
#else
var cmd = new byte[2];
#endif
int uncompressedPixels = 0;
while (uncompressedPixels < buffer.Length)
@ -1213,11 +1201,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
private void ReadInfoHeader()
{
#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[BmpInfoHeader.MaxHeaderSize];
#else
var buffer = new byte[BmpInfoHeader.MaxHeaderSize];
#endif
// Read the header size.
this.stream.Read(buffer, 0, BmpInfoHeader.HeaderSizeSize);
@ -1339,11 +1323,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
private void ReadFileHeader()
{
#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[BmpFileHeader.Size];
#else
var buffer = new byte[BmpFileHeader.Size];
#endif
this.stream.Read(buffer, 0, BmpFileHeader.Size);
short fileTypeMarker = BinaryPrimitives.ReadInt16LittleEndian(buffer);

4
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -173,11 +173,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
reserved: 0,
offset: BmpFileHeader.Size + infoHeaderSize + colorPaletteSize);
#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[infoHeaderSize];
#else
var buffer = new byte[infoHeaderSize];
#endif
fileHeader.WriteTo(buffer);
stream.Write(buffer, 0, BmpFileHeader.Size);

8
src/ImageSharp/Formats/Gif/LzwDecoder.cs

@ -113,11 +113,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
Unsafe.Add(ref suffixRef, code) = (byte)code;
}
#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[255];
#else
var buffer = new byte[255];
#endif
while (xyz < length)
{
@ -227,11 +223,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// The <see cref="int"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#if NETCOREAPP2_1
private int ReadBlock(Span<byte> buffer)
#else
private int ReadBlock(byte[] buffer)
#endif
{
int bufferSize = this.stream.ReadByte();

11
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -22,11 +22,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
this.Frame = frame;
this.Id = id;
// Valid sampling factors are 1..2
if (horizontalFactor == 0
|| verticalFactor == 0
|| horizontalFactor > 2
|| verticalFactor > 2)
// Validate sampling factors.
if (horizontalFactor == 0 || verticalFactor == 0)
{
JpegThrowHelper.ThrowBadSampling();
}
@ -138,4 +135,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
this.SpectralBlocks = this.memoryAllocator.Allocate2D<Block8x8>(width, height, AllocationOptions.Clean);
}
}
}
}

2
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -764,7 +764,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
for (int i = 0; i < this.ComponentCount; i++)
{
byte hv = this.temp[index + 1];
int h = hv >> 4;
int h = (hv >> 4) & 15;
int v = hv & 15;
if (maxH < h)

5
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs

@ -565,11 +565,8 @@ namespace SixLabors.ImageSharp.Formats.Tga
{
this.currentStream = stream;
#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[TgaFileHeader.Size];
#else
var buffer = new byte[TgaFileHeader.Size];
#endif
this.currentStream.Read(buffer, 0, TgaFileHeader.Size);
this.fileHeader = TgaFileHeader.Parse(buffer);
this.metadata = new ImageMetadata();

4
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -97,11 +97,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
pixelDepth: (byte)this.bitsPerPixel.Value,
imageDescriptor: imageDescriptor);
#if NETCOREAPP2_1
Span<byte> buffer = stackalloc byte[TgaFileHeader.Size];
#else
byte[] buffer = new byte[TgaFileHeader.Size];
#endif
fileHeader.WriteTo(buffer);
stream.Write(buffer, 0, TgaFileHeader.Size);

18
src/ImageSharp/ImageSharp.csproj

@ -12,6 +12,7 @@
<TargetFrameworks>netcoreapp2.1;netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="$(skipFullFramework) != 'true'">$(TargetFrameworks);net472</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;netstandard2.0;netstandard1.3;net472</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@ -20,23 +21,6 @@
<RootNamespace>SixLabors.ImageSharp</RootNamespace>
</PropertyGroup>
<!-- TODO: Include .NETSTANDARD2.1 when released-->
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcoreapp2')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcoreapp2.1')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_HASHCODE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1' OR '$(TargetFramework)' == 'net472' ">
<DefineConstants>$(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Shared\*.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\shared-infrastructure\**\*.cs" />
</ItemGroup>

16
tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs

@ -433,5 +433,21 @@ namespace SixLabors.ImageSharp.Tests.Drawing
}
}
[Theory]
[WithBlankImages(200, 200, PixelTypes.Rgb24)]
public void BrushApplicatorIsThreadSafeIssue1044<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
provider.VerifyOperation(
TolerantComparer,
img =>
{
var brush = new PathGradientBrush(
new[] { new PointF(0, 0), new PointF(200, 0), new PointF(200, 200), new PointF(0, 200), new PointF(0, 0) },
new[] { Color.Red, Color.Yellow, Color.Green, Color.DarkCyan, Color.Red });
img.Mutate(m => m.Fill(brush));
}, false, false);
}
}
}

5
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs

@ -31,6 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
TestImages.Jpeg.Issues.InvalidAPP0721,
TestImages.Jpeg.Issues.ExifGetString750Load,
TestImages.Jpeg.Issues.ExifGetString750Transform,
TestImages.Jpeg.Issues.BadSubSampling1076,
// LibJpeg can open this despite the invalid density units.
TestImages.Jpeg.Issues.Fuzz.ArgumentOutOfRangeException825B,
@ -38,6 +39,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
// LibJpeg can open this despite incorrect colorspace metadata.
TestImages.Jpeg.Issues.IncorrectColorspace855,
// LibJpeg can open this despite the invalid subsampling units.
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824C,
// High depth images
TestImages.Jpeg.Baseline.Testorig12bit,
};
@ -71,7 +75,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
TestImages.Jpeg.Issues.Fuzz.NullReferenceException823,
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824A,
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824B,
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824C,
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824D,
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824E,
TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException824F,

1
tests/ImageSharp.Tests/TestImages.cs

@ -192,6 +192,7 @@ namespace SixLabors.ImageSharp.Tests
public const string IncorrectColorspace855 = "Jpg/issues/issue855-incorrect-colorspace.jpg";
public const string IncorrectResize1006 = "Jpg/issues/issue1006-incorrect-resize.jpg";
public const string ExifResize1049 = "Jpg/issues/issue1049-exif-resize.jpg";
public const string BadSubSampling1076 = "Jpg/issues/issue-1076-invalid-subsampling.jpg";
public static class Fuzz
{

2
tests/Images/External

@ -1 +1 @@
Subproject commit d8ea82085ac39a6aa6ca8e0806a9518d3a7d3337
Subproject commit fbba5e2a78aa479c0752dc0fd91ec25b4948704a

3
tests/Images/Input/Jpg/issues/issue-1076-invalid-subsampling.jpg

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1507746a6c37697cb985fc7427709fd68478ff7cbdfe20f6cfbe7257ed6c7ccd
size 39149
Loading…
Cancel
Save