Browse Source

Merge branch 'master' into tiff-codec

pull/1570/head
Andrew Wilkinson 9 years ago
parent
commit
2ed1bb3da8
  1. 13
      .editorconfig
  2. 6
      .gitignore
  3. 5
      .travis.yml
  4. 11
      .vscode/tasks.json
  5. 8
      ImageSharp.ruleset
  6. 151
      ImageSharp.sln
  7. 33
      README.md
  8. 15
      appveyor.yml
  9. 98
      build/Program.cs
  10. 3
      build/Properties/launchSettings.json
  11. 16
      build/build.csproj
  12. 25
      build/build.xproj
  13. 4
      build/icons/imagesharp-logo-128.png
  14. 4
      build/icons/imagesharp-logo-256.png
  15. 4
      build/icons/imagesharp-logo-32.png
  16. 4
      build/icons/imagesharp-logo-512.png
  17. 4
      build/icons/imagesharp-logo-64.png
  18. 3
      build/icons/imagesharp-logo-heading.png
  19. 4
      build/icons/imagesharp-logo.png
  20. 22
      build/project.json
  21. 4
      codecov.yml
  22. 4
      config.wyam
  23. 29
      dotnet-latest.ps1
  24. 16
      features.md
  25. 6
      global.json
  26. 3
      input/about.md
  27. 25
      src/ImageSharp.Drawing.Paths/ImageSharp.Drawing.Paths.xproj
  28. 6
      src/ImageSharp.Drawing.Paths/Properties/AssemblyInfo.cs
  29. 95
      src/ImageSharp.Drawing.Paths/project.json
  30. 51
      src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
  31. 25
      src/ImageSharp.Drawing/ImageSharp.Drawing.xproj
  32. 0
      src/ImageSharp.Drawing/Paths/DrawBeziers.cs
  33. 0
      src/ImageSharp.Drawing/Paths/DrawLines.cs
  34. 0
      src/ImageSharp.Drawing/Paths/DrawPath.cs
  35. 0
      src/ImageSharp.Drawing/Paths/DrawPolygon.cs
  36. 0
      src/ImageSharp.Drawing/Paths/DrawRectangle.cs
  37. 0
      src/ImageSharp.Drawing/Paths/FillPaths.cs
  38. 0
      src/ImageSharp.Drawing/Paths/FillPolygon.cs
  39. 0
      src/ImageSharp.Drawing/Paths/FillRectangle.cs
  40. 0
      src/ImageSharp.Drawing/Paths/RectangleExtensions.cs
  41. 0
      src/ImageSharp.Drawing/Paths/ShapePath.cs
  42. 0
      src/ImageSharp.Drawing/Paths/ShapeRegion.cs
  43. 1
      src/ImageSharp.Drawing/Processors/DrawPathProcessor.cs
  44. 1
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  45. 203
      src/ImageSharp.Drawing/Text/DrawText.cs
  46. 126
      src/ImageSharp.Drawing/Text/GlyphBuilder.cs
  47. 68
      src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs
  48. 94
      src/ImageSharp.Drawing/project.json
  49. 25
      src/ImageSharp.Formats.Bmp/ImageSharp.Formats.Bmp.xproj
  50. 6
      src/ImageSharp.Formats.Bmp/Properties/AssemblyInfo.cs
  51. 92
      src/ImageSharp.Formats.Bmp/project.json
  52. 25
      src/ImageSharp.Formats.Gif/ImageSharp.Formats.Gif.xproj
  53. 6
      src/ImageSharp.Formats.Gif/Properties/AssemblyInfo.cs
  54. 92
      src/ImageSharp.Formats.Gif/project.json
  55. 25
      src/ImageSharp.Formats.Jpeg/ImageSharp.Formats.Jpeg.xproj
  56. 6
      src/ImageSharp.Formats.Jpeg/Properties/AssemblyInfo.cs
  57. 92
      src/ImageSharp.Formats.Jpeg/project.json
  58. 25
      src/ImageSharp.Formats.Png/ImageSharp.Formats.Png.xproj
  59. 6
      src/ImageSharp.Formats.Png/Properties/AssemblyInfo.cs
  60. 92
      src/ImageSharp.Formats.Png/project.json
  61. 25
      src/ImageSharp.Processing/ImageSharp.Processing.xproj
  62. 6
      src/ImageSharp.Processing/Properties/AssemblyInfo.cs
  63. 91
      src/ImageSharp.Processing/project.json
  64. 249
      src/ImageSharp/Colors/Color.BulkOperations.cs
  65. 3
      src/ImageSharp/Colors/Color.cs
  66. 3
      src/ImageSharp/Colors/PackedPixel/Alpha8.cs
  67. 3
      src/ImageSharp/Colors/PackedPixel/Argb.cs
  68. 3
      src/ImageSharp/Colors/PackedPixel/Bgr565.cs
  69. 3
      src/ImageSharp/Colors/PackedPixel/Bgra4444.cs
  70. 3
      src/ImageSharp/Colors/PackedPixel/Bgra5551.cs
  71. 256
      src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs
  72. 3
      src/ImageSharp/Colors/PackedPixel/Byte4.cs
  73. 3
      src/ImageSharp/Colors/PackedPixel/HalfSingle.cs
  74. 3
      src/ImageSharp/Colors/PackedPixel/HalfVector2.cs
  75. 3
      src/ImageSharp/Colors/PackedPixel/HalfVector4.cs
  76. 6
      src/ImageSharp/Colors/PackedPixel/IPixel.cs
  77. 3
      src/ImageSharp/Colors/PackedPixel/NormalizedByte2.cs
  78. 3
      src/ImageSharp/Colors/PackedPixel/NormalizedByte4.cs
  79. 3
      src/ImageSharp/Colors/PackedPixel/NormalizedShort2.cs
  80. 3
      src/ImageSharp/Colors/PackedPixel/NormalizedShort4.cs
  81. 3
      src/ImageSharp/Colors/PackedPixel/Rg32.cs
  82. 3
      src/ImageSharp/Colors/PackedPixel/Rgba1010102.cs
  83. 3
      src/ImageSharp/Colors/PackedPixel/Rgba64.cs
  84. 3
      src/ImageSharp/Colors/PackedPixel/Short2.cs
  85. 3
      src/ImageSharp/Colors/PackedPixel/Short4.cs
  86. 29
      src/ImageSharp/Common/Extensions/ArrayExtensions.cs
  87. 130
      src/ImageSharp/Common/Helpers/DebugGuard.cs
  88. 85
      src/ImageSharp/Common/Memory/ArrayPointer{T}.cs
  89. 129
      src/ImageSharp/Common/Memory/BufferPointer.cs
  90. 143
      src/ImageSharp/Common/Memory/BufferPointer{T}.cs
  91. 214
      src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs
  92. 60
      src/ImageSharp/Common/Memory/PixelDataPool{T}.cs
  93. 8
      src/ImageSharp/Configuration.cs
  94. 0
      src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs
  95. 0
      src/ImageSharp/Formats/Bmp/BmpCompression.cs
  96. 0
      src/ImageSharp/Formats/Bmp/BmpDecoder.cs
  97. 0
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  98. 0
      src/ImageSharp/Formats/Bmp/BmpEncoder.cs
  99. 0
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  100. 0
      src/ImageSharp/Formats/Bmp/BmpEncoderOptions.cs

13
.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

6
.gitignore

@ -211,5 +211,9 @@ artifacts/
#BenchmarkDotNet
**/BenchmarkDotNet.Artifacts/
# Build process
*.csproj.bak
#CodeCoverage
**/CodeCoverage/*
**/CodeCoverage/*
docs/

5
.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:

11
.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"

8
ImageSharp.ruleset

@ -1,7 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="ImageSharp" ToolsVersion="14.0">
<RuleSet Name="ImageSharp" ToolsVersion="15.0">
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="AD0001" Action="None" />
<Rule Id="SA1405" Action="None" />
<Rule Id="SA1413" Action="None" />
<!-- temp remove the header requiremnet as stylecop is currently failing to read the stylecop.json file from 'dotnet build' -->
<Rule Id="SA1636" Action="None" />
<Rule Id="SA1633" Action="None" />
</Rules>
</RuleSet>
</RuleSet>

151
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

33
README.md

@ -1,5 +1,5 @@
# <img src="build/icons/imagesharp-logo-64.png" width="52" height="52"/> ImageSharp
# <img src="build/icons/imagesharp-logo-heading.png" alt="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.

15
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

98
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;
/// <summary>
@ -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<SourceProject> projects)
private static void CreateBuildScript(IEnumerable<SourceProject> 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<SourceProject> projects)
private static void ResetProject(IEnumerable<string> 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<string> dependencies;
private readonly ProjectRootElement project;
/// <summary>
/// Initializes a new instance of the <see cref="SourceProject"/> class.
/// </summary>
/// <param name="project">The project.</param>
/// <param name="root">The root.</param>
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;
}
/// <summary>
@ -223,7 +226,7 @@ namespace ConsoleApplication
/// <value>
/// The version.
/// </value>
public NuGetVersion Version { get; }
public NuGetVersion Version { get; private set; }
/// <summary>
/// Gets the dependent projects.
@ -279,7 +282,18 @@ namespace ConsoleApplication
/// <param name="projects">The projects.</param>
public void PopulateDependencies(IEnumerable<SourceProject> projects)
{
this.DependentProjects = projects.Where(x => this.dependencies.Contains(x.Name)).ToList();
this.DependentProjects = projects.Where(x => this.dependencies.Contains(x.FullProjectFilePath)).ToList();
}
/// <summary>
/// Update the version number in the project file
/// </summary>
/// <param name="versionnumber">the new version number to save.</param>
internal void UpdateVersion(string versionnumber)
{
this.project.AddProperty("VersionPrefix", versionnumber);
this.Version = new NuGetVersion(versionnumber);
this.project.Save();
}
/// <summary>
@ -334,11 +348,15 @@ namespace ConsoleApplication
var blob = repo.Lookup<Blob>(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;
}
}
}
}

3
build/Properties/launchSettings.json

@ -1,7 +1,8 @@
{
"profiles": {
"build": {
"commandName": "Project"
"commandName": "Project",
"commandLineArgs": "reset"
}
}
}

16
build/build.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<DebugType>portable</DebugType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>build</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>build</PackageId>
<CodeAnalysisRuleSet>..\ImageSharp.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.ProjectModel" Version="1.0.0-rc3-1-003177" />
<PackageReference Include="Microsoft.Build" Version="15.1.548" />
<PackageReference Include="LibGit2Sharp.Portable" Version="0.24.10" />
</ItemGroup>
</Project>

25
build/build.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>575a5002-dd9f-4335-aa47-1dd87fa13645</ProjectGuid>
<RootNamespace>build</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

4
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

4
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

4
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

4
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

4
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

3
build/icons/imagesharp-logo-heading.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bf2335642c6fd291befa0b203dbfb3387d99434369399b35aeea037c0f9eba45
size 10474

4
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

22
build/project.json

@ -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.
}
}
}

4
codecov.yml

@ -0,0 +1,4 @@
ignore:
"src/ImageSharp/Common/Helpers/DebugGuard.cs"

4
config.wyam

@ -0,0 +1,4 @@
#recipe Docs
Settings[Keys.Host] = "imagesharp.org";
Settings[Keys.Title] = "Image Sharp";
FileSystem.OutputPath = "./docs";

29
dotnet-latest.ps1

@ -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
}

16
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\<TPacked\>).
- [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.

6
global.json

@ -1,6 +0,0 @@
{
"projects": [ "src" ],
"sdk": {
"version": "1.0.0-preview2-003121"
}
}

3
input/about.md

@ -0,0 +1,3 @@
Title: About This Project
---
This project is awesome!

25
src/ImageSharp.Drawing.Paths/ImageSharp.Drawing.Paths.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>e5bd4f96-28a8-410c-8b63-1c5731948549</ProjectGuid>
<RootNamespace>ImageSharp.Drawing</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

6
src/ImageSharp.Drawing.Paths/Properties/AssemblyInfo.cs

@ -1,6 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// Common values read from `AssemblyInfo.Common.cs`

95
src/ImageSharp.Drawing.Paths/project.json

@ -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"
}
}
}
}

51
src/ImageSharp.Drawing/ImageSharp.Drawing.csproj

@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<AssemblyTitle>ImageSharp.Drawing</AssemblyTitle>
<VersionPrefix>1.0.0-alpha3</VersionPrefix>
<Authors>James Jackson-South and contributors</Authors>
<TargetFramework>netstandard1.1</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>ImageSharp.Drawing</AssemblyName>
<PackageId>ImageSharp.Drawing</PackageId>
<PackageTags>Image Draw Shape Path Font</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/JimBobSquarePants/ImageSharp</PackageProjectUrl>
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/JimBobSquarePants/ImageSharp</RepositoryUrl>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<DebugType Condition="$(codecov) != ''">full</DebugType>
<DebugType Condition="$(codecov) == ''">portable</DebugType>
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
<AdditionalFiles Include="..\Shared\stylecop.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ImageSharp\ImageSharp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta001">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="SixLabors.Fonts" Version="0.1.0-alpha0002" />
<PackageReference Include="SixLabors.Shapes" Version="0.1.0-alpha0008" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\ImageSharp.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>

25
src/ImageSharp.Drawing/ImageSharp.Drawing.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>2e33181e-6e28-4662-a801-e2e7dc206029</ProjectGuid>
<RootNamespace>ImageSharp.Drawing</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

0
src/ImageSharp.Drawing.Paths/DrawBeziers.cs → src/ImageSharp.Drawing/Paths/DrawBeziers.cs

0
src/ImageSharp.Drawing.Paths/DrawLines.cs → src/ImageSharp.Drawing/Paths/DrawLines.cs

0
src/ImageSharp.Drawing.Paths/DrawPath.cs → src/ImageSharp.Drawing/Paths/DrawPath.cs

0
src/ImageSharp.Drawing.Paths/DrawPolygon.cs → src/ImageSharp.Drawing/Paths/DrawPolygon.cs

0
src/ImageSharp.Drawing.Paths/DrawRectangle.cs → src/ImageSharp.Drawing/Paths/DrawRectangle.cs

0
src/ImageSharp.Drawing.Paths/FillPaths.cs → src/ImageSharp.Drawing/Paths/FillPaths.cs

0
src/ImageSharp.Drawing.Paths/FillPolygon.cs → src/ImageSharp.Drawing/Paths/FillPolygon.cs

0
src/ImageSharp.Drawing.Paths/FillRectangle.cs → src/ImageSharp.Drawing/Paths/FillRectangle.cs

0
src/ImageSharp.Drawing.Paths/RectangleExtensions.cs → src/ImageSharp.Drawing/Paths/RectangleExtensions.cs

0
src/ImageSharp.Drawing.Paths/ShapePath.cs → src/ImageSharp.Drawing/Paths/ShapePath.cs

0
src/ImageSharp.Drawing.Paths/ShapeRegion.cs → src/ImageSharp.Drawing/Paths/ShapeRegion.cs

1
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);

1
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);

203
src/ImageSharp.Drawing/Text/DrawText.cs

@ -0,0 +1,203 @@
// <copyright file="DrawText.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System.Numerics;
using Drawing;
using Drawing.Brushes;
using Drawing.Pens;
using SixLabors.Fonts;
/// <summary>
/// Extension methods for the <see cref="Image{TColor}"/> type.
/// </summary>
public static partial class ImageExtensions
{
/// <summary>
/// Draws the text onto the the image filled via the brush.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="color">The color.</param>
/// <param name="location">The location.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, TColor color, Vector2 location)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, color, location, TextGraphicsOptions.Default);
}
/// <summary>
/// Draws the text onto the the image filled via the brush.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="color">The color.</param>
/// <param name="location">The location.</param>
/// <param name="options">The options.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, TColor color, Vector2 location, TextGraphicsOptions options)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, Brushes<TColor>.Solid(color), null, location, options);
}
/// <summary>
/// Draws the text onto the the image filled via the brush.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="brush">The brush.</param>
/// <param name="location">The location.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, Vector2 location)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, brush, location, TextGraphicsOptions.Default);
}
/// <summary>
/// Draws the text onto the the image filled via the brush.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="brush">The brush.</param>
/// <param name="location">The location.</param>
/// <param name="options">The options.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, Vector2 location, TextGraphicsOptions options)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, brush, null, location, options);
}
/// <summary>
/// Draws the text onto the the image outlined via the pen.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="pen">The pen.</param>
/// <param name="location">The location.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IPen<TColor> pen, Vector2 location)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, pen, location, TextGraphicsOptions.Default);
}
/// <summary>
/// Draws the text onto the the image outlined via the pen.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="pen">The pen.</param>
/// <param name="location">The location.</param>
/// <param name="options">The options.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IPen<TColor> pen, Vector2 location, TextGraphicsOptions options)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, null, pen, location, options);
}
/// <summary>
/// Draws the text onto the the image filled via the brush then outlined via the pen.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="brush">The brush.</param>
/// <param name="pen">The pen.</param>
/// <param name="location">The location.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, IPen<TColor> pen, Vector2 location)
where TColor : struct, IPixel<TColor>
{
return source.DrawText(text, font, brush, pen, location, TextGraphicsOptions.Default);
}
/// <summary>
/// Draws the text onto the the image filled via the brush then outlined via the pen.
/// </summary>
/// <typeparam name="TColor">The type of the color.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="text">The text.</param>
/// <param name="font">The font.</param>
/// <param name="brush">The brush.</param>
/// <param name="pen">The pen.</param>
/// <param name="location">The location.</param>
/// <param name="options">The options.</param>
/// <returns>
/// The <see cref="Image{TColor}" />.
/// </returns>
public static Image<TColor> DrawText<TColor>(this Image<TColor> source, string text, Font font, IBrush<TColor> brush, IPen<TColor> pen, Vector2 location, TextGraphicsOptions options)
where TColor : struct, IPixel<TColor>
{
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<SixLabors.Shapes.IPath> 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;
}
}
}

126
src/ImageSharp.Drawing/Text/GlyphBuilder.cs

@ -0,0 +1,126 @@
// <copyright file="GlyphBuilder.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing
{
using System.Collections.Generic;
using System.Numerics;
using SixLabors.Fonts;
using SixLabors.Shapes;
/// <summary>
/// rendering surface that Fonts can use to generate Shapes.
/// </summary>
internal class GlyphBuilder : IGlyphRenderer
{
private readonly PathBuilder builder = new PathBuilder();
private readonly List<IPath> paths = new List<IPath>();
private Vector2 currentPoint = default(Vector2);
/// <summary>
/// Initializes a new instance of the <see cref="GlyphBuilder"/> class.
/// </summary>
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();
}
/// <summary>
/// Initializes a new instance of the <see cref="GlyphBuilder"/> class.
/// </summary>
/// <param name="origin">The origin.</param>
public GlyphBuilder(Vector2 origin)
{
this.builder = new PathBuilder();
this.builder.SetOrigin(origin);
}
/// <summary>
/// Gets the paths that have been rendered by this.
/// </summary>
public IEnumerable<IPath> Paths => this.paths;
/// <summary>
/// Begins the glyph.
/// </summary>
void IGlyphRenderer.BeginGlyph()
{
this.builder.Clear();
}
/// <summary>
/// Begins the figure.
/// </summary>
void IGlyphRenderer.BeginFigure()
{
this.builder.StartFigure();
}
/// <summary>
/// Draws a cubic bezier from the current point to the <paramref name="point"/>
/// </summary>
/// <param name="secondControlPoint">The second control point.</param>
/// <param name="thirdControlPoint">The third control point.</param>
/// <param name="point">The point.</param>
void IGlyphRenderer.CubicBezierTo(Vector2 secondControlPoint, Vector2 thirdControlPoint, Vector2 point)
{
this.builder.AddBezier(this.currentPoint, secondControlPoint, thirdControlPoint, point);
this.currentPoint = point;
}
/// <summary>
/// Ends the glyph.
/// </summary>
void IGlyphRenderer.EndGlyph()
{
this.paths.Add(this.builder.Build());
}
/// <summary>
/// Ends the figure.
/// </summary>
void IGlyphRenderer.EndFigure()
{
this.builder.CloseFigure();
}
/// <summary>
/// Draws a line from the current point to the <paramref name="point"/>.
/// </summary>
/// <param name="point">The point.</param>
void IGlyphRenderer.LineTo(Vector2 point)
{
this.builder.AddLine(this.currentPoint, point);
this.currentPoint = point;
}
/// <summary>
/// Moves to current point to the supplied vector.
/// </summary>
/// <param name="point">The point.</param>
void IGlyphRenderer.MoveTo(Vector2 point)
{
this.builder.StartFigure();
this.currentPoint = point;
}
/// <summary>
/// Draws a quadratics bezier from the current point to the <paramref name="point"/>
/// </summary>
/// <param name="secondControlPoint">The second control point.</param>
/// <param name="point">The point.</param>
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;
}
}
}

68
src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs

@ -0,0 +1,68 @@
// <copyright file="TextGraphicsOptions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing
{
/// <summary>
/// Options for influencing the drawing functions.
/// </summary>
public struct TextGraphicsOptions
{
/// <summary>
/// Represents the default <see cref="TextGraphicsOptions"/>.
/// </summary>
public static readonly TextGraphicsOptions Default = new TextGraphicsOptions(true);
/// <summary>
/// Whether antialiasing should be applied.
/// </summary>
public bool Antialias;
/// <summary>
/// Whether the text should be drawing with kerning enabled.
/// </summary>
public bool ApplyKerning;
/// <summary>
/// The number of space widths a tab should lock to.
/// </summary>
public float TabWidth;
/// <summary>
/// Initializes a new instance of the <see cref="TextGraphicsOptions" /> struct.
/// </summary>
/// <param name="enableAntialiasing">If set to <c>true</c> [enable antialiasing].</param>
public TextGraphicsOptions(bool enableAntialiasing)
{
this.Antialias = enableAntialiasing;
this.ApplyKerning = true;
this.TabWidth = 4;
}
/// <summary>
/// Performs an implicit conversion from <see cref="GraphicsOptions"/> to <see cref="TextGraphicsOptions"/>.
/// </summary>
/// <param name="options">The options.</param>
/// <returns>
/// The result of the conversion.
/// </returns>
public static implicit operator TextGraphicsOptions(GraphicsOptions options)
{
return new TextGraphicsOptions(options.Antialias);
}
/// <summary>
/// Performs an explicit conversion from <see cref="TextGraphicsOptions"/> to <see cref="GraphicsOptions"/>.
/// </summary>
/// <param name="options">The options.</param>
/// <returns>
/// The result of the conversion.
/// </returns>
public static explicit operator GraphicsOptions(TextGraphicsOptions options)
{
return new GraphicsOptions(options.Antialias);
}
}
}

94
src/ImageSharp.Drawing/project.json

@ -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"
}
}
}
}

25
src/ImageSharp.Formats.Bmp/ImageSharp.Formats.Bmp.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>c77661b9-f793-422e-8e27-ac60ecc5f215</ProjectGuid>
<RootNamespace>ImageSharp.Formats.Bmp</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

6
src/ImageSharp.Formats.Bmp/Properties/AssemblyInfo.cs

@ -1,6 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// Common values read from `AssemblyInfo.Common.cs`

92
src/ImageSharp.Formats.Bmp/project.json

@ -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"
}
}
}
}

25
src/ImageSharp.Formats.Gif/ImageSharp.Formats.Gif.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>27ad4b5f-ecc4-4c63-9ecb-04ec772fdb6f</ProjectGuid>
<RootNamespace>ImageSharp.Formats.Gif</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

6
src/ImageSharp.Formats.Gif/Properties/AssemblyInfo.cs

@ -1,6 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// Common values read from `AssemblyInfo.Common.cs`

92
src/ImageSharp.Formats.Gif/project.json

@ -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"
}
}
}
}

25
src/ImageSharp.Formats.Jpeg/ImageSharp.Formats.Jpeg.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>7213767c-0003-41ca-ab18-0223cfa7ce4b</ProjectGuid>
<RootNamespace>ImageSharp.Formats</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

6
src/ImageSharp.Formats.Jpeg/Properties/AssemblyInfo.cs

@ -1,6 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// Common values read from `AssemblyInfo.Common.cs`

92
src/ImageSharp.Formats.Jpeg/project.json

@ -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"
}
}
}
}

25
src/ImageSharp.Formats.Png/ImageSharp.Formats.Png.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>556abdcf-ed93-4327-be98-f6815f78b9b8</ProjectGuid>
<RootNamespace>ImageSharp.Formats.Png</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

6
src/ImageSharp.Formats.Png/Properties/AssemblyInfo.cs

@ -1,6 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// Common values read from `AssemblyInfo.Common.cs`

92
src/ImageSharp.Formats.Png/project.json

@ -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"
}
}
}
}

25
src/ImageSharp.Processing/ImageSharp.Processing.xproj

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>a623cfe9-9d2b-4528-ad1f-2e834b061134</ProjectGuid>
<RootNamespace>ImageSharp.Processing</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
</PropertyGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

6
src/ImageSharp.Processing/Properties/AssemblyInfo.cs

@ -1,6 +0,0 @@
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// Common values read from `AssemblyInfo.Common.cs`

91
src/ImageSharp.Processing/project.json

@ -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"
}
}
}
}

249
src/ImageSharp/Colors/Color.BulkOperations.cs

@ -0,0 +1,249 @@
// <copyright file="Color.BulkOperations.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <content>
/// Conains the definition of <see cref="BulkOperations"/>
/// </content>
public partial struct Color
{
/// <summary>
/// <see cref="BulkPixelOperations{TColor}"/> implementation optimized for <see cref="Color"/>.
/// </summary>
internal class BulkOperations : BulkPixelOperations<Color>
{
/// <summary>
/// SIMD optimized bulk implementation of <see cref="IPixel.PackFromVector4(Vector4)"/>
/// that works only with `count` divisible by <see cref="Vector{UInt32}.Count"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param>
/// <param name="destVectors">The <see cref="BufferPointer{T}"/> to the dstination vectors.</param>
/// <param name="count">The number of pixels to convert.</param>
/// <remarks>
/// Implementation adapted from:
/// <see>
/// <cref>http://stackoverflow.com/a/5362789</cref>
/// </see>
/// TODO: We can replace this implementation in the future using new Vector API-s:
/// <see>
/// <cref>https://github.com/dotnet/corefx/issues/15957</cref>
/// </see>
/// </remarks>
internal static unsafe void ToVector4SimdAligned(
BufferPointer<Color> sourceColors,
BufferPointer<Vector4> destVectors,
int count)
{
int vecSize = Vector<uint>.Count;
DebugGuard.IsTrue(
count % vecSize == 0,
nameof(count),
"Argument 'count' should divisible by Vector<uint>.Count!");
Vector<float> bVec = new Vector<float>(256.0f / 255.0f);
Vector<float> magicFloat = new Vector<float>(32768.0f);
Vector<uint> magicInt = new Vector<uint>(1191182336); // reinterpreded value of 32768.0f
Vector<uint> mask = new Vector<uint>(255);
int unpackedRawCount = count * 4;
uint* src = (uint*)sourceColors.PointerAtOffset;
uint* srcEnd = src + count;
using (PinnedBuffer<uint> tempBuf = new PinnedBuffer<uint>(
unpackedRawCount + Vector<uint>.Count))
{
uint* tPtr = (uint*)tempBuf.Pointer;
uint[] temp = tempBuf.Array;
float[] fTemp = Unsafe.As<float[]>(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<uint> vi = new Vector<uint>(temp, i);
vi &= mask;
vi |= magicInt;
Vector<float> vf = Vector.AsVectorSingle(vi);
vf = (vf - magicFloat) * bVec;
vf.CopyTo(fTemp, i);
}
BufferPointer.Copy<uint>(tempBuf, (BufferPointer<byte>)destVectors, unpackedRawCount);
}
}
/// <inheritdoc />
internal override void ToVector4(BufferPointer<Color> sourceColors, BufferPointer<Vector4> destVectors, int count)
{
if (count < 256)
{
// Doesn't worth to bother with SIMD:
base.ToVector4(sourceColors, destVectors, count);
return;
}
int remainder = count % Vector<uint>.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);
}
}
/// <inheritdoc />
internal override unsafe void PackFromXyzBytes(BufferPointer<byte> sourceBytes, BufferPointer<Color> 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;
}
}
/// <inheritdoc />
internal override unsafe void ToXyzBytes(BufferPointer<Color> sourceColors, BufferPointer<byte> 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;
}
}
/// <inheritdoc />
internal override void PackFromXyzwBytes(BufferPointer<byte> sourceBytes, BufferPointer<Color> destColors, int count)
{
BufferPointer.Copy(sourceBytes, destColors, count);
}
/// <inheritdoc />
internal override void ToXyzwBytes(BufferPointer<Color> sourceColors, BufferPointer<byte> destBytes, int count)
{
BufferPointer.Copy(sourceColors, destBytes, count);
}
/// <inheritdoc />
internal override unsafe void PackFromZyxBytes(BufferPointer<byte> sourceBytes, BufferPointer<Color> 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;
}
}
/// <inheritdoc />
internal override unsafe void ToZyxBytes(BufferPointer<Color> sourceColors, BufferPointer<byte> 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;
}
}
/// <inheritdoc />
internal override unsafe void PackFromZyxwBytes(BufferPointer<byte> sourceBytes, BufferPointer<Color> 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;
}
}
/// <inheritdoc />
internal override unsafe void ToZyxwBytes(BufferPointer<Color> sourceColors, BufferPointer<byte> 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;
}
}
/// <summary>
/// Value type to store <see cref="Color"/>-s unpacked into multiple <see cref="uint"/>-s.
/// </summary>
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;
}
}
}
}
}

3
src/ImageSharp/Colors/Color.cs

@ -245,6 +245,9 @@ namespace ImageSharp
return ColorBuilder<Color>.FromHex(hex);
}
/// <inheritdoc />
public BulkPixelOperations<Color> CreateBulkOperations() => new Color.BulkOperations();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBytes(byte x, byte y, byte z, byte w)

3
src/ImageSharp/Colors/PackedPixel/Alpha8.cs

@ -58,6 +58,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Alpha8> CreateBulkOperations() => new BulkPixelOperations<Alpha8>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

3
src/ImageSharp/Colors/PackedPixel/Argb.cs

@ -220,6 +220,9 @@ namespace ImageSharp
this.PackedValue = Pack(ref vector);
}
/// <inheritdoc />
public BulkPixelOperations<Argb> CreateBulkOperations() => new BulkPixelOperations<Argb>();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToVector4()

3
src/ImageSharp/Colors/PackedPixel/Bgr565.cs

@ -67,6 +67,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Bgr565> CreateBulkOperations() => new BulkPixelOperations<Bgr565>();
/// <summary>
/// Expands the packed representation into a <see cref="Vector3"/>.
/// The vector components are typically expanded in least to greatest significance order.

3
src/ImageSharp/Colors/PackedPixel/Bgra4444.cs

@ -66,6 +66,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Bgra4444> CreateBulkOperations() => new BulkPixelOperations<Bgra4444>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToVector4()

3
src/ImageSharp/Colors/PackedPixel/Bgra5551.cs

@ -68,6 +68,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Bgra5551> CreateBulkOperations() => new BulkPixelOperations<Bgra5551>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToVector4()

256
src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs

@ -0,0 +1,256 @@
// <copyright file="BulkPixelOperations{TColor}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System.Numerics;
using System.Runtime.CompilerServices;
/// <summary>
/// A stateless class implementing Strategy Pattern for batched pixel-data conversion operations
/// for pixel buffers of type <typeparamref name="TColor"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public unsafe class BulkPixelOperations<TColor>
where TColor : struct, IPixel<TColor>
{
/// <summary>
/// The size of <typeparamref name="TColor"/> in bytes
/// </summary>
private static readonly int ColorSize = Unsafe.SizeOf<TColor>();
/// <summary>
/// Gets the global <see cref="BulkPixelOperations{TColor}"/> instance for the pixel type <typeparamref name="TColor"/>
/// </summary>
public static BulkPixelOperations<TColor> Instance { get; } = default(TColor).CreateBulkOperations();
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromVector4(Vector4)"/>
/// </summary>
/// <param name="sourceVectors">The <see cref="BufferPointer{T}"/> to the source vectors.</param>
/// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromVector4(
BufferPointer<Vector4> sourceVectors,
BufferPointer<TColor> destColors,
int count)
{
Vector4* sp = (Vector4*)sourceVectors.PointerAtOffset;
byte* dp = (byte*)destColors;
for (int i = 0; i < count; i++)
{
Vector4 v = Unsafe.Read<Vector4>(sp);
TColor c = default(TColor);
c.PackFromVector4(v);
Unsafe.Write(dp, c);
sp++;
dp += ColorSize;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToVector4()"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param>
/// <param name="destVectors">The <see cref="BufferPointer{T}"/> to the destination vectors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToVector4(
BufferPointer<TColor> sourceColors,
BufferPointer<Vector4> destVectors,
int count)
{
byte* sp = (byte*)sourceColors;
Vector4* dp = (Vector4*)destVectors.PointerAtOffset;
for (int i = 0; i < count; i++)
{
TColor c = Unsafe.Read<TColor>(sp);
*dp = c.ToVector4();
sp += ColorSize;
dp++;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyz"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferPointer{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromXyzBytes(
BufferPointer<byte> sourceBytes,
BufferPointer<TColor> 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;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToXyzBytes(byte[], int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferPointer{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToXyzBytes(BufferPointer<TColor> sourceColors, BufferPointer<byte> 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<TColor>(sp);
c.ToXyzBytes(dest, i);
sp += ColorSize;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyzw"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferPointer{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromXyzwBytes(
BufferPointer<byte> sourceBytes,
BufferPointer<TColor> 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;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToXyzwBytes(byte[], int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferPointer{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToXyzwBytes(
BufferPointer<TColor> sourceColors,
BufferPointer<byte> 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<TColor>(sp);
c.ToXyzwBytes(dest, i);
sp += ColorSize;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Zyx"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferPointer{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromZyxBytes(
BufferPointer<byte> sourceBytes,
BufferPointer<TColor> 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;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToZyxBytes(byte[], int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferPointer{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToZyxBytes(BufferPointer<TColor> sourceColors, BufferPointer<byte> 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<TColor>(sp);
c.ToZyxBytes(dest, i);
sp += ColorSize;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Zyxw"/>.
/// </summary>
/// <param name="sourceBytes">The <see cref="BufferPointer{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromZyxwBytes(
BufferPointer<byte> sourceBytes,
BufferPointer<TColor> 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;
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToZyxwBytes(byte[], int)"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="BufferPointer{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToZyxwBytes(
BufferPointer<TColor> sourceColors,
BufferPointer<byte> 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<TColor>(sp);
c.ToZyxwBytes(dest, i);
sp += ColorSize;
}
}
}
}

3
src/ImageSharp/Colors/PackedPixel/Byte4.cs

@ -69,6 +69,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Byte4> CreateBulkOperations() => new BulkPixelOperations<Byte4>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

3
src/ImageSharp/Colors/PackedPixel/HalfSingle.cs

@ -72,6 +72,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<HalfSingle> CreateBulkOperations() => new BulkPixelOperations<HalfSingle>();
/// <summary>
/// Expands the packed representation into a <see cref="float"/>.
/// </summary>

3
src/ImageSharp/Colors/PackedPixel/HalfVector2.cs

@ -82,6 +82,9 @@ namespace ImageSharp
return !left.Equals(right);
}
/// <inheritdoc />
public BulkPixelOperations<HalfVector2> CreateBulkOperations() => new BulkPixelOperations<HalfVector2>();
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// </summary>

3
src/ImageSharp/Colors/PackedPixel/HalfVector4.cs

@ -85,6 +85,9 @@ namespace ImageSharp
return !left.Equals(right);
}
/// <inheritdoc />
public BulkPixelOperations<HalfVector4> CreateBulkOperations() => new BulkPixelOperations<HalfVector4>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

6
src/ImageSharp/Colors/PackedPixel/IPixel.cs

@ -15,6 +15,12 @@ namespace ImageSharp
public interface IPixel<TSelf> : IPixel, IEquatable<TSelf>
where TSelf : struct, IPixel<TSelf>
{
/// <summary>
/// Creates a <see cref="BulkPixelOperations{TColor}"/> instance for this pixel type.
/// This method is not intended to be consumed directly. Use <see cref="BulkPixelOperations{TColor}.Instance"/> instead.
/// </summary>
/// <returns>The <see cref="BulkPixelOperations{TColor}"/> instance.</returns>
BulkPixelOperations<TSelf> CreateBulkOperations();
}
/// <summary>

3
src/ImageSharp/Colors/PackedPixel/NormalizedByte2.cs

@ -87,6 +87,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<NormalizedByte2> CreateBulkOperations() => new BulkPixelOperations<NormalizedByte2>();
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// The vector components are typically expanded in least to greatest significance order.

3
src/ImageSharp/Colors/PackedPixel/NormalizedByte4.cs

@ -89,6 +89,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<NormalizedByte4> CreateBulkOperations() => new BulkPixelOperations<NormalizedByte4>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

3
src/ImageSharp/Colors/PackedPixel/NormalizedShort2.cs

@ -87,6 +87,9 @@ namespace ImageSharp
return !left.Equals(right);
}
/// <inheritdoc />
public BulkPixelOperations<NormalizedShort2> CreateBulkOperations() => new BulkPixelOperations<NormalizedShort2>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

3
src/ImageSharp/Colors/PackedPixel/NormalizedShort4.cs

@ -89,6 +89,9 @@ namespace ImageSharp
return !left.Equals(right);
}
/// <inheritdoc />
public BulkPixelOperations<NormalizedShort4> CreateBulkOperations() => new BulkPixelOperations<NormalizedShort4>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

3
src/ImageSharp/Colors/PackedPixel/Rg32.cs

@ -72,6 +72,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Rg32> CreateBulkOperations() => new BulkPixelOperations<Rg32>();
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// The vector components are typically expanded in least to greatest significance order.

3
src/ImageSharp/Colors/PackedPixel/Rgba1010102.cs

@ -75,6 +75,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Rgba1010102> CreateBulkOperations() => new BulkPixelOperations<Rgba1010102>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToVector4()

3
src/ImageSharp/Colors/PackedPixel/Rgba64.cs

@ -74,6 +74,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Rgba64> CreateBulkOperations() => new BulkPixelOperations<Rgba64>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 ToVector4()

3
src/ImageSharp/Colors/PackedPixel/Short2.cs

@ -87,6 +87,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Short2> CreateBulkOperations() => new BulkPixelOperations<Short2>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

3
src/ImageSharp/Colors/PackedPixel/Short4.cs

@ -89,6 +89,9 @@ namespace ImageSharp
return left.PackedValue != right.PackedValue;
}
/// <inheritdoc />
public BulkPixelOperations<Short4> CreateBulkOperations() => new BulkPixelOperations<Short4>();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector)

29
src/ImageSharp/Common/Extensions/ArrayExtensions.cs

@ -1,29 +0,0 @@
// <copyright file="ArrayExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
/// <summary>
/// Extension methods for arrays.
/// </summary>
public static class ArrayExtensions
{
/// <summary>
/// Locks the pixel buffer providing access to the pixels.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="pixels">The pixel buffer.</param>
/// <param name="width">Gets the width of the image represented by the pixel buffer.</param>
/// <param name="height">The height of the image represented by the pixel buffer.</param>
/// <returns>The <see cref="PixelAccessor{TColor}"/></returns>
public static PixelAccessor<TColor> Lock<TColor>(this TColor[] pixels, int width, int height)
where TColor : struct, IPixel<TColor>
{
return new PixelAccessor<TColor>(width, height, pixels);
}
}
}

130
src/ImageSharp/Common/Helpers/DebugGuard.cs

@ -29,5 +29,135 @@ namespace ImageSharp
throw new ArgumentNullException(parameterName);
}
}
/// <summary>
/// Verifies that the specified value is less than a maximum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is greater than the maximum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeLessThan<TValue>(TValue value, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(max) >= 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than {max}.");
}
}
/// <summary>
/// Verifies that the specified value is less than or equal to a maximum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="max">The maximum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is greater than the maximum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeLessThanOrEqualTo<TValue>(TValue value, TValue max, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(max) > 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be less than or equal to {max}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than a minimum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is less than the minimum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeGreaterThan<TValue>(TValue value, TValue min, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) <= 0)
{
throw new ArgumentOutOfRangeException(
parameterName,
$"Value must be greater than {min}.");
}
}
/// <summary>
/// Verifies that the specified value is greater than or equal to a minimum value
/// and throws an exception if it is not.
/// </summary>
/// <param name="value">The target value, which should be validated.</param>
/// <param name="min">The minimum value.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is less than the minimum value.
/// </exception>
[Conditional("DEBUG")]
public static void MustBeGreaterThanOrEqualTo<TValue>(TValue value, TValue min, string parameterName)
where TValue : IComparable<TValue>
{
if (value.CompareTo(min) < 0)
{
throw new ArgumentOutOfRangeException(parameterName, $"Value must be greater than or equal to {min}.");
}
}
/// <summary>
/// Verifies, that the method parameter with specified target value is true
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">
/// The target value, which cannot be false.
/// </param>
/// <param name="parameterName">
/// The name of the parameter that is to be checked.
/// </param>
/// <param name="message">
/// The error message, if any to add to the exception.
/// </param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is false
/// </exception>
[Conditional("DEBUG")]
public static void IsTrue(bool target, string parameterName, string message)
{
if (!target)
{
throw new ArgumentException(message, parameterName);
}
}
/// <summary>
/// Verifies, that the method parameter with specified target value is false
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">The target value, which cannot be true.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <param name="message">The error message, if any to add to the exception.</param>
/// <exception cref="ArgumentException">
/// <paramref name="target"/> is true
/// </exception>
[Conditional("DEBUG")]
public static void IsFalse(bool target, string parameterName, string message)
{
if (target)
{
throw new ArgumentException(message, parameterName);
}
}
}
}

85
src/ImageSharp/Common/Memory/ArrayPointer{T}.cs

@ -1,85 +0,0 @@
// <copyright file="ArrayPointer{T}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Provides access to elements in an array from a given position.
/// This type shares many similarities with corefx System.Span&lt;T&gt; 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 (<see cref="Array"/>) so we can pass it to API-s like <see cref="Marshal.Copy(byte[], int, IntPtr, int)"/>
/// - 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 <see cref="ArrayPointer{T}"/> an unsafe type!
/// - Currently the arrays provided to ArrayPointer need to be pinned. This behaviour could be changed using C#7 features.
/// </summary>
/// <typeparam name="T">The type of elements of the array</typeparam>
internal unsafe struct ArrayPointer<T>
where T : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="ArrayPointer{T}"/> struct from a pinned array and an offset.
/// </summary>
/// <param name="array">The pinned array</param>
/// <param name="pointerToArray">Pointer to the beginning of array</param>
/// <param name="offset">The offset inside the array</param>
[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<T>() * offset);
}
/// <summary>
/// Initializes a new instance of the <see cref="ArrayPointer{T}"/> struct from a pinned array.
/// </summary>
/// <param name="array">The pinned array</param>
/// <param name="pointerToArray">Pointer to the start of 'array'</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ArrayPointer(T[] array, void* pointerToArray)
{
DebugGuard.NotNull(array, nameof(array));
this.Array = array;
this.Offset = 0;
this.PointerAtOffset = (IntPtr)pointerToArray;
}
/// <summary>
/// Gets the array
/// </summary>
public T[] Array { get; private set; }
/// <summary>
/// Gets the offset inside <see cref="Array"/>
/// </summary>
public int Offset { get; private set; }
/// <summary>
/// Gets the pointer to the offseted array position
/// </summary>
public IntPtr PointerAtOffset { get; private set; }
/// <summary>
/// Forms a slice out of the given ArrayPointer, beginning at 'offset'.
/// </summary>
/// <param name="offset">The offset in number of elements</param>
/// <returns>The offseted (sliced) ArrayPointer</returns>
public ArrayPointer<T> Slice(int offset)
{
ArrayPointer<T> result = default(ArrayPointer<T>);
result.Array = this.Array;
result.Offset = this.Offset + offset;
result.PointerAtOffset = this.PointerAtOffset + (Unsafe.SizeOf<T>() * offset);
return result;
}
}
}

129
src/ImageSharp/Common/Memory/BufferPointer.cs

@ -0,0 +1,129 @@
// <copyright file="BufferPointer.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Utility methods for <see cref="BufferPointer{T}"/>
/// </summary>
internal static class BufferPointer
{
/// <summary>
/// It's worth to use Marshal.Copy() or Buffer.BlockCopy() over this size.
/// </summary>
private const int ByteCountThreshold = 1024;
/// <summary>
/// Copy 'count' number of elements of the same type from 'source' to 'dest'
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The input <see cref="BufferPointer{T}"/></param>
/// <param name="destination">The destination <see cref="BufferPointer{T}"/>.</param>
/// <param name="count">The number of elements to copy</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy<T>(BufferPointer<T> source, BufferPointer<T> destination, int count)
where T : struct
{
CopyImpl(source, destination, count);
}
/// <summary>
/// Copy 'countInSource' elements of <typeparamref name="T"/> from 'source' into the raw byte buffer 'destination'.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The source buffer of <typeparamref name="T"/> elements to copy from.</param>
/// <param name="destination">The destination buffer.</param>
/// <param name="countInSource">The number of elements to copy from 'source'</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy<T>(BufferPointer<T> source, BufferPointer<byte> destination, int countInSource)
where T : struct
{
CopyImpl(source, destination, countInSource);
}
/// <summary>
/// Copy 'countInDest' number of <typeparamref name="T"/> elements into 'dest' from a raw byte buffer defined by 'source'.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The raw source buffer to copy from"/></param>
/// <param name="destination">The destination buffer"/></param>
/// <param name="countInDest">The number of <typeparamref name="T"/> elements to copy.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Copy<T>(BufferPointer<byte> source, BufferPointer<T> destination, int countInDest)
where T : struct
{
int byteCount = SizeOf<T>(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);
}
}
/// <summary>
/// Gets the size of `count` elements in bytes.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="count">The count of the elements</param>
/// <returns>The size in bytes as int</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int SizeOf<T>(int count)
where T : struct => Unsafe.SizeOf<T>() * count;
/// <summary>
/// Gets the size of `count` elements in bytes as UInt32
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="count">The count of the elements</param>
/// <returns>The size in bytes as UInt32</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint USizeOf<T>(int count)
where T : struct
=> (uint)SizeOf<T>(count);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void CopyImpl<T, TDest>(BufferPointer<T> source, BufferPointer<TDest> destination, int count)
where T : struct
where TDest : struct
{
int byteCount = SizeOf<T>(count);
if (byteCount > ByteCountThreshold)
{
if (Unsafe.SizeOf<T>() == sizeof(long))
{
Marshal.Copy(Unsafe.As<long[]>(source.Array), source.Offset, destination.PointerAtOffset, count);
return;
}
else if (Unsafe.SizeOf<T>() == sizeof(int))
{
Marshal.Copy(Unsafe.As<int[]>(source.Array), source.Offset, destination.PointerAtOffset, count);
return;
}
else if (Unsafe.SizeOf<T>() == sizeof(short))
{
Marshal.Copy(Unsafe.As<short[]>(source.Array), source.Offset, destination.PointerAtOffset, count);
return;
}
else if (Unsafe.SizeOf<T>() == sizeof(byte))
{
Marshal.Copy(Unsafe.As<byte[]>(source.Array), source.Offset, destination.PointerAtOffset, count);
return;
}
}
Unsafe.CopyBlock((void*)destination.PointerAtOffset, (void*)source.PointerAtOffset, (uint)byteCount);
}
}
}

143
src/ImageSharp/Common/Memory/BufferPointer{T}.cs

@ -0,0 +1,143 @@
// <copyright file="BufferPointer{T}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Provides access to elements in an array from a given position.
/// This type shares many similarities with corefx System.Span&lt;T&gt; 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 (<see cref="Array"/>) so we can pass it to API-s like <see cref="Marshal.Copy(byte[], int, IntPtr, int)"/>
/// - 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 <see cref="BufferPointer{T}"/> an unsafe type!
/// - Currently the arrays provided to BufferPointer need to be pinned. This behaviour could be changed using C#7 features.
/// </summary>
/// <typeparam name="T">The type of elements of the array</typeparam>
internal unsafe struct BufferPointer<T>
where T : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="BufferPointer{T}"/> struct from a pinned array and an offset.
/// </summary>
/// <param name="array">The pinned array</param>
/// <param name="pointerToArray">Pointer to the beginning of array</param>
/// <param name="offset">The offset inside the array</param>
[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<T>() * offset);
}
/// <summary>
/// Initializes a new instance of the <see cref="BufferPointer{T}"/> struct from a pinned array.
/// </summary>
/// <param name="array">The pinned array</param>
/// <param name="pointerToArray">Pointer to the start of 'array'</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferPointer(T[] array, void* pointerToArray)
{
DebugGuard.NotNull(array, nameof(array));
this.Array = array;
this.Offset = 0;
this.PointerAtOffset = (IntPtr)pointerToArray;
}
/// <summary>
/// Gets the array
/// </summary>
public T[] Array { get; private set; }
/// <summary>
/// Gets the offset inside <see cref="Array"/>
/// </summary>
public int Offset { get; private set; }
/// <summary>
/// Gets the offset inside <see cref="Array"/> in bytes.
/// </summary>
public int ByteOffset => this.Offset * Unsafe.SizeOf<T>();
/// <summary>
/// Gets the pointer to the offseted array position
/// </summary>
public IntPtr PointerAtOffset { get; private set; }
/// <summary>
/// Convertes <see cref="BufferPointer{T}"/> instance to a raw 'void*' pointer
/// </summary>
/// <param name="bufferPointer">The <see cref="BufferPointer{T}"/> to convert</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator void*(BufferPointer<T> bufferPointer)
{
return (void*)bufferPointer.PointerAtOffset;
}
/// <summary>
/// Converts <see cref="BufferPointer{T}"/> instance to a raw 'byte*' pointer
/// </summary>
/// <param name="bufferPointer">The <see cref="BufferPointer{T}"/> to convert</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator byte*(BufferPointer<T> bufferPointer)
{
return (byte*)bufferPointer.PointerAtOffset;
}
/// <summary>
/// Converts <see cref="BufferPointer{T}"/> instance to <see cref="BufferPointer{Byte}"/>
/// setting it's <see cref="Offset"/> and <see cref="PointerAtOffset"/> to correct values.
/// </summary>
/// <param name="source">The <see cref="BufferPointer{T}"/> to convert</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator BufferPointer<byte>(BufferPointer<T> source)
{
BufferPointer<byte> result = default(BufferPointer<byte>);
result.Array = Unsafe.As<byte[]>(source.Array);
result.Offset = source.Offset * Unsafe.SizeOf<T>();
result.PointerAtOffset = source.PointerAtOffset;
return result;
}
/// <summary>
/// Forms a slice out of the given BufferPointer, beginning at 'offset'.
/// </summary>
/// <param name="offset">The offset in number of elements</param>
/// <returns>The offseted (sliced) BufferPointer</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public BufferPointer<T> Slice(int offset)
{
BufferPointer<T> result = default(BufferPointer<T>);
result.Array = this.Array;
result.Offset = this.Offset + offset;
result.PointerAtOffset = this.PointerAtOffset + (Unsafe.SizeOf<T>() * offset);
return result;
}
/// <summary>
/// Clears `count` elements beginning from the pointed position.
/// </summary>
/// <param name="count">The number of elements to clear</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear(int count)
{
if (count < 256)
{
Unsafe.InitBlock((void*)this.PointerAtOffset, 0, BufferPointer.USizeOf<T>(count));
}
else
{
System.Array.Clear(this.Array, this.Offset, count);
}
}
}
}

214
src/ImageSharp/Common/Memory/PinnedBuffer{T}.cs

@ -0,0 +1,214 @@
// <copyright file="PinnedBuffer{T}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
/// <summary>
/// Manages a pinned buffer of value type data 'T' as a Disposable resource.
/// The backing array is either pooled or comes from the outside.
/// </summary>
/// <typeparam name="T">The value type.</typeparam>
internal class PinnedBuffer<T> : IDisposable
where T : struct
{
/// <summary>
/// A handle that allows to access the managed <see cref="Array"/> as an unmanaged memory by pinning.
/// </summary>
private GCHandle handle;
/// <summary>
/// A value indicating wheter <see cref="Array"/> should be returned to <see cref="PixelDataPool{T}"/>
/// when disposing this <see cref="PinnedBuffer{T}"/> instance.
/// </summary>
private bool isPoolingOwner;
/// <summary>
/// Initializes a new instance of the <see cref="PinnedBuffer{T}"/> class.
/// </summary>
/// <param name="count">The desired count of elements. (Minimum size for <see cref="Array"/>)</param>
public PinnedBuffer(int count)
{
this.Count = count;
this.Array = PixelDataPool<T>.Rent(count);
this.isPoolingOwner = true;
this.Pin();
}
/// <summary>
/// Initializes a new instance of the <see cref="PinnedBuffer{T}"/> class.
/// </summary>
/// <param name="array">The array to pin.</param>
public PinnedBuffer(T[] array)
{
this.Count = array.Length;
this.Array = array;
this.isPoolingOwner = false;
this.Pin();
}
/// <summary>
/// Initializes a new instance of the <see cref="PinnedBuffer{T}"/> class.
/// </summary>
/// <param name="count">The count of "relevant" elements in 'array'.</param>
/// <param name="array">The array to pin.</param>
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();
}
/// <summary>
/// Finalizes an instance of the <see cref="PinnedBuffer{T}"/> class.
/// </summary>
~PinnedBuffer()
{
this.UnPin();
}
/// <summary>
/// Gets a value indicating whether this <see cref="PinnedBuffer{T}"/> instance is disposed, or has lost ownership of <see cref="Array"/>.
/// </summary>
public bool IsDisposedOrLostArrayOwnership { get; private set; }
/// <summary>
/// Gets the count of "relevant" elements. Usually be smaller than 'Array.Length' when <see cref="Array"/> is pooled.
/// </summary>
public int Count { get; private set; }
/// <summary>
/// Gets the backing pinned array.
/// </summary>
public T[] Array { get; private set; }
/// <summary>
/// Gets a pointer to the pinned <see cref="Array"/>.
/// </summary>
public IntPtr Pointer { get; private set; }
/// <summary>
/// Converts <see cref="PinnedBuffer{T}"/> to an <see cref="BufferPointer{T}"/>.
/// </summary>
/// <param name="buffer">The <see cref="PinnedBuffer{T}"/> to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator BufferPointer<T>(PinnedBuffer<T> buffer)
{
return buffer.Slice();
}
/// <summary>
/// Gets a <see cref="BufferPointer{T}"/> to the beginning of the raw data of the buffer.
/// </summary>
/// <returns>The <see cref="BufferPointer{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe BufferPointer<T> Slice()
{
return new BufferPointer<T>(this.Array, (void*)this.Pointer);
}
/// <summary>
/// Gets a <see cref="BufferPointer{T}"/> to an offseted position inside the buffer.
/// </summary>
/// <param name="offset">The offset</param>
/// <returns>The <see cref="BufferPointer{T}"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe BufferPointer<T> Slice(int offset)
{
return new BufferPointer<T>(this.Array, (void*)this.Pointer, offset);
}
/// <summary>
/// Disposes the <see cref="PinnedBuffer{T}"/> instance by unpinning the array, and returning the pooled buffer when necessary.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
if (this.IsDisposedOrLostArrayOwnership)
{
return;
}
this.IsDisposedOrLostArrayOwnership = true;
this.UnPin();
if (this.isPoolingOwner)
{
PixelDataPool<T>.Return(this.Array);
}
this.isPoolingOwner = false;
this.Array = null;
this.Count = 0;
GC.SuppressFinalize(this);
}
/// <summary>
/// Unpins <see cref="Array"/> and makes the object "quasi-disposed" so the array is no longer owned by this object.
/// If <see cref="Array"/> is rented, it's the callers responsibility to return it to it's pool. (Most likely <see cref="PixelDataPool{T}"/>)
/// </summary>
/// <returns>The unpinned <see cref="Array"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T[] UnPinAndTakeArrayOwnership()
{
if (this.IsDisposedOrLostArrayOwnership)
{
throw new InvalidOperationException("UnPinAndTakeArrayOwnership() is invalid: either PinnedBuffer<T> 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;
}
/// <summary>
/// Clears the buffer, filling elements between 0 and <see cref="Count"/>-1 with default(T)
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear()
{
this.Slice().Clear(this.Count);
}
/// <summary>
/// Pins <see cref="Array"/>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Pin()
{
this.handle = GCHandle.Alloc(this.Array, GCHandleType.Pinned);
this.Pointer = this.handle.AddrOfPinnedObject();
}
/// <summary>
/// Unpins <see cref="Array"/>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UnPin()
{
if (this.Pointer == IntPtr.Zero || !this.handle.IsAllocated)
{
return;
}
this.handle.Free();
this.Pointer = IntPtr.Zero;
}
}
}

60
src/ImageSharp/Common/Memory/PixelDataPool{T}.cs

@ -0,0 +1,60 @@
// <copyright file="PixelDataPool{T}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Buffers;
/// <summary>
/// Provides a resource pool that enables reusing instances of value type arrays for image data <see cref="T:T[]"/>.
/// </summary>
/// <typeparam name="T">The value type.</typeparam>
public class PixelDataPool<T>
where T : struct
{
/// <summary>
/// The <see cref="ArrayPool{T}"/> which is not kept clean.
/// </summary>
private static readonly ArrayPool<T> ArrayPool = ArrayPool<T>.Create(CalculateMaxArrayLength(), 50);
/// <summary>
/// Rents the pixel array from the pool.
/// </summary>
/// <param name="minimumLength">The minimum length of the array to return.</param>
/// <returns>The <see cref="T:TColor[]"/></returns>
public static T[] Rent(int minimumLength)
{
return ArrayPool.Rent(minimumLength);
}
/// <summary>
/// Returns the rented pixel array back to the pool.
/// </summary>
/// <param name="array">The array to return to the buffer pool.</param>
public static void Return(T[] array)
{
ArrayPool.Return(array);
}
/// <summary>
/// Heuristically calculates a reasonable maxArrayLength value for the backing <see cref="ArrayPool{T}"/>.
/// </summary>
/// <returns>The maxArrayLength value</returns>
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;
}
}
}
}

8
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;
}

0
src/ImageSharp.Formats.Bmp/BmpBitsPerPixel.cs → src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs

0
src/ImageSharp.Formats.Bmp/BmpCompression.cs → src/ImageSharp/Formats/Bmp/BmpCompression.cs

0
src/ImageSharp.Formats.Bmp/BmpDecoder.cs → src/ImageSharp/Formats/Bmp/BmpDecoder.cs

0
src/ImageSharp.Formats.Bmp/BmpDecoderCore.cs → src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

0
src/ImageSharp.Formats.Bmp/BmpEncoder.cs → src/ImageSharp/Formats/Bmp/BmpEncoder.cs

0
src/ImageSharp.Formats.Bmp/BmpEncoderCore.cs → src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

0
src/ImageSharp.Formats.Bmp/BmpEncoderOptions.cs → src/ImageSharp/Formats/Bmp/BmpEncoderOptions.cs

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save