diff --git a/.editorconfig b/.editorconfig index f39b26725..c3fb970c3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,16 @@ +# top-most EditorConfig file +root = true + [*.cs] indent_style = space indent_size = 4 +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_elsewhere = false:warning +csharp_style_var_when_type_is_apparent = false:warning +end_of_line = crlf +dotnet_sort_system_directives_first = true +dotnet_style_predefined_type_for_locals_parameters_members = true:warning +dotnet_style_predefined_type_for_member_access = true:warning +dotnet_style_qualification_for_field = true:warning +dotnet_style_qualification_for_method = true:warning +dotnet_style_qualification_for_property = true:warning \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6e291ec94..fb8af2320 100644 --- a/.gitignore +++ b/.gitignore @@ -211,5 +211,9 @@ artifacts/ #BenchmarkDotNet **/BenchmarkDotNet.Artifacts/ +# Build process +*.csproj.bak + #CodeCoverage -**/CodeCoverage/* \ No newline at end of file +**/CodeCoverage/* +docs/ diff --git a/.travis.yml b/.travis.yml index 172079df2..af8d4ad9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ matrix: - os: linux # Ubuntu 14.04 dist: trusty sudo: required - dotnet: 1.0.0-preview2-003121 + dotnet: 1.0.1 mono: latest # - os: osx # OSX 10.11 # osx_image: xcode7.3.1 @@ -20,8 +20,7 @@ branches: script: - dotnet restore - - dotnet build -c Release src/*/project.json - - dotnet test tests/ImageSharp.Tests/project.json -c Release -f "netcoreapp1.1" + - dotnet test tests/ImageSharp.Tests/ImageSharp.Tests.csproj -c Release -f "netcoreapp1.1" env: global: diff --git a/.vscode/tasks.json b/.vscode/tasks.json index aeae5c6ca..a1a55a389 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -8,14 +8,21 @@ "tasks": [ { "taskName": "build", - "args": [ "src/*/project.json", "-f", "netstandard1.1" ], + "args": [ "ImageSharp.sln" ], "isBuildCommand": true, "showOutput": "always", "problemMatcher": "$msCompile" }, + { + "taskName": "build benchmark", + "suppressTaskName": true, + "args": [ "build", "tests/ImageSharp.Benchmarks/project.json", "-f", "netcoreapp1.1", "-c", "Release" ], + "showOutput": "always", + "problemMatcher": "$msCompile" + }, { "taskName": "test", - "args": ["tests/ImageSharp.Tests/project.json", "-f", "netcoreapp1.1"], + "args": ["tests/ImageSharp.Tests/ImageSharp.Tests.csproj", "-c", "release", "-f", "netcoreapp1.1"], "isTestCommand": true, "showOutput": "always", "problemMatcher": "$msCompile" diff --git a/ImageSharp.ruleset b/ImageSharp.ruleset index 2daf6243a..3f10206fc 100644 --- a/ImageSharp.ruleset +++ b/ImageSharp.ruleset @@ -1,7 +1,11 @@  - + + + + + - + \ No newline at end of file diff --git a/ImageSharp.sln b/ImageSharp.sln index 503a5b860..9c729493b 100644 --- a/ImageSharp.sln +++ b/ImageSharp.sln @@ -1,14 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp", "src\ImageSharp\ImageSharp.xproj", "{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Tests", "tests\ImageSharp.Tests\ImageSharp.Tests.xproj", "{F836E8E6-B4D9-4208-8346-140C74678B91}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Benchmarks", "tests\ImageSharp.Benchmarks\ImageSharp.Benchmarks.xproj", "{299D8E18-102C-42DE-ADBF-79098EE706A8}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig @@ -31,114 +25,119 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{815C06 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{56801022-D71A-4FBE-BC5B-CBA08E2284EC}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Drawing", "src\ImageSharp.Drawing\ImageSharp.Drawing.xproj", "{2E33181E-6E28-4662-A801-E2E7DC206029}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{E919DF0B-2607-4462-8FC0-5C98FE50F8C9}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "build", "build\build.xproj", "{575A5002-DD9F-4335-AA47-1DD87FA13645}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Formats.Bmp", "src\ImageSharp.Formats.Bmp\ImageSharp.Formats.Bmp.xproj", "{C77661B9-F793-422E-8E27-AC60ECC5F215}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Formats.Gif", "src\ImageSharp.Formats.Gif\ImageSharp.Formats.Gif.xproj", "{27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Formats.Jpeg", "src\ImageSharp.Formats.Jpeg\ImageSharp.Formats.Jpeg.xproj", "{7213767C-0003-41CA-AB18-0223CFA7CE4B}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Formats.Png", "src\ImageSharp.Formats.Png\ImageSharp.Formats.Png.xproj", "{556ABDCF-ED93-4327-BE98-F6815F78B9B8}" -EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Processing", "src\ImageSharp.Processing\ImageSharp.Processing.xproj", "{A623CFE9-9D2B-4528-AD1F-2E834B061134}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E574A07-F879-4811-9C41-5CBDC6BAFDB7}" ProjectSection(SolutionItems) = preProject src\Shared\AssemblyInfo.Common.cs = src\Shared\AssemblyInfo.Common.cs src\Shared\stylecop.json = src\Shared\stylecop.json EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp.Sandbox46", "tests\ImageSharp.Sandbox46\ImageSharp.Sandbox46.csproj", "{96188137-5FA6-4924-AB6E-4EFF79C6E0BB}" - ProjectSection(ProjectDependencies) = postProject - {299D8E18-102C-42DE-ADBF-79098EE706A8} = {299D8E18-102C-42DE-ADBF-79098EE706A8} - {2E33181E-6E28-4662-A801-E2E7DC206029} = {2E33181E-6E28-4662-A801-E2E7DC206029} - {2AA31A1F-142C-43F4-8687-09ABCA4B3A26} = {2AA31A1F-142C-43F4-8687-09ABCA4B3A26} - {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F} = {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F} - {7213767C-0003-41CA-AB18-0223CFA7CE4B} = {7213767C-0003-41CA-AB18-0223CFA7CE4B} - {E5BD4F96-28A8-410C-8B63-1C5731948549} = {E5BD4F96-28A8-410C-8B63-1C5731948549} - {C77661B9-F793-422E-8E27-AC60ECC5F215} = {C77661B9-F793-422E-8E27-AC60ECC5F215} - {556ABDCF-ED93-4327-BE98-F6815F78B9B8} = {556ABDCF-ED93-4327-BE98-F6815F78B9B8} - {A623CFE9-9D2B-4528-AD1F-2E834B061134} = {A623CFE9-9D2B-4528-AD1F-2E834B061134} - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp", "src\ImageSharp\ImageSharp.csproj", "{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Drawing", "src\ImageSharp.Drawing\ImageSharp.Drawing.csproj", "{2E33181E-6E28-4662-A801-E2E7DC206029}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "build", "build\build.csproj", "{575A5002-DD9F-4335-AA47-1DD87FA13645}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Tests", "tests\ImageSharp.Tests\ImageSharp.Tests.csproj", "{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageSharp.Drawing.Paths", "src\ImageSharp.Drawing.Paths\ImageSharp.Drawing.Paths.xproj", "{E5BD4F96-28A8-410C-8B63-1C5731948549}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Benchmarks", "tests\ImageSharp.Benchmarks\ImageSharp.Benchmarks.csproj", "{2BF743D8-2A06-412D-96D7-F448F00C5EA5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp.Sandbox46", "tests\ImageSharp.Sandbox46\ImageSharp.Sandbox46.csproj", "{96188137-5FA6-4924-AB6E-4EFF79C6E0BB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x64.ActiveCfg = Debug|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x64.Build.0 = Debug|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x86.ActiveCfg = Debug|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x86.Build.0 = Debug|Any CPU {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|Any CPU.ActiveCfg = Release|Any CPU {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|Any CPU.Build.0 = Release|Any CPU - {F836E8E6-B4D9-4208-8346-140C74678B91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F836E8E6-B4D9-4208-8346-140C74678B91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F836E8E6-B4D9-4208-8346-140C74678B91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F836E8E6-B4D9-4208-8346-140C74678B91}.Release|Any CPU.Build.0 = Release|Any CPU - {299D8E18-102C-42DE-ADBF-79098EE706A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {299D8E18-102C-42DE-ADBF-79098EE706A8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {299D8E18-102C-42DE-ADBF-79098EE706A8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {299D8E18-102C-42DE-ADBF-79098EE706A8}.Release|Any CPU.Build.0 = Release|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x64.ActiveCfg = Release|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x64.Build.0 = Release|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x86.ActiveCfg = Release|Any CPU + {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x86.Build.0 = Release|Any CPU {2E33181E-6E28-4662-A801-E2E7DC206029}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E33181E-6E28-4662-A801-E2E7DC206029}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Debug|x64.ActiveCfg = Debug|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Debug|x64.Build.0 = Debug|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Debug|x86.ActiveCfg = Debug|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Debug|x86.Build.0 = Debug|Any CPU {2E33181E-6E28-4662-A801-E2E7DC206029}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E33181E-6E28-4662-A801-E2E7DC206029}.Release|Any CPU.Build.0 = Release|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Release|x64.ActiveCfg = Release|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Release|x64.Build.0 = Release|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Release|x86.ActiveCfg = Release|Any CPU + {2E33181E-6E28-4662-A801-E2E7DC206029}.Release|x86.Build.0 = Release|Any CPU {575A5002-DD9F-4335-AA47-1DD87FA13645}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {575A5002-DD9F-4335-AA47-1DD87FA13645}.Debug|Any CPU.Build.0 = Debug|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Debug|x64.ActiveCfg = Debug|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Debug|x64.Build.0 = Debug|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Debug|x86.ActiveCfg = Debug|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Debug|x86.Build.0 = Debug|Any CPU {575A5002-DD9F-4335-AA47-1DD87FA13645}.Release|Any CPU.ActiveCfg = Release|Any CPU {575A5002-DD9F-4335-AA47-1DD87FA13645}.Release|Any CPU.Build.0 = Release|Any CPU - {C77661B9-F793-422E-8E27-AC60ECC5F215}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C77661B9-F793-422E-8E27-AC60ECC5F215}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C77661B9-F793-422E-8E27-AC60ECC5F215}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C77661B9-F793-422E-8E27-AC60ECC5F215}.Release|Any CPU.Build.0 = Release|Any CPU - {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F}.Release|Any CPU.Build.0 = Release|Any CPU - {7213767C-0003-41CA-AB18-0223CFA7CE4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7213767C-0003-41CA-AB18-0223CFA7CE4B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7213767C-0003-41CA-AB18-0223CFA7CE4B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7213767C-0003-41CA-AB18-0223CFA7CE4B}.Release|Any CPU.Build.0 = Release|Any CPU - {556ABDCF-ED93-4327-BE98-F6815F78B9B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {556ABDCF-ED93-4327-BE98-F6815F78B9B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {556ABDCF-ED93-4327-BE98-F6815F78B9B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {556ABDCF-ED93-4327-BE98-F6815F78B9B8}.Release|Any CPU.Build.0 = Release|Any CPU - {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A623CFE9-9D2B-4528-AD1F-2E834B061134}.Release|Any CPU.Build.0 = Release|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Release|x64.ActiveCfg = Release|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Release|x64.Build.0 = Release|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Release|x86.ActiveCfg = Release|Any CPU + {575A5002-DD9F-4335-AA47-1DD87FA13645}.Release|x86.Build.0 = Release|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x64.ActiveCfg = Debug|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x64.Build.0 = Debug|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x86.ActiveCfg = Debug|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x86.Build.0 = Debug|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|Any CPU.Build.0 = Release|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x64.ActiveCfg = Release|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x64.Build.0 = Release|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x86.ActiveCfg = Release|Any CPU + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x86.Build.0 = Release|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x64.Build.0 = Debug|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x86.Build.0 = Debug|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|Any CPU.Build.0 = Release|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x64.ActiveCfg = Release|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x64.Build.0 = Release|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x86.ActiveCfg = Release|Any CPU + {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x86.Build.0 = Release|Any CPU {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|x64.ActiveCfg = Debug|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|x64.Build.0 = Debug|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Debug|x86.Build.0 = Debug|Any CPU {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|Any CPU.Build.0 = Release|Any CPU - {E5BD4F96-28A8-410C-8B63-1C5731948549}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E5BD4F96-28A8-410C-8B63-1C5731948549}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E5BD4F96-28A8-410C-8B63-1C5731948549}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E5BD4F96-28A8-410C-8B63-1C5731948549}.Release|Any CPU.Build.0 = Release|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|x64.ActiveCfg = Release|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|x64.Build.0 = Release|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|x86.ActiveCfg = Release|Any CPU + {96188137-5FA6-4924-AB6E-4EFF79C6E0BB}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {9E574A07-F879-4811-9C41-5CBDC6BAFDB7} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} {2AA31A1F-142C-43F4-8687-09ABCA4B3A26} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} - {F836E8E6-B4D9-4208-8346-140C74678B91} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} - {299D8E18-102C-42DE-ADBF-79098EE706A8} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} {2E33181E-6E28-4662-A801-E2E7DC206029} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} {575A5002-DD9F-4335-AA47-1DD87FA13645} = {E919DF0B-2607-4462-8FC0-5C98FE50F8C9} - {C77661B9-F793-422E-8E27-AC60ECC5F215} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} - {27AD4B5F-ECC4-4C63-9ECB-04EC772FDB6F} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} - {7213767C-0003-41CA-AB18-0223CFA7CE4B} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} - {556ABDCF-ED93-4327-BE98-F6815F78B9B8} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} - {A623CFE9-9D2B-4528-AD1F-2E834B061134} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} - {9E574A07-F879-4811-9C41-5CBDC6BAFDB7} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} + {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} + {2BF743D8-2A06-412D-96D7-F448F00C5EA5} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} {96188137-5FA6-4924-AB6E-4EFF79C6E0BB} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} - {E5BD4F96-28A8-410C-8B63-1C5731948549} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} EndGlobalSection EndGlobal diff --git a/README.md b/README.md index cbe03bb4e..967bccf8a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# ImageSharp +# ImageSharp **ImageSharp** is a new cross-platform 2D graphics API designed to allow the processing of images without the use of `System.Drawing`. @@ -28,38 +28,31 @@ We already have a [MyGet package repository](https://www.myget.org/gallery/image ### Packages -The **ImageSharp** library is made up of multiple packages, to make **ImageSharp** do anything useful you will want to make sure you include at least one format as a dependency otherwise you will not be able to save/load any images. +The **ImageSharp** library is made up of multiple packages. Packages include: - **ImageSharp** - Contains the Image classes, Colors, Primitives, Bootstrapper, IImageFormat interface, and other core functionality. -- **ImageSharp.Formats.Jpeg** - The jpeg decoder/encoder (Auto registered) -- **ImageSharp.Formats.Png** - The png decoder/encoder (Auto registered) -- **ImageSharp.Formats.Gif** - The gif decoder/encoder (Auto registered) -- **ImageSharp.Formats.Bmp** - The bmp decoder/encoder (Auto registered) -- **ImageSharp.Processing** - Contains methods like Resize, Crop, Skew, Rotate - Anything that alters the dimensions of the image. - Contains methods like Gaussian Blur, Pixelate, Edge Detection - Anything that maintains the original image dimensions. + - Contains the Image classes, Colors, Primitives, Configuration, and other core functionality. + - The IImageFormat interface, Jpeg, Png, Bmp, and Gif formats. + - Transform methods like Resize, Crop, Skew, Rotate - Anything that alters the dimensions of the image. + - Non-transform methods like Gaussian Blur, Pixelate, Edge Detection - Anything that maintains the original image dimensions. + - **ImageSharp.Drawing** - Brushes and various drawing algorithms, including drawing Images - - **ImageSharp.Drawing.Paths** - Various vector drawing methods for drawing paths, polygons etc. + - Brushes and various drawing algorithms, including drawing images. + - Various vector drawing methods for drawing paths, polygons etc. + - Text drawing. ### Manual build If you prefer, you can compile ImageSharp yourself (please do and help!), you'll need: -- [Visual Studio 2015 with Update 3 (or above)](https://www.visualstudio.com/news/releasenotes/vs2015-update3-vs) -- The [.NET Core 1.0 SDK Installer](https://www.microsoft.com/net/core#windows) - Non VSCode link. +- [Visual Studio 2017 (or above)](https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes) +- The [.NET Core SDK Installer](https://www.microsoft.com/net/core#windows) - Non VSCode link. Alternatively on Linux you can use: - [Visual Studio Code](https://code.visualstudio.com/) with [C# Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp) -- [.Net Core 1.1](https://www.microsoft.com/net/core#linuxubuntu) +- [.Net Core](https://www.microsoft.com/net/core#linuxubuntu) To clone it locally click the "Clone in Windows" button above or run the following git commands. diff --git a/appveyor.yml b/appveyor.yml index 2792ab0fc..c456a8d72 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,22 +1,9 @@ version: 1.0.0.{build} -os: Visual Studio 2015 +image: Visual Studio 2017 init: - ps: iex ((new-object net.webclient).DownloadString('https://gist.githubusercontent.com/PureKrome/0f79e25693d574807939/raw/8cf3160c9516ef1f4effc825c0a44acc918a0b5a/appveyor-build-info.ps')) -environment: - # Version Suffix - version_suffix: alpha - -install: -# Use the install script to grab the latest dotnet install -- ps: iex .\dotnet-latest.ps1 - -# Prepend newly installed dotnet cli to the PATH of this build (this cannot be -# done from inside the powershell script as it would require to restart -# the parent CMD process). -- "SET PATH=C:\\Program Files\\dotnet\\bin;%PATH%" - build_script: - cmd: build.cmd diff --git a/build/Program.cs b/build/Program.cs index a79743393..6e04dc1df 100644 --- a/build/Program.cs +++ b/build/Program.cs @@ -10,10 +10,10 @@ namespace ConsoleApplication using System.IO; using System.Linq; using System.Text; - + using System.Xml; using LibGit2Sharp; - using Microsoft.DotNet.ProjectModel; - using Newtonsoft.Json; + using Microsoft.Build.Construction; + using Microsoft.Build.Evaluation; using NuGet.Versioning; /// @@ -65,31 +65,29 @@ namespace ConsoleApplication { var resetmode = args.Contains("reset"); - // Find the project root where glbal.json lives - var root = ProjectRootResolver.ResolveRootDirectory("."); + // Find the project root + var root = Path.GetFullPath(Path.Combine(LibGit2Sharp.Repository.Discover("."), "..")); // Lets find the repo var repo = new LibGit2Sharp.Repository(root); // Lets find all the project.json files in the src folder (don't care about versioning `tests`) - var projectFiles = Directory.EnumerateFiles(Path.Combine(root, "src"), Project.FileName, SearchOption.AllDirectories); + var projectFiles = Directory.EnumerateFiles(Path.Combine(root, "src"), "*.csproj", SearchOption.AllDirectories); + + ResetProject(projectFiles); // Open them and convert them to source projects - var projects = projectFiles.Select(x => ProjectReader.GetProject(x)) + var projects = projectFiles.Select(x => ProjectRootElement.Open(x, ProjectCollection.GlobalProjectCollection, true)) .Select(x => new SourceProject(x, repo.Info.WorkingDirectory)) .ToList(); - if (resetmode) - { - ResetProject(projects); - } - else + if (!resetmode) { CaclulateProjectVersionNumber(projects, repo); UpdateVersionNumbers(projects); - CreateBuildScript(projects); + CreateBuildScript(projects, root); foreach (var p in projects) { @@ -98,12 +96,14 @@ namespace ConsoleApplication } } - private static void CreateBuildScript(IEnumerable projects) + private static void CreateBuildScript(IEnumerable projects, string root) { + var outputDir = Path.GetFullPath(Path.Combine(root, @"artifacts\bin\ImageSharp")); + var sb = new StringBuilder(); foreach (var p in projects) { - sb.AppendLine($@"dotnet pack --configuration Release --output ""artifacts\bin\ImageSharp"" ""{p.ProjectFilePath}"""); + sb.AppendLine($@"dotnet pack --configuration Release --output ""{outputDir}"" ""{p.ProjectFilePath}"""); } File.WriteAllText("build-inner.cmd", sb.ToString()); @@ -113,17 +113,17 @@ namespace ConsoleApplication { foreach (var p in projects) { - // TODO force update of all dependent projects to point to the newest build. - // we skip the build number and standard CI prefix on first commits - var newVersion = p.FinalVersionNumber; - // create a backup file so we can rollback later without breaking formatting File.Copy(p.FullProjectFilePath, $"{p.FullProjectFilePath}.bak", true); + } - dynamic projectFile = JsonConvert.DeserializeObject(File.ReadAllText(p.FullProjectFilePath)); + foreach (var p in projects) + { + // TODO force update of all dependent projects to point to the newest build. + // we skip the build number and standard CI prefix on first commits + var newVersion = p.FinalVersionNumber; - projectFile.version = $"{newVersion}-*"; - File.WriteAllText(p.FullProjectFilePath, JsonConvert.SerializeObject(projectFile, Formatting.Indented)); + p.UpdateVersion(newVersion); } } @@ -168,7 +168,7 @@ namespace ConsoleApplication projects.ForEach(x => x.CalculateVersion(repo, branch)); } - private static void ResetProject(List projects) + private static void ResetProject(IEnumerable projectPaths) { if (File.Exists("build-inner.cmd")) { @@ -176,12 +176,12 @@ namespace ConsoleApplication } // revert the project.json change be reverting it but skipp all the git stuff as its not needed - foreach (var p in projects) + foreach (var p in projectPaths) { - if (File.Exists($"{p.FullProjectFilePath}.bak")) + if (File.Exists($"{p}.bak")) { - File.Copy($"{p.FullProjectFilePath}.bak", p.FullProjectFilePath, true); - File.Delete($"{p.FullProjectFilePath}.bak"); + File.Copy($"{p}.bak", p, true); + File.Delete($"{p}.bak"); } } } @@ -192,21 +192,24 @@ namespace ConsoleApplication public class SourceProject { private readonly IEnumerable dependencies; + private readonly ProjectRootElement project; /// /// Initializes a new instance of the class. /// /// The project. /// The root. - public SourceProject(Project project, string root) + public SourceProject(ProjectRootElement project, string root) { - this.Name = project.Name; - this.ProjectDirectory = project.ProjectDirectory.Substring(root.Length); - this.ProjectFilePath = project.ProjectFilePath.Substring(root.Length); - this.FullProjectFilePath = project.ProjectFilePath; - this.Version = project.Version; - this.dependencies = project.Dependencies.Select(x => x.Name); + this.Name = project.Properties.FirstOrDefault(x => x.Name == "AssemblyTitle").Value; + + this.ProjectDirectory = project.DirectoryPath.Substring(root.Length); + this.ProjectFilePath = project.ProjectFileLocation.File.Substring(root.Length); + this.FullProjectFilePath = Path.GetFullPath(project.ProjectFileLocation.File); + this.Version = new NuGetVersion(project.Properties.FirstOrDefault(x => x.Name == "VersionPrefix").Value); + this.dependencies = project.Items.Where(x => x.ItemType == "ProjectReference").Select(x => Path.GetFullPath(Path.Combine(project.DirectoryPath, x.Include))); this.FinalVersionNumber = this.Version.ToFullString(); + this.project = project; } /// @@ -223,7 +226,7 @@ namespace ConsoleApplication /// /// The version. /// - public NuGetVersion Version { get; } + public NuGetVersion Version { get; private set; } /// /// Gets the dependent projects. @@ -279,7 +282,18 @@ namespace ConsoleApplication /// The projects. public void PopulateDependencies(IEnumerable projects) { - this.DependentProjects = projects.Where(x => this.dependencies.Contains(x.Name)).ToList(); + this.DependentProjects = projects.Where(x => this.dependencies.Contains(x.FullProjectFilePath)).ToList(); + } + + /// + /// Update the version number in the project file + /// + /// the new version number to save. + internal void UpdateVersion(string versionnumber) + { + this.project.AddProperty("VersionPrefix", versionnumber); + this.Version = new NuGetVersion(versionnumber); + this.project.Save(); } /// @@ -334,11 +348,15 @@ namespace ConsoleApplication var blob = repo.Lookup(projectFileChange.Oid); using (var s = blob.GetContentStream()) { - var project = new ProjectReader().ReadProject(s, this.Name, this.FullProjectFilePath, null); - if (project.Version != this.Version) + using (var reader = XmlReader.Create(s)) { - // version changed - return false; + var proj = ProjectRootElement.Create(reader); + var version = new NuGetVersion(proj.Properties.FirstOrDefault(x => x.Name == "VersionPrefix").Value); + if (version != this.Version) + { + // version changed + return false; + } } } } diff --git a/build/Properties/launchSettings.json b/build/Properties/launchSettings.json index b3ff6cb02..d175ae754 100644 --- a/build/Properties/launchSettings.json +++ b/build/Properties/launchSettings.json @@ -1,7 +1,8 @@ { "profiles": { "build": { - "commandName": "Project" + "commandName": "Project", + "commandLineArgs": "reset" } } } \ No newline at end of file diff --git a/build/build.csproj b/build/build.csproj new file mode 100644 index 000000000..dc431284e --- /dev/null +++ b/build/build.csproj @@ -0,0 +1,16 @@ + + + netcoreapp1.1 + portable + true + build + Exe + build + ..\ImageSharp.ruleset + + + + + + + \ No newline at end of file diff --git a/build/build.xproj b/build/build.xproj deleted file mode 100644 index 3b85ca872..000000000 --- a/build/build.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 575a5002-dd9f-4335-aa47-1dd87fa13645 - build - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/build/icons/imagesharp-logo-128.png b/build/icons/imagesharp-logo-128.png index a7be6e512..d9ae997ba 100644 --- a/build/icons/imagesharp-logo-128.png +++ b/build/icons/imagesharp-logo-128.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ae6327b2d554c25640756650865eeb5e96aa5bd58b3922ae5247400dc516ed0 -size 6622 +oid sha256:47f14bb7d24f7228cd8833d8d1881a72750b2c7813f391bd2a0dd0eeea936841 +size 6569 diff --git a/build/icons/imagesharp-logo-256.png b/build/icons/imagesharp-logo-256.png index 2fbd57d8c..f1e67dd78 100644 --- a/build/icons/imagesharp-logo-256.png +++ b/build/icons/imagesharp-logo-256.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a78ad79663c58544bba12b431ed83659e60a12a4fcb9b358e7a1c22bc76034bc -size 14020 +oid sha256:757ec2f45cc5f9c2083fc65a236100f1a7776eee16bd1095a550e05783106a9f +size 13949 diff --git a/build/icons/imagesharp-logo-32.png b/build/icons/imagesharp-logo-32.png index 3a8e28e85..80435989a 100644 --- a/build/icons/imagesharp-logo-32.png +++ b/build/icons/imagesharp-logo-32.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a911690b45b1614ca0dcd08d09ec4d257edc244ccc352e6384370cc197cac1e0 -size 1479 +oid sha256:0f3a5375ce20321c2cfdc888a21dcb629d3e6a85641df5cca7c66e5b2a5f70f6 +size 1439 diff --git a/build/icons/imagesharp-logo-512.png b/build/icons/imagesharp-logo-512.png index eabef882f..a5f880e3a 100644 --- a/build/icons/imagesharp-logo-512.png +++ b/build/icons/imagesharp-logo-512.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1381533f41d07c6d3d2604e20c605cd7dd70654056cffd73e67bdc75353476b2 -size 31672 +oid sha256:0e4cd18406375999c2bee1c39ad439b37f9524485d6e247ab0f14d2eb90a65f3 +size 31256 diff --git a/build/icons/imagesharp-logo-64.png b/build/icons/imagesharp-logo-64.png index a45ea0afc..f59e202bf 100644 --- a/build/icons/imagesharp-logo-64.png +++ b/build/icons/imagesharp-logo-64.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d28e405019add224bd0156332e16e152c6b3822de406c7d5a79cc78e15396a8f -size 3143 +oid sha256:fa25e5dbe84f942107a1c29f4f68ff2a73f497412ae91b6e60fc5464bc9b5f05 +size 3132 diff --git a/build/icons/imagesharp-logo-heading.png b/build/icons/imagesharp-logo-heading.png new file mode 100644 index 000000000..20779215f --- /dev/null +++ b/build/icons/imagesharp-logo-heading.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf2335642c6fd291befa0b203dbfb3387d99434369399b35aeea037c0f9eba45 +size 10474 diff --git a/build/icons/imagesharp-logo.png b/build/icons/imagesharp-logo.png index e0ab59b8d..e0f1854cc 100644 --- a/build/icons/imagesharp-logo.png +++ b/build/icons/imagesharp-logo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d21730b397705c2312383d1f7c3f614d2bc2daecf3f9b667f8cbf48a679b4da -size 59600 +oid sha256:e4217fe820af06a593903441f0719cab1ca650fd4de795f0e6808c4240a89819 +size 59646 diff --git a/build/project.json b/build/project.json deleted file mode 100644 index cf95cc8a0..000000000 --- a/build/project.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "version": "1.0.0-*", - "buildOptions": { - "debugType": "portable", - "emitEntryPoint": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../src/Shared/stylecop.json", "/ruleset:../ImageSharp.ruleset" ] - }, - "dependencies": { - "Microsoft.DotNet.ProjectModel": "1.0.0-rc3-003121", - "LibGit2Sharp": "0.23.0", - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - } - }, - "frameworks": { - "net46": { - // this is only a net46 app because of LibGit2Sharp once they have a version that works on coreclr we can shift over. - } - } -} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..ae6dd5f6b --- /dev/null +++ b/codecov.yml @@ -0,0 +1,4 @@ +ignore: + "src/ImageSharp/Common/Helpers/DebugGuard.cs" + + \ No newline at end of file diff --git a/config.wyam b/config.wyam new file mode 100644 index 000000000..3a4b64c54 --- /dev/null +++ b/config.wyam @@ -0,0 +1,4 @@ +#recipe Docs +Settings[Keys.Host] = "imagesharp.org"; +Settings[Keys.Title] = "Image Sharp"; +FileSystem.OutputPath = "./docs"; \ No newline at end of file diff --git a/dotnet-latest.ps1 b/dotnet-latest.ps1 deleted file mode 100644 index bb2c5dcfe..000000000 --- a/dotnet-latest.ps1 +++ /dev/null @@ -1,29 +0,0 @@ -# Set up everything for using the dotnet cli. This should mean we do not have to wait for Appveyor images to be updated. - -# Clean and recreate the folder in which all output packages should be placed -$ArtifactsPath = "artifacts" - -if (Test-Path $ArtifactsPath) { - Remove-Item -Path $ArtifactsPath -Recurse -Force -ErrorAction Ignore -} - -New-Item $ArtifactsPath -ItemType Directory -ErrorAction Ignore | Out-Null - -Write-Host "Created artifacts folder '$ArtifactsPath'" - -# Install the latest dotnet cli -if (Get-Command "dotnet.exe" -ErrorAction SilentlyContinue) { - Write-Host "dotnet SDK already installed" - dotnet --version -} else { - Write-Host "Installing dotnet SDK" - - $installScript = Join-Path $ArtifactsPath "dotnet-install.ps1" - - Write-Host $installScript - - Invoke-WebRequest "https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1" ` - -OutFile $installScript - - & $installScript -} diff --git a/features.md b/features.md index 764d7c4a6..6bc5630ee 100644 --- a/features.md +++ b/features.md @@ -10,13 +10,23 @@ We've achieved a lot so far and hope to do a lot more in the future. We're alway - [x] Bmp (Read: 32bit, 24bit, 16 bit. Write: 32bit, 24bit just now) - [x] Png (Read: Rgb, Rgba, Grayscale, Grayscale + alpha, Palette. Write: Rgb, Rgba, Grayscale, Grayscale + alpha, Palette) Supports interlaced decoding - [x] Gif (Includes animated) - - [ ] Tiff + - [ ] Tiff (Help needed) - **Metadata** - [x] EXIF Read/Write (Jpeg just now) -- **Quantizers (IQuantizer with alpha channel support + thresholding)** +- **Quantizers (IQuantizer with alpha channel support, dithering, and thresholding)** - [x] Octree - [x] Xiaolin Wu - [x] Palette +- **DIthering (Error diffusion and Ordered)** + - [x] Atkinson + - [x] Burks + - [x] FloydSteinburg + - [x] JarvisJudiceNinke + - [x] Sieera2 + - [x] Sierra3 + - [x] SerraLite + - [x] Bayer + - [x] Ordered - **Basic color structs with implicit operators.** - [x] Color - 32bit color in RGBA order (IPackedPixel\). - [x] Bgra32 @@ -133,5 +143,5 @@ We've achieved a lot so far and hope to do a lot more in the future. We're alway - [x] DrawImage - [ ] Gradient brush (Need help) - **DrawingText** - - [x] DrawString (Single variant support just now, no italic,bold) + - [ ] DrawString (In-progress. Single variant support just now, no italic,bold) - Other stuff I haven't thought of. \ No newline at end of file diff --git a/global.json b/global.json deleted file mode 100644 index 7346bdc28..000000000 --- a/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "projects": [ "src" ], - "sdk": { - "version": "1.0.0-preview2-003121" - } -} \ No newline at end of file diff --git a/input/about.md b/input/about.md new file mode 100644 index 000000000..42739928a --- /dev/null +++ b/input/about.md @@ -0,0 +1,3 @@ +Title: About This Project +--- +This project is awesome! \ No newline at end of file diff --git a/src/ImageSharp.Drawing.Paths/ImageSharp.Drawing.Paths.xproj b/src/ImageSharp.Drawing.Paths/ImageSharp.Drawing.Paths.xproj deleted file mode 100644 index 196f7bc1b..000000000 --- a/src/ImageSharp.Drawing.Paths/ImageSharp.Drawing.Paths.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - e5bd4f96-28a8-410c-8b63-1c5731948549 - ImageSharp.Drawing - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Drawing.Paths/Properties/AssemblyInfo.cs b/src/ImageSharp.Drawing.Paths/Properties/AssemblyInfo.cs deleted file mode 100644 index fba25a9db..000000000 --- a/src/ImageSharp.Drawing.Paths/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -// Common values read from `AssemblyInfo.Common.cs` diff --git a/src/ImageSharp.Drawing.Paths/project.json b/src/ImageSharp.Drawing.Paths/project.json deleted file mode 100644 index bf6b1fae8..000000000 --- a/src/ImageSharp.Drawing.Paths/project.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Drawing.Paths", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project" - }, - "ImageSharp.Drawing": { - "target": "project" - }, - "SixLabors.Shapes": "0.1.0-alpha0005", - "StyleCop.Analyzers": { - "version": "1.0.0", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj new file mode 100644 index 000000000..cc1c526ae --- /dev/null +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -0,0 +1,51 @@ + + + An extension to ImageSharp that allows the drawing of images, paths, and text. + ImageSharp.Drawing + 1.0.0-alpha3 + James Jackson-South and contributors + netstandard1.1 + true + true + ImageSharp.Drawing + ImageSharp.Drawing + Image Draw Shape Path Font + https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png + https://github.com/JimBobSquarePants/ImageSharp + http://www.apache.org/licenses/LICENSE-2.0 + git + https://github.com/JimBobSquarePants/ImageSharp + false + false + false + false + false + false + false + false + false + full + portable + True + + + + + + + + + + + All + + + + + + ..\..\ImageSharp.ruleset + + + true + + \ No newline at end of file diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.xproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.xproj deleted file mode 100644 index 488f86bc7..000000000 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 2e33181e-6e28-4662-a801-e2e7dc206029 - ImageSharp.Drawing - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Drawing.Paths/DrawBeziers.cs b/src/ImageSharp.Drawing/Paths/DrawBeziers.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/DrawBeziers.cs rename to src/ImageSharp.Drawing/Paths/DrawBeziers.cs diff --git a/src/ImageSharp.Drawing.Paths/DrawLines.cs b/src/ImageSharp.Drawing/Paths/DrawLines.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/DrawLines.cs rename to src/ImageSharp.Drawing/Paths/DrawLines.cs diff --git a/src/ImageSharp.Drawing.Paths/DrawPath.cs b/src/ImageSharp.Drawing/Paths/DrawPath.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/DrawPath.cs rename to src/ImageSharp.Drawing/Paths/DrawPath.cs diff --git a/src/ImageSharp.Drawing.Paths/DrawPolygon.cs b/src/ImageSharp.Drawing/Paths/DrawPolygon.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/DrawPolygon.cs rename to src/ImageSharp.Drawing/Paths/DrawPolygon.cs diff --git a/src/ImageSharp.Drawing.Paths/DrawRectangle.cs b/src/ImageSharp.Drawing/Paths/DrawRectangle.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/DrawRectangle.cs rename to src/ImageSharp.Drawing/Paths/DrawRectangle.cs diff --git a/src/ImageSharp.Drawing.Paths/FillPaths.cs b/src/ImageSharp.Drawing/Paths/FillPaths.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/FillPaths.cs rename to src/ImageSharp.Drawing/Paths/FillPaths.cs diff --git a/src/ImageSharp.Drawing.Paths/FillPolygon.cs b/src/ImageSharp.Drawing/Paths/FillPolygon.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/FillPolygon.cs rename to src/ImageSharp.Drawing/Paths/FillPolygon.cs diff --git a/src/ImageSharp.Drawing.Paths/FillRectangle.cs b/src/ImageSharp.Drawing/Paths/FillRectangle.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/FillRectangle.cs rename to src/ImageSharp.Drawing/Paths/FillRectangle.cs diff --git a/src/ImageSharp.Drawing.Paths/RectangleExtensions.cs b/src/ImageSharp.Drawing/Paths/RectangleExtensions.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/RectangleExtensions.cs rename to src/ImageSharp.Drawing/Paths/RectangleExtensions.cs diff --git a/src/ImageSharp.Drawing.Paths/ShapePath.cs b/src/ImageSharp.Drawing/Paths/ShapePath.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/ShapePath.cs rename to src/ImageSharp.Drawing/Paths/ShapePath.cs diff --git a/src/ImageSharp.Drawing.Paths/ShapeRegion.cs b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs similarity index 100% rename from src/ImageSharp.Drawing.Paths/ShapeRegion.cs rename to src/ImageSharp.Drawing/Paths/ShapeRegion.cs diff --git a/src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs b/src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs index 913293ff3..95f4ab472 100644 --- a/src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs @@ -110,7 +110,6 @@ namespace ImageSharp.Drawing.Processors Vector4 sourceVector = color.Color.ToVector4(); Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity); - finalColor.W = backgroundVector.W; TColor packed = default(TColor); packed.PackFromVector4(finalColor); diff --git a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs index fed97275d..4f468c707 100644 --- a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs @@ -202,7 +202,6 @@ namespace ImageSharp.Drawing.Processors Vector4 sourceVector = applicator[x, y].ToVector4(); Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity); - finalColor.W = backgroundVector.W; TColor packed = default(TColor); packed.PackFromVector4(finalColor); diff --git a/src/ImageSharp.Drawing/Text/DrawText.cs b/src/ImageSharp.Drawing/Text/DrawText.cs new file mode 100644 index 000000000..28781fab2 --- /dev/null +++ b/src/ImageSharp.Drawing/Text/DrawText.cs @@ -0,0 +1,203 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System.Numerics; + + using Drawing; + using Drawing.Brushes; + using Drawing.Pens; + + using SixLabors.Fonts; + + /// + /// Extension methods for the type. + /// + public static partial class ImageExtensions + { + /// + /// Draws the text onto the the image filled via the brush. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The color. + /// The location. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, TColor color, Vector2 location) + where TColor : struct, IPixel + { + return source.DrawText(text, font, color, location, TextGraphicsOptions.Default); + } + + /// + /// Draws the text onto the the image filled via the brush. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The color. + /// The location. + /// The options. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, TColor color, Vector2 location, TextGraphicsOptions options) + where TColor : struct, IPixel + { + return source.DrawText(text, font, Brushes.Solid(color), null, location, options); + } + + /// + /// Draws the text onto the the image filled via the brush. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The brush. + /// The location. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, IBrush brush, Vector2 location) + where TColor : struct, IPixel + { + return source.DrawText(text, font, brush, location, TextGraphicsOptions.Default); + } + + /// + /// Draws the text onto the the image filled via the brush. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The brush. + /// The location. + /// The options. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, IBrush brush, Vector2 location, TextGraphicsOptions options) + where TColor : struct, IPixel + { + return source.DrawText(text, font, brush, null, location, options); + } + + /// + /// Draws the text onto the the image outlined via the pen. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The pen. + /// The location. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, IPen pen, Vector2 location) + where TColor : struct, IPixel + { + return source.DrawText(text, font, pen, location, TextGraphicsOptions.Default); + } + + /// + /// Draws the text onto the the image outlined via the pen. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The pen. + /// The location. + /// The options. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, IPen pen, Vector2 location, TextGraphicsOptions options) + where TColor : struct, IPixel + { + return source.DrawText(text, font, null, pen, location, options); + } + + /// + /// Draws the text onto the the image filled via the brush then outlined via the pen. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The brush. + /// The pen. + /// The location. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, IBrush brush, IPen pen, Vector2 location) + where TColor : struct, IPixel + { + return source.DrawText(text, font, brush, pen, location, TextGraphicsOptions.Default); + } + + /// + /// Draws the text onto the the image filled via the brush then outlined via the pen. + /// + /// The type of the color. + /// The image this method extends. + /// The text. + /// The font. + /// The brush. + /// The pen. + /// The location. + /// The options. + /// + /// The . + /// + public static Image DrawText(this Image source, string text, Font font, IBrush brush, IPen pen, Vector2 location, TextGraphicsOptions options) + where TColor : struct, IPixel + { + GlyphBuilder glyphBuilder = new GlyphBuilder(location); + + TextRenderer renderer = new TextRenderer(glyphBuilder); + + Vector2 dpi = new Vector2((float)source.MetaData.HorizontalResolution, (float)source.MetaData.VerticalResolution); + FontSpan style = new FontSpan(font) + { + ApplyKerning = options.ApplyKerning, + TabWidth = options.TabWidth + }; + + renderer.RenderText(text, style, dpi); + + System.Collections.Generic.IEnumerable shapesToDraw = glyphBuilder.Paths; + + GraphicsOptions pathOptions = (GraphicsOptions)options; + if (brush != null) + { + foreach (SixLabors.Shapes.IPath s in shapesToDraw) + { + source.Fill(brush, s, pathOptions); + } + } + + if (pen != null) + { + foreach (SixLabors.Shapes.IPath s in shapesToDraw) + { + source.Draw(pen, s, pathOptions); + } + } + + return source; + } + } +} diff --git a/src/ImageSharp.Drawing/Text/GlyphBuilder.cs b/src/ImageSharp.Drawing/Text/GlyphBuilder.cs new file mode 100644 index 000000000..ac5d01de7 --- /dev/null +++ b/src/ImageSharp.Drawing/Text/GlyphBuilder.cs @@ -0,0 +1,126 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Drawing +{ + using System.Collections.Generic; + using System.Numerics; + + using SixLabors.Fonts; + using SixLabors.Shapes; + + /// + /// rendering surface that Fonts can use to generate Shapes. + /// + internal class GlyphBuilder : IGlyphRenderer + { + private readonly PathBuilder builder = new PathBuilder(); + private readonly List paths = new List(); + private Vector2 currentPoint = default(Vector2); + + /// + /// Initializes a new instance of the class. + /// + public GlyphBuilder() + : this(Vector2.Zero) + { + // glyphs are renderd realative to bottom left so invert the Y axis to allow it to render on top left origin surface + this.builder = new PathBuilder(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The origin. + public GlyphBuilder(Vector2 origin) + { + this.builder = new PathBuilder(); + this.builder.SetOrigin(origin); + } + + /// + /// Gets the paths that have been rendered by this. + /// + public IEnumerable Paths => this.paths; + + /// + /// Begins the glyph. + /// + void IGlyphRenderer.BeginGlyph() + { + this.builder.Clear(); + } + + /// + /// Begins the figure. + /// + void IGlyphRenderer.BeginFigure() + { + this.builder.StartFigure(); + } + + /// + /// Draws a cubic bezier from the current point to the + /// + /// The second control point. + /// The third control point. + /// The point. + void IGlyphRenderer.CubicBezierTo(Vector2 secondControlPoint, Vector2 thirdControlPoint, Vector2 point) + { + this.builder.AddBezier(this.currentPoint, secondControlPoint, thirdControlPoint, point); + this.currentPoint = point; + } + + /// + /// Ends the glyph. + /// + void IGlyphRenderer.EndGlyph() + { + this.paths.Add(this.builder.Build()); + } + + /// + /// Ends the figure. + /// + void IGlyphRenderer.EndFigure() + { + this.builder.CloseFigure(); + } + + /// + /// Draws a line from the current point to the . + /// + /// The point. + void IGlyphRenderer.LineTo(Vector2 point) + { + this.builder.AddLine(this.currentPoint, point); + this.currentPoint = point; + } + + /// + /// Moves to current point to the supplied vector. + /// + /// The point. + void IGlyphRenderer.MoveTo(Vector2 point) + { + this.builder.StartFigure(); + this.currentPoint = point; + } + + /// + /// Draws a quadratics bezier from the current point to the + /// + /// The second control point. + /// The point. + void IGlyphRenderer.QuadraticBezierTo(Vector2 secondControlPoint, Vector2 point) + { + Vector2 c1 = (((secondControlPoint - this.currentPoint) * 2) / 3) + this.currentPoint; + Vector2 c2 = (((secondControlPoint - point) * 2) / 3) + point; + + this.builder.AddBezier(this.currentPoint, c1, c2, point); + this.currentPoint = point; + } + } +} diff --git a/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs b/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs new file mode 100644 index 000000000..e707ef5e5 --- /dev/null +++ b/src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs @@ -0,0 +1,68 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Drawing +{ + /// + /// Options for influencing the drawing functions. + /// + public struct TextGraphicsOptions + { + /// + /// Represents the default . + /// + public static readonly TextGraphicsOptions Default = new TextGraphicsOptions(true); + + /// + /// Whether antialiasing should be applied. + /// + public bool Antialias; + + /// + /// Whether the text should be drawing with kerning enabled. + /// + public bool ApplyKerning; + + /// + /// The number of space widths a tab should lock to. + /// + public float TabWidth; + + /// + /// Initializes a new instance of the struct. + /// + /// If set to true [enable antialiasing]. + public TextGraphicsOptions(bool enableAntialiasing) + { + this.Antialias = enableAntialiasing; + this.ApplyKerning = true; + this.TabWidth = 4; + } + + /// + /// Performs an implicit conversion from to . + /// + /// The options. + /// + /// The result of the conversion. + /// + public static implicit operator TextGraphicsOptions(GraphicsOptions options) + { + return new TextGraphicsOptions(options.Antialias); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The options. + /// + /// The result of the conversion. + /// + public static explicit operator GraphicsOptions(TextGraphicsOptions options) + { + return new GraphicsOptions(options.Antialias); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp.Drawing/project.json b/src/ImageSharp.Drawing/project.json deleted file mode 100644 index 98cf20c1d..000000000 --- a/src/ImageSharp.Drawing/project.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Drawing", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project" - }, - "ImageSharp.Processing": { - "target": "project" - }, - "StyleCop.Analyzers": { - "version": "1.0.0", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Formats.Bmp/ImageSharp.Formats.Bmp.xproj b/src/ImageSharp.Formats.Bmp/ImageSharp.Formats.Bmp.xproj deleted file mode 100644 index 94916399b..000000000 --- a/src/ImageSharp.Formats.Bmp/ImageSharp.Formats.Bmp.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - c77661b9-f793-422e-8e27-ac60ecc5f215 - ImageSharp.Formats.Bmp - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Formats.Bmp/Properties/AssemblyInfo.cs b/src/ImageSharp.Formats.Bmp/Properties/AssemblyInfo.cs deleted file mode 100644 index d6e98c6d6..000000000 --- a/src/ImageSharp.Formats.Bmp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -// Common values read from `AssemblyInfo.Common.cs` \ No newline at end of file diff --git a/src/ImageSharp.Formats.Bmp/project.json b/src/ImageSharp.Formats.Bmp/project.json deleted file mode 100644 index 0c96fd7df..000000000 --- a/src/ImageSharp.Formats.Bmp/project.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Formats.Bmp", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project", - "version": "1.0.0-*" - }, - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Formats.Gif/ImageSharp.Formats.Gif.xproj b/src/ImageSharp.Formats.Gif/ImageSharp.Formats.Gif.xproj deleted file mode 100644 index d11c20c48..000000000 --- a/src/ImageSharp.Formats.Gif/ImageSharp.Formats.Gif.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 27ad4b5f-ecc4-4c63-9ecb-04ec772fdb6f - ImageSharp.Formats.Gif - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Formats.Gif/Properties/AssemblyInfo.cs b/src/ImageSharp.Formats.Gif/Properties/AssemblyInfo.cs deleted file mode 100644 index d6e98c6d6..000000000 --- a/src/ImageSharp.Formats.Gif/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -// Common values read from `AssemblyInfo.Common.cs` \ No newline at end of file diff --git a/src/ImageSharp.Formats.Gif/project.json b/src/ImageSharp.Formats.Gif/project.json deleted file mode 100644 index 6fe75dbcb..000000000 --- a/src/ImageSharp.Formats.Gif/project.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Formats.Gif", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project", - "version": "1.0.0-*" - }, - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Formats.Jpeg/ImageSharp.Formats.Jpeg.xproj b/src/ImageSharp.Formats.Jpeg/ImageSharp.Formats.Jpeg.xproj deleted file mode 100644 index a22dc5ea3..000000000 --- a/src/ImageSharp.Formats.Jpeg/ImageSharp.Formats.Jpeg.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 7213767c-0003-41ca-ab18-0223cfa7ce4b - ImageSharp.Formats - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Formats.Jpeg/Properties/AssemblyInfo.cs b/src/ImageSharp.Formats.Jpeg/Properties/AssemblyInfo.cs deleted file mode 100644 index d6e98c6d6..000000000 --- a/src/ImageSharp.Formats.Jpeg/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -// Common values read from `AssemblyInfo.Common.cs` \ No newline at end of file diff --git a/src/ImageSharp.Formats.Jpeg/project.json b/src/ImageSharp.Formats.Jpeg/project.json deleted file mode 100644 index 2d84ff053..000000000 --- a/src/ImageSharp.Formats.Jpeg/project.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Formats.Jpeg", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project", - "version": "1.0.0-*" - }, - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Formats.Png/ImageSharp.Formats.Png.xproj b/src/ImageSharp.Formats.Png/ImageSharp.Formats.Png.xproj deleted file mode 100644 index f12901d6b..000000000 --- a/src/ImageSharp.Formats.Png/ImageSharp.Formats.Png.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 556abdcf-ed93-4327-be98-f6815f78b9b8 - ImageSharp.Formats.Png - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Formats.Png/Properties/AssemblyInfo.cs b/src/ImageSharp.Formats.Png/Properties/AssemblyInfo.cs deleted file mode 100644 index d6e98c6d6..000000000 --- a/src/ImageSharp.Formats.Png/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -// Common values read from `AssemblyInfo.Common.cs` \ No newline at end of file diff --git a/src/ImageSharp.Formats.Png/project.json b/src/ImageSharp.Formats.Png/project.json deleted file mode 100644 index a56397fb0..000000000 --- a/src/ImageSharp.Formats.Png/project.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Formats.Png", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project", - "version": "1.0.0-*" - }, - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Processing/ImageSharp.Processing.xproj b/src/ImageSharp.Processing/ImageSharp.Processing.xproj deleted file mode 100644 index 1fdba5ce9..000000000 --- a/src/ImageSharp.Processing/ImageSharp.Processing.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - a623cfe9-9d2b-4528-ad1f-2e834b061134 - ImageSharp.Processing - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp.Processing/Properties/AssemblyInfo.cs b/src/ImageSharp.Processing/Properties/AssemblyInfo.cs deleted file mode 100644 index d6e98c6d6..000000000 --- a/src/ImageSharp.Processing/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -// Common values read from `AssemblyInfo.Common.cs` \ No newline at end of file diff --git a/src/ImageSharp.Processing/project.json b/src/ImageSharp.Processing/project.json deleted file mode 100644 index 910d5fc83..000000000 --- a/src/ImageSharp.Processing/project.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp.Processing", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project" - }, - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Colors/Color.BulkOperations.cs b/src/ImageSharp/Colors/Color.BulkOperations.cs new file mode 100644 index 000000000..5c040e04c --- /dev/null +++ b/src/ImageSharp/Colors/Color.BulkOperations.cs @@ -0,0 +1,249 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System; + using System.Numerics; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Conains the definition of + /// + public partial struct Color + { + /// + /// implementation optimized for . + /// + internal class BulkOperations : BulkPixelOperations + { + /// + /// SIMD optimized bulk implementation of + /// that works only with `count` divisible by . + /// + /// The to the source colors. + /// The to the dstination vectors. + /// The number of pixels to convert. + /// + /// Implementation adapted from: + /// + /// http://stackoverflow.com/a/5362789 + /// + /// TODO: We can replace this implementation in the future using new Vector API-s: + /// + /// https://github.com/dotnet/corefx/issues/15957 + /// + /// + internal static unsafe void ToVector4SimdAligned( + BufferPointer sourceColors, + BufferPointer destVectors, + int count) + { + int vecSize = Vector.Count; + + DebugGuard.IsTrue( + count % vecSize == 0, + nameof(count), + "Argument 'count' should divisible by Vector.Count!"); + + Vector bVec = new Vector(256.0f / 255.0f); + Vector magicFloat = new Vector(32768.0f); + Vector magicInt = new Vector(1191182336); // reinterpreded value of 32768.0f + Vector mask = new Vector(255); + + int unpackedRawCount = count * 4; + + uint* src = (uint*)sourceColors.PointerAtOffset; + uint* srcEnd = src + count; + + using (PinnedBuffer tempBuf = new PinnedBuffer( + unpackedRawCount + Vector.Count)) + { + uint* tPtr = (uint*)tempBuf.Pointer; + uint[] temp = tempBuf.Array; + float[] fTemp = Unsafe.As(temp); + UnpackedRGBA* dst = (UnpackedRGBA*)tPtr; + + for (; src < srcEnd; src++, dst++) + { + // This call is the bottleneck now: + dst->Load(*src); + } + + for (int i = 0; i < unpackedRawCount; i += vecSize) + { + Vector vi = new Vector(temp, i); + + vi &= mask; + vi |= magicInt; + + Vector vf = Vector.AsVectorSingle(vi); + vf = (vf - magicFloat) * bVec; + vf.CopyTo(fTemp, i); + } + + BufferPointer.Copy(tempBuf, (BufferPointer)destVectors, unpackedRawCount); + } + } + + /// + internal override void ToVector4(BufferPointer sourceColors, BufferPointer destVectors, int count) + { + if (count < 256) + { + // Doesn't worth to bother with SIMD: + base.ToVector4(sourceColors, destVectors, count); + return; + } + + int remainder = count % Vector.Count; + + int alignedCount = count - remainder; + + if (alignedCount > 0) + { + ToVector4SimdAligned(sourceColors, destVectors, alignedCount); + } + + if (remainder > 0) + { + sourceColors = sourceColors.Slice(alignedCount); + destVectors = destVectors.Slice(alignedCount); + base.ToVector4(sourceColors, destVectors, remainder); + } + } + + /// + internal override unsafe void PackFromXyzBytes(BufferPointer sourceBytes, BufferPointer destColors, int count) + { + byte* source = (byte*)sourceBytes; + byte* destination = (byte*)destColors; + + for (int x = 0; x < count; x++) + { + Unsafe.Write(destination, (uint)(*source << 0 | *(source + 1) << 8 | *(source + 2) << 16 | 255 << 24)); + + source += 3; + destination += 4; + } + } + + /// + internal override unsafe void ToXyzBytes(BufferPointer sourceColors, BufferPointer destBytes, int count) + { + byte* source = (byte*)sourceColors; + byte* destination = (byte*)destBytes; + + for (int x = 0; x < count; x++) + { + *destination = *(source + 0); + *(destination + 1) = *(source + 1); + *(destination + 2) = *(source + 2); + + source += 4; + destination += 3; + } + } + + /// + internal override void PackFromXyzwBytes(BufferPointer sourceBytes, BufferPointer destColors, int count) + { + BufferPointer.Copy(sourceBytes, destColors, count); + } + + /// + internal override void ToXyzwBytes(BufferPointer sourceColors, BufferPointer destBytes, int count) + { + BufferPointer.Copy(sourceColors, destBytes, count); + } + + /// + internal override unsafe void PackFromZyxBytes(BufferPointer sourceBytes, BufferPointer destColors, int count) + { + byte* source = (byte*)sourceBytes; + byte* destination = (byte*)destColors; + + for (int x = 0; x < count; x++) + { + Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | 255 << 24)); + + source += 3; + destination += 4; + } + } + + /// + internal override unsafe void ToZyxBytes(BufferPointer sourceColors, BufferPointer destBytes, int count) + { + byte* source = (byte*)sourceColors; + byte* destination = (byte*)destBytes; + + for (int x = 0; x < count; x++) + { + *destination = *(source + 2); + *(destination + 1) = *(source + 1); + *(destination + 2) = *(source + 0); + + source += 4; + destination += 3; + } + } + + /// + internal override unsafe void PackFromZyxwBytes(BufferPointer sourceBytes, BufferPointer destColors, int count) + { + byte* source = (byte*)sourceBytes; + byte* destination = (byte*)destColors; + + for (int x = 0; x < count; x++) + { + Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | *(source + 3) << 24)); + + source += 4; + destination += 4; + } + } + + /// + internal override unsafe void ToZyxwBytes(BufferPointer sourceColors, BufferPointer destBytes, int count) + { + byte* source = (byte*)sourceColors; + byte* destination = (byte*)destBytes; + + for (int x = 0; x < count; x++) + { + *destination = *(source + 2); + *(destination + 1) = *(source + 1); + *(destination + 2) = *(source + 0); + *(destination + 3) = *(source + 3); + + source += 4; + destination += 4; + } + } + + /// + /// Value type to store -s unpacked into multiple -s. + /// + private struct UnpackedRGBA + { + private uint r; + private uint g; + private uint b; + private uint a; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Load(uint p) + { + this.r = p; + this.g = p >> Color.GreenShift; + this.b = p >> Color.BlueShift; + this.a = p >> Color.AlphaShift; + } + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Colors/Color.cs b/src/ImageSharp/Colors/Color.cs index 469774b34..597730937 100644 --- a/src/ImageSharp/Colors/Color.cs +++ b/src/ImageSharp/Colors/Color.cs @@ -245,6 +245,9 @@ namespace ImageSharp return ColorBuilder.FromHex(hex); } + /// + public BulkPixelOperations CreateBulkOperations() => new Color.BulkOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromBytes(byte x, byte y, byte z, byte w) diff --git a/src/ImageSharp/Colors/PackedPixel/Alpha8.cs b/src/ImageSharp/Colors/PackedPixel/Alpha8.cs index 485725d71..9a340544c 100644 --- a/src/ImageSharp/Colors/PackedPixel/Alpha8.cs +++ b/src/ImageSharp/Colors/PackedPixel/Alpha8.cs @@ -58,6 +58,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/Argb.cs b/src/ImageSharp/Colors/PackedPixel/Argb.cs index bef986fb9..70fd7de8a 100644 --- a/src/ImageSharp/Colors/PackedPixel/Argb.cs +++ b/src/ImageSharp/Colors/PackedPixel/Argb.cs @@ -220,6 +220,9 @@ namespace ImageSharp this.PackedValue = Pack(ref vector); } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() diff --git a/src/ImageSharp/Colors/PackedPixel/Bgr565.cs b/src/ImageSharp/Colors/PackedPixel/Bgr565.cs index ebe8d2533..77d943478 100644 --- a/src/ImageSharp/Colors/PackedPixel/Bgr565.cs +++ b/src/ImageSharp/Colors/PackedPixel/Bgr565.cs @@ -67,6 +67,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// /// Expands the packed representation into a . /// The vector components are typically expanded in least to greatest significance order. diff --git a/src/ImageSharp/Colors/PackedPixel/Bgra4444.cs b/src/ImageSharp/Colors/PackedPixel/Bgra4444.cs index ccd6ab1f3..1346a54ef 100644 --- a/src/ImageSharp/Colors/PackedPixel/Bgra4444.cs +++ b/src/ImageSharp/Colors/PackedPixel/Bgra4444.cs @@ -66,6 +66,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() diff --git a/src/ImageSharp/Colors/PackedPixel/Bgra5551.cs b/src/ImageSharp/Colors/PackedPixel/Bgra5551.cs index a7a2e899a..7989804cf 100644 --- a/src/ImageSharp/Colors/PackedPixel/Bgra5551.cs +++ b/src/ImageSharp/Colors/PackedPixel/Bgra5551.cs @@ -68,6 +68,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() diff --git a/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs b/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs new file mode 100644 index 000000000..259b1c9b4 --- /dev/null +++ b/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs @@ -0,0 +1,256 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System.Numerics; + using System.Runtime.CompilerServices; + + /// + /// A stateless class implementing Strategy Pattern for batched pixel-data conversion operations + /// for pixel buffers of type . + /// + /// The pixel format. + public unsafe class BulkPixelOperations + where TColor : struct, IPixel + { + /// + /// The size of in bytes + /// + private static readonly int ColorSize = Unsafe.SizeOf(); + + /// + /// Gets the global instance for the pixel type + /// + public static BulkPixelOperations Instance { get; } = default(TColor).CreateBulkOperations(); + + /// + /// Bulk version of + /// + /// The to the source vectors. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void PackFromVector4( + BufferPointer sourceVectors, + BufferPointer destColors, + int count) + { + Vector4* sp = (Vector4*)sourceVectors.PointerAtOffset; + byte* dp = (byte*)destColors; + + for (int i = 0; i < count; i++) + { + Vector4 v = Unsafe.Read(sp); + TColor c = default(TColor); + c.PackFromVector4(v); + Unsafe.Write(dp, c); + + sp++; + dp += ColorSize; + } + } + + /// + /// Bulk version of . + /// + /// The to the source colors. + /// The to the destination vectors. + /// The number of pixels to convert. + internal virtual void ToVector4( + BufferPointer sourceColors, + BufferPointer destVectors, + int count) + { + byte* sp = (byte*)sourceColors; + Vector4* dp = (Vector4*)destVectors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = Unsafe.Read(sp); + *dp = c.ToVector4(); + sp += ColorSize; + dp++; + } + } + + /// + /// Bulk version of that converts data in . + /// + /// The to the source bytes. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void PackFromXyzBytes( + BufferPointer sourceBytes, + BufferPointer destColors, + int count) + { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[0], sp[1], sp[2], 255); + Unsafe.Write(dp, c); + sp += 3; + dp += ColorSize; + } + } + + /// + /// Bulk version of . + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + internal virtual void ToXyzBytes(BufferPointer sourceColors, BufferPointer destBytes, int count) + { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + (count * 3); i += 3) + { + TColor c = Unsafe.Read(sp); + c.ToXyzBytes(dest, i); + sp += ColorSize; + } + } + + /// + /// Bulk version of that converts data in . + /// + /// The to the source bytes. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void PackFromXyzwBytes( + BufferPointer sourceBytes, + BufferPointer destColors, + int count) + { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[0], sp[1], sp[2], sp[3]); + Unsafe.Write(dp, c); + sp += 4; + dp += ColorSize; + } + } + + /// + /// Bulk version of . + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + internal virtual void ToXyzwBytes( + BufferPointer sourceColors, + BufferPointer destBytes, + int count) + { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + (count * 4); i += 4) + { + TColor c = Unsafe.Read(sp); + c.ToXyzwBytes(dest, i); + sp += ColorSize; + } + } + + /// + /// Bulk version of that converts data in . + /// + /// The to the source bytes. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void PackFromZyxBytes( + BufferPointer sourceBytes, + BufferPointer destColors, + int count) + { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[2], sp[1], sp[0], 255); + Unsafe.Write(dp, c); + sp += 3; + dp += ColorSize; + } + } + + /// + /// Bulk version of . + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + internal virtual void ToZyxBytes(BufferPointer sourceColors, BufferPointer destBytes, int count) + { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + (count * 3); i += 3) + { + TColor c = Unsafe.Read(sp); + c.ToZyxBytes(dest, i); + sp += ColorSize; + } + } + + /// + /// Bulk version of that converts data in . + /// + /// The to the source bytes. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void PackFromZyxwBytes( + BufferPointer sourceBytes, + BufferPointer destColors, + int count) + { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[2], sp[1], sp[0], sp[3]); + Unsafe.Write(dp, c); + sp += 4; + dp += ColorSize; + } + } + + /// + /// Bulk version of . + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + internal virtual void ToZyxwBytes( + BufferPointer sourceColors, + BufferPointer destBytes, + int count) + { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + (count * 4); i += 4) + { + TColor c = Unsafe.Read(sp); + c.ToZyxwBytes(dest, i); + sp += ColorSize; + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Colors/PackedPixel/Byte4.cs b/src/ImageSharp/Colors/PackedPixel/Byte4.cs index 9d5eb9be8..11ec5eaf4 100644 --- a/src/ImageSharp/Colors/PackedPixel/Byte4.cs +++ b/src/ImageSharp/Colors/PackedPixel/Byte4.cs @@ -69,6 +69,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/HalfSingle.cs b/src/ImageSharp/Colors/PackedPixel/HalfSingle.cs index acfa639b7..4c785a863 100644 --- a/src/ImageSharp/Colors/PackedPixel/HalfSingle.cs +++ b/src/ImageSharp/Colors/PackedPixel/HalfSingle.cs @@ -72,6 +72,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// /// Expands the packed representation into a . /// diff --git a/src/ImageSharp/Colors/PackedPixel/HalfVector2.cs b/src/ImageSharp/Colors/PackedPixel/HalfVector2.cs index e02c226dd..d06ab6ba0 100644 --- a/src/ImageSharp/Colors/PackedPixel/HalfVector2.cs +++ b/src/ImageSharp/Colors/PackedPixel/HalfVector2.cs @@ -82,6 +82,9 @@ namespace ImageSharp return !left.Equals(right); } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// /// Expands the packed representation into a . /// diff --git a/src/ImageSharp/Colors/PackedPixel/HalfVector4.cs b/src/ImageSharp/Colors/PackedPixel/HalfVector4.cs index 7c7f640e4..a5fa796e1 100644 --- a/src/ImageSharp/Colors/PackedPixel/HalfVector4.cs +++ b/src/ImageSharp/Colors/PackedPixel/HalfVector4.cs @@ -85,6 +85,9 @@ namespace ImageSharp return !left.Equals(right); } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/IPixel.cs b/src/ImageSharp/Colors/PackedPixel/IPixel.cs index 1c3e20a7e..67e013a42 100644 --- a/src/ImageSharp/Colors/PackedPixel/IPixel.cs +++ b/src/ImageSharp/Colors/PackedPixel/IPixel.cs @@ -15,6 +15,12 @@ namespace ImageSharp public interface IPixel : IPixel, IEquatable where TSelf : struct, IPixel { + /// + /// Creates a instance for this pixel type. + /// This method is not intended to be consumed directly. Use instead. + /// + /// The instance. + BulkPixelOperations CreateBulkOperations(); } /// diff --git a/src/ImageSharp/Colors/PackedPixel/NormalizedByte2.cs b/src/ImageSharp/Colors/PackedPixel/NormalizedByte2.cs index 116a68172..56be64a86 100644 --- a/src/ImageSharp/Colors/PackedPixel/NormalizedByte2.cs +++ b/src/ImageSharp/Colors/PackedPixel/NormalizedByte2.cs @@ -87,6 +87,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// /// Expands the packed representation into a . /// The vector components are typically expanded in least to greatest significance order. diff --git a/src/ImageSharp/Colors/PackedPixel/NormalizedByte4.cs b/src/ImageSharp/Colors/PackedPixel/NormalizedByte4.cs index 7aaa30c52..a1f9b8d84 100644 --- a/src/ImageSharp/Colors/PackedPixel/NormalizedByte4.cs +++ b/src/ImageSharp/Colors/PackedPixel/NormalizedByte4.cs @@ -89,6 +89,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/NormalizedShort2.cs b/src/ImageSharp/Colors/PackedPixel/NormalizedShort2.cs index 2f4ef89d6..b34c1e88b 100644 --- a/src/ImageSharp/Colors/PackedPixel/NormalizedShort2.cs +++ b/src/ImageSharp/Colors/PackedPixel/NormalizedShort2.cs @@ -87,6 +87,9 @@ namespace ImageSharp return !left.Equals(right); } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/NormalizedShort4.cs b/src/ImageSharp/Colors/PackedPixel/NormalizedShort4.cs index 60c5c9805..f33ac25a6 100644 --- a/src/ImageSharp/Colors/PackedPixel/NormalizedShort4.cs +++ b/src/ImageSharp/Colors/PackedPixel/NormalizedShort4.cs @@ -89,6 +89,9 @@ namespace ImageSharp return !left.Equals(right); } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/Rg32.cs b/src/ImageSharp/Colors/PackedPixel/Rg32.cs index 9e5e5a711..f8486f7f2 100644 --- a/src/ImageSharp/Colors/PackedPixel/Rg32.cs +++ b/src/ImageSharp/Colors/PackedPixel/Rg32.cs @@ -72,6 +72,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// /// Expands the packed representation into a . /// The vector components are typically expanded in least to greatest significance order. diff --git a/src/ImageSharp/Colors/PackedPixel/Rgba1010102.cs b/src/ImageSharp/Colors/PackedPixel/Rgba1010102.cs index 95a8d3b97..56f304070 100644 --- a/src/ImageSharp/Colors/PackedPixel/Rgba1010102.cs +++ b/src/ImageSharp/Colors/PackedPixel/Rgba1010102.cs @@ -75,6 +75,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() diff --git a/src/ImageSharp/Colors/PackedPixel/Rgba64.cs b/src/ImageSharp/Colors/PackedPixel/Rgba64.cs index 679a55c4e..816401d4e 100644 --- a/src/ImageSharp/Colors/PackedPixel/Rgba64.cs +++ b/src/ImageSharp/Colors/PackedPixel/Rgba64.cs @@ -74,6 +74,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 ToVector4() diff --git a/src/ImageSharp/Colors/PackedPixel/Short2.cs b/src/ImageSharp/Colors/PackedPixel/Short2.cs index 1c1cb28c3..802df7c1d 100644 --- a/src/ImageSharp/Colors/PackedPixel/Short2.cs +++ b/src/ImageSharp/Colors/PackedPixel/Short2.cs @@ -87,6 +87,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Colors/PackedPixel/Short4.cs b/src/ImageSharp/Colors/PackedPixel/Short4.cs index 2c11a1f8b..2517ef7a8 100644 --- a/src/ImageSharp/Colors/PackedPixel/Short4.cs +++ b/src/ImageSharp/Colors/PackedPixel/Short4.cs @@ -89,6 +89,9 @@ namespace ImageSharp return left.PackedValue != right.PackedValue; } + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) diff --git a/src/ImageSharp/Common/Extensions/ArrayExtensions.cs b/src/ImageSharp/Common/Extensions/ArrayExtensions.cs deleted file mode 100644 index cce442c52..000000000 --- a/src/ImageSharp/Common/Extensions/ArrayExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp -{ - using System; - - /// - /// Extension methods for arrays. - /// - public static class ArrayExtensions - { - /// - /// Locks the pixel buffer providing access to the pixels. - /// - /// The pixel format. - /// The pixel buffer. - /// Gets the width of the image represented by the pixel buffer. - /// The height of the image represented by the pixel buffer. - /// The - public static PixelAccessor Lock(this TColor[] pixels, int width, int height) - where TColor : struct, IPixel - { - return new PixelAccessor(width, height, pixels); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Common/Helpers/DebugGuard.cs b/src/ImageSharp/Common/Helpers/DebugGuard.cs index 0ca6f0912..c1fa46191 100644 --- a/src/ImageSharp/Common/Helpers/DebugGuard.cs +++ b/src/ImageSharp/Common/Helpers/DebugGuard.cs @@ -29,5 +29,135 @@ namespace ImageSharp throw new ArgumentNullException(parameterName); } } + + /// + /// Verifies that the specified value is less than a maximum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is greater than the maximum value. + /// + [Conditional("DEBUG")] + public static void MustBeLessThan(TValue value, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(max) >= 0) + { + throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than {max}."); + } + } + + /// + /// Verifies that the specified value is less than or equal to a maximum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The maximum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is greater than the maximum value. + /// + [Conditional("DEBUG")] + public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(max) > 0) + { + throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than or equal to {max}."); + } + } + + /// + /// Verifies that the specified value is greater than a minimum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value. + /// + [Conditional("DEBUG")] + public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) <= 0) + { + throw new ArgumentOutOfRangeException( + parameterName, + $"Value must be greater than {min}."); + } + } + + /// + /// Verifies that the specified value is greater than or equal to a minimum value + /// and throws an exception if it is not. + /// + /// The target value, which should be validated. + /// The minimum value. + /// The name of the parameter that is to be checked. + /// The type of the value. + /// + /// is less than the minimum value. + /// + [Conditional("DEBUG")] + public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) + where TValue : IComparable + { + if (value.CompareTo(min) < 0) + { + throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min}."); + } + } + + /// + /// Verifies, that the method parameter with specified target value is true + /// and throws an exception if it is found to be so. + /// + /// + /// The target value, which cannot be false. + /// + /// + /// The name of the parameter that is to be checked. + /// + /// + /// The error message, if any to add to the exception. + /// + /// + /// is false + /// + [Conditional("DEBUG")] + public static void IsTrue(bool target, string parameterName, string message) + { + if (!target) + { + throw new ArgumentException(message, parameterName); + } + } + + /// + /// Verifies, that the method parameter with specified target value is false + /// and throws an exception if it is found to be so. + /// + /// The target value, which cannot be true. + /// The name of the parameter that is to be checked. + /// The error message, if any to add to the exception. + /// + /// is true + /// + [Conditional("DEBUG")] + public static void IsFalse(bool target, string parameterName, string message) + { + if (target) + { + throw new ArgumentException(message, parameterName); + } + } } } \ No newline at end of file diff --git a/src/ImageSharp/Common/Memory/ArrayPointer{T}.cs b/src/ImageSharp/Common/Memory/ArrayPointer{T}.cs deleted file mode 100644 index 1ea7706d4..000000000 --- a/src/ImageSharp/Common/Memory/ArrayPointer{T}.cs +++ /dev/null @@ -1,85 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp -{ - using System; - using System.Runtime.CompilerServices; - using System.Runtime.InteropServices; - - /// - /// Provides access to elements in an array from a given position. - /// This type shares many similarities with corefx System.Span<T> but there are significant differences in it's functionalities and semantics: - /// - It's not possible to use it with stack objects or pointers to unmanaged memory, only with managed arrays - /// - It's possible to retrieve a reference to the array () so we can pass it to API-s like - /// - There is no bounds checking for performance reasons. Therefore we don't need to store length. (However this could be added as DEBUG-only feature.) - /// This makes an unsafe type! - /// - Currently the arrays provided to ArrayPointer need to be pinned. This behaviour could be changed using C#7 features. - /// - /// The type of elements of the array - internal unsafe struct ArrayPointer - where T : struct - { - /// - /// Initializes a new instance of the struct from a pinned array and an offset. - /// - /// The pinned array - /// Pointer to the beginning of array - /// The offset inside the array - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ArrayPointer(T[] array, void* pointerToArray, int offset) - { - DebugGuard.NotNull(array, nameof(array)); - - this.Array = array; - this.Offset = offset; - this.PointerAtOffset = (IntPtr)pointerToArray + (Unsafe.SizeOf() * offset); - } - - /// - /// Initializes a new instance of the struct from a pinned array. - /// - /// The pinned array - /// Pointer to the start of 'array' - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ArrayPointer(T[] array, void* pointerToArray) - { - DebugGuard.NotNull(array, nameof(array)); - - this.Array = array; - this.Offset = 0; - this.PointerAtOffset = (IntPtr)pointerToArray; - } - - /// - /// Gets the array - /// - public T[] Array { get; private set; } - - /// - /// Gets the offset inside - /// - public int Offset { get; private set; } - - /// - /// Gets the pointer to the offseted array position - /// - public IntPtr PointerAtOffset { get; private set; } - - /// - /// Forms a slice out of the given ArrayPointer, beginning at 'offset'. - /// - /// The offset in number of elements - /// The offseted (sliced) ArrayPointer - public ArrayPointer Slice(int offset) - { - ArrayPointer result = default(ArrayPointer); - result.Array = this.Array; - result.Offset = this.Offset + offset; - result.PointerAtOffset = this.PointerAtOffset + (Unsafe.SizeOf() * offset); - return result; - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Common/Memory/BufferPointer.cs b/src/ImageSharp/Common/Memory/BufferPointer.cs new file mode 100644 index 000000000..523889611 --- /dev/null +++ b/src/ImageSharp/Common/Memory/BufferPointer.cs @@ -0,0 +1,129 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System; + using System.Numerics; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Utility methods for + /// + internal static class BufferPointer + { + /// + /// It's worth to use Marshal.Copy() or Buffer.BlockCopy() over this size. + /// + private const int ByteCountThreshold = 1024; + + /// + /// Copy 'count' number of elements of the same type from 'source' to 'dest' + /// + /// The element type. + /// The input + /// The destination . + /// The number of elements to copy + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Copy(BufferPointer source, BufferPointer destination, int count) + where T : struct + { + CopyImpl(source, destination, count); + } + + /// + /// Copy 'countInSource' elements of from 'source' into the raw byte buffer 'destination'. + /// + /// The element type. + /// The source buffer of elements to copy from. + /// The destination buffer. + /// The number of elements to copy from 'source' + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Copy(BufferPointer source, BufferPointer destination, int countInSource) + where T : struct + { + CopyImpl(source, destination, countInSource); + } + + /// + /// Copy 'countInDest' number of elements into 'dest' from a raw byte buffer defined by 'source'. + /// + /// The element type. + /// The raw source buffer to copy from"/> + /// The destination buffer"/> + /// The number of elements to copy. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void Copy(BufferPointer source, BufferPointer destination, int countInDest) + where T : struct + { + int byteCount = SizeOf(countInDest); + + if (byteCount > (int)ByteCountThreshold) + { + Marshal.Copy(source.Array, source.Offset, destination.PointerAtOffset, byteCount); + } + else + { + Unsafe.CopyBlock((void*)destination.PointerAtOffset, (void*)source.PointerAtOffset, (uint)byteCount); + } + } + + /// + /// Gets the size of `count` elements in bytes. + /// + /// The element type. + /// The count of the elements + /// The size in bytes as int + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SizeOf(int count) + where T : struct => Unsafe.SizeOf() * count; + + /// + /// Gets the size of `count` elements in bytes as UInt32 + /// + /// The element type. + /// The count of the elements + /// The size in bytes as UInt32 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint USizeOf(int count) + where T : struct + => (uint)SizeOf(count); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe void CopyImpl(BufferPointer source, BufferPointer destination, int count) + where T : struct + where TDest : struct + { + int byteCount = SizeOf(count); + + if (byteCount > ByteCountThreshold) + { + if (Unsafe.SizeOf() == sizeof(long)) + { + Marshal.Copy(Unsafe.As(source.Array), source.Offset, destination.PointerAtOffset, count); + return; + } + else if (Unsafe.SizeOf() == sizeof(int)) + { + Marshal.Copy(Unsafe.As(source.Array), source.Offset, destination.PointerAtOffset, count); + return; + } + else if (Unsafe.SizeOf() == sizeof(short)) + { + Marshal.Copy(Unsafe.As(source.Array), source.Offset, destination.PointerAtOffset, count); + return; + } + else if (Unsafe.SizeOf() == sizeof(byte)) + { + Marshal.Copy(Unsafe.As(source.Array), source.Offset, destination.PointerAtOffset, count); + return; + } + } + + Unsafe.CopyBlock((void*)destination.PointerAtOffset, (void*)source.PointerAtOffset, (uint)byteCount); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Memory/BufferPointer{T}.cs b/src/ImageSharp/Common/Memory/BufferPointer{T}.cs new file mode 100644 index 000000000..441f6b8ce --- /dev/null +++ b/src/ImageSharp/Common/Memory/BufferPointer{T}.cs @@ -0,0 +1,143 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides access to elements in an array from a given position. + /// This type shares many similarities with corefx System.Span<T> but there are significant differences in it's functionalities and semantics: + /// - It's not possible to use it with stack objects or pointers to unmanaged memory, only with managed arrays + /// - It's possible to retrieve a reference to the array () so we can pass it to API-s like + /// - There is no bounds checking for performance reasons. Therefore we don't need to store length. (However this could be added as DEBUG-only feature.) + /// This makes an unsafe type! + /// - Currently the arrays provided to BufferPointer need to be pinned. This behaviour could be changed using C#7 features. + /// + /// The type of elements of the array + internal unsafe struct BufferPointer + where T : struct + { + /// + /// Initializes a new instance of the struct from a pinned array and an offset. + /// + /// The pinned array + /// Pointer to the beginning of array + /// The offset inside the array + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BufferPointer(T[] array, void* pointerToArray, int offset) + { + DebugGuard.NotNull(array, nameof(array)); + + this.Array = array; + this.Offset = offset; + this.PointerAtOffset = (IntPtr)pointerToArray + (Unsafe.SizeOf() * offset); + } + + /// + /// Initializes a new instance of the struct from a pinned array. + /// + /// The pinned array + /// Pointer to the start of 'array' + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BufferPointer(T[] array, void* pointerToArray) + { + DebugGuard.NotNull(array, nameof(array)); + + this.Array = array; + this.Offset = 0; + this.PointerAtOffset = (IntPtr)pointerToArray; + } + + /// + /// Gets the array + /// + public T[] Array { get; private set; } + + /// + /// Gets the offset inside + /// + public int Offset { get; private set; } + + /// + /// Gets the offset inside in bytes. + /// + public int ByteOffset => this.Offset * Unsafe.SizeOf(); + + /// + /// Gets the pointer to the offseted array position + /// + public IntPtr PointerAtOffset { get; private set; } + + /// + /// Convertes instance to a raw 'void*' pointer + /// + /// The to convert + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator void*(BufferPointer bufferPointer) + { + return (void*)bufferPointer.PointerAtOffset; + } + + /// + /// Converts instance to a raw 'byte*' pointer + /// + /// The to convert + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator byte*(BufferPointer bufferPointer) + { + return (byte*)bufferPointer.PointerAtOffset; + } + + /// + /// Converts instance to + /// setting it's and to correct values. + /// + /// The to convert + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static explicit operator BufferPointer(BufferPointer source) + { + BufferPointer result = default(BufferPointer); + result.Array = Unsafe.As(source.Array); + result.Offset = source.Offset * Unsafe.SizeOf(); + result.PointerAtOffset = source.PointerAtOffset; + return result; + } + + /// + /// Forms a slice out of the given BufferPointer, beginning at 'offset'. + /// + /// The offset in number of elements + /// The offseted (sliced) BufferPointer + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BufferPointer Slice(int offset) + { + BufferPointer result = default(BufferPointer); + result.Array = this.Array; + result.Offset = this.Offset + offset; + result.PointerAtOffset = this.PointerAtOffset + (Unsafe.SizeOf() * offset); + return result; + } + + /// + /// Clears `count` elements beginning from the pointed position. + /// + /// The number of elements to clear + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear(int count) + { + if (count < 256) + { + Unsafe.InitBlock((void*)this.PointerAtOffset, 0, BufferPointer.USizeOf(count)); + } + else + { + System.Array.Clear(this.Array, this.Offset, count); + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs b/src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs new file mode 100644 index 000000000..2d3d44dda --- /dev/null +++ b/src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs @@ -0,0 +1,214 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System; + using System.Buffers; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Manages a pinned buffer of value type data 'T' as a Disposable resource. + /// The backing array is either pooled or comes from the outside. + /// + /// The value type. + internal class PinnedBuffer : IDisposable + where T : struct + { + /// + /// A handle that allows to access the managed as an unmanaged memory by pinning. + /// + private GCHandle handle; + + /// + /// A value indicating wheter should be returned to + /// when disposing this instance. + /// + private bool isPoolingOwner; + + /// + /// Initializes a new instance of the class. + /// + /// The desired count of elements. (Minimum size for ) + public PinnedBuffer(int count) + { + this.Count = count; + this.Array = PixelDataPool.Rent(count); + this.isPoolingOwner = true; + this.Pin(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The array to pin. + public PinnedBuffer(T[] array) + { + this.Count = array.Length; + this.Array = array; + this.isPoolingOwner = false; + this.Pin(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The count of "relevant" elements in 'array'. + /// The array to pin. + public PinnedBuffer(int count, T[] array) + { + if (array.Length < count) + { + throw new ArgumentException("Can't initialize a PinnedBuffer with array.Length < count", nameof(array)); + } + + this.Count = count; + this.Array = array; + this.isPoolingOwner = false; + this.Pin(); + } + + /// + /// Finalizes an instance of the class. + /// + ~PinnedBuffer() + { + this.UnPin(); + } + + /// + /// Gets a value indicating whether this instance is disposed, or has lost ownership of . + /// + public bool IsDisposedOrLostArrayOwnership { get; private set; } + + /// + /// Gets the count of "relevant" elements. Usually be smaller than 'Array.Length' when is pooled. + /// + public int Count { get; private set; } + + /// + /// Gets the backing pinned array. + /// + public T[] Array { get; private set; } + + /// + /// Gets a pointer to the pinned . + /// + public IntPtr Pointer { get; private set; } + + /// + /// Converts to an . + /// + /// The to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator BufferPointer(PinnedBuffer buffer) + { + return buffer.Slice(); + } + + /// + /// Gets a to the beginning of the raw data of the buffer. + /// + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe BufferPointer Slice() + { + return new BufferPointer(this.Array, (void*)this.Pointer); + } + + /// + /// Gets a to an offseted position inside the buffer. + /// + /// The offset + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe BufferPointer Slice(int offset) + { + return new BufferPointer(this.Array, (void*)this.Pointer, offset); + } + + /// + /// Disposes the instance by unpinning the array, and returning the pooled buffer when necessary. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + if (this.IsDisposedOrLostArrayOwnership) + { + return; + } + + this.IsDisposedOrLostArrayOwnership = true; + this.UnPin(); + + if (this.isPoolingOwner) + { + PixelDataPool.Return(this.Array); + } + + this.isPoolingOwner = false; + this.Array = null; + this.Count = 0; + + GC.SuppressFinalize(this); + } + + /// + /// Unpins and makes the object "quasi-disposed" so the array is no longer owned by this object. + /// If is rented, it's the callers responsibility to return it to it's pool. (Most likely ) + /// + /// The unpinned + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T[] UnPinAndTakeArrayOwnership() + { + if (this.IsDisposedOrLostArrayOwnership) + { + throw new InvalidOperationException("UnPinAndTakeArrayOwnership() is invalid: either PinnedBuffer is disposed or UnPinAndTakeArrayOwnership() has been called multiple times!"); + } + + this.IsDisposedOrLostArrayOwnership = true; + this.UnPin(); + T[] array = this.Array; + this.Array = null; + this.isPoolingOwner = false; + return array; + } + + /// + /// Clears the buffer, filling elements between 0 and -1 with default(T) + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Clear() + { + this.Slice().Clear(this.Count); + } + + /// + /// Pins . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void Pin() + { + this.handle = GCHandle.Alloc(this.Array, GCHandleType.Pinned); + this.Pointer = this.handle.AddrOfPinnedObject(); + } + + /// + /// Unpins . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void UnPin() + { + if (this.Pointer == IntPtr.Zero || !this.handle.IsAllocated) + { + return; + } + + this.handle.Free(); + this.Pointer = IntPtr.Zero; + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Common/Memory/PixelDataPool{T}.cs b/src/ImageSharp/Common/Memory/PixelDataPool{T}.cs new file mode 100644 index 000000000..dcd031f6e --- /dev/null +++ b/src/ImageSharp/Common/Memory/PixelDataPool{T}.cs @@ -0,0 +1,60 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System; + using System.Buffers; + + /// + /// Provides a resource pool that enables reusing instances of value type arrays for image data . + /// + /// The value type. + public class PixelDataPool + where T : struct + { + /// + /// The which is not kept clean. + /// + private static readonly ArrayPool ArrayPool = ArrayPool.Create(CalculateMaxArrayLength(), 50); + + /// + /// Rents the pixel array from the pool. + /// + /// The minimum length of the array to return. + /// The + public static T[] Rent(int minimumLength) + { + return ArrayPool.Rent(minimumLength); + } + + /// + /// Returns the rented pixel array back to the pool. + /// + /// The array to return to the buffer pool. + public static void Return(T[] array) + { + ArrayPool.Return(array); + } + + /// + /// Heuristically calculates a reasonable maxArrayLength value for the backing . + /// + /// The maxArrayLength value + internal static int CalculateMaxArrayLength() + { + // ReSharper disable once SuspiciousTypeConversion.Global + if (default(T) is IPixel) + { + const int MaximumExpectedImageSize = 16384; + return MaximumExpectedImageSize * MaximumExpectedImageSize; + } + else + { + return int.MaxValue; + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index daf68d81b..e9120aa47 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -78,10 +78,10 @@ namespace ImageSharp Configuration config = new Configuration(); // lets try auto loading the known image formats - config.TryAddImageFormat("ImageSharp.Formats.PngFormat, ImageSharp.Formats.Png"); - config.TryAddImageFormat("ImageSharp.Formats.JpegFormat, ImageSharp.Formats.Jpeg"); - config.TryAddImageFormat("ImageSharp.Formats.GifFormat, ImageSharp.Formats.Gif"); - config.TryAddImageFormat("ImageSharp.Formats.BmpFormat, ImageSharp.Formats.Bmp"); + config.AddImageFormat(new Formats.PngFormat()); + config.AddImageFormat(new Formats.JpegFormat()); + config.AddImageFormat(new Formats.GifFormat()); + config.AddImageFormat(new Formats.BmpFormat()); return config; } diff --git a/src/ImageSharp.Formats.Bmp/BmpBitsPerPixel.cs b/src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpBitsPerPixel.cs rename to src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpCompression.cs b/src/ImageSharp/Formats/Bmp/BmpCompression.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpCompression.cs rename to src/ImageSharp/Formats/Bmp/BmpCompression.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpDecoder.cs rename to src/ImageSharp/Formats/Bmp/BmpDecoder.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpDecoderCore.cs rename to src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpEncoder.cs b/src/ImageSharp/Formats/Bmp/BmpEncoder.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpEncoder.cs rename to src/ImageSharp/Formats/Bmp/BmpEncoder.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpEncoderCore.cs rename to src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpEncoderOptions.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpEncoderOptions.cs rename to src/ImageSharp/Formats/Bmp/BmpEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpFileHeader.cs b/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpFileHeader.cs rename to src/ImageSharp/Formats/Bmp/BmpFileHeader.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpFormat.cs b/src/ImageSharp/Formats/Bmp/BmpFormat.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpFormat.cs rename to src/ImageSharp/Formats/Bmp/BmpFormat.cs diff --git a/src/ImageSharp.Formats.Bmp/BmpInfoHeader.cs b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/BmpInfoHeader.cs rename to src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs diff --git a/src/ImageSharp.Formats.Bmp/IBmpEncoderOptions.cs b/src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/IBmpEncoderOptions.cs rename to src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Bmp/ImageExtensions.cs b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs similarity index 100% rename from src/ImageSharp.Formats.Bmp/ImageExtensions.cs rename to src/ImageSharp/Formats/Bmp/ImageExtensions.cs diff --git a/src/ImageSharp.Formats.Bmp/README.md b/src/ImageSharp/Formats/Bmp/README.md similarity index 100% rename from src/ImageSharp.Formats.Bmp/README.md rename to src/ImageSharp/Formats/Bmp/README.md diff --git a/src/ImageSharp.Formats.Gif/DisposalMethod.cs b/src/ImageSharp/Formats/Gif/DisposalMethod.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/DisposalMethod.cs rename to src/ImageSharp/Formats/Gif/DisposalMethod.cs diff --git a/src/ImageSharp.Formats.Gif/GifConstants.cs b/src/ImageSharp/Formats/Gif/GifConstants.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifConstants.cs rename to src/ImageSharp/Formats/Gif/GifConstants.cs diff --git a/src/ImageSharp.Formats.Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifDecoder.cs rename to src/ImageSharp/Formats/Gif/GifDecoder.cs diff --git a/src/ImageSharp.Formats.Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifDecoderCore.cs rename to src/ImageSharp/Formats/Gif/GifDecoderCore.cs diff --git a/src/ImageSharp.Formats.Gif/GifDecoderOptions.cs b/src/ImageSharp/Formats/Gif/GifDecoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifDecoderOptions.cs rename to src/ImageSharp/Formats/Gif/GifDecoderOptions.cs diff --git a/src/ImageSharp.Formats.Gif/GifEncoder.cs b/src/ImageSharp/Formats/Gif/GifEncoder.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifEncoder.cs rename to src/ImageSharp/Formats/Gif/GifEncoder.cs diff --git a/src/ImageSharp.Formats.Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifEncoderCore.cs rename to src/ImageSharp/Formats/Gif/GifEncoderCore.cs diff --git a/src/ImageSharp.Formats.Gif/GifEncoderOptions.cs b/src/ImageSharp/Formats/Gif/GifEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifEncoderOptions.cs rename to src/ImageSharp/Formats/Gif/GifEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Gif/GifFormat.cs b/src/ImageSharp/Formats/Gif/GifFormat.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/GifFormat.cs rename to src/ImageSharp/Formats/Gif/GifFormat.cs diff --git a/src/ImageSharp.Formats.Gif/IGifDecoderOptions.cs b/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/IGifDecoderOptions.cs rename to src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs diff --git a/src/ImageSharp.Formats.Gif/IGifEncoderOptions.cs b/src/ImageSharp/Formats/Gif/IGifEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/IGifEncoderOptions.cs rename to src/ImageSharp/Formats/Gif/IGifEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/ImageExtensions.cs rename to src/ImageSharp/Formats/Gif/ImageExtensions.cs diff --git a/src/ImageSharp.Formats.Gif/LzwDecoder.cs b/src/ImageSharp/Formats/Gif/LzwDecoder.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/LzwDecoder.cs rename to src/ImageSharp/Formats/Gif/LzwDecoder.cs diff --git a/src/ImageSharp.Formats.Gif/LzwEncoder.cs b/src/ImageSharp/Formats/Gif/LzwEncoder.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/LzwEncoder.cs rename to src/ImageSharp/Formats/Gif/LzwEncoder.cs diff --git a/src/ImageSharp.Formats.Gif/PackedField.cs b/src/ImageSharp/Formats/Gif/PackedField.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/PackedField.cs rename to src/ImageSharp/Formats/Gif/PackedField.cs diff --git a/src/ImageSharp.Formats.Gif/README.md b/src/ImageSharp/Formats/Gif/README.md similarity index 100% rename from src/ImageSharp.Formats.Gif/README.md rename to src/ImageSharp/Formats/Gif/README.md diff --git a/src/ImageSharp.Formats.Gif/Sections/GifGraphicsControlExtension.cs b/src/ImageSharp/Formats/Gif/Sections/GifGraphicsControlExtension.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/Sections/GifGraphicsControlExtension.cs rename to src/ImageSharp/Formats/Gif/Sections/GifGraphicsControlExtension.cs diff --git a/src/ImageSharp.Formats.Gif/Sections/GifImageDescriptor.cs b/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/Sections/GifImageDescriptor.cs rename to src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs diff --git a/src/ImageSharp.Formats.Gif/Sections/GifLogicalScreenDescriptor.cs b/src/ImageSharp/Formats/Gif/Sections/GifLogicalScreenDescriptor.cs similarity index 100% rename from src/ImageSharp.Formats.Gif/Sections/GifLogicalScreenDescriptor.cs rename to src/ImageSharp/Formats/Gif/Sections/GifLogicalScreenDescriptor.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Block8x8F.Generated.cs rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Block8x8F.Generated.tt rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt diff --git a/src/ImageSharp.Formats.Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Block8x8F.cs rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/BlockQuad.cs b/src/ImageSharp/Formats/Jpeg/Components/BlockQuad.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/BlockQuad.cs rename to src/ImageSharp/Formats/Jpeg/Components/BlockQuad.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/DCT.cs b/src/ImageSharp/Formats/Jpeg/Components/DCT.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/DCT.cs rename to src/ImageSharp/Formats/Jpeg/Components/DCT.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/Bits.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/Bits.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/Bits.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/Bits.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/Bytes.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/Bytes.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/Bytes.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/Bytes.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/Component.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/Component.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/Component.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/Component.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/ComponentScan.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentScan.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/ComponentScan.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentScan.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/DecodedBlock.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlock.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/DecodedBlock.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlock.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/DecodedBlockArray.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlockArray.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/DecodedBlockArray.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlockArray.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/DecoderErrorCode.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecoderErrorCode.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/DecoderErrorCode.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/DecoderErrorCode.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/DecoderThrowHelper.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecoderThrowHelper.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/DecoderThrowHelper.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/DecoderThrowHelper.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/EOFException.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/EOFException.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/EOFException.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/EOFException.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/HuffmanTree.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTree.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/HuffmanTree.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTree.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/InputProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/InputProcessor.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/InputProcessor.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/InputProcessor.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegBlockProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegBlockProcessor.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegPixelArea.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegPixelArea.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegPixelArea.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.ComputationData.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.ComputationData.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.ComputationData.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.ComputationData.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.DataPointers.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.DataPointers.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.DataPointers.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.DataPointers.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.md b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.md similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.md rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.md diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/MissingFF00Exception.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/MissingFF00Exception.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/MissingFF00Exception.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/MissingFF00Exception.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Decoder/YCbCrImage.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrImage.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Decoder/YCbCrImage.cs rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrImage.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Encoder/HuffIndex.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffIndex.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Encoder/HuffIndex.cs rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffIndex.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Encoder/HuffmanLut.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Encoder/HuffmanLut.cs rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Encoder/HuffmanSpec.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Encoder/HuffmanSpec.cs rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs diff --git a/src/ImageSharp.Formats.Jpeg/Components/Encoder/QuantIndex.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/QuantIndex.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Components/Encoder/QuantIndex.cs rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/QuantIndex.cs diff --git a/src/ImageSharp.Formats.Jpeg/IJpegEncoderOptions.cs b/src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/IJpegEncoderOptions.cs rename to src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Jpeg/ImageExtensions.cs b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/ImageExtensions.cs rename to src/ImageSharp/Formats/Jpeg/ImageExtensions.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegConstants.cs b/src/ImageSharp/Formats/Jpeg/JpegConstants.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegConstants.cs rename to src/ImageSharp/Formats/Jpeg/JpegConstants.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegDecoder.cs rename to src/ImageSharp/Formats/Jpeg/JpegDecoder.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs rename to src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegEncoder.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegEncoder.cs rename to src/ImageSharp/Formats/Jpeg/JpegEncoder.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegEncoderCore.cs rename to src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegEncoderOptions.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegEncoderOptions.cs rename to src/ImageSharp/Formats/Jpeg/JpegEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegFormat.cs b/src/ImageSharp/Formats/Jpeg/JpegFormat.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegFormat.cs rename to src/ImageSharp/Formats/Jpeg/JpegFormat.cs diff --git a/src/ImageSharp.Formats.Jpeg/JpegSubsample.cs b/src/ImageSharp/Formats/Jpeg/JpegSubsample.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/JpegSubsample.cs rename to src/ImageSharp/Formats/Jpeg/JpegSubsample.cs diff --git a/src/ImageSharp.Formats.Jpeg/README.md b/src/ImageSharp/Formats/Jpeg/README.md similarity index 100% rename from src/ImageSharp.Formats.Jpeg/README.md rename to src/ImageSharp/Formats/Jpeg/README.md diff --git a/src/ImageSharp.Formats.Jpeg/UnzigData.cs b/src/ImageSharp/Formats/Jpeg/UnzigData.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/UnzigData.cs rename to src/ImageSharp/Formats/Jpeg/UnzigData.cs diff --git a/src/ImageSharp.Formats.Jpeg/Utils/JpegUtils.cs b/src/ImageSharp/Formats/Jpeg/Utils/JpegUtils.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Utils/JpegUtils.cs rename to src/ImageSharp/Formats/Jpeg/Utils/JpegUtils.cs diff --git a/src/ImageSharp.Formats.Jpeg/Utils/MutableSpan.cs b/src/ImageSharp/Formats/Jpeg/Utils/MutableSpan.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Utils/MutableSpan.cs rename to src/ImageSharp/Formats/Jpeg/Utils/MutableSpan.cs diff --git a/src/ImageSharp.Formats.Jpeg/Utils/MutableSpanExtensions.cs b/src/ImageSharp/Formats/Jpeg/Utils/MutableSpanExtensions.cs similarity index 100% rename from src/ImageSharp.Formats.Jpeg/Utils/MutableSpanExtensions.cs rename to src/ImageSharp/Formats/Jpeg/Utils/MutableSpanExtensions.cs diff --git a/src/ImageSharp.Formats.Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Filters/AverageFilter.cs rename to src/ImageSharp/Formats/Png/Filters/AverageFilter.cs diff --git a/src/ImageSharp.Formats.Png/Filters/FilterType.cs b/src/ImageSharp/Formats/Png/Filters/FilterType.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Filters/FilterType.cs rename to src/ImageSharp/Formats/Png/Filters/FilterType.cs diff --git a/src/ImageSharp.Formats.Png/Filters/NoneFilter.cs b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Filters/NoneFilter.cs rename to src/ImageSharp/Formats/Png/Filters/NoneFilter.cs diff --git a/src/ImageSharp.Formats.Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Filters/PaethFilter.cs rename to src/ImageSharp/Formats/Png/Filters/PaethFilter.cs diff --git a/src/ImageSharp.Formats.Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Filters/SubFilter.cs rename to src/ImageSharp/Formats/Png/Filters/SubFilter.cs diff --git a/src/ImageSharp.Formats.Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Filters/UpFilter.cs rename to src/ImageSharp/Formats/Png/Filters/UpFilter.cs diff --git a/src/ImageSharp.Formats.Png/IPngDecoderOptions.cs b/src/ImageSharp/Formats/Png/IPngDecoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Png/IPngDecoderOptions.cs rename to src/ImageSharp/Formats/Png/IPngDecoderOptions.cs diff --git a/src/ImageSharp.Formats.Png/IPngEncoderOptions.cs b/src/ImageSharp/Formats/Png/IPngEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Png/IPngEncoderOptions.cs rename to src/ImageSharp/Formats/Png/IPngEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Png/ImageExtensions.cs b/src/ImageSharp/Formats/Png/ImageExtensions.cs similarity index 100% rename from src/ImageSharp.Formats.Png/ImageExtensions.cs rename to src/ImageSharp/Formats/Png/ImageExtensions.cs diff --git a/src/ImageSharp.Formats.Png/PngChunk.cs b/src/ImageSharp/Formats/Png/PngChunk.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngChunk.cs rename to src/ImageSharp/Formats/Png/PngChunk.cs diff --git a/src/ImageSharp.Formats.Png/PngChunkTypes.cs b/src/ImageSharp/Formats/Png/PngChunkTypes.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngChunkTypes.cs rename to src/ImageSharp/Formats/Png/PngChunkTypes.cs diff --git a/src/ImageSharp.Formats.Png/PngColorType.cs b/src/ImageSharp/Formats/Png/PngColorType.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngColorType.cs rename to src/ImageSharp/Formats/Png/PngColorType.cs diff --git a/src/ImageSharp.Formats.Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngDecoder.cs rename to src/ImageSharp/Formats/Png/PngDecoder.cs diff --git a/src/ImageSharp.Formats.Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs similarity index 99% rename from src/ImageSharp.Formats.Png/PngDecoderCore.cs rename to src/ImageSharp/Formats/Png/PngDecoderCore.cs index a7765342e..fd03ed39b 100644 --- a/src/ImageSharp.Formats.Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -109,6 +109,11 @@ namespace ImageSharp.Formats /// private byte[] paletteAlpha; + /// + /// A value indicating whether the end chunk has been reached. + /// + private bool isEndChunkReached; + /// /// Initializes static members of the class. /// @@ -158,18 +163,11 @@ namespace ImageSharp.Formats this.currentStream = stream; this.currentStream.Skip(8); - bool isEndChunkReached = false; - using (MemoryStream dataStream = new MemoryStream()) { PngChunk currentChunk; - while ((currentChunk = this.ReadChunk()) != null) + while (!this.isEndChunkReached && (currentChunk = this.ReadChunk()) != null) { - if (isEndChunkReached) - { - throw new ImageFormatException("Image does not end with end chunk."); - } - try { switch (currentChunk.Type) @@ -199,7 +197,7 @@ namespace ImageSharp.Formats this.ReadTextChunk(currentImage, currentChunk.Data, currentChunk.Length); break; case PngChunkTypes.End: - isEndChunkReached = true; + this.isEndChunkReached = true; break; } } diff --git a/src/ImageSharp.Formats.Png/PngDecoderOptions.cs b/src/ImageSharp/Formats/Png/PngDecoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngDecoderOptions.cs rename to src/ImageSharp/Formats/Png/PngDecoderOptions.cs diff --git a/src/ImageSharp.Formats.Png/PngEncoder.cs b/src/ImageSharp/Formats/Png/PngEncoder.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngEncoder.cs rename to src/ImageSharp/Formats/Png/PngEncoder.cs diff --git a/src/ImageSharp.Formats.Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngEncoderCore.cs rename to src/ImageSharp/Formats/Png/PngEncoderCore.cs diff --git a/src/ImageSharp.Formats.Png/PngEncoderOptions.cs b/src/ImageSharp/Formats/Png/PngEncoderOptions.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngEncoderOptions.cs rename to src/ImageSharp/Formats/Png/PngEncoderOptions.cs diff --git a/src/ImageSharp.Formats.Png/PngFormat.cs b/src/ImageSharp/Formats/Png/PngFormat.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngFormat.cs rename to src/ImageSharp/Formats/Png/PngFormat.cs diff --git a/src/ImageSharp.Formats.Png/PngHeader.cs b/src/ImageSharp/Formats/Png/PngHeader.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngHeader.cs rename to src/ImageSharp/Formats/Png/PngHeader.cs diff --git a/src/ImageSharp.Formats.Png/PngInterlaceMode.cs b/src/ImageSharp/Formats/Png/PngInterlaceMode.cs similarity index 100% rename from src/ImageSharp.Formats.Png/PngInterlaceMode.cs rename to src/ImageSharp/Formats/Png/PngInterlaceMode.cs diff --git a/src/ImageSharp.Formats.Png/README.md b/src/ImageSharp/Formats/Png/README.md similarity index 100% rename from src/ImageSharp.Formats.Png/README.md rename to src/ImageSharp/Formats/Png/README.md diff --git a/src/ImageSharp.Formats.Png/Zlib/Adler32.cs b/src/ImageSharp/Formats/Png/Zlib/Adler32.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Zlib/Adler32.cs rename to src/ImageSharp/Formats/Png/Zlib/Adler32.cs diff --git a/src/ImageSharp.Formats.Png/Zlib/Crc32.cs b/src/ImageSharp/Formats/Png/Zlib/Crc32.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Zlib/Crc32.cs rename to src/ImageSharp/Formats/Png/Zlib/Crc32.cs diff --git a/src/ImageSharp.Formats.Png/Zlib/IChecksum.cs b/src/ImageSharp/Formats/Png/Zlib/IChecksum.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Zlib/IChecksum.cs rename to src/ImageSharp/Formats/Png/Zlib/IChecksum.cs diff --git a/src/ImageSharp.Formats.Png/Zlib/README.md b/src/ImageSharp/Formats/Png/Zlib/README.md similarity index 100% rename from src/ImageSharp.Formats.Png/Zlib/README.md rename to src/ImageSharp/Formats/Png/Zlib/README.md diff --git a/src/ImageSharp.Formats.Png/Zlib/ZlibDeflateStream.cs b/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Zlib/ZlibDeflateStream.cs rename to src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs diff --git a/src/ImageSharp.Formats.Png/Zlib/ZlibInflateStream.cs b/src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs similarity index 100% rename from src/ImageSharp.Formats.Png/Zlib/ZlibInflateStream.cs rename to src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs diff --git a/src/ImageSharp/Image.cs b/src/ImageSharp/Image.cs index af31eff79..8bfd8ee1a 100644 --- a/src/ImageSharp/Image.cs +++ b/src/ImageSharp/Image.cs @@ -223,17 +223,5 @@ namespace ImageSharp : base(other) { } - - /// - public override PixelAccessor Lock() - { - return new PixelAccessor(this); - } - - /// - internal override ImageFrame ToFrame() - { - return new ImageFrame(this); - } } } diff --git a/src/ImageSharp/Image/ImageBase{TColor}.cs b/src/ImageSharp/Image/ImageBase{TColor}.cs index e4b4485c7..878ba09b3 100644 --- a/src/ImageSharp/Image/ImageBase{TColor}.cs +++ b/src/ImageSharp/Image/ImageBase{TColor}.cs @@ -60,6 +60,7 @@ namespace ImageSharp { this.Configuration = configuration ?? Configuration.Default; this.InitPixels(width, height); + this.ClearPixels(); } /// @@ -150,7 +151,7 @@ namespace ImageSharp } /// - public virtual PixelAccessor Lock() + public PixelAccessor Lock() { return new PixelAccessor(this); } @@ -162,13 +163,12 @@ namespace ImageSharp internal void SwapPixelsBuffers(PixelAccessor pixelSource) { Guard.NotNull(pixelSource, nameof(pixelSource)); - Guard.IsTrue(pixelSource.PooledMemory, nameof(pixelSource.PooledMemory), "pixelSource must be using pooled memory"); int newWidth = pixelSource.Width; int newHeight = pixelSource.Height; // Push my memory into the accessor (which in turn unpins the old puffer ready for the images use) - TColor[] newPixels = pixelSource.ReturnCurrentPixelsAndReplaceThemInternally(this.Width, this.Height, this.pixelBuffer, true); + TColor[] newPixels = pixelSource.ReturnCurrentPixelsAndReplaceThemInternally(this.Width, this.Height, this.pixelBuffer); this.Width = newWidth; this.Height = newHeight; this.pixelBuffer = newPixels; @@ -222,7 +222,7 @@ namespace ImageSharp /// private void RentPixels() { - this.pixelBuffer = PixelPool.RentPixels(this.Width * this.Height); + this.pixelBuffer = PixelDataPool.Rent(this.Width * this.Height); } /// @@ -230,8 +230,16 @@ namespace ImageSharp /// private void ReturnPixels() { - PixelPool.ReturnPixels(this.pixelBuffer); + PixelDataPool.Return(this.pixelBuffer); this.pixelBuffer = null; } + + /// + /// Clears the pixel array. + /// + private void ClearPixels() + { + Array.Clear(this.pixelBuffer, 0, this.Width * this.Height); + } } } \ No newline at end of file diff --git a/src/ImageSharp/Image/PixelAccessor{TColor}.cs b/src/ImageSharp/Image/PixelAccessor{TColor}.cs index 338f49182..a10676565 100644 --- a/src/ImageSharp/Image/PixelAccessor{TColor}.cs +++ b/src/ImageSharp/Image/PixelAccessor{TColor}.cs @@ -15,24 +15,14 @@ namespace ImageSharp /// Provides per-pixel access to generic pixels. /// /// The pixel format. - public unsafe class PixelAccessor : IDisposable + public sealed unsafe class PixelAccessor : IDisposable where TColor : struct, IPixel { - /// - /// The pointer to the pixel buffer. - /// - private IntPtr dataPointer; - /// /// The position of the first pixel in the image. /// private byte* pixelsBase; - /// - /// Provides a way to access the pixels from unmanaged memory. - /// - private GCHandle pixelsHandle; - /// /// A value indicating whether this instance of the given entity has been disposed. /// @@ -45,9 +35,9 @@ namespace ImageSharp private bool isDisposed; /// - /// The pixel buffer + /// The containing the pixel data. /// - private TColor[] pixelBuffer; + private PinnedBuffer pixelBuffer; /// /// Initializes a new instance of the class. @@ -59,28 +49,17 @@ namespace ImageSharp Guard.MustBeGreaterThan(image.Width, 0, "image width"); Guard.MustBeGreaterThan(image.Height, 0, "image height"); - this.SetPixelBufferUnsafe(image.Width, image.Height, image.Pixels, false); + this.SetPixelBufferUnsafe(image.Width, image.Height, image.Pixels); this.ParallelOptions = image.Configuration.ParallelOptions; } - /// - /// Initializes a new instance of the class. - /// - /// The width of the image represented by the pixel buffer. - /// The height of the image represented by the pixel buffer. - /// The pixel buffer. - public PixelAccessor(int width, int height, TColor[] pixels) - : this(width, height, pixels, false) - { - } - /// /// Initializes a new instance of the class. /// /// The width of the image represented by the pixel buffer. /// The height of the image represented by the pixel buffer. public PixelAccessor(int width, int height) - : this(width, height, PixelPool.RentPixels(width * height), true) + : this(width, height, new PinnedBuffer(width * height)) { } @@ -90,19 +69,13 @@ namespace ImageSharp /// The width of the image represented by the pixel buffer. /// The height of the image represented by the pixel buffer. /// The pixel buffer. - /// if set to true then the is from the thus should be returned once disposed. - private PixelAccessor(int width, int height, TColor[] pixels, bool pooledMemory) + private PixelAccessor(int width, int height, PinnedBuffer pixels) { Guard.NotNull(pixels, nameof(pixels)); Guard.MustBeGreaterThan(width, 0, nameof(width)); Guard.MustBeGreaterThan(height, 0, nameof(height)); - if (!(pixels.Length >= width * height)) - { - throw new ArgumentException($"Pixel array must have the length of at least {width * height}."); - } - - this.SetPixelBufferUnsafe(width, height, pixels, pooledMemory); + this.SetPixelBufferUnsafe(width, height, pixels); this.ParallelOptions = Configuration.Default.ParallelOptions; } @@ -116,14 +89,14 @@ namespace ImageSharp } /// - /// Gets a value indicating whether the current pixel buffer is from a pooled source. + /// Gets the pixel buffer array. /// - public bool PooledMemory { get; private set; } + public TColor[] PixelArray => this.pixelBuffer.Array; /// /// Gets the pointer to the pixel buffer. /// - public IntPtr DataPointer => this.dataPointer; + public IntPtr DataPointer => this.pixelBuffer.Pointer; /// /// Gets the size of a single pixel in the number of bytes. @@ -150,6 +123,8 @@ namespace ImageSharp /// public ParallelOptions ParallelOptions { get; } + private static BulkPixelOperations Operations => BulkPixelOperations.Instance; + /// /// Gets or sets the pixel at the specified position. /// @@ -242,23 +217,17 @@ namespace ImageSharp return; } - this.UnPinPixels(); - // Note disposing is done. this.isDisposed = true; + this.pixelBuffer.Dispose(); + // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SuppressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); - - if (this.PooledMemory) - { - PixelPool.ReturnPixels(this.pixelBuffer); - this.pixelBuffer = null; - } } /// @@ -269,19 +238,29 @@ namespace ImageSharp Unsafe.InitBlock(this.pixelsBase, 0, (uint)(this.RowStride * this.Height)); } + /// + /// Gets a to the row 'y' beginning from the pixel at 'x'. + /// + /// The x coordinate + /// The y coordinate + /// The + internal BufferPointer GetRowPointer(int x, int y) + { + return this.pixelBuffer.Slice((y * this.Width) + x); + } + /// /// Sets the pixel buffer in an unsafe manner. This should not be used unless you know what its doing!!! /// /// The width. /// The height. /// The pixels. - /// If set to true this indicates that the pixel buffer is from a pooled source. /// Returns the old pixel data thats has gust been replaced. - /// If is true then caller is responsible for ensuring is called. - internal TColor[] ReturnCurrentPixelsAndReplaceThemInternally(int width, int height, TColor[] pixels, bool pooledMemory) + /// If is true then caller is responsible for ensuring is called. + internal TColor[] ReturnCurrentPixelsAndReplaceThemInternally(int width, int height, TColor[] pixels) { - TColor[] oldPixels = this.pixelBuffer; - this.SetPixelBufferUnsafe(width, height, pixels, pooledMemory); + TColor[] oldPixels = this.pixelBuffer.UnPinAndTakeArrayOwnership(); + this.SetPixelBufferUnsafe(width, height, pixels); return oldPixels; } @@ -304,24 +283,15 @@ namespace ImageSharp /// The target row index. /// The width. /// The height. - protected virtual void CopyFromZyx(PixelArea area, int targetX, int targetY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyFromZyx(PixelArea area, int targetX, int targetY, int width, int height) { - TColor packed = default(TColor); - int size = Unsafe.SizeOf(); - for (int y = 0; y < height; y++) { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); + BufferPointer source = area.GetRowPointer(y); + BufferPointer destination = this.GetRowPointer(targetX, targetY + y); - for (int x = 0; x < width; x++) - { - packed.PackFromBytes(*(source + 2), *(source + 1), *source, 255); - Unsafe.Write(destination, packed); - - source += 3; - destination += size; - } + Operations.PackFromZyxBytes(source, destination, width); } } @@ -333,24 +303,15 @@ namespace ImageSharp /// The target row index. /// The width. /// The height. - protected virtual void CopyFromZyxw(PixelArea area, int targetX, int targetY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyFromZyxw(PixelArea area, int targetX, int targetY, int width, int height) { - TColor packed = default(TColor); - int size = Unsafe.SizeOf(); - for (int y = 0; y < height; y++) { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); + BufferPointer source = area.GetRowPointer(y); + BufferPointer destination = this.GetRowPointer(targetX, targetY + y); - for (int x = 0; x < width; x++) - { - packed.PackFromBytes(*(source + 2), *(source + 1), *source, *(source + 3)); - Unsafe.Write(destination, packed); - - source += 4; - destination += size; - } + Operations.PackFromZyxwBytes(source, destination, width); } } @@ -362,24 +323,15 @@ namespace ImageSharp /// The target row index. /// The width. /// The height. - protected virtual void CopyFromXyz(PixelArea area, int targetX, int targetY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyFromXyz(PixelArea area, int targetX, int targetY, int width, int height) { - TColor packed = default(TColor); - int size = Unsafe.SizeOf(); - for (int y = 0; y < height; y++) { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); - - for (int x = 0; x < width; x++) - { - packed.PackFromBytes(*source, *(source + 1), *(source + 2), 255); - Unsafe.Write(destination, packed); + BufferPointer source = area.GetRowPointer(y); + BufferPointer destination = this.GetRowPointer(targetX, targetY + y); - source += 3; - destination += size; - } + Operations.PackFromXyzBytes(source, destination, width); } } @@ -391,24 +343,14 @@ namespace ImageSharp /// The target row index. /// The width. /// The height. - protected virtual void CopyFromXyzw(PixelArea area, int targetX, int targetY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyFromXyzw(PixelArea area, int targetX, int targetY, int width, int height) { - TColor packed = default(TColor); - int size = Unsafe.SizeOf(); - for (int y = 0; y < height; y++) { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); - - for (int x = 0; x < width; x++) - { - packed.PackFromBytes(*source, *(source + 1), *(source + 2), *(source + 3)); - Unsafe.Write(destination, packed); - - source += 4; - destination += size; - } + BufferPointer source = area.GetRowPointer(y); + BufferPointer destination = this.GetRowPointer(targetX, targetY + y); + Operations.PackFromXyzwBytes(source, destination, width); } } @@ -420,16 +362,14 @@ namespace ImageSharp /// The source row index. /// The width. /// The height. - protected virtual void CopyToZyx(PixelArea area, int sourceX, int sourceY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyToZyx(PixelArea area, int sourceX, int sourceY, int width, int height) { for (int y = 0; y < height; y++) { - int offset = y * area.RowStride; - for (int x = 0; x < width; x++) - { - this[sourceX + x, sourceY + y].ToZyxBytes(area.Bytes, offset); - offset += 3; - } + BufferPointer source = this.GetRowPointer(sourceX, sourceY + y); + BufferPointer destination = area.GetRowPointer(y); + Operations.ToZyxBytes(source, destination, width); } } @@ -441,16 +381,14 @@ namespace ImageSharp /// The source row index. /// The width. /// The height. - protected virtual void CopyToZyxw(PixelArea area, int sourceX, int sourceY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyToZyxw(PixelArea area, int sourceX, int sourceY, int width, int height) { for (int y = 0; y < height; y++) { - int offset = y * area.RowStride; - for (int x = 0; x < width; x++) - { - this[sourceX + x, sourceY + y].ToZyxwBytes(area.Bytes, offset); - offset += 4; - } + BufferPointer source = this.GetRowPointer(sourceX, sourceY + y); + BufferPointer destination = area.GetRowPointer(y); + Operations.ToZyxwBytes(source, destination, width); } } @@ -462,16 +400,14 @@ namespace ImageSharp /// The source row index. /// The width. /// The height. - protected virtual void CopyToXyz(PixelArea area, int sourceX, int sourceY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyToXyz(PixelArea area, int sourceX, int sourceY, int width, int height) { for (int y = 0; y < height; y++) { - int offset = y * area.RowStride; - for (int x = 0; x < width; x++) - { - this[sourceX + x, sourceY + y].ToXyzBytes(area.Bytes, offset); - offset += 3; - } + BufferPointer source = this.GetRowPointer(sourceX, sourceY + y); + BufferPointer destination = area.GetRowPointer(y); + Operations.ToXyzBytes(source, destination, width); } } @@ -483,30 +419,20 @@ namespace ImageSharp /// The source row index. /// The width. /// The height. - protected virtual void CopyToXyzw(PixelArea area, int sourceX, int sourceY, int width, int height) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CopyToXyzw(PixelArea area, int sourceX, int sourceY, int width, int height) { for (int y = 0; y < height; y++) { - int offset = y * area.RowStride; - for (int x = 0; x < width; x++) - { - this[sourceX + x, sourceY + y].ToXyzwBytes(area.Bytes, offset); - offset += 4; - } + BufferPointer source = this.GetRowPointer(sourceX, sourceY + y); + BufferPointer destination = area.GetRowPointer(y); + Operations.ToXyzwBytes(source, destination, width); } } - /// - /// Gets the pointer at the specified row. - /// - /// The column index. - /// The row index. - /// - /// The . - /// - protected byte* GetRowPointer(int x, int y) + private void SetPixelBufferUnsafe(int width, int height, TColor[] pixels) { - return this.pixelsBase + (((y * this.Width) + x) * Unsafe.SizeOf()); + this.SetPixelBufferUnsafe(width, height, new PinnedBuffer(width * height, pixels)); } /// @@ -514,49 +440,18 @@ namespace ImageSharp /// /// The width. /// The height. - /// The pixels. - /// If set to true this indicates that the pixel buffer is from a pooled source. - private void SetPixelBufferUnsafe(int width, int height, TColor[] pixels, bool pooledMemory) + /// The pixel buffer + private void SetPixelBufferUnsafe(int width, int height, PinnedBuffer pixels) { this.pixelBuffer = pixels; - this.PooledMemory = pooledMemory; + this.pixelsBase = (byte*)pixels.Pointer; + this.Width = width; this.Height = height; - this.PinPixels(); this.PixelSize = Unsafe.SizeOf(); this.RowStride = this.Width * this.PixelSize; } - /// - /// Pins the pixels data. - /// - private void PinPixels() - { - // unpin any old pixels just incase - this.UnPinPixels(); - - this.pixelsHandle = GCHandle.Alloc(this.pixelBuffer, GCHandleType.Pinned); - this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); - this.pixelsBase = (byte*)this.dataPointer.ToPointer(); - } - - /// - /// Unpins pixels data. - /// - private void UnPinPixels() - { - if (this.pixelsBase != null) - { - if (this.pixelsHandle.IsAllocated) - { - this.pixelsHandle.Free(); - } - - this.dataPointer = IntPtr.Zero; - this.pixelsBase = null; - } - } - /// /// Copy an area of pixels to the image. /// diff --git a/src/ImageSharp/Image/PixelArea{TColor}.cs b/src/ImageSharp/Image/PixelArea{TColor}.cs index 77b648ca5..be6debba2 100644 --- a/src/ImageSharp/Image/PixelArea{TColor}.cs +++ b/src/ImageSharp/Image/PixelArea{TColor}.cs @@ -18,21 +18,6 @@ namespace ImageSharp public sealed unsafe class PixelArea : IDisposable where TColor : struct, IPixel { - /// - /// True if was rented from by the constructor - /// - private readonly bool isBufferRented; - - /// - /// Provides a way to access the pixels from unmanaged memory. - /// - private readonly GCHandle pixelsHandle; - - /// - /// The pointer to the pixel buffer. - /// - private IntPtr dataPointer; - /// /// A value indicating whether this instance of the given entity has been disposed. /// @@ -44,6 +29,11 @@ namespace ImageSharp /// private bool isDisposed; + /// + /// The underlying buffer containing the raw pixel data. + /// + private PinnedBuffer byteBuffer; + /// /// Initializes a new instance of the class. /// @@ -76,14 +66,10 @@ namespace ImageSharp this.Height = height; this.ComponentOrder = componentOrder; this.RowStride = width * GetComponentCount(componentOrder); - this.Bytes = bytes; - this.Length = bytes.Length; - this.isBufferRented = false; - this.pixelsHandle = GCHandle.Alloc(this.Bytes, GCHandleType.Pinned); + this.Length = bytes.Length; // TODO: Is this the right value for Length? - // TODO: Why is Resharper warning us about an impure method call? - this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); - this.PixelBase = (byte*)this.dataPointer.ToPointer(); + this.byteBuffer = new PinnedBuffer(bytes); + this.PixelBase = (byte*)this.byteBuffer.Pointer; } /// @@ -132,27 +118,15 @@ namespace ImageSharp this.ComponentOrder = componentOrder; this.RowStride = (width * GetComponentCount(componentOrder)) + padding; this.Length = this.RowStride * height; - this.Bytes = BytesPool.Rent(this.Length); - this.isBufferRented = true; - this.pixelsHandle = GCHandle.Alloc(this.Bytes, GCHandleType.Pinned); - - // TODO: Why is Resharper warning us about an impure method call? - this.dataPointer = this.pixelsHandle.AddrOfPinnedObject(); - this.PixelBase = (byte*)this.dataPointer.ToPointer(); - } - /// - /// Finalizes an instance of the class. - /// - ~PixelArea() - { - this.Dispose(false); + this.byteBuffer = new PinnedBuffer(this.Length); + this.PixelBase = (byte*)this.byteBuffer.Pointer; } /// /// Gets the data in bytes. /// - public byte[] Bytes { get; } + public byte[] Bytes => this.byteBuffer.Array; /// /// Gets the length of the buffer. @@ -167,7 +141,7 @@ namespace ImageSharp /// /// Gets the pointer to the pixel buffer. /// - public IntPtr DataPointer => this.dataPointer; + public IntPtr DataPointer => this.byteBuffer.Pointer; /// /// Gets the height. @@ -189,25 +163,18 @@ namespace ImageSharp /// public int Width { get; } - /// - /// Gets the pool used to rent bytes, when it's not coming from an external source. - /// - // TODO: Use own pool? - private static ArrayPool BytesPool => ArrayPool.Shared; - /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { - this.Dispose(true); + if (this.isDisposed) + { + return; + } - // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SuppressFinalize to - // take this object off the finalization queue - // and prevent finalization code for this object - // from executing a second time. - GC.SuppressFinalize(this); + this.byteBuffer.Dispose(); + this.isDisposed = true; } /// @@ -236,6 +203,16 @@ namespace ImageSharp Unsafe.InitBlock(this.PixelBase, 0, (uint)(this.RowStride * this.Height)); } + /// + /// Gets a to the row y. + /// + /// The y coordinate + /// The + internal BufferPointer GetRowPointer(int y) + { + return this.byteBuffer.Slice(y * this.RowStride); + } + /// /// Gets component count for the given order. /// @@ -282,37 +259,5 @@ namespace ImageSharp $"Invalid byte array length. Length {bytes.Length}; Should be {requiredLength}."); } } - - /// - /// Disposes the object and frees resources for the Garbage Collector. - /// - /// If true, the object gets disposed. - private void Dispose(bool disposing) - { - if (this.isDisposed) - { - return; - } - - if (this.PixelBase == null) - { - return; - } - - if (this.pixelsHandle.IsAllocated) - { - this.pixelsHandle.Free(); - } - - if (disposing && this.isBufferRented) - { - BytesPool.Return(this.Bytes); - } - - this.dataPointer = IntPtr.Zero; - this.PixelBase = null; - - this.isDisposed = true; - } } } \ No newline at end of file diff --git a/src/ImageSharp/Image/PixelPool{TColor}.cs b/src/ImageSharp/Image/PixelPool{TColor}.cs deleted file mode 100644 index 8193600da..000000000 --- a/src/ImageSharp/Image/PixelPool{TColor}.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp -{ - using System; - using System.Buffers; - - /// - /// Provides a resource pool that enables reusing instances of type . - /// - /// The pixel format. - public static class PixelPool - where TColor : struct, IPixel - { - /// - /// The used to pool data. TODO: Choose sensible default size and count - /// - private static readonly ArrayPool ArrayPool = ArrayPool.Create(int.MaxValue, 50); - - /// - /// Rents the pixel array from the pool. - /// - /// The minimum length of the array to return. - /// The - public static TColor[] RentPixels(int minimumLength) - { - return ArrayPool.Rent(minimumLength); - } - - /// - /// Returns the rented pixel array back to the pool. - /// - /// The array to return to the buffer pool. - public static void ReturnPixels(TColor[] array) - { - ArrayPool.Return(array, true); - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/ImageFrame.cs b/src/ImageSharp/ImageFrame.cs deleted file mode 100644 index be654111d..000000000 --- a/src/ImageSharp/ImageFrame.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp -{ - using System.Diagnostics; - - /// - /// An optimized frame for the class. - /// - [DebuggerDisplay("ImageFrame: {Width}x{Height}")] - public sealed class ImageFrame : ImageFrame - { - /// - /// Initializes a new instance of the class. - /// - /// The width of the image in pixels. - /// The height of the image in pixels. - /// - /// The configuration providing initialization code which allows extending the library. - /// - public ImageFrame(int width, int height, Configuration configuration = null) - : base(width, height, configuration) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The image to create the frame from. - /// - public ImageFrame(ImageBase image) - : base(image) - { - } - - /// - public override PixelAccessor Lock() - { - return new PixelAccessor(this); - } - - /// - internal override ImageFrame Clone() - { - return new ImageFrame(this); - } - } -} diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj new file mode 100644 index 000000000..de3e76473 --- /dev/null +++ b/src/ImageSharp/ImageSharp.csproj @@ -0,0 +1,56 @@ + + + A cross-platform library for the processing of image files; written in C# + ImageSharp + 1.0.0-alpha3 + James Jackson-South and contributors + netstandard1.3;netstandard1.1 + true + true + ImageSharp + ImageSharp + Image Resize Crop Gif Jpg Jpeg Bitmap Png Core + https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png + https://github.com/JimBobSquarePants/ImageSharp + http://www.apache.org/licenses/LICENSE-2.0 + git + https://github.com/JimBobSquarePants/ImageSharp + false + false + false + false + false + false + false + false + false + full + portable + True + IOperation + + + + + + + + All + + + + + + + + ..\..\ImageSharp.ruleset + + + true + + + + TextTemplatingFileGenerator + + + \ No newline at end of file diff --git a/src/ImageSharp/ImageSharp.xproj b/src/ImageSharp/ImageSharp.xproj deleted file mode 100644 index bf2f6a67b..000000000 --- a/src/ImageSharp/ImageSharp.xproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 2aa31a1f-142c-43f4-8687-09abca4b3a26 - ImageSharp - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - True - - - - - - \ No newline at end of file diff --git a/src/ImageSharp/PixelAccessor.cs b/src/ImageSharp/PixelAccessor.cs deleted file mode 100644 index 7827e7b47..000000000 --- a/src/ImageSharp/PixelAccessor.cs +++ /dev/null @@ -1,153 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp -{ - using System.Runtime.CompilerServices; - - /// - /// An optimized pixel accessor for the class. - /// - public sealed unsafe class PixelAccessor : PixelAccessor - { - /// - /// Initializes a new instance of the class. - /// - /// The image to provide pixel access for. - public PixelAccessor(ImageBase image) - : base(image) - { - } - - /// - protected override void CopyFromXyzw(PixelArea area, int targetX, int targetY, int width, int height) - { - uint byteCount = (uint)width * 4; - - for (int y = 0; y < height; y++) - { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); - - Unsafe.CopyBlock(destination, source, byteCount); - } - } - - /// - protected override void CopyFromXyz(PixelArea area, int targetX, int targetY, int width, int height) - { - for (int y = 0; y < height; y++) - { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); - - for (int x = 0; x < width; x++) - { - Unsafe.Write(destination, (uint)(*source << 0 | *(source + 1) << 8 | *(source + 2) << 16 | 255 << 24)); - - source += 3; - destination += 4; - } - } - } - - /// - protected override void CopyFromZyx(PixelArea area, int targetX, int targetY, int width, int height) - { - for (int y = 0; y < height; y++) - { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); - - for (int x = 0; x < width; x++) - { - Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | 255 << 24)); - - source += 3; - destination += 4; - } - } - } - - /// - protected override void CopyFromZyxw(PixelArea area, int targetX, int targetY, int width, int height) - { - for (int y = 0; y < height; y++) - { - byte* source = area.PixelBase + (y * area.RowStride); - byte* destination = this.GetRowPointer(targetX, targetY + y); - - for (int x = 0; x < width; x++) - { - Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | *(source + 3) << 24)); - - source += 4; - destination += 4; - } - } - } - - /// - protected override void CopyToZyx(PixelArea area, int sourceX, int sourceY, int width, int height) - { - for (int y = 0; y < height; y++) - { - byte* source = this.GetRowPointer(sourceX, sourceY + y); - byte* destination = area.PixelBase + (y * area.RowStride); - - for (int x = 0; x < width; x++) - { - *destination = *(source + 2); - *(destination + 1) = *(source + 1); - *(destination + 2) = *(source + 0); - - source += 4; - destination += 3; - } - } - } - - /// - protected override void CopyToXyz(PixelArea area, int sourceX, int sourceY, int width, int height) - { - for (int y = 0; y < height; y++) - { - byte* source = this.GetRowPointer(sourceX, sourceY + y); - byte* destination = area.PixelBase + (y * area.RowStride); - - for (int x = 0; x < width; x++) - { - *destination = *(source + 0); - *(destination + 1) = *(source + 1); - *(destination + 2) = *(source + 2); - - source += 4; - destination += 3; - } - } - } - - /// - protected override void CopyToZyxw(PixelArea area, int sourceX, int sourceY, int width, int height) - { - for (int y = 0; y < height; y++) - { - byte* source = this.GetRowPointer(sourceX, sourceY + y); - byte* destination = area.PixelBase + (y * area.RowStride); - - for (int x = 0; x < width; x++) - { - *destination = *(source + 2); - *(destination + 1) = *(source + 1); - *(destination + 2) = *(source + 0); - *(destination + 3) = *(source + 3); - - source += 4; - destination += 4; - } - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp.Processing/Binarization/BinaryThreshold.cs b/src/ImageSharp/Processing/Binarization/BinaryThreshold.cs similarity index 100% rename from src/ImageSharp.Processing/Binarization/BinaryThreshold.cs rename to src/ImageSharp/Processing/Binarization/BinaryThreshold.cs diff --git a/src/ImageSharp.Processing/Binarization/Dither.cs b/src/ImageSharp/Processing/Binarization/Dither.cs similarity index 100% rename from src/ImageSharp.Processing/Binarization/Dither.cs rename to src/ImageSharp/Processing/Binarization/Dither.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/BlackWhite.cs b/src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/BlackWhite.cs rename to src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/ColorBlindness.cs b/src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/ColorBlindness.cs rename to src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Grayscale.cs b/src/ImageSharp/Processing/ColorMatrix/Grayscale.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Grayscale.cs rename to src/ImageSharp/Processing/ColorMatrix/Grayscale.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Hue.cs b/src/ImageSharp/Processing/ColorMatrix/Hue.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Hue.cs rename to src/ImageSharp/Processing/ColorMatrix/Hue.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Kodachrome.cs b/src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Kodachrome.cs rename to src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Lomograph.cs b/src/ImageSharp/Processing/ColorMatrix/Lomograph.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Lomograph.cs rename to src/ImageSharp/Processing/ColorMatrix/Lomograph.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Options/ColorBlindness.cs b/src/ImageSharp/Processing/ColorMatrix/Options/ColorBlindness.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Options/ColorBlindness.cs rename to src/ImageSharp/Processing/ColorMatrix/Options/ColorBlindness.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Options/GrayscaleMode.cs b/src/ImageSharp/Processing/ColorMatrix/Options/GrayscaleMode.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Options/GrayscaleMode.cs rename to src/ImageSharp/Processing/ColorMatrix/Options/GrayscaleMode.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Polaroid.cs b/src/ImageSharp/Processing/ColorMatrix/Polaroid.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Polaroid.cs rename to src/ImageSharp/Processing/ColorMatrix/Polaroid.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Saturation.cs b/src/ImageSharp/Processing/ColorMatrix/Saturation.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Saturation.cs rename to src/ImageSharp/Processing/ColorMatrix/Saturation.cs diff --git a/src/ImageSharp.Processing/ColorMatrix/Sepia.cs b/src/ImageSharp/Processing/ColorMatrix/Sepia.cs similarity index 100% rename from src/ImageSharp.Processing/ColorMatrix/Sepia.cs rename to src/ImageSharp/Processing/ColorMatrix/Sepia.cs diff --git a/src/ImageSharp.Processing/Convolution/BoxBlur.cs b/src/ImageSharp/Processing/Convolution/BoxBlur.cs similarity index 100% rename from src/ImageSharp.Processing/Convolution/BoxBlur.cs rename to src/ImageSharp/Processing/Convolution/BoxBlur.cs diff --git a/src/ImageSharp.Processing/Convolution/DetectEdges.cs b/src/ImageSharp/Processing/Convolution/DetectEdges.cs similarity index 100% rename from src/ImageSharp.Processing/Convolution/DetectEdges.cs rename to src/ImageSharp/Processing/Convolution/DetectEdges.cs diff --git a/src/ImageSharp.Processing/Convolution/GaussianBlur.cs b/src/ImageSharp/Processing/Convolution/GaussianBlur.cs similarity index 100% rename from src/ImageSharp.Processing/Convolution/GaussianBlur.cs rename to src/ImageSharp/Processing/Convolution/GaussianBlur.cs diff --git a/src/ImageSharp.Processing/Convolution/GaussianSharpen.cs b/src/ImageSharp/Processing/Convolution/GaussianSharpen.cs similarity index 100% rename from src/ImageSharp.Processing/Convolution/GaussianSharpen.cs rename to src/ImageSharp/Processing/Convolution/GaussianSharpen.cs diff --git a/src/ImageSharp.Processing/Convolution/Options/EdgeDetection.cs b/src/ImageSharp/Processing/Convolution/Options/EdgeDetection.cs similarity index 100% rename from src/ImageSharp.Processing/Convolution/Options/EdgeDetection.cs rename to src/ImageSharp/Processing/Convolution/Options/EdgeDetection.cs diff --git a/src/ImageSharp.Processing/Effects/Alpha.cs b/src/ImageSharp/Processing/Effects/Alpha.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/Alpha.cs rename to src/ImageSharp/Processing/Effects/Alpha.cs diff --git a/src/ImageSharp.Processing/Effects/BackgroundColor.cs b/src/ImageSharp/Processing/Effects/BackgroundColor.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/BackgroundColor.cs rename to src/ImageSharp/Processing/Effects/BackgroundColor.cs diff --git a/src/ImageSharp.Processing/Effects/Brightness.cs b/src/ImageSharp/Processing/Effects/Brightness.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/Brightness.cs rename to src/ImageSharp/Processing/Effects/Brightness.cs diff --git a/src/ImageSharp.Processing/Effects/Contrast.cs b/src/ImageSharp/Processing/Effects/Contrast.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/Contrast.cs rename to src/ImageSharp/Processing/Effects/Contrast.cs diff --git a/src/ImageSharp.Processing/Effects/Invert.cs b/src/ImageSharp/Processing/Effects/Invert.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/Invert.cs rename to src/ImageSharp/Processing/Effects/Invert.cs diff --git a/src/ImageSharp.Processing/Effects/OilPainting.cs b/src/ImageSharp/Processing/Effects/OilPainting.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/OilPainting.cs rename to src/ImageSharp/Processing/Effects/OilPainting.cs diff --git a/src/ImageSharp.Processing/Effects/Pixelate.cs b/src/ImageSharp/Processing/Effects/Pixelate.cs similarity index 100% rename from src/ImageSharp.Processing/Effects/Pixelate.cs rename to src/ImageSharp/Processing/Effects/Pixelate.cs diff --git a/src/ImageSharp.Processing/Overlays/Glow.cs b/src/ImageSharp/Processing/Overlays/Glow.cs similarity index 100% rename from src/ImageSharp.Processing/Overlays/Glow.cs rename to src/ImageSharp/Processing/Overlays/Glow.cs diff --git a/src/ImageSharp.Processing/Overlays/Vignette.cs b/src/ImageSharp/Processing/Overlays/Vignette.cs similarity index 100% rename from src/ImageSharp.Processing/Overlays/Vignette.cs rename to src/ImageSharp/Processing/Overlays/Vignette.cs diff --git a/src/ImageSharp.Processing/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Binarization/BinaryThresholdProcessor.cs rename to src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs rename to src/ImageSharp/Processing/Processors/Binarization/ErrorDiffusionDitherProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Binarization/OrderedDitherProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Binarization/OrderedDitherProcessor.cs rename to src/ImageSharp/Processing/Processors/Binarization/OrderedDitherProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/BlackWhiteProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/BlackWhiteProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/BlackWhiteProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/BlackWhiteProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/README.md b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/README.md similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/README.md rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/README.md diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/ColorMatrixFilter.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/ColorMatrixFilter.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/ColorMatrixFilter.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/ColorMatrixFilter.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/GrayscaleBt601Processor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt601Processor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/GrayscaleBt601Processor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt601Processor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/GrayscaleBt709Processor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt709Processor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/GrayscaleBt709Processor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/GrayscaleBt709Processor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/HueProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/HueProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/HueProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/HueProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/IColorMatrixFilter.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/IColorMatrixFilter.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/IColorMatrixFilter.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/IColorMatrixFilter.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/KodachromeProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/KodachromeProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/KodachromeProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/KodachromeProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/LomographProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/LomographProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/LomographProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/PolaroidProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/PolaroidProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/SaturationProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/SaturationProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/SaturationProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/SaturationProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/ColorMatrix/SepiaProcessor.cs b/src/ImageSharp/Processing/Processors/ColorMatrix/SepiaProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/ColorMatrix/SepiaProcessor.cs rename to src/ImageSharp/Processing/Processors/ColorMatrix/SepiaProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/BoxBlurProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/Convolution2DProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/Convolution2PassProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/ConvolutionProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/IEdgeDetectorProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/KirschProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/PrewittProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/ScharrProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/EdgeDetection/SobelProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/GaussianBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/GaussianBlurProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Convolution/GaussianSharpenProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Convolution/GaussianSharpenProcessor.cs rename to src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/AlphaProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/AlphaProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/AlphaProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/AlphaProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/BackgroundColorProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/BackgroundColorProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/BrightnessProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/BrightnessProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/BrightnessProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/BrightnessProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/ContrastProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/ContrastProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/ContrastProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/ContrastProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/InvertProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/InvertProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/InvertProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/InvertProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/OilPaintingProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/OilPaintingProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Effects/PixelateProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Effects/PixelateProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Overlays/GlowProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Overlays/GlowProcessor.cs rename to src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Overlays/VignetteProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Overlays/VignetteProcessor.cs rename to src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/CompandingResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/CompandingResizeProcessor.cs similarity index 94% rename from src/ImageSharp.Processing/Processors/Transforms/CompandingResizeProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/CompandingResizeProcessor.cs index 53da21483..2190254f0 100644 --- a/src/ImageSharp.Processing/Processors/Transforms/CompandingResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/CompandingResizeProcessor.cs @@ -56,6 +56,8 @@ namespace ImageSharp.Processing.Processors int width = this.Width; int height = this.Height; + int sourceX = sourceRectangle.X; + int sourceY = sourceRectangle.Y; int startY = this.ResizeRectangle.Y; int endY = this.ResizeRectangle.Bottom; int startX = this.ResizeRectangle.X; @@ -83,12 +85,12 @@ namespace ImageSharp.Processing.Processors y => { // Y coordinates of source points - int originY = (int)((y - startY) * heightFactor); + int originY = (int)(((y - startY) * heightFactor) + sourceY); for (int x = minX; x < maxX; x++) { // X coordinates of source points - targetPixels[x, y] = sourcePixels[(int)((x - startX) * widthFactor), originY]; + targetPixels[x, y] = sourcePixels[(int)(((x - startX) * widthFactor) + sourceX), originY]; } }); } @@ -110,7 +112,7 @@ namespace ImageSharp.Processing.Processors { Parallel.For( 0, - sourceRectangle.Height, + sourceRectangle.Bottom, this.ParallelOptions, y => { @@ -125,7 +127,7 @@ namespace ImageSharp.Processing.Processors for (int i = 0; i < horizontalValues.Length; i++) { Weight xw = horizontalValues[i]; - destination += sourcePixels[xw.Index, y].ToVector4().Expand() * xw.Value; + destination += sourcePixels[xw.Index + sourceX, y].ToVector4().Expand() * xw.Value; } TColor d = default(TColor); @@ -152,7 +154,7 @@ namespace ImageSharp.Processing.Processors for (int i = 0; i < verticalValues.Length; i++) { Weight yw = verticalValues[i]; - destination += firstPassPixels[x, yw.Index].ToVector4().Expand() * yw.Value; + destination += firstPassPixels[x, yw.Index + sourceY].ToVector4().Expand() * yw.Value; } TColor d = default(TColor); diff --git a/src/ImageSharp.Processing/Processors/Transforms/CropProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/CropProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/CropProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/EntropyCropProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/FlipProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/FlipProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/FlipProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/Matrix3x2Processor.cs b/src/ImageSharp/Processing/Processors/Transforms/Matrix3x2Processor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/Matrix3x2Processor.cs rename to src/ImageSharp/Processing/Processors/Transforms/Matrix3x2Processor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/ResamplingWeightedProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/ResamplingWeightedProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs similarity index 94% rename from src/ImageSharp.Processing/Processors/Transforms/ResizeProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index f4ec39f78..9ec804aa4 100644 --- a/src/ImageSharp.Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -55,6 +55,8 @@ namespace ImageSharp.Processing.Processors int width = this.Width; int height = this.Height; + int sourceX = sourceRectangle.X; + int sourceY = sourceRectangle.Y; int startY = this.ResizeRectangle.Y; int endY = this.ResizeRectangle.Bottom; int startX = this.ResizeRectangle.X; @@ -82,12 +84,12 @@ namespace ImageSharp.Processing.Processors y => { // Y coordinates of source points - int originY = (int)((y - startY) * heightFactor); + int originY = (int)(((y - startY) * heightFactor) + sourceY); for (int x = minX; x < maxX; x++) { // X coordinates of source points - targetPixels[x, y] = sourcePixels[(int)((x - startX) * widthFactor), originY]; + targetPixels[x, y] = sourcePixels[(int)(((x - startX) * widthFactor) + sourceX), originY]; } }); } @@ -109,7 +111,7 @@ namespace ImageSharp.Processing.Processors { Parallel.For( 0, - sourceRectangle.Height, + sourceRectangle.Bottom, this.ParallelOptions, y => { @@ -124,7 +126,7 @@ namespace ImageSharp.Processing.Processors for (int i = 0; i < horizontalValues.Length; i++) { Weight xw = horizontalValues[i]; - destination += sourcePixels[xw.Index, y].ToVector4() * xw.Value; + destination += sourcePixels[xw.Index + sourceX, y].ToVector4() * xw.Value; } TColor d = default(TColor); @@ -151,7 +153,7 @@ namespace ImageSharp.Processing.Processors for (int i = 0; i < verticalValues.Length; i++) { Weight yw = verticalValues[i]; - destination += firstPassPixels[x, yw.Index].ToVector4() * yw.Value; + destination += firstPassPixels[x, yw.Index + sourceY].ToVector4() * yw.Value; } TColor d = default(TColor); diff --git a/src/ImageSharp.Processing/Processors/Transforms/RotateProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/RotateProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs diff --git a/src/ImageSharp.Processing/Processors/Transforms/SkewProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs similarity index 100% rename from src/ImageSharp.Processing/Processors/Transforms/SkewProcessor.cs rename to src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs diff --git a/src/ImageSharp.Processing/Transforms/AutoOrient.cs b/src/ImageSharp/Processing/Transforms/AutoOrient.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/AutoOrient.cs rename to src/ImageSharp/Processing/Transforms/AutoOrient.cs diff --git a/src/ImageSharp.Processing/Transforms/Crop.cs b/src/ImageSharp/Processing/Transforms/Crop.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Crop.cs rename to src/ImageSharp/Processing/Transforms/Crop.cs diff --git a/src/ImageSharp.Processing/Transforms/EntropyCrop.cs b/src/ImageSharp/Processing/Transforms/EntropyCrop.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/EntropyCrop.cs rename to src/ImageSharp/Processing/Transforms/EntropyCrop.cs diff --git a/src/ImageSharp.Processing/Transforms/Flip.cs b/src/ImageSharp/Processing/Transforms/Flip.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Flip.cs rename to src/ImageSharp/Processing/Transforms/Flip.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/AnchorPosition.cs b/src/ImageSharp/Processing/Transforms/Options/AnchorPosition.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/AnchorPosition.cs rename to src/ImageSharp/Processing/Transforms/Options/AnchorPosition.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/FlipType.cs b/src/ImageSharp/Processing/Transforms/Options/FlipType.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/FlipType.cs rename to src/ImageSharp/Processing/Transforms/Options/FlipType.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/Orientation.cs b/src/ImageSharp/Processing/Transforms/Options/Orientation.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/Orientation.cs rename to src/ImageSharp/Processing/Transforms/Options/Orientation.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/ResizeHelper.cs b/src/ImageSharp/Processing/Transforms/Options/ResizeHelper.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/ResizeHelper.cs rename to src/ImageSharp/Processing/Transforms/Options/ResizeHelper.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/ResizeMode.cs b/src/ImageSharp/Processing/Transforms/Options/ResizeMode.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/ResizeMode.cs rename to src/ImageSharp/Processing/Transforms/Options/ResizeMode.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/ResizeOptions.cs b/src/ImageSharp/Processing/Transforms/Options/ResizeOptions.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/ResizeOptions.cs rename to src/ImageSharp/Processing/Transforms/Options/ResizeOptions.cs diff --git a/src/ImageSharp.Processing/Transforms/Options/RotateType.cs b/src/ImageSharp/Processing/Transforms/Options/RotateType.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Options/RotateType.cs rename to src/ImageSharp/Processing/Transforms/Options/RotateType.cs diff --git a/src/ImageSharp.Processing/Transforms/Pad.cs b/src/ImageSharp/Processing/Transforms/Pad.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Pad.cs rename to src/ImageSharp/Processing/Transforms/Pad.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/BicubicResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/BicubicResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/BicubicResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/BicubicResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/BoxResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/BoxResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/BoxResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/BoxResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/CatmullRomResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/CatmullRomResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/CatmullRomResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/CatmullRomResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/HermiteResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/HermiteResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/HermiteResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/HermiteResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/IResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/IResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/IResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/IResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/Lanczos2Resampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/Lanczos2Resampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/Lanczos2Resampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/Lanczos2Resampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/Lanczos3Resampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/Lanczos3Resampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/Lanczos3Resampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/Lanczos3Resampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/Lanczos5Resampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/Lanczos5Resampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/Lanczos5Resampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/Lanczos5Resampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/Lanczos8Resampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/Lanczos8Resampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/Lanczos8Resampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/Lanczos8Resampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/MitchellNetravaliResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/MitchellNetravaliResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/MitchellNetravaliResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/MitchellNetravaliResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/NearestNeighborResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/NearestNeighborResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/NearestNeighborResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/NearestNeighborResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/RobidouxResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/RobidouxResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/RobidouxResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/RobidouxResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/RobidouxSharpResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/RobidouxSharpResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/RobidouxSharpResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/RobidouxSharpResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/SplineResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/SplineResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/SplineResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/SplineResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/TriangleResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/TriangleResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/TriangleResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/TriangleResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resamplers/WelchResampler.cs b/src/ImageSharp/Processing/Transforms/Resamplers/WelchResampler.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resamplers/WelchResampler.cs rename to src/ImageSharp/Processing/Transforms/Resamplers/WelchResampler.cs diff --git a/src/ImageSharp.Processing/Transforms/Resize.cs b/src/ImageSharp/Processing/Transforms/Resize.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Resize.cs rename to src/ImageSharp/Processing/Transforms/Resize.cs diff --git a/src/ImageSharp.Processing/Transforms/Rotate.cs b/src/ImageSharp/Processing/Transforms/Rotate.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Rotate.cs rename to src/ImageSharp/Processing/Transforms/Rotate.cs diff --git a/src/ImageSharp.Processing/Transforms/RotateFlip.cs b/src/ImageSharp/Processing/Transforms/RotateFlip.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/RotateFlip.cs rename to src/ImageSharp/Processing/Transforms/RotateFlip.cs diff --git a/src/ImageSharp.Processing/Transforms/Skew.cs b/src/ImageSharp/Processing/Transforms/Skew.cs similarity index 100% rename from src/ImageSharp.Processing/Transforms/Skew.cs rename to src/ImageSharp/Processing/Transforms/Skew.cs diff --git a/src/ImageSharp/Properties/AssemblyInfo.cs b/src/ImageSharp/Properties/AssemblyInfo.cs index 407a17b85..e791dff5a 100644 --- a/src/ImageSharp/Properties/AssemblyInfo.cs +++ b/src/ImageSharp/Properties/AssemblyInfo.cs @@ -5,9 +5,4 @@ using System.Runtime.CompilerServices; // Ensure the other projects can see the internal helpers -[assembly: InternalsVisibleTo("ImageSharp.Drawing")] -[assembly: InternalsVisibleTo("ImageSharp.Formats.Bmp")] -[assembly: InternalsVisibleTo("ImageSharp.Formats.Gif")] -[assembly: InternalsVisibleTo("ImageSharp.Formats.Jpeg")] -[assembly: InternalsVisibleTo("ImageSharp.Formats.Png")] -[assembly: InternalsVisibleTo("ImageSharp.Processing")] \ No newline at end of file +[assembly: InternalsVisibleTo("ImageSharp.Drawing")] \ No newline at end of file diff --git a/src/ImageSharp/project.json b/src/ImageSharp/project.json deleted file mode 100644 index 639773377..000000000 --- a/src/ImageSharp/project.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "version": "1.0.0-alpha2-*", - "title": "ImageSharp", - "description": "A cross-platform library for the processing of image files; written in C#", - "authors": [ - "James Jackson-South and contributors" - ], - "packOptions": { - "owners": [ - "James Jackson-South and contributors" - ], - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", - "requireLicenseAcceptance": false, - "repository": { - "type": "git", - "url": "https://github.com/JimBobSquarePants/ImageSharp" - }, - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true, - "xmlDoc": true, - "additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], - "compile": [ - "../Shared/*.cs" - ] - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true, - "optimize": true - } - } - }, - "dependencies": { - "StyleCop.Analyzers": { - "version": "1.1.0-beta001", - "type": "build" - }, - "System.Buffers": "4.0.0", - "System.Runtime.CompilerServices.Unsafe": "4.0.0" - }, - "frameworks": { - "netstandard1.3": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.FileSystem": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "netstandard1.1": { - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.ObjectModel": "4.0.12", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Runtime.Numerics": "4.0.1", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - } - }, - "net45": { - "dependencies": { - "System.Numerics.Vectors": "4.1.1", - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" } - } - }, - "net461": { - "dependencies": { - "System.Threading.Tasks.Parallel": "4.0.0" - }, - "frameworkAssemblies": { - "System.Runtime": { "type": "build" }, - "System.Numerics": "4.0.0.0" - } - } - } -} \ No newline at end of file diff --git a/src/Shared/AssemblyInfo.Common.cs b/src/Shared/AssemblyInfo.Common.cs index 11f16769b..252ef3eae 100644 --- a/src/Shared/AssemblyInfo.Common.cs +++ b/src/Shared/AssemblyInfo.Common.cs @@ -33,7 +33,8 @@ using System.Runtime.CompilerServices; [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0.0")] -// Ensure the internals can be tested. +// Ensure the internals can be built and tested. +[assembly: InternalsVisibleTo("ImageSharp.Drawing")] [assembly: InternalsVisibleTo("ImageSharp.Benchmarks")] [assembly: InternalsVisibleTo("ImageSharp.Tests")] [assembly: InternalsVisibleTo("ImageSharp.Sandbox46")] \ No newline at end of file diff --git a/tests/CodeCoverage/CodeCoverage.cmd b/tests/CodeCoverage/CodeCoverage.cmd index e4fe3f938..1e16d5c14 100644 --- a/tests/CodeCoverage/CodeCoverage.cmd +++ b/tests/CodeCoverage/CodeCoverage.cmd @@ -1,18 +1,17 @@ @echo off + cd tests\CodeCoverage nuget restore packages.config -PackagesDirectory . -cd ..\ImageSharp.Tests - -dotnet restore - cd .. cd .. +dotnet restore ImageSharp.sln +dotnet build ImageSharp.sln --no-incremental -c release /p:codecov=true rem The -threshold options prevents this taking ages... -tests\CodeCoverage\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:"C:\Program Files\dotnet\dotnet.exe" -targetargs:"test tests\ImageSharp.Tests -c Release -f net451" -threshold:10 -register:user -filter:"+[ImageSharp*]*" -excludebyattribute:*.ExcludeFromCodeCoverage* -hideskipped:All -returntargetcode -output:.\ImageSharp.Coverage.xml +tests\CodeCoverage\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:"dotnet.exe" -targetargs:"test tests\ImageSharp.Tests\ImageSharp.Tests.csproj --no-build -c release /p:codecov=true" -register:user -threshold:10 -oldStyle -safemode:off -output:.\ImageSharp.Coverage.xml -hideskipped:All -returntargetcode -filter:"+[ImageSharp*]*" if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/tests/ImageSharp.Benchmarks/Benchmark.cmd b/tests/ImageSharp.Benchmarks/Benchmark.cmd deleted file mode 100644 index f777e5b8f..000000000 --- a/tests/ImageSharp.Benchmarks/Benchmark.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -dotnet run --configuration Release -pause diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs new file mode 100644 index 000000000..1c541d28b --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs @@ -0,0 +1,63 @@ +// ReSharper disable InconsistentNaming +namespace ImageSharp.Benchmarks.Color.Bulk +{ + using BenchmarkDotNet.Attributes; + + using Color = ImageSharp.Color; + + public abstract class PackFromXyzw + where TColor : struct, IPixel + { + private PinnedBuffer destination; + + private PinnedBuffer source; + + [Params(16, 128, 1024)] + public int Count { get; set; } + + [Setup] + public void Setup() + { + this.destination = new PinnedBuffer(this.Count); + this.source = new PinnedBuffer(this.Count * 4); + } + + [Cleanup] + public void Cleanup() + { + this.destination.Dispose(); + this.source.Dispose(); + } + + [Benchmark(Baseline = true)] + public void PerElement() + { + byte[] s = this.source.Array; + TColor[] d = this.destination.Array; + + for (int i = 0; i < this.Count; i++) + { + int i4 = i * 4; + TColor c = default(TColor); + c.PackFromBytes(s[i4], s[i4 + 1], s[i4 + 2], s[i4 + 3]); + d[i] = c; + } + } + + [Benchmark] + public void CommonBulk() + { + new BulkPixelOperations().PackFromXyzwBytes(this.source, this.destination, this.Count); + } + + [Benchmark] + public void OptimizedBulk() + { + BulkPixelOperations.Instance.PackFromXyzwBytes(this.source, this.destination, this.Count); + } + } + + public class PackFromXyzw_Color : PackFromXyzw + { + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs new file mode 100644 index 000000000..b48eaa35a --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -0,0 +1,61 @@ +// ReSharper disable InconsistentNaming +namespace ImageSharp.Benchmarks.Color.Bulk +{ + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public abstract class ToVector4 + where TColor : struct, IPixel + { + private PinnedBuffer source; + + private PinnedBuffer destination; + + [Params(64, 300, 1024)] + public int Count { get; set; } + + [Setup] + public void Setup() + { + this.source = new PinnedBuffer(this.Count); + this.destination = new PinnedBuffer(this.Count); + } + + [Cleanup] + public void Cleanup() + { + this.source.Dispose(); + this.destination.Dispose(); + } + + [Benchmark(Baseline = true)] + public void PerElement() + { + TColor[] s = this.source.Array; + Vector4[] d = this.destination.Array; + + for (int i = 0; i < this.Count; i++) + { + TColor c = s[i]; + d[i] = c.ToVector4(); + } + } + + [Benchmark] + public void CommonBulk() + { + new BulkPixelOperations().ToVector4(this.source, this.destination, this.Count); + } + + [Benchmark] + public void OptimizedBulk() + { + BulkPixelOperations.Instance.ToVector4(this.source, this.destination, this.Count); + } + } + + public class ToVector4_Color : ToVector4 + { + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs new file mode 100644 index 000000000..bc59dba4e --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs @@ -0,0 +1,61 @@ +// ReSharper disable InconsistentNaming +namespace ImageSharp.Benchmarks.Color.Bulk +{ + using BenchmarkDotNet.Attributes; + + using Color = ImageSharp.Color; + + public abstract class ToXyz + where TColor : struct, IPixel + { + private PinnedBuffer source; + + private PinnedBuffer destination; + + [Params(16, 128, 1024)] + public int Count { get; set; } + + [Setup] + public void Setup() + { + this.source = new PinnedBuffer(this.Count); + this.destination = new PinnedBuffer(this.Count * 3); + } + + [Cleanup] + public void Cleanup() + { + this.source.Dispose(); + this.destination.Dispose(); + } + + [Benchmark(Baseline = true)] + public void PerElement() + { + TColor[] s = this.source.Array; + byte[] d = this.destination.Array; + + for (int i = 0; i < this.Count; i++) + { + TColor c = s[i]; + c.ToXyzBytes(d, i * 4); + } + } + + [Benchmark] + public void CommonBulk() + { + new BulkPixelOperations().ToXyzBytes(this.source, this.destination, this.Count); + } + + [Benchmark] + public void OptimizedBulk() + { + BulkPixelOperations.Instance.ToXyzBytes(this.source, this.destination, this.Count); + } + } + + public class ToXyz_Color : ToXyz + { + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs new file mode 100644 index 000000000..a4ec6f6dc --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +// ReSharper disable InconsistentNaming + +namespace ImageSharp.Benchmarks.Color.Bulk +{ + using BenchmarkDotNet.Attributes; + + using Color = ImageSharp.Color; + + public abstract class ToXyzw + where TColor : struct, IPixel + { + private PinnedBuffer source; + + private PinnedBuffer destination; + + [Params(16, 128, 1024)] + public int Count { get; set; } + + [Setup] + public void Setup() + { + this.source = new PinnedBuffer(this.Count); + this.destination = new PinnedBuffer(this.Count * 4); + } + + [Cleanup] + public void Cleanup() + { + this.source.Dispose(); + this.destination.Dispose(); + } + + [Benchmark(Baseline = true)] + public void PerElement() + { + TColor[] s = this.source.Array; + byte[] d = this.destination.Array; + + for (int i = 0; i < this.Count; i++) + { + TColor c = s[i]; + c.ToXyzwBytes(d, i * 4); + } + } + + [Benchmark] + public void CommonBulk() + { + new BulkPixelOperations().ToXyzwBytes(this.source, this.destination, this.Count); + } + + [Benchmark] + public void OptimizedBulk() + { + BulkPixelOperations.Instance.ToXyzwBytes(this.source, this.destination, this.Count); + } + } + + public class ToXyzw_Color : ToXyzw + { + } + + public class ToXyzw_Argb : ToXyzw + { + } +} diff --git a/tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs b/tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs index c066ac18c..a10417b90 100644 --- a/tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs +++ b/tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs @@ -28,7 +28,7 @@ namespace ImageSharp.Benchmarks { graphics.InterpolationMode = InterpolationMode.Default; graphics.SmoothingMode = SmoothingMode.AntiAlias; - var pen = new Pen(Color.HotPink, 10); + var pen = new Pen(System.Drawing.Color.HotPink, 10); graphics.DrawBeziers(pen, new[] { new PointF(10, 500), new PointF(30, 10), diff --git a/tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs b/tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs index 78f71b660..146def363 100644 --- a/tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs +++ b/tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs @@ -28,7 +28,7 @@ namespace ImageSharp.Benchmarks { graphics.InterpolationMode = InterpolationMode.Default; graphics.SmoothingMode = SmoothingMode.AntiAlias; - var pen = new Pen(Color.HotPink, 10); + var pen = new Pen(System.Drawing.Color.HotPink, 10); graphics.DrawLines(pen, new[] { new PointF(10, 10), new PointF(550, 50), diff --git a/tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs b/tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs index 88618b912..e6c1ac0d6 100644 --- a/tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs +++ b/tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs @@ -27,7 +27,7 @@ namespace ImageSharp.Benchmarks { graphics.InterpolationMode = InterpolationMode.Default; graphics.SmoothingMode = SmoothingMode.AntiAlias; - var pen = new Pen(Color.HotPink, 10); + var pen = new Pen(System.Drawing.Color.HotPink, 10); graphics.DrawPolygon(pen, new[] { new PointF(10, 10), new PointF(550, 50), diff --git a/tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs b/tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs index 718474f1f..589ac0cd4 100644 --- a/tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs +++ b/tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs @@ -25,7 +25,7 @@ namespace ImageSharp.Benchmarks using (Graphics graphics = Graphics.FromImage(destination)) { graphics.SmoothingMode = SmoothingMode.AntiAlias; - var brush = new HatchBrush(HatchStyle.BackwardDiagonal, Color.HotPink); + var brush = new HatchBrush(HatchStyle.BackwardDiagonal, System.Drawing.Color.HotPink); graphics.FillRectangle(brush, new Rectangle(0,0, 800,800)); // can't find a way to flood fill with a brush } using (MemoryStream ms = new MemoryStream()) diff --git a/tests/ImageSharp.Benchmarks/General/ArrayCopy.cs b/tests/ImageSharp.Benchmarks/General/ArrayCopy.cs index dddd83e42..72fd6dc24 100644 --- a/tests/ImageSharp.Benchmarks/General/ArrayCopy.cs +++ b/tests/ImageSharp.Benchmarks/General/ArrayCopy.cs @@ -2,22 +2,23 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // - namespace ImageSharp.Benchmarks.General { using System; using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; + [Config(typeof(Config.Short))] public class ArrayCopy { - [Params(100, 1000, 10000)] + [Params(10, 100, 1000, 10000)] public int Count { get; set; } - private byte[] source; + byte[] source; - private byte[] destination; + byte[] destination; [Setup] public void SetUp() @@ -42,6 +43,12 @@ namespace ImageSharp.Benchmarks.General } } + [Benchmark(Description = "Copy using Buffer.BlockCopy()")] + public void CopyUsingBufferBlockCopy() + { + Buffer.BlockCopy(this.source, 0, this.destination, 0, this.Count); + } + [Benchmark(Description = "Copy using Buffer.MemoryCopy")] public unsafe void CopyUsingBufferMemoryCopy() { @@ -51,5 +58,15 @@ namespace ImageSharp.Benchmarks.General Buffer.MemoryCopy(pinnedSource, pinnedDestination, this.Count, this.Count); } } + + + [Benchmark(Description = "Copy using Marshal.Copy")] + public unsafe void CopyUsingMarshalCopy() + { + fixed (byte* pinnedDestination = this.destination) + { + Marshal.Copy(this.source, 0, (IntPtr)pinnedDestination, this.Count); + } + } } } diff --git a/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs b/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs new file mode 100644 index 000000000..9aa836de5 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs @@ -0,0 +1,43 @@ +// ReSharper disable InconsistentNaming +namespace ImageSharp.Benchmarks.General +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + using BenchmarkDotNet.Attributes; + + using Color = ImageSharp.Color; + + public unsafe class ClearBuffer + { + private PinnedBuffer buffer; + + [Params(32, 128, 512)] + public int Count { get; set; } + + [Setup] + public void Setup() + { + this.buffer = new PinnedBuffer(this.Count); + } + + [Cleanup] + public void Cleanup() + { + this.buffer.Dispose(); + } + + [Benchmark(Baseline = true)] + public void Array_Clear() + { + Array.Clear(this.buffer.Array, 0, this.Count); + } + + [Benchmark] + public void Unsafe_InitBlock() + { + Unsafe.InitBlock((void*)this.buffer.Pointer, default(byte), (uint)this.Count*sizeof(uint)); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs new file mode 100644 index 000000000..dd20e85d5 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs @@ -0,0 +1,54 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public class BitwiseOrUInt32 + { + private uint[] input; + + private uint[] result; + + [Params(32)] + public int InputSize { get; set; } + + private uint testValue; + + [Setup] + public void Setup() + { + this.input = new uint[this.InputSize]; + this.result = new uint[this.InputSize]; + this.testValue = 42; + + for (int i = 0; i < this.InputSize; i++) + { + this.input[i] = (uint) i; + } + } + + [Benchmark(Baseline = true)] + public void Standard() + { + uint v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] | v; + } + } + + [Benchmark] + public void Simd() + { + Vector v = new Vector(this.testValue); + + for (int i = 0; i < this.input.Length; i+=Vector.Count) + { + Vector a = new Vector(this.input, i); + a = Vector.BitwiseOr(a, v); + a.CopyTo(this.result, i); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs new file mode 100644 index 000000000..61582b7dc --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs @@ -0,0 +1,54 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public class DivFloat + { + private float[] input; + + private float[] result; + + [Params(32)] + public int InputSize { get; set; } + + private float testValue; + + [Setup] + public void Setup() + { + this.input = new float[this.InputSize]; + this.result = new float[this.InputSize]; + this.testValue = 42; + + for (int i = 0; i < this.InputSize; i++) + { + this.input[i] = (uint)i; + } + } + + [Benchmark(Baseline = true)] + public void Standard() + { + float v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] / v; + } + } + + [Benchmark] + public void Simd() + { + Vector v = new Vector(this.testValue); + + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = new Vector(this.input, i); + a = a / v; + a.CopyTo(this.result, i); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs new file mode 100644 index 000000000..75fa03c04 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs @@ -0,0 +1,54 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public class DivUInt32 + { + private uint[] input; + + private uint[] result; + + [Params(32)] + public int InputSize { get; set; } + + private uint testValue; + + [Setup] + public void Setup() + { + this.input = new uint[this.InputSize]; + this.result = new uint[this.InputSize]; + this.testValue = 42; + + for (int i = 0; i < this.InputSize; i++) + { + this.input[i] = (uint)i; + } + } + + [Benchmark(Baseline = true)] + public void Standard() + { + uint v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] / v; + } + } + + [Benchmark] + public void Simd() + { + Vector v = new Vector(this.testValue); + + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = new Vector(this.input, i); + a = a / v; + a.CopyTo(this.result, i); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs new file mode 100644 index 000000000..151145e12 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs @@ -0,0 +1,54 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public class MulFloat + { + private float[] input; + + private float[] result; + + [Params(32)] + public int InputSize { get; set; } + + private float testValue; + + [Setup] + public void Setup() + { + this.input = new float[this.InputSize]; + this.result = new float[this.InputSize]; + this.testValue = 42; + + for (int i = 0; i < this.InputSize; i++) + { + this.input[i] = (uint)i; + } + } + + [Benchmark(Baseline = true)] + public void Standard() + { + float v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] * v; + } + } + + [Benchmark] + public void Simd() + { + Vector v = new Vector(this.testValue); + + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = new Vector(this.input, i); + a = a * v; + a.CopyTo(this.result, i); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs new file mode 100644 index 000000000..f7d6cf9b9 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs @@ -0,0 +1,54 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + + using BenchmarkDotNet.Attributes; + + public class MulUInt32 + { + private uint[] input; + + private uint[] result; + + [Params(32)] + public int InputSize { get; set; } + + private uint testValue; + + [Setup] + public void Setup() + { + this.input = new uint[this.InputSize]; + this.result = new uint[this.InputSize]; + this.testValue = 42; + + for (int i = 0; i < this.InputSize; i++) + { + this.input[i] = (uint)i; + } + } + + [Benchmark(Baseline = true)] + public void Standard() + { + uint v = this.testValue; + for (int i = 0; i < this.input.Length; i++) + { + this.result[i] = this.input[i] * v; + } + } + + [Benchmark] + public void Simd() + { + Vector v = new Vector(this.testValue); + + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = new Vector(this.input, i); + a = a * v; + a.CopyTo(this.result, i); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs new file mode 100644 index 000000000..b0ca181cd --- /dev/null +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs @@ -0,0 +1,62 @@ +namespace ImageSharp.Benchmarks.General.Vectorization +{ + using System.Numerics; + using System.Runtime.InteropServices; + + using BenchmarkDotNet.Attributes; + + public class ReinterpretUInt32AsFloat + { + private uint[] input; + + private float[] result; + + [Params(32)] + public int InputSize { get; set; } + + [StructLayout(LayoutKind.Explicit)] + struct UIntFloatUnion + { + [FieldOffset(0)] + public float f; + + [FieldOffset(0)] + public uint i; + } + + + [Setup] + public void Setup() + { + this.input = new uint[this.InputSize]; + this.result = new float[this.InputSize]; + + for (int i = 0; i < this.InputSize; i++) + { + this.input[i] = (uint)i; + } + } + + [Benchmark(Baseline = true)] + public void Standard() + { + UIntFloatUnion u = default(UIntFloatUnion); + for (int i = 0; i < this.input.Length; i++) + { + u.i = this.input[i]; + this.result[i] = u.f; + } + } + + [Benchmark] + public void Simd() + { + for (int i = 0; i < this.input.Length; i += Vector.Count) + { + Vector a = new Vector(this.input, i); + Vector b = Vector.AsVectorSingle(a); + b.CopyTo(this.result, i); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Image/EncodePng.cs b/tests/ImageSharp.Benchmarks/Image/EncodePng.cs index dd1882c80..0bb0e922c 100644 --- a/tests/ImageSharp.Benchmarks/Image/EncodePng.cs +++ b/tests/ImageSharp.Benchmarks/Image/EncodePng.cs @@ -10,6 +10,10 @@ namespace ImageSharp.Benchmarks.Image using System.IO; using BenchmarkDotNet.Attributes; + + using ImageSharp.Formats; + using ImageSharp.Quantizers; + using CoreImage = ImageSharp.Image; public class EncodePng : BenchmarkBase @@ -19,12 +23,21 @@ namespace ImageSharp.Benchmarks.Image private Image bmpDrawing; private CoreImage bmpCore; + [Params(false)] + public bool LargeImage { get; set; } + + [Params(false)] + public bool UseOctreeQuantizer { get; set; } + [Setup] public void ReadImages() { if (this.bmpStream == null) { - this.bmpStream = File.OpenRead("../ImageSharp.Tests/TestImages/Formats/Bmp/Car.bmp"); + string path = this.LargeImage + ? "../ImageSharp.Tests/TestImages/Formats/Jpg/baseline/jpeg420exif.jpg" + : "../ImageSharp.Tests/TestImages/Formats/Bmp/Car.bmp"; + this.bmpStream = File.OpenRead(path); this.bmpCore = new CoreImage(this.bmpStream); this.bmpStream.Position = 0; this.bmpDrawing = Image.FromStream(this.bmpStream); @@ -53,7 +66,13 @@ namespace ImageSharp.Benchmarks.Image { using (MemoryStream memoryStream = new MemoryStream()) { - this.bmpCore.SaveAsPng(memoryStream); + Quantizer quantizer = this.UseOctreeQuantizer + ? (Quantizer) + new OctreeQuantizer() + : new PaletteQuantizer(); + + PngEncoderOptions options = new PngEncoderOptions() { Quantizer = quantizer }; + this.bmpCore.SaveAsPng(memoryStream, options); } } } diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj new file mode 100644 index 000000000..b2070c0de --- /dev/null +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -0,0 +1,17 @@ + + + Exe + net461 + win7-x64 + True + false + + + + + + + + + + \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.xproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.xproj deleted file mode 100644 index 184faefd8..000000000 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.xproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 299d8e18-102c-42de-adbf-79098ee706a8 - ImageSharp.Benchmarks - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Program.cs b/tests/ImageSharp.Benchmarks/Program.cs index 8c609f015..789068426 100644 --- a/tests/ImageSharp.Benchmarks/Program.cs +++ b/tests/ImageSharp.Benchmarks/Program.cs @@ -6,8 +6,9 @@ namespace ImageSharp.Benchmarks { using BenchmarkDotNet.Running; - + using ImageSharp.Formats; + using System.Reflection; public class Program { @@ -19,7 +20,7 @@ namespace ImageSharp.Benchmarks /// public static void Main(string[] args) { - new BenchmarkSwitcher(typeof(Program).Assembly).Run(args); + new BenchmarkSwitcher(typeof(Program).GetTypeInfo().Assembly).Run(args); } } } diff --git a/tests/ImageSharp.Benchmarks/Properties/AssemblyInfo.cs b/tests/ImageSharp.Benchmarks/Properties/AssemblyInfo.cs deleted file mode 100644 index 39f8b862d..000000000 --- a/tests/ImageSharp.Benchmarks/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using BenchmarkDotNet.Attributes; -using ImageSharp.Benchmarks; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ImageSharp.Benchmarks")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ImageSharp.Benchmarks")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("299d8e18-102c-42de-adbf-79098ee706a8")] - -[assembly: Config(typeof(Config))] \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/benchmark.sh b/tests/ImageSharp.Benchmarks/benchmark.sh new file mode 100755 index 000000000..1966475bc --- /dev/null +++ b/tests/ImageSharp.Benchmarks/benchmark.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Build in release mode +dotnet build -c Release -f netcoreapp1.1 + +# Run benchmarks +dotnet bin/Release/netcoreapp1.1/ImageSharp.Benchmarks.dll \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/project.json b/tests/ImageSharp.Benchmarks/project.json deleted file mode 100644 index 866a36faa..000000000 --- a/tests/ImageSharp.Benchmarks/project.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "version": "1.0.0-*", - "description": "ImageSharp.Benchmarks Console Application", - "authors": [ "James.South" ], - "packOptions": { - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "emitEntryPoint": true, - "allowUnsafe": true - }, - "dependencies": { - "BenchmarkDotNet.Diagnostics.Windows": "0.10.1", - "ImageSharp": { - "target": "project" - }, - "ImageSharp.Drawing": { - "target": "project" - }, - "ImageSharp.Drawing.Paths": { - "target": "project" - }, - "ImageSharp.Formats.Jpeg": { - "target": "project" - }, - "ImageSharp.Formats.Png": { - "target": "project" - }, - "ImageSharp.Formats.Bmp": { - "target": "project" - }, - "ImageSharp.Formats.Gif": { - "target": "project" - }, - "ImageSharp.Processing": { - "target": "project" - } - }, - "commands": { - "ImageSharp.Benchmarks": "ImageSharp.Benchmarks" - }, - "frameworks": { - "net46": { - "dependencies": { - }, - "frameworkAssemblies": { - "System.Drawing": "" - } - } - } -} diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index 2444db031..23a5c59a3 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -1,353 +1,32 @@ - - - - + - Debug - AnyCPU - {96188137-5FA6-4924-AB6E-4EFF79C6E0BB} Exe - Properties - ImageSharp - ImageSharp.Sandbox46 - v4.6.1 - 512 - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - false - - - pdbonly - true - bin\Release\ - TRACE;BENCHMARKING - prompt - 4 - true + net461 + win7-x64 + True false - - - ImageSharp.Sandbox46.Program + ImageSharp.Sandbox46 + A cross-platform library for processing of image files written in C# + Copyright © James Jackson-South and contributors. + James Jackson-South and contributors + James Jackson-South - - ..\..\packages\BenchmarkDotNet.0.10.2\lib\net45\BenchmarkDotNet.dll - True - - - ..\..\packages\BenchmarkDotNet.Core.0.10.2\lib\net45\BenchmarkDotNet.Core.dll - True - - - ..\..\packages\BenchmarkDotNet.Diagnostics.Windows.0.10.2\lib\net45\BenchmarkDotNet.Diagnostics.Windows.dll - True - - - ..\..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.10.2\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll - True - - - ..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - True - - - ..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - True - - - ..\..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll - True - - - - ..\..\packages\System.AppContext.4.1.0\lib\net46\System.AppContext.dll - True - - - ..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True - - - - ..\..\packages\System.Console.4.0.0\lib\net46\System.Console.dll - True - - - - ..\..\packages\System.Diagnostics.FileVersionInfo.4.0.0\lib\net46\System.Diagnostics.FileVersionInfo.dll - True - - - ..\..\packages\System.Diagnostics.StackTrace.4.0.1\lib\net46\System.Diagnostics.StackTrace.dll - True - - - ..\..\packages\System.IO.FileSystem.4.0.1\lib\net46\System.IO.FileSystem.dll - True - - - ..\..\packages\System.IO.FileSystem.Primitives.4.0.1\lib\net46\System.IO.FileSystem.Primitives.dll - True - - - - - ..\..\packages\System.Numerics.Vectors.4.1.1\lib\net46\System.Numerics.Vectors.dll - True - - - ..\..\packages\System.Reflection.Metadata.1.3.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - True - - - ..\..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll - True - - - ..\..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll - True - - - ..\..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll - True - - - ..\..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll - True - - - ..\..\packages\System.Text.Encoding.CodePages.4.0.1\lib\net46\System.Text.Encoding.CodePages.dll - True - - - ..\..\packages\System.Threading.Tasks.Extensions.4.0.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - True - - - ..\..\packages\System.Threading.Thread.4.0.0\lib\net46\System.Threading.Thread.dll - True - - - - - - - - - ..\..\packages\System.Xml.XmlDocument.4.0.1\lib\net46\System.Xml.XmlDocument.dll - True - - - ..\..\packages\System.Xml.XPath.4.0.1\lib\net46\System.Xml.XPath.dll - True - - - ..\..\packages\System.Xml.XPath.XDocument.4.0.1\lib\net46\System.Xml.XPath.XDocument.dll - True - - - ..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - True - - - ..\..\packages\xunit.assert.2.2.0-beta4-build3444\lib\netstandard1.0\xunit.assert.dll - True - - - ..\..\packages\xunit.extensibility.core.2.2.0-beta4-build3444\lib\net45\xunit.core.dll - True - - - ..\..\packages\xunit.extensibility.execution.2.2.0-beta4-build3444\lib\net45\xunit.execution.desktop.dll - True - + + - - ..\..\src\ImageSharp\bin\$(Configuration)\net461\ImageSharp.dll - - - ..\..\src\ImageSharp.Drawing\bin\$(Configuration)\net461\ImageSharp.Drawing.dll - - - ..\..\src\ImageSharp.Drawing.Paths\bin\$(Configuration)\net461\ImageSharp.Drawing.Paths.dll - - - ..\..\src\ImageSharp.Drawing.Paths\bin\$(Configuration)\net461\SixLabors.Shapes.dll - - - ..\..\src\ImageSharp.Formats.Bmp\bin\$(Configuration)\net461\ImageSharp.Formats.Bmp.dll - - - ..\..\src\ImageSharp.Formats.Gif\bin\$(Configuration)\net461\ImageSharp.Formats.Gif.dll - - - ..\..\src\ImageSharp.Formats.Jpeg\bin\$(Configuration)\net461\ImageSharp.Formats.Jpeg.dll - - - ..\..\src\ImageSharp.Formats.Png\bin\$(Configuration)\net461\ImageSharp.Formats.Png.dll - - - ..\..\src\ImageSharp.Processing\bin\$(Configuration)\net461\ImageSharp.Processing.dll - + + + + - - Tests\Drawing\PolygonTests.cs - - - Tests\FileTestBase.cs - - - Tests\Formats\Jpg\BadEofJpegTests.cs - - - Tests\Formats\Jpg\Block8x8FTests.cs - - - Tests\Formats\Jpg\JpegDecoderTests.cs - - - Tests\Formats\Jpg\JpegEncoderTests.cs - - - Tests\Formats\Jpg\JpegProfilingBenchmarks.cs - - - Tests\Formats\Jpg\JpegUtilityTestFixture.cs - - - Tests\Formats\Jpg\JpegUtilsTests.cs - - - Tests\Formats\Jpg\ReferenceImplementations.cs - - - Tests\Formats\Jpg\ReferenceImplementationsTests.cs - - - Tests\Formats\Jpg\YCbCrImageTests.cs - - - Tests\MetaData\ImagePropertyTests.cs - - - Tests\Image\ImageTests.cs - - - Tests\Image\PixelAccessorTests.cs - - - Tests\Processors\Filters\ResizeTests.cs - - - Tests\TestBase.cs - - - Tests\TestFile.cs - - - Tests\TestImages.cs - - - Tests\TestUtilities\Attributes\ImageDataAttributeBase.cs - - - Tests\TestUtilities\Attributes\WithBlankImageAttribute.cs - - - Tests\TestUtilities\Attributes\WithFileAttribute.cs - - - Tests\TestUtilities\Attributes\WithFileCollectionAttribute.cs - - - Tests\TestUtilities\Attributes\WithMemberFactoryAttribute.cs - - - Tests\TestUtilities\Attributes\WithSolidFilledImagesAttribute.cs - - - Tests\TestUtilities\Factories\GenericFactory.cs - - - Tests\TestUtilities\Factories\ImageFactory.cs - - - Tests\TestUtilities\ImageProviders\BlankProvider.cs - - - Tests\TestUtilities\ImageProviders\FileProvider.cs - - - Tests\TestUtilities\ImageProviders\LambdaProvider.cs - - - Tests\TestUtilities\ImageProviders\SolidProvider.cs - - - Tests\TestUtilities\ImageProviders\TestImageProvider.cs - - - Tests\TestUtilities\ImagingTestCaseUtility.cs - - - Tests\TestUtilities\MeasureFixture.cs - - - Tests\TestUtilities\PixelTypes.cs - - - Tests\TestUtilities\Tests\TestImageProviderTests.cs - - - Tests\TestUtilities\Tests\TestUtilityExtensionsTests.cs - - - Tests\TestUtilities\TestUtilityExtensions.cs - - - + + + - - - - - - - - - - - - - + - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - \ No newline at end of file diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index 48219902b..467663a53 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -7,8 +7,9 @@ namespace ImageSharp.Sandbox46 { using System; using System.Runtime.DesignerServices; - + using ImageSharp.Tests; + using ImageSharp.Tests.Colors; using Xunit.Abstractions; @@ -36,9 +37,19 @@ namespace ImageSharp.Sandbox46 /// public static void Main(string[] args) { - RunDecodeJpegProfilingTests(); + // RunDecodeJpegProfilingTests(); + + RunToVector4ProfilingTest(); + + Console.ReadLine(); } + private static void RunToVector4ProfilingTest() + { + BulkPixelOperationsTests.Color tests = new BulkPixelOperationsTests.Color(new ConsoleOutput()); + tests.Benchmark_ToVector4(); + } + private static void RunDecodeJpegProfilingTests() { Console.WriteLine("RunDecodeJpegProfilingTests..."); diff --git a/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs b/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs index 51b205188..a10fc12fe 100644 --- a/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs +++ b/tests/ImageSharp.Sandbox46/Properties/AssemblyInfo.cs @@ -6,16 +6,6 @@ using System.Runtime.InteropServices; // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("ImageSharp.Sandbox46")] -[assembly: AssemblyDescription("A cross-platform library for processing of image files written in C#")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ImageSharp.Sandbox46")] -[assembly: AssemblyCopyright("Copyright © James Jackson-South and contributors.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - - // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. diff --git a/tests/ImageSharp.Sandbox46/app.config b/tests/ImageSharp.Sandbox46/app.config index 5a049c66e..3328297a5 100644 --- a/tests/ImageSharp.Sandbox46/app.config +++ b/tests/ImageSharp.Sandbox46/app.config @@ -10,6 +10,10 @@ + + + + \ No newline at end of file diff --git a/tests/ImageSharp.Sandbox46/packages.config b/tests/ImageSharp.Sandbox46/packages.config deleted file mode 100644 index 65ad74fa6..000000000 --- a/tests/ImageSharp.Sandbox46/packages.config +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs b/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs new file mode 100644 index 000000000..6621292ec --- /dev/null +++ b/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs @@ -0,0 +1,427 @@ +// ReSharper disable InconsistentNaming +// ReSharper disable AccessToDisposedClosure +namespace ImageSharp.Tests.Colors +{ + using System; + using System.Numerics; + + using Xunit; + using Xunit.Abstractions; + + public class BulkPixelOperationsTests + { + public class Color : BulkPixelOperationsTests + { + public Color(ITestOutputHelper output) + : base(output) + { + } + + // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() + { + Assert.IsType(BulkPixelOperations.Instance); + } + + [Fact] + public void ToVector4SimdAligned() + { + ImageSharp.Color[] source = CreatePixelTestData(64); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => ImageSharp.Color.BulkOperations.ToVector4SimdAligned(s, d, 64) + ); + } + + // [Fact] // Profiling benchmark - enable manually! + public void Benchmark_ToVector4() + { + int times = 200000; + int count = 1024; + + using (PinnedBuffer source = new PinnedBuffer(count)) + using (PinnedBuffer dest = new PinnedBuffer(count)) + { + this.Measure( + times, + () => + { + BulkPixelOperations.Instance.ToVector4(source, dest, count); + }); + } + } + } + + public class Argb : BulkPixelOperationsTests + { + // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + public Argb(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + } + + [Theory] + [WithBlankImages(1, 1, PixelTypes.All)] + public void GetGlobalInstance(TestImageProvider dummy) + where TColor:struct, IPixel + { + Assert.NotNull(BulkPixelOperations.Instance); + } + } + + public abstract class BulkPixelOperationsTests : MeasureFixture + where TColor : struct, IPixel + { + protected BulkPixelOperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + private static BulkPixelOperations Operations => BulkPixelOperations.Instance; + + internal static TColor[] CreateExpectedPixelData(Vector4[] source) + { + TColor[] expected = new TColor[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i].PackFromVector4(source[i]); + } + return expected; + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromVector4(int count) + { + Vector4[] source = CreateVector4TestData(count); + TColor[] expected = CreateExpectedPixelData(source); + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromVector4(s, d, count) + ); + } + + internal static Vector4[] CreateExpectedVector4Data(TColor[] source) + { + Vector4[] expected = new Vector4[source.Length]; + + for (int i = 0; i < expected.Length; i++) + { + expected[i] = source[i].ToVector4(); + } + return expected; + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToVector4(int count) + { + TColor[] source = CreatePixelTestData(count); + Vector4[] expected = CreateExpectedVector4Data(source); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4(s, d, count) + ); + } + + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromXyzBytes(int count) + { + byte[] source = CreateByteTestData(count * 3); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromBytes(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromXyzBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToXyzBytes(int count) + { + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + source[i].ToXyzBytes(expected, i3); + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToXyzBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromXyzwBytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromBytes(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromXyzwBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToXyzwBytes(int count) + { + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToXyzwBytes(expected, i4); + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToXyzwBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromZyxBytes(int count) + { + byte[] source = CreateByteTestData(count * 3); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromBytes(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromZyxBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToZyxBytes(int count) + { + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + source[i].ToZyxBytes(expected, i3); + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToZyxBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromZyxwBytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromBytes(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromZyxwBytes(s, d, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToZyxwBytes(int count) + { + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToZyxwBytes(expected, i4); + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToZyxwBytes(s, d, count) + ); + } + + + private class TestBuffers : IDisposable + where TSource : struct + where TDest : struct + { + public PinnedBuffer SourceBuffer { get; } + public PinnedBuffer ActualDestBuffer { get; } + public PinnedBuffer ExpectedDestBuffer { get; } + + public BufferPointer Source => this.SourceBuffer.Slice(); + public BufferPointer ActualDest => this.ActualDestBuffer.Slice(); + + public TestBuffers(TSource[] source, TDest[] expectedDest) + { + this.SourceBuffer = new PinnedBuffer(source); + this.ExpectedDestBuffer = new PinnedBuffer(expectedDest); + this.ActualDestBuffer = new PinnedBuffer(expectedDest.Length); + } + + public void Dispose() + { + this.SourceBuffer.Dispose(); + this.ActualDestBuffer.Dispose(); + this.ExpectedDestBuffer.Dispose(); + } + + private const float Tolerance = 0.0001f; + + public void Verify() + { + int count = this.ExpectedDestBuffer.Count; + + if (typeof(TDest) == typeof(Vector4)) + { + Vector4[] expected = this.ExpectedDestBuffer.Array as Vector4[]; + Vector4[] actual = this.ActualDestBuffer.Array as Vector4[]; + + for (int i = 0; i < count; i++) + { + // ReSharper disable PossibleNullReferenceException + Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); + // ReSharper restore PossibleNullReferenceException + } + } + else + { + TDest[] expected = this.ExpectedDestBuffer.Array; + TDest[] actual = this.ActualDestBuffer.Array; + for (int i = 0; i < count; i++) + { + Assert.Equal(expected[i], actual[i]); + } + } + } + } + + internal static void TestOperation( + TSource[] source, + TDest[] expected, + Action, BufferPointer> action) + where TSource : struct + where TDest : struct + { + using (var buffers = new TestBuffers(source, expected)) + { + action(buffers.Source, buffers.ActualDest); + buffers.Verify(); + } + } + + internal static Vector4[] CreateVector4TestData(int length) + { + Vector4[] result = new Vector4[length]; + Random rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + result[i] = GetVector(rnd); + } + return result; + } + + internal static TColor[] CreatePixelTestData(int length) + { + TColor[] result = new TColor[length]; + + Random rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + Vector4 v = GetVector(rnd); + result[i].PackFromVector4(v); + } + + return result; + } + + internal static byte[] CreateByteTestData(int length) + { + byte[] result = new byte[length]; + Random rnd = new Random(42); // Deterministic random values + + for (int i = 0; i < result.Length; i++) + { + result[i] = (byte)rnd.Next(255); + } + return result; + } + + internal static Vector4 GetVector(Random rnd) + { + return new Vector4( + (float)rnd.NextDouble(), + (float)rnd.NextDouble(), + (float)rnd.NextDouble(), + (float)rnd.NextDouble() + ); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Common/ArrayPointerTests.cs b/tests/ImageSharp.Tests/Common/ArrayPointerTests.cs deleted file mode 100644 index 076e2512c..000000000 --- a/tests/ImageSharp.Tests/Common/ArrayPointerTests.cs +++ /dev/null @@ -1,83 +0,0 @@ -// ReSharper disable ObjectCreationAsStatement -// ReSharper disable InconsistentNaming -namespace ImageSharp.Tests.Common -{ - using System; - - using Xunit; - - public unsafe class ArrayPointerTests - { - public struct Foo - { -#pragma warning disable CS0414 - private int a; - - private double b; -#pragma warning restore CS0414 - - internal static Foo[] CreateArray(int size) - { - Foo[] result = new Foo[size]; - for (int i = 0; i < size; i++) - { - result[i] = new Foo() { a = i, b = i }; - } - return result; - } - } - - [Fact] - public void ConstructWithoutOffset() - { - Foo[] array = Foo.CreateArray(3); - fixed (Foo* p = array) - { - // Act: - ArrayPointer ap = new ArrayPointer(array, p); - - // Assert: - Assert.Equal(array, ap.Array); - Assert.Equal((IntPtr)p, ap.PointerAtOffset); - } - } - - [Fact] - public void ConstructWithOffset() - { - Foo[] array = Foo.CreateArray(3); - int offset = 2; - fixed (Foo* p = array) - { - // Act: - ArrayPointer ap = new ArrayPointer(array, p, offset); - - // Assert: - Assert.Equal(array, ap.Array); - Assert.Equal(offset, ap.Offset); - Assert.Equal((IntPtr)(p+offset), ap.PointerAtOffset); - } - } - - [Fact] - public void Slice() - { - Foo[] array = Foo.CreateArray(5); - int offset0 = 2; - int offset1 = 2; - int totalOffset = offset0 + offset1; - fixed (Foo* p = array) - { - ArrayPointer ap = new ArrayPointer(array, p, offset0); - - // Act: - ap = ap.Slice(offset1); - - // Assert: - Assert.Equal(array, ap.Array); - Assert.Equal(totalOffset, ap.Offset); - Assert.Equal((IntPtr)(p + totalOffset), ap.PointerAtOffset); - } - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Common/BufferPointerTests.cs b/tests/ImageSharp.Tests/Common/BufferPointerTests.cs new file mode 100644 index 000000000..c82b63f11 --- /dev/null +++ b/tests/ImageSharp.Tests/Common/BufferPointerTests.cs @@ -0,0 +1,435 @@ +// ReSharper disable ObjectCreationAsStatement +// ReSharper disable InconsistentNaming +namespace ImageSharp.Tests.Common +{ + using System; + using System.Runtime.CompilerServices; + + using Xunit; + + public unsafe class BufferPointerTests + { + public struct Foo + { + public int A; + + public double B; + + public Foo(int a, double b) + { + this.A = a; + this.B = b; + } + + internal static Foo[] CreateArray(int size) + { + Foo[] result = new Foo[size]; + for (int i = 0; i < size; i++) + { + result[i] = new Foo(i+1, i+1); + } + return result; + } + } + + /// + /// sizeof(AlignedFoo) == sizeof(long) + /// + public struct AlignedFoo + { + public int A; + + public int B; + + static AlignedFoo() + { + Assert.Equal(sizeof(AlignedFoo), sizeof(long)); + } + + public AlignedFoo(int a, int b) + { + this.A = a; + this.B = b; + } + + internal static AlignedFoo[] CreateArray(int size) + { + AlignedFoo[] result = new AlignedFoo[size]; + for (int i = 0; i < size; i++) + { + result[i] = new AlignedFoo(i + 1, i + 1); + } + return result; + } + } + + [Fact] + public void AsBytes() + { + Foo[] fooz = { new Foo(1, 2), new Foo(3, 4), new Foo(5, 6) }; + + using (PinnedBuffer colorBuf = new PinnedBuffer(fooz)) + { + BufferPointer orig = colorBuf.Slice(1); + BufferPointer asBytes = (BufferPointer < byte > )orig; + + Assert.Equal(asBytes.Offset, sizeof(Foo)); + Assert.Equal(orig.PointerAtOffset, asBytes.PointerAtOffset); + } + } + + [Fact] + public void ConstructWithoutOffset() + { + Foo[] array = Foo.CreateArray(3); + fixed (Foo* p = array) + { + // Act: + BufferPointer ap = new BufferPointer(array, p); + + // Assert: + Assert.Equal(array, ap.Array); + Assert.Equal((IntPtr)p, ap.PointerAtOffset); + } + } + + [Fact] + public void ConstructWithOffset() + { + Foo[] array = Foo.CreateArray(3); + int offset = 2; + fixed (Foo* p = array) + { + // Act: + BufferPointer ap = new BufferPointer(array, p, offset); + + // Assert: + Assert.Equal(array, ap.Array); + Assert.Equal(offset, ap.Offset); + Assert.Equal((IntPtr)(p+offset), ap.PointerAtOffset); + } + } + + [Fact] + public void Slice() + { + Foo[] array = Foo.CreateArray(5); + int offset0 = 2; + int offset1 = 2; + int totalOffset = offset0 + offset1; + fixed (Foo* p = array) + { + BufferPointer ap = new BufferPointer(array, p, offset0); + + // Act: + ap = ap.Slice(offset1); + + // Assert: + Assert.Equal(array, ap.Array); + Assert.Equal(totalOffset, ap.Offset); + Assert.Equal((IntPtr)(p + totalOffset), ap.PointerAtOffset); + } + } + + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void Clear(int count) + { + Foo[] array = Foo.CreateArray(count + 42); + + int offset = 2; + fixed (Foo* p = array) + { + BufferPointer ap = new BufferPointer(array, p, offset); + + // Act: + ap.Clear(count); + + Assert.NotEqual(default(Foo), array[offset-1]); + Assert.Equal(default(Foo), array[offset]); + Assert.Equal(default(Foo), array[offset + count-1]); + Assert.NotEqual(default(Foo), array[offset + count]); + } + } + + + public class Copy + { + private static void AssertNotDefault(T[] data, int idx) + where T : struct + { + Assert.NotEqual(default(T), data[idx]); + } + + private static byte[] CreateTestBytes(int count) + { + byte[] result = new byte[count]; + for (int i = 0; i < result.Length; i++) + { + result[i] = (byte)((i % 200) + 1); + } + return result; + } + + private static int[] CreateTestInts(int count) + { + int[] result = new int[count]; + for (int i = 0; i < result.Length; i++) + { + result[i] = i + 1; + } + return result; + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void GenericToOwnType(int count) + { + Foo[] source = Foo.CreateArray(count + 2); + Foo[] dest = new Foo[count + 5]; + + fixed (Foo* pSource = source) + fixed (Foo* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource, 1); + BufferPointer apDest = new BufferPointer(dest, pDest, 1); + + BufferPointer.Copy(apSource, apDest, count-1); + } + + AssertNotDefault(source, 1); + AssertNotDefault(dest, 1); + + Assert.NotEqual(source[0], dest[0]); + Assert.Equal(source[1], dest[1]); + Assert.Equal(source[2], dest[2]); + Assert.Equal(source[count-1], dest[count-1]); + Assert.NotEqual(source[count], dest[count]); + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void GenericToOwnType_Aligned(int count) + { + AlignedFoo[] source = AlignedFoo.CreateArray(count + 2); + AlignedFoo[] dest = new AlignedFoo[count + 5]; + + fixed (AlignedFoo* pSource = source) + fixed (AlignedFoo* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource, 1); + BufferPointer apDest = new BufferPointer(dest, pDest, 1); + + BufferPointer.Copy(apSource, apDest, count - 1); + } + + AssertNotDefault(source, 1); + AssertNotDefault(dest, 1); + + Assert.NotEqual(source[0], dest[0]); + Assert.Equal(source[1], dest[1]); + Assert.Equal(source[2], dest[2]); + Assert.Equal(source[count - 1], dest[count - 1]); + Assert.NotEqual(source[count], dest[count]); + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void IntToInt(int count) + { + int[] source = CreateTestInts(count+2); + int[] dest = new int[count + 5]; + + fixed (int* pSource = source) + fixed (int* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource, 1); + BufferPointer apDest = new BufferPointer(dest, pDest, 1); + + BufferPointer.Copy(apSource, apDest, count -1); + } + + AssertNotDefault(source, 1); + AssertNotDefault(dest, 1); + + Assert.NotEqual(source[0], dest[0]); + Assert.Equal(source[1], dest[1]); + Assert.Equal(source[2], dest[2]); + Assert.Equal(source[count - 1], dest[count - 1]); + Assert.NotEqual(source[count], dest[count]); + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void GenericToBytes(int count) + { + int destCount = count * sizeof(Foo); + Foo[] source = Foo.CreateArray(count+2); + byte[] dest = new byte[destCount + sizeof(Foo)*2]; + + fixed (Foo* pSource = source) + fixed (byte* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource, 1); + BufferPointer apDest = new BufferPointer(dest, pDest, sizeof(Foo)); + + BufferPointer.Copy(apSource, apDest, count - 1); + } + + AssertNotDefault(source, 1); + + Assert.False(ElementsAreEqual(source, dest, 0)); + Assert.True(ElementsAreEqual(source, dest, 1)); + Assert.True(ElementsAreEqual(source, dest, 2)); + Assert.True(ElementsAreEqual(source, dest, count - 1)); + Assert.False(ElementsAreEqual(source, dest, count)); + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void GenericToBytes_Aligned(int count) + { + int destCount = count * sizeof(Foo); + AlignedFoo[] source = AlignedFoo.CreateArray(count + 2); + byte[] dest = new byte[destCount + sizeof(AlignedFoo) * 2]; + + fixed (AlignedFoo* pSource = source) + fixed (byte* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource, 1); + BufferPointer apDest = new BufferPointer(dest, pDest, sizeof(AlignedFoo)); + + BufferPointer.Copy(apSource, apDest, count - 1); + } + + AssertNotDefault(source, 1); + + Assert.False(ElementsAreEqual(source, dest, 0)); + Assert.True(ElementsAreEqual(source, dest, 1)); + Assert.True(ElementsAreEqual(source, dest, 2)); + Assert.True(ElementsAreEqual(source, dest, count - 1)); + Assert.False(ElementsAreEqual(source, dest, count)); + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void IntToBytes(int count) + { + int destCount = count * sizeof(int); + int[] source = CreateTestInts(count+2); + byte[] dest = new byte[destCount + sizeof(int) + 1]; + + fixed (int* pSource = source) + fixed (byte* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource); + BufferPointer apDest = new BufferPointer(dest, pDest); + + BufferPointer.Copy(apSource, apDest, count); + } + + AssertNotDefault(source, 1); + + Assert.True(ElementsAreEqual(source, dest, 0)); + Assert.True(ElementsAreEqual(source, dest, count - 1)); + Assert.False(ElementsAreEqual(source, dest, count)); + } + + [Theory] + [InlineData(4)] + [InlineData(1500)] + public void BytesToGeneric(int count) + { + int srcCount = count * sizeof(Foo); + byte[] source = CreateTestBytes(srcCount); + Foo[] dest = new Foo[count + 2]; + + fixed(byte* pSource = source) + fixed (Foo* pDest = dest) + { + BufferPointer apSource = new BufferPointer(source, pSource); + BufferPointer apDest = new BufferPointer(dest, pDest); + + BufferPointer.Copy(apSource, apDest, count); + } + + AssertNotDefault(source, sizeof(Foo) + 1); + AssertNotDefault(dest, 1); + + Assert.True(ElementsAreEqual(dest, source, 0)); + Assert.True(ElementsAreEqual(dest, source, 1)); + Assert.True(ElementsAreEqual(dest, source, count - 1)); + Assert.False(ElementsAreEqual(dest, source, count)); + } + + [Fact] + public void ColorToBytes() + { + Color[] colors = { new Color(0, 1, 2, 3), new Color(4, 5, 6, 7), new Color(8, 9, 10, 11), }; + + using (PinnedBuffer colorBuf = new PinnedBuffer(colors)) + using (PinnedBuffer byteBuf = new PinnedBuffer(colors.Length*4)) + { + BufferPointer.Copy(colorBuf, byteBuf, colorBuf.Count); + + byte[] a = byteBuf.Array; + + for (int i = 0; i < byteBuf.Count; i++) + { + Assert.Equal((byte)i, a[i]); + } + } + } + + internal static bool ElementsAreEqual(Foo[] array, byte[] rawArray, int index) + { + fixed (Foo* pArray = array) + fixed (byte* pRaw = rawArray) + { + Foo* pCasted = (Foo*)pRaw; + + Foo val1 = pArray[index]; + Foo val2 = pCasted[index]; + + return val1.Equals(val2); + } + } + + internal static bool ElementsAreEqual(AlignedFoo[] array, byte[] rawArray, int index) + { + fixed (AlignedFoo* pArray = array) + fixed (byte* pRaw = rawArray) + { + AlignedFoo* pCasted = (AlignedFoo*)pRaw; + + AlignedFoo val1 = pArray[index]; + AlignedFoo val2 = pCasted[index]; + + return val1.Equals(val2); + } + } + + internal static bool ElementsAreEqual(int[] array, byte[] rawArray, int index) + { + fixed (int* pArray = array) + fixed (byte* pRaw = rawArray) + { + int* pCasted = (int*)pRaw; + + int val1 = pArray[index]; + int val2 = pCasted[index]; + + return val1.Equals(val2); + } + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Common/PinnedBufferTests.cs b/tests/ImageSharp.Tests/Common/PinnedBufferTests.cs new file mode 100644 index 000000000..3688763b9 --- /dev/null +++ b/tests/ImageSharp.Tests/Common/PinnedBufferTests.cs @@ -0,0 +1,109 @@ +namespace ImageSharp.Tests.Common +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + using Xunit; + + public unsafe class PinnedBufferTests + { + public struct Foo + { + public int A; + + public double B; + } + + [Theory] + [InlineData(42)] + [InlineData(1111)] + public void ConstructWithOwnArray(int count) + { + using (PinnedBuffer buffer = new PinnedBuffer(count)) + { + Assert.False(buffer.IsDisposedOrLostArrayOwnership); + Assert.NotNull(buffer.Array); + Assert.Equal(count, buffer.Count); + Assert.True(buffer.Array.Length >= count); + + VerifyPointer(buffer); + } + } + + [Theory] + [InlineData(42)] + [InlineData(1111)] + public void ConstructWithExistingArray(int count) + { + Foo[] array = new Foo[count]; + using (PinnedBuffer buffer = new PinnedBuffer(array)) + { + Assert.False(buffer.IsDisposedOrLostArrayOwnership); + Assert.Equal(array, buffer.Array); + Assert.Equal(count, buffer.Count); + + VerifyPointer(buffer); + } + } + + [Theory] + [InlineData(42)] + [InlineData(1111)] + public void Clear(int count) + { + Foo[] a = { new Foo() { A = 1, B = 2 }, new Foo() { A = 3, B = 4 } }; + using (PinnedBuffer buffer = new PinnedBuffer(a)) + { + buffer.Clear(); + + Assert.Equal(default(Foo), a[0]); + Assert.Equal(default(Foo), a[1]); + } + } + + [Fact] + public void Dispose() + { + PinnedBuffer buffer = new PinnedBuffer(42); + buffer.Dispose(); + + Assert.True(buffer.IsDisposedOrLostArrayOwnership); + } + + [Fact] + public void Slice() + { + Foo[] a = { new Foo() { A = 1, B = 2 }, new Foo() { A = 3, B = 4 } }; + + using (PinnedBuffer buffer = new PinnedBuffer(a)) + { + var arrayPtr = buffer.Slice(); + + Assert.Equal(a, arrayPtr.Array); + Assert.Equal(0, arrayPtr.Offset); + Assert.Equal(buffer.Pointer, arrayPtr.PointerAtOffset); + } + } + + [Fact] + public void UnPinAndTakeArrayOwnership() + { + Foo[] data = null; + using (PinnedBuffer buffer = new PinnedBuffer(42)) + { + data = buffer.UnPinAndTakeArrayOwnership(); + Assert.True(buffer.IsDisposedOrLostArrayOwnership); + } + + Assert.NotNull(data); + Assert.True(data.Length >= 42); + } + + private static void VerifyPointer(PinnedBuffer buffer) + { + IntPtr ptr = (IntPtr)Unsafe.AsPointer(ref buffer.Array[0]); + Assert.Equal(ptr, buffer.Pointer); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Common/PixelDataPoolTests.cs b/tests/ImageSharp.Tests/Common/PixelDataPoolTests.cs new file mode 100644 index 000000000..403dffba9 --- /dev/null +++ b/tests/ImageSharp.Tests/Common/PixelDataPoolTests.cs @@ -0,0 +1,55 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +// ReSharper disable InconsistentNaming +namespace ImageSharp.Tests +{ + using System.Linq; + + using Xunit; + + /// + /// Tests the class. + /// + public class PixelDataPoolTests + { + [Fact] + public void PixelDataPoolRentsMinimumSize() + { + Color[] pixels = PixelDataPool.Rent(1024); + + Assert.True(pixels.Length >= 1024); + } + + [Fact] + public void PixelDataPoolDoesNotThrowWhenReturningNonPooled() + { + Color[] pixels = new Color[1024]; + + PixelDataPool.Return(pixels); + + Assert.True(pixels.Length >= 1024); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void CalculateMaxArrayLength(bool isRawData) + { + int max = isRawData ? PixelDataPool.CalculateMaxArrayLength() + : PixelDataPool.CalculateMaxArrayLength(); + + Assert.Equal(max < int.MaxValue, !isRawData); + } + + [Fact] + public void RentNonIPixelData() + { + byte[] data = PixelDataPool.Rent(16384); + + Assert.True(data.Length >= 16384); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs b/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs index a41afd333..9c6c6d234 100644 --- a/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs +++ b/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs @@ -32,7 +32,6 @@ namespace ImageSharp.Tests.Drawing using (FileStream output = File.OpenWrite($"{path}/Simple.png")) { image - .BackgroundColor(Color.Blue) .FillPolygon(Color.HotPink, simplePath, new GraphicsOptions(true)) .Save(output); } @@ -45,7 +44,7 @@ namespace ImageSharp.Tests.Drawing Assert.Equal(Color.HotPink, sourcePixels[50, 50]); - Assert.Equal(Color.Blue, sourcePixels[2, 2]); + Assert.NotEqual(Color.HotPink, sourcePixels[2, 2]); } } } @@ -243,5 +242,32 @@ namespace ImageSharp.Tests.Drawing } } } + + [Fact] + public void ImageShouldBeOverlayedBySquareWithCornerClipped() + { + string path = this.CreateOutputDirectory("Drawing", "FilledPolygons"); + + var config = Configuration.CreateDefaultInstance(); + config.ParallelOptions.MaxDegreeOfParallelism = 1; + using (Image image = new Image(200, 200, config)) + { + using (FileStream output = File.OpenWrite($"{path}/clipped-corner.png")) + { + image + .Fill(Color.Blue) + .FillPolygon(Color.HotPink, new[] + { + new Vector2( 8, 8 ), + new Vector2( 64, 8 ), + new Vector2( 64, 64 ), + new Vector2( 120, 64 ), + new Vector2( 120, 120 ), + new Vector2( 8, 120 ) + } ) + .Save(output); + } + } + } } } diff --git a/tests/ImageSharp.Tests/Drawing/Text/DrawText.cs b/tests/ImageSharp.Tests/Drawing/Text/DrawText.cs new file mode 100644 index 000000000..2a2cb8a07 --- /dev/null +++ b/tests/ImageSharp.Tests/Drawing/Text/DrawText.cs @@ -0,0 +1,194 @@ + +namespace ImageSharp.Tests.Drawing.Text +{ + using System; + using System.IO; + using ImageSharp; + using ImageSharp.Drawing.Brushes; + using Processing; + using System.Collections.Generic; + using Xunit; + using ImageSharp.Drawing; + using System.Numerics; + using SixLabors.Shapes; + using ImageSharp.Drawing.Processors; + using ImageSharp.Drawing.Pens; + using SixLabors.Fonts; + using Paths; + + public class DrawText : IDisposable + { + Color color = Color.HotPink; + SolidBrush brush = Brushes.Solid(Color.HotPink); + IPath path = new SixLabors.Shapes.Path(new LinearLineSegment(new Vector2[] { + new Vector2(10,10), + new Vector2(20,10), + new Vector2(20,10), + new Vector2(30,10), + })); + private ProcessorWatchingImage img; + private readonly FontCollection FontCollection; + private readonly Font Font; + + public DrawText() + { + this.FontCollection = new FontCollection(); + this.Font = FontCollection.Install(TestFontUtilities.GetPath("SixLaborsSampleAB.woff")); + this.img = new ProcessorWatchingImage(10, 10); + } + + public void Dispose() + { + img.Dispose(); + } + + [Fact] + public void FillsForEachACharachterWhenBrushSetAndNotPen() + { + img.DrawText("123", this.Font, Brushes.Solid(Color.Red), null, Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + [Fact] + public void FillsForEachACharachterWhenBrushSetAndNotPenDefaultOptions() + { + img.DrawText("123", this.Font, Brushes.Solid(Color.Red), null, Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + + [Fact] + public void FillsForEachACharachterWhenBrushSet() + { + img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + [Fact] + public void FillsForEachACharachterWhenBrushSetDefaultOptions() + { + img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + [Fact] + public void FillsForEachACharachterWhenColorSet() + { + img.DrawText("123", this.Font, Color.Red, Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); + FillRegionProcessor processor = Assert.IsType>(img.ProcessorApplications[0].processor); + + SolidBrush brush = Assert.IsType>(processor.Brush); + Assert.Equal(Color.Red, brush.Color); + } + + [Fact] + public void FillsForEachACharachterWhenColorSetDefaultOptions() + { + img.DrawText("123", this.Font, Color.Red, Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); + Assert.IsType>(img.ProcessorApplications[0].processor); + FillRegionProcessor processor = Assert.IsType>(img.ProcessorApplications[0].processor); + + SolidBrush brush = Assert.IsType>(processor.Brush); + Assert.Equal(Color.Red, brush.Color); + } + + [Fact] + public void DrawForEachACharachterWhenPenSetAndNotBrush() + { + img.DrawText("123", this.Font, null, Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + [Fact] + public void DrawForEachACharachterWhenPenSetAndNotBrushDefaultOptions() + { + img.DrawText("123", this.Font, null, Pens.Dash(Color.Red, 1), Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + + [Fact] + public void DrawForEachACharachterWhenPenSet() + { + img.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + [Fact] + public void DrawForEachACharachterWhenPenSetDefaultOptions() + { + img.DrawText("123", this.Font, Pens.Dash(Color.Red, 1), Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(3, img.ProcessorApplications.Count); // 3 fills where applied + Assert.IsType>(img.ProcessorApplications[0].processor); + } + + [Fact] + public void DrawForEachACharachterWhenPenSetAndFillFroEachWhenBrushSet() + { + img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(6, img.ProcessorApplications.Count); + } + + [Fact] + public void DrawForEachACharachterWhenPenSetAndFillFroEachWhenBrushSetDefaultOptions() + { + img.DrawText("123", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(6, img.ProcessorApplications.Count); + } + + [Fact] + public void BrushAppliesBeforPen() + { + img.DrawText("1", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero, new TextGraphicsOptions(true)); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(2, img.ProcessorApplications.Count); + Assert.IsType>(img.ProcessorApplications[0].processor); + Assert.IsType>(img.ProcessorApplications[1].processor); + } + + [Fact] + public void BrushAppliesBeforPenDefaultOptions() + { + img.DrawText("1", this.Font, Brushes.Solid(Color.Red), Pens.Dash(Color.Red, 1), Vector2.Zero); + + Assert.NotEmpty(img.ProcessorApplications); + Assert.Equal(2, img.ProcessorApplications.Count); + Assert.IsType>(img.ProcessorApplications[0].processor); + Assert.IsType>(img.ProcessorApplications[1].processor); + } + } +} diff --git a/tests/ImageSharp.Tests/Drawing/Text/GlyphBuilder.cs b/tests/ImageSharp.Tests/Drawing/Text/GlyphBuilder.cs new file mode 100644 index 000000000..1faa5edd3 --- /dev/null +++ b/tests/ImageSharp.Tests/Drawing/Text/GlyphBuilder.cs @@ -0,0 +1,68 @@ + +namespace ImageSharp.Tests.Drawing.Text +{ + using ImageSharp.Drawing; + using SixLabors.Fonts; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Numerics; + using System.Threading.Tasks; + using Xunit; + + public class GlyphBuilderTests + { + [Fact] + public void OriginUsed() + { + // Y axis is inverted as it expects to be drawing for bottom left + var fullBuilder = new GlyphBuilder(new System.Numerics.Vector2(10, 99)); + IGlyphRenderer builder = fullBuilder; + + builder.BeginGlyph(); + builder.BeginFigure(); + builder.MoveTo(new Vector2(0, 0)); + builder.LineTo(new Vector2(0, 10)); // becomes 0, -10 + + builder.CubicBezierTo( + new Vector2(15, 15), // control point - will not be in the final point collection + new Vector2(15, 10), // control point - will not be in the final point collection + new Vector2(10, 10));// becomes 10, -10 + + builder.QuadraticBezierTo( + new Vector2(10, 5), // control point - will not be in the final point collection + new Vector2(10, 0)); + + builder.EndFigure(); + builder.EndGlyph(); + + var points = fullBuilder.Paths.Single().Flatten().Single().Points; + + Assert.Contains(new Vector2(10, 99), points); + Assert.Contains(new Vector2(10, 109), points); + Assert.Contains(new Vector2(20, 99), points); + Assert.Contains(new Vector2(20, 109), points); + } + + [Fact] + public void EachGlypeCausesNewPath() + { + // Y axis is inverted as it expects to be drawing for bottom left + GlyphBuilder fullBuilder = new GlyphBuilder(); + IGlyphRenderer builder = fullBuilder; + for (var i = 0; i < 10; i++) + { + builder.BeginGlyph(); + builder.BeginFigure(); + builder.MoveTo(new Vector2(0, 0)); + builder.LineTo(new Vector2(0, 10)); // becomes 0, -10 + builder.LineTo(new Vector2(10, 10));// becomes 10, -10 + builder.LineTo(new Vector2(10, 0)); + builder.EndFigure(); + builder.EndGlyph(); + } + + Assert.Equal(10, fullBuilder.Paths.Count()); + } + } +} diff --git a/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs b/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs new file mode 100644 index 000000000..ae007727a --- /dev/null +++ b/tests/ImageSharp.Tests/Drawing/Text/OutputText.cs @@ -0,0 +1,41 @@ + +namespace ImageSharp.Tests.Drawing.Text +{ + using System; + using System.IO; + using ImageSharp; + using ImageSharp.Drawing.Brushes; + using Processing; + using System.Collections.Generic; + using Xunit; + using ImageSharp.Drawing; + using System.Numerics; + using SixLabors.Shapes; + using ImageSharp.Drawing.Processors; + using ImageSharp.Drawing.Pens; + using SixLabors.Fonts; + + public class OutputText : FileTestBase + { + private readonly FontCollection FontCollection; + private readonly Font Font; + + public OutputText() + { + this.FontCollection = new FontCollection(); + this.Font = FontCollection.Install(TestFontUtilities.GetPath("SixLaborsSampleAB.woff")); + } + + [Fact] + public void DrawAB() + { + //draws 2 overlapping triangle glyphs twice 1 set on each line + using (var img = new Image(100, 200)) + { + img.Fill(Color.DarkBlue) + .DrawText("AB\nAB", new Font(this.Font, 50), Color.Red, new Vector2(0, 0)); + img.Save($"{this.CreateOutputDirectory("Drawing", "Text")}/AB.png"); + } + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs index 736225680..252b01138 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegUtilityTestFixture.cs @@ -4,14 +4,13 @@ // using System.Text; -using ImageSharp.Formats; + using Xunit.Abstractions; // ReSharper disable InconsistentNaming namespace ImageSharp.Tests { using System; - using System.Collections.Generic; using System.Diagnostics; using ImageSharp.Formats.Jpg; @@ -99,28 +98,6 @@ namespace ImageSharp.Tests this.Output.WriteLine(bld.ToString()); } - internal struct ApproximateFloatComparer : IEqualityComparer - { - private readonly float Eps; - - public ApproximateFloatComparer(float eps = 1f) - { - this.Eps = eps; - } - - public bool Equals(float x, float y) - { - float d = x - y; - - return d > -this.Eps && d < this.Eps; - } - - public int GetHashCode(float obj) - { - throw new InvalidOperationException(); - } - } - protected void Print(string msg) { Debug.WriteLine(msg); diff --git a/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs b/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs index f3cd20f45..cd9cd04b7 100644 --- a/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs +++ b/tests/ImageSharp.Tests/Image/PixelAccessorTests.cs @@ -130,16 +130,7 @@ namespace ImageSharp.Tests CopyFromZYX(image); } } - - [Fact] - public void CopyFromZYXOptimized() - { - using (Image image = new Image(1, 1)) - { - CopyFromZYX(image); - } - } - + [Fact] public void CopyFromZYXW() { @@ -148,16 +139,7 @@ namespace ImageSharp.Tests CopyFromZYXW(image); } } - - [Fact] - public void CopyFromZYXWOptimized() - { - using (Image image = new Image(1, 1)) - { - CopyFromZYXW(image); - } - } - + [Fact] public void CopyToZYX() { @@ -166,16 +148,7 @@ namespace ImageSharp.Tests CopyToZYX(image); } } - - [Fact] - public void CopyToZYXOptimized() - { - using (Image image = new Image(1, 1)) - { - CopyToZYX(image); - } - } - + [Fact] public void CopyToZYXW() { @@ -184,16 +157,7 @@ namespace ImageSharp.Tests CopyToZYXW(image); } } - - [Fact] - public void CopyToZYXWOptimized() - { - using (Image image = new Image(1, 1)) - { - CopyToZYXW(image); - } - } - + private static void CopyFromZYX(Image image) where TColor : struct, IPixel { diff --git a/tests/ImageSharp.Tests/Image/PixelPoolTests.cs b/tests/ImageSharp.Tests/Image/PixelPoolTests.cs deleted file mode 100644 index 0b762cf7c..000000000 --- a/tests/ImageSharp.Tests/Image/PixelPoolTests.cs +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Tests -{ - using System.Linq; - - using Xunit; - - /// - /// Tests the class. - /// - public class PixelPoolTests - { - [Fact] - public void PixelPoolRentsMinimumSize() - { - Color[] pixels = PixelPool.RentPixels(1024); - - Assert.True(pixels.Length >= 1024); - } - - [Fact] - public void PixelPoolRentsEmptyArray() - { - for (int i = 16; i < 1024; i += 16) - { - Color[] pixels = PixelPool.RentPixels(i); - - Assert.True(pixels.All(p => p == default(Color))); - - PixelPool.ReturnPixels(pixels); - } - - for (int i = 16; i < 1024; i += 16) - { - Color[] pixels = PixelPool.RentPixels(i); - - Assert.True(pixels.All(p => p == default(Color))); - - PixelPool.ReturnPixels(pixels); - } - } - - [Fact] - public void PixelPoolDoesNotThrowWhenReturningNonPooled() - { - Color[] pixels = new Color[1024]; - - PixelPool.ReturnPixels(pixels); - - Assert.True(pixels.Length >= 1024); - } - - [Fact] - public void PixelPoolCleansRentedArray() - { - Color[] pixels = PixelPool.RentPixels(256); - - for (int i = 0; i < pixels.Length; i++) - { - pixels[i] = Color.Azure; - } - - Assert.True(pixels.All(p => p == Color.Azure)); - - PixelPool.ReturnPixels(pixels); - - Assert.True(pixels.All(p => p == default(Color))); - } - } -} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj new file mode 100644 index 000000000..c6f916e00 --- /dev/null +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -0,0 +1,22 @@ + + + netcoreapp1.1 + True + full + portable + True + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.xproj b/tests/ImageSharp.Tests/ImageSharp.Tests.xproj deleted file mode 100644 index d2c2d15a0..000000000 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.xproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - f836e8e6-b4d9-4208-8346-140c74678b91 - ImageSharp.Tests - .\obj - .\bin\ - v4.5.1 - - - 2.0 - - - - - - \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs b/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs index 5acbe0f3e..06ab245c9 100644 --- a/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs @@ -50,6 +50,27 @@ namespace ImageSharp.Tests } } + [Theory] + [MemberData(nameof(ReSamplers))] + public void ImageShouldResizeFromSourceRectangle(string name, IResampler sampler) + { + name = $"{name}-SourceRect"; + + string path = this.CreateOutputDirectory("Resize"); + + foreach (TestFile file in Files) + { + string filename = file.GetFileName(name); + using (Image image = file.CreateImage()) + using (FileStream output = File.OpenWrite($"{path}/{filename}")) + { + var sourceRectangle = new Rectangle(image.Width / 8, image.Height / 8, image.Width / 4, image.Height / 4); + var destRectangle = new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + image.Resize(image.Width, image.Height, sampler, sourceRectangle, destRectangle, false).Save(output); + } + } + } + [Theory] [MemberData(nameof(ReSamplers))] public void ImageShouldResizeWidthAndKeepAspect(string name, IResampler sampler) diff --git a/tests/ImageSharp.Tests/Properties/AssemblyInfo.cs b/tests/ImageSharp.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 3d57ceff5..000000000 --- a/tests/ImageSharp.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ImageSharp.Tests")] -[assembly: AssemblyDescription("A cross-platform library for processing of image files written in C#")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ImageSharp.Tests")] -[assembly: AssemblyCopyright("Copyright © James Jackson-South and contributors.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f836e8e6-b4d9-4208-8346-140c74678b91")] diff --git a/tests/ImageSharp.Tests/TestBase.cs b/tests/ImageSharp.Tests/TestBase.cs index 2b92591eb..c7514d5ae 100644 --- a/tests/ImageSharp.Tests/TestBase.cs +++ b/tests/ImageSharp.Tests/TestBase.cs @@ -6,6 +6,8 @@ namespace ImageSharp.Tests { using System.IO; + using System.Reflection; + using ImageSharp.Formats; /// @@ -23,7 +25,9 @@ namespace ImageSharp.Tests /// protected string CreateOutputDirectory(string path, params string[] pathParts) { - path = Path.Combine("TestOutput", path); + string assemblyLocation = typeof(TestFile).GetTypeInfo().Assembly.Location; + assemblyLocation = Path.GetDirectoryName(assemblyLocation); + path = Path.GetFullPath(Path.Combine(assemblyLocation, "../../../TestOutput", path)); if (pathParts != null && pathParts.Length > 0) { diff --git a/tests/ImageSharp.Tests/TestFile.cs b/tests/ImageSharp.Tests/TestFile.cs index 0c9cc5f47..42340dc44 100644 --- a/tests/ImageSharp.Tests/TestFile.cs +++ b/tests/ImageSharp.Tests/TestFile.cs @@ -154,7 +154,8 @@ namespace ImageSharp.Tests "TestImages/Formats/", // Here for code coverage tests. "tests/ImageSharp.Tests/TestImages/Formats/", // from travis/build script "../../../ImageSharp.Tests/TestImages/Formats/", // from Sandbox46 - "../../../../TestImages/Formats/" + "../../../../TestImages/Formats/", + "../../../TestImages/Formats/" }; directories = directories.SelectMany(x => new[] diff --git a/tests/ImageSharp.Tests/TestFont.cs b/tests/ImageSharp.Tests/TestFont.cs new file mode 100644 index 000000000..3a5bb2b2c --- /dev/null +++ b/tests/ImageSharp.Tests/TestFont.cs @@ -0,0 +1,90 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests +{ + using System; + using System.Collections.Concurrent; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + + /// + /// A test image file. + /// + public static class TestFontUtilities + { + /// + /// The formats directory. + /// + private static readonly string FormatsDirectory = GetFontsDirectory(); + + /// + /// Gets the full qualified path to the file. + /// + /// + /// The file path. + /// + /// + /// The . + /// + public static string GetPath(string file) + { + return Path.Combine(FormatsDirectory, file); + } + + /// + /// Gets the correct path to the formats directory. + /// + /// + /// The . + /// + private static string GetFontsDirectory() + { + List directories = new List< string > { + "TestFonts/", // Here for code coverage tests. + "tests/ImageSharp.Tests/TestFonts/", // from travis/build script + "../../../ImageSharp.Tests/TestFonts/", // from Sandbox46 + "../../../../TestFonts/" + }; + + directories = directories.SelectMany(x => new[] + { + Path.GetFullPath(x) + }).ToList(); + + AddFormatsDirectoryFromTestAssebmlyPath(directories); + + var directory = directories.FirstOrDefault(x => Directory.Exists(x)); + + if(directory != null) + { + return directory; + } + + throw new System.Exception($"Unable to find Fonts directory at any of these locations [{string.Join(", ", directories)}]"); + } + + /// + /// The path returned by Path.GetFullPath(x) can be relative to dotnet framework directory + /// in certain scenarios like dotTrace test profiling. + /// This method calculates and adds the format directory based on the ImageSharp.Tests assembly location. + /// + /// The directories list + private static void AddFormatsDirectoryFromTestAssebmlyPath(List directories) + { + string assemblyLocation = typeof(TestFile).GetTypeInfo().Assembly.Location; + assemblyLocation = Path.GetDirectoryName(assemblyLocation); + + if (assemblyLocation != null) + { + string dirFromAssemblyLocation = Path.Combine(assemblyLocation, "../../../TestFonts/"); + dirFromAssemblyLocation = Path.GetFullPath(dirFromAssemblyLocation); + directories.Add(dirFromAssemblyLocation); + } + } + } +} diff --git a/tests/ImageSharp.Tests/TestFonts/SixLaborsSampleAB.woff b/tests/ImageSharp.Tests/TestFonts/SixLaborsSampleAB.woff new file mode 100644 index 000000000..277749dfb Binary files /dev/null and b/tests/ImageSharp.Tests/TestFonts/SixLaborsSampleAB.woff differ diff --git a/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs new file mode 100644 index 000000000..333b645de --- /dev/null +++ b/tests/ImageSharp.Tests/TestUtilities/ApproximateFloatComparer.cs @@ -0,0 +1,38 @@ +namespace ImageSharp.Tests +{ + using System; + using System.Collections.Generic; + using System.Numerics; + + internal struct ApproximateFloatComparer : IEqualityComparer, IEqualityComparer + { + private readonly float Eps; + + public ApproximateFloatComparer(float eps = 1f) + { + this.Eps = eps; + } + + public bool Equals(float x, float y) + { + float d = x - y; + + return d > -this.Eps && d < this.Eps; + } + + public int GetHashCode(float obj) + { + throw new InvalidOperationException(); + } + + public bool Equals(Vector4 a, Vector4 b) + { + return this.Equals(a.X, b.X) && this.Equals(a.Y, b.Y) && this.Equals(a.Z, b.Z) && this.Equals(a.W, b.W); + } + + public int GetHashCode(Vector4 obj) + { + throw new InvalidOperationException(); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 09c81b761..1acb9e149 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -154,7 +154,7 @@ namespace ImageSharp.Tests TestImageProvider.Blank(10, 20), TestImageProvider.Blank( 10, - 20) + 20), }; [Theory] diff --git a/tests/ImageSharp.Tests/project.json b/tests/ImageSharp.Tests/project.json deleted file mode 100644 index 3761bb385..000000000 --- a/tests/ImageSharp.Tests/project.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "version": "1.0.0-*", - "description": "ImageSharp.Tests Class Library", - "authors": [ "James Jackson-South and contributors" ], - "packOptions": { - "projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", - "tags": [ - "Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" - ] - }, - "buildOptions": { - "allowUnsafe": true - }, - "configurations": { - "Release": { - "buildOptions": { - "warningsAsErrors": true - } - } - }, - "dependencies": { - "ImageSharp": { - "target": "project" - }, - "xunit": "2.2.0-*", - "dotnet-test-xunit": "2.2.0-*", - "ImageSharp.Drawing": { - "target": "project" - }, - "ImageSharp.Drawing.Paths": { - "target": "project" - }, - "ImageSharp.Formats.Png": { - "target": "project" - }, - "ImageSharp.Formats.Jpeg": { - "target": "project" - }, - "ImageSharp.Formats.Bmp": { - "target": "project" - }, - "ImageSharp.Formats.Gif": { - "target": "project" - }, - "ImageSharp.Processing": { - "target": "project" - }, - //alpha supports netstandard - "Moq": "4.6.38-alpha" - }, - "frameworks": { - "netcoreapp1.1": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0-*" - }, - "Microsoft.CodeCoverage": "1.0.2" - } - }, - "net451": { - "dependencies": { - } - } - }, - "testRunner": "xunit" -} \ No newline at end of file diff --git a/theme/index.cshtml b/theme/index.cshtml new file mode 100644 index 000000000..d3656f800 --- /dev/null +++ b/theme/index.cshtml @@ -0,0 +1,3 @@ +Title: Home +--- +Welcome to the documentation for ImageSharp \ No newline at end of file