Skip to content

Commit 73454f5

Browse files
authored
Merge branch 'master' into af/fix-Decode_IsCancellable
2 parents 5748d3d + adf56a4 commit 73454f5

File tree

75 files changed

+3207
-904
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+3207
-904
lines changed

.github/workflows/build-and-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ jobs:
1717
- os: ubuntu-latest
1818
framework: netcoreapp3.1
1919
runtime: -x64
20-
codecov: false
20+
codecov: true
2121
- os: windows-latest
2222
framework: netcoreapp3.1
2323
runtime: -x64
24-
codecov: true
24+
codecov: false
2525
- os: windows-latest
2626
framework: netcoreapp2.1
2727
runtime: -x64

.runsettings

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<RunSettings>
3+
<RunConfiguration>
4+
<!--Used in conjunction with ActiveIssueAttribute to skip tests with known issues-->
5+
<TestCaseFilter>category!=failing</TestCaseFilter>
6+
</RunConfiguration>
7+
</RunSettings>

Directory.Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<BaseArtifactsPath>$(MSBuildThisFileDirectory)artifacts/</BaseArtifactsPath>
1616
<BaseArtifactsPathSuffix>$(SixLaborsProjectCategory)/$(MSBuildProjectName)</BaseArtifactsPathSuffix>
1717
<RepositoryUrl Condition="'$(RepositoryUrl)' == ''">https://github.com/SixLabors/ImageSharp/</RepositoryUrl>
18+
<RunSettingsFilePath>$(MSBuildThisFileDirectory)/.runsettings</RunSettingsFilePath>
1819
</PropertyGroup>
1920

2021
<!-- Default settings that explicitly differ from the Sdk.props defaults -->
@@ -120,6 +121,7 @@
120121
https://api.nuget.org/v3/index.json;
121122
<!-- Contains RemoteExecutor. Taken from: https://github.com/dotnet/runtime/blob/master/NuGet.config -->
122123
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json;
124+
https://www.myget.org/F/coverlet-dev/api/v3/index.json;
123125
</RestoreSources>
124126
<SignAssembly>true</SignAssembly>
125127
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)shared-infrastructure/SixLabors.snk</AssemblyOriginatorKeyFile>

Directory.Build.targets

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,18 @@
1818
<!-- Package versions for package references across all projects -->
1919
<ItemGroup>
2020
<!--Global Dependencies-->
21-
<PackageReference Update="Microsoft.Net.Compilers.Toolset" PrivateAssets="All" Version="3.3.1" />
21+
<PackageReference Update="Microsoft.Net.Compilers.Toolset" PrivateAssets="All" Version="3.7.0" />
2222
<PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" />
2323
<PackageReference Update="StyleCop.Analyzers" PrivateAssets="All" Version="1.1.118" />
2424

2525
<!--Src Dependencies-->
2626
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
27-
<PackageReference Update="MinVer" PrivateAssets="All" Version="2.3.0" />
27+
<PackageReference Update="MinVer" PrivateAssets="All" Version="2.3.1" />
2828
<PackageReference Update="System.Buffers" Version="4.5.1" />
2929
<PackageReference Update="System.IO.Compression" Version="4.3.0" />
3030
<PackageReference Update="System.IO.UnmanagedMemoryStream" Version="4.3.0" />
3131
<PackageReference Update="System.Numerics.Vectors" Version="4.5.0" />
32-
<!--
33-
Do no update System.Memory as it currently breaks the CI build
34-
with FileNotFoundException for SixLabors.ImageSharp.Tests.dll.config
35-
-->
36-
<PackageReference Update="System.Memory" Version="4.5.3" />
32+
<PackageReference Update="System.Memory" Version="4.5.4" />
3733
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.7.1" />
3834
<PackageReference Update="System.Threading.Tasks.Parallel" Version="4.3.0" />
3935
<PackageReference Update="System.ValueTuple" Version="4.5.0" />

ImageSharp.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
99
.gitattributes = .gitattributes
1010
.gitignore = .gitignore
1111
.gitmodules = .gitmodules
12+
.runsettings = .runsettings
1213
ci-build.ps1 = ci-build.ps1
1314
ci-pack.ps1 = ci-pack.ps1
1415
ci-test.ps1 = ci-test.ps1

src/Directory.Build.targets

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,25 @@
2121
</PropertyGroup>
2222

2323
<!-- Workaround for running Coverlet with Determenistic builds -->
24-
<!-- https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/DeterministicBuild.md -->
24+
<PropertyGroup>
25+
<TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
26+
</PropertyGroup>
27+
<ItemGroup>
28+
<EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)"/>
29+
</ItemGroup>
30+
<ItemGroup>
31+
<SourceRoot Include="$(NuGetPackageRoot)" />
32+
</ItemGroup>
33+
2534
<Target Name="CoverletGetPathMap"
26-
DependsOnTargets="InitializeSourceRootMappedPaths"
27-
Returns="@(_LocalTopLevelSourceRoot)"
28-
Condition="'$(DeterministicSourcePaths)' == 'true'">
35+
DependsOnTargets="InitializeSourceRootMappedPaths"
36+
Returns="@(_LocalTopLevelSourceRoot)"
37+
Condition="'$(DeterministicSourcePaths)' == 'true'">
2938
<ItemGroup>
3039
<_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
3140
</ItemGroup>
3241
</Target>
33-
42+
3443
<ItemDefinitionGroup>
3544
<InternalsVisibleTo>
3645
<Visible>false</Visible>
@@ -62,7 +71,7 @@
6271
<!-- Empty target so that `dotnet test` will work on the solution -->
6372
<!-- https://github.com/Microsoft/vstest/issues/411 -->
6473
<Target Name="VSTest" Condition="'$(IsTestProject)' == 'true'"/>
65-
74+
6675
<ItemGroup>
6776
<!--Shared config files that have to exist at root level.-->
6877
<ConfigFilesToCopy Include="..\..\shared-infrastructure\.editorconfig;..\..\shared-infrastructure\.gitattributes" />
@@ -74,13 +83,13 @@
7483
SkipUnchangedFiles = "true"
7584
DestinationFolder="..\..\" />
7685
</Target>
77-
86+
7887
<!-- Allows regenerating T4-generated files at build time using MsBuild -->
7988
<!-- Enable on Windows OS to build all T4 templates. TODO: XPlat
8089
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets" />
8190
<PropertyGroup>
8291
<TransformOnBuild>true</TransformOnBuild>
8392
</PropertyGroup>
8493
-->
85-
94+
8695
</Project>
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using System.Buffers.Binary;
6+
using System.Runtime.CompilerServices;
7+
using System.Runtime.InteropServices;
8+
9+
namespace SixLabors.ImageSharp
10+
{
11+
/// <summary>
12+
/// Defines the contract for methods that allow the shuffling of pixel components.
13+
/// Used for shuffling on platforms that do not support Hardware Intrinsics.
14+
/// </summary>
15+
internal interface IComponentShuffle
16+
{
17+
/// <summary>
18+
/// Gets the shuffle control.
19+
/// </summary>
20+
byte Control { get; }
21+
22+
/// <summary>
23+
/// Shuffle 8-bit integers within 128-bit lanes in <paramref name="source"/>
24+
/// using the control and store the results in <paramref name="dest"/>.
25+
/// </summary>
26+
/// <param name="source">The source span of bytes.</param>
27+
/// <param name="dest">The destination span of bytes.</param>
28+
void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest);
29+
}
30+
31+
internal readonly struct DefaultShuffle4 : IComponentShuffle
32+
{
33+
public DefaultShuffle4(byte p3, byte p2, byte p1, byte p0)
34+
: this(SimdUtils.Shuffle.MmShuffle(p3, p2, p1, p0))
35+
{
36+
}
37+
38+
public DefaultShuffle4(byte control) => this.Control = control;
39+
40+
public byte Control { get; }
41+
42+
[MethodImpl(InliningOptions.ShortMethod)]
43+
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
44+
{
45+
ref byte sBase = ref MemoryMarshal.GetReference(source);
46+
ref byte dBase = ref MemoryMarshal.GetReference(dest);
47+
SimdUtils.Shuffle.InverseMmShuffle(
48+
this.Control,
49+
out int p3,
50+
out int p2,
51+
out int p1,
52+
out int p0);
53+
54+
for (int i = 0; i < source.Length; i += 4)
55+
{
56+
Unsafe.Add(ref dBase, i) = Unsafe.Add(ref sBase, p0 + i);
57+
Unsafe.Add(ref dBase, i + 1) = Unsafe.Add(ref sBase, p1 + i);
58+
Unsafe.Add(ref dBase, i + 2) = Unsafe.Add(ref sBase, p2 + i);
59+
Unsafe.Add(ref dBase, i + 3) = Unsafe.Add(ref sBase, p3 + i);
60+
}
61+
}
62+
}
63+
64+
internal readonly struct WXYZShuffle4 : IComponentShuffle
65+
{
66+
public byte Control => SimdUtils.Shuffle.MmShuffle(2, 1, 0, 3);
67+
68+
[MethodImpl(InliningOptions.ShortMethod)]
69+
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
70+
{
71+
ReadOnlySpan<uint> s = MemoryMarshal.Cast<byte, uint>(source);
72+
Span<uint> d = MemoryMarshal.Cast<byte, uint>(dest);
73+
ref uint sBase = ref MemoryMarshal.GetReference(s);
74+
ref uint dBase = ref MemoryMarshal.GetReference(d);
75+
76+
// The JIT can detect and optimize rotation idioms ROTL (Rotate Left)
77+
// and ROTR (Rotate Right) emitting efficient CPU instructions:
78+
// https://github.com/dotnet/coreclr/pull/1830
79+
for (int i = 0; i < s.Length; i++)
80+
{
81+
uint packed = Unsafe.Add(ref sBase, i);
82+
83+
// packed = [W Z Y X]
84+
// ROTL(8, packed) = [Z Y X W]
85+
Unsafe.Add(ref dBase, i) = (packed << 8) | (packed >> 24);
86+
}
87+
}
88+
}
89+
90+
internal readonly struct WZYXShuffle4 : IComponentShuffle
91+
{
92+
public byte Control => SimdUtils.Shuffle.MmShuffle(0, 1, 2, 3);
93+
94+
[MethodImpl(InliningOptions.ShortMethod)]
95+
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
96+
{
97+
ReadOnlySpan<uint> s = MemoryMarshal.Cast<byte, uint>(source);
98+
Span<uint> d = MemoryMarshal.Cast<byte, uint>(dest);
99+
ref uint sBase = ref MemoryMarshal.GetReference(s);
100+
ref uint dBase = ref MemoryMarshal.GetReference(d);
101+
102+
for (int i = 0; i < s.Length; i++)
103+
{
104+
uint packed = Unsafe.Add(ref sBase, i);
105+
106+
// packed = [W Z Y X]
107+
// REVERSE(packedArgb) = [X Y Z W]
108+
Unsafe.Add(ref dBase, i) = BinaryPrimitives.ReverseEndianness(packed);
109+
}
110+
}
111+
}
112+
113+
internal readonly struct YZWXShuffle4 : IComponentShuffle
114+
{
115+
public byte Control => SimdUtils.Shuffle.MmShuffle(0, 3, 2, 1);
116+
117+
[MethodImpl(InliningOptions.ShortMethod)]
118+
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
119+
{
120+
ReadOnlySpan<uint> s = MemoryMarshal.Cast<byte, uint>(source);
121+
Span<uint> d = MemoryMarshal.Cast<byte, uint>(dest);
122+
ref uint sBase = ref MemoryMarshal.GetReference(s);
123+
ref uint dBase = ref MemoryMarshal.GetReference(d);
124+
125+
for (int i = 0; i < s.Length; i++)
126+
{
127+
uint packed = Unsafe.Add(ref sBase, i);
128+
129+
// packed = [W Z Y X]
130+
// ROTR(8, packedArgb) = [Y Z W X]
131+
Unsafe.Add(ref dBase, i) = (packed >> 8) | (packed << 24);
132+
}
133+
}
134+
}
135+
136+
internal readonly struct ZYXWShuffle4 : IComponentShuffle
137+
{
138+
public byte Control => SimdUtils.Shuffle.MmShuffle(3, 0, 1, 2);
139+
140+
[MethodImpl(InliningOptions.ShortMethod)]
141+
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
142+
{
143+
ReadOnlySpan<uint> s = MemoryMarshal.Cast<byte, uint>(source);
144+
Span<uint> d = MemoryMarshal.Cast<byte, uint>(dest);
145+
ref uint sBase = ref MemoryMarshal.GetReference(s);
146+
ref uint dBase = ref MemoryMarshal.GetReference(d);
147+
148+
for (int i = 0; i < s.Length; i++)
149+
{
150+
uint packed = Unsafe.Add(ref sBase, i);
151+
152+
// packed = [W Z Y X]
153+
// tmp1 = [W 0 Y 0]
154+
// tmp2 = [0 Z 0 X]
155+
// tmp3=ROTL(16, tmp2) = [0 X 0 Z]
156+
// tmp1 + tmp3 = [W X Y Z]
157+
uint tmp1 = packed & 0xFF00FF00;
158+
uint tmp2 = packed & 0x00FF00FF;
159+
uint tmp3 = (tmp2 << 16) | (tmp2 >> 16);
160+
161+
Unsafe.Add(ref dBase, i) = tmp1 + tmp3;
162+
}
163+
}
164+
}
165+
}

src/ImageSharp/Common/Helpers/ImageMaths.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ public static int LeastCommonMultiple(int a, int b)
132132
return (a / GreatestCommonDivisor(a, b)) * b;
133133
}
134134

135+
/// <summary>
136+
/// Calculates <paramref name="x"/> % 2
137+
/// </summary>
138+
[MethodImpl(InliningOptions.ShortMethod)]
139+
public static int Modulo2(int x) => x & 1;
140+
135141
/// <summary>
136142
/// Calculates <paramref name="x"/> % 4
137143
/// </summary>

0 commit comments

Comments
 (0)