mirror of https://github.com/SixLabors/ImageSharp
382 changed files with 4418 additions and 2794 deletions
@ -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 |
|||
@ -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> |
|||
@ -1,7 +1,8 @@ |
|||
{ |
|||
"profiles": { |
|||
"build": { |
|||
"commandName": "Project" |
|||
"commandName": "Project", |
|||
"commandLineArgs": "reset" |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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> |
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:7ae6327b2d554c25640756650865eeb5e96aa5bd58b3922ae5247400dc516ed0 |
|||
size 6622 |
|||
oid sha256:47f14bb7d24f7228cd8833d8d1881a72750b2c7813f391bd2a0dd0eeea936841 |
|||
size 6569 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:a78ad79663c58544bba12b431ed83659e60a12a4fcb9b358e7a1c22bc76034bc |
|||
size 14020 |
|||
oid sha256:757ec2f45cc5f9c2083fc65a236100f1a7776eee16bd1095a550e05783106a9f |
|||
size 13949 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:a911690b45b1614ca0dcd08d09ec4d257edc244ccc352e6384370cc197cac1e0 |
|||
size 1479 |
|||
oid sha256:0f3a5375ce20321c2cfdc888a21dcb629d3e6a85641df5cca7c66e5b2a5f70f6 |
|||
size 1439 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:1381533f41d07c6d3d2604e20c605cd7dd70654056cffd73e67bdc75353476b2 |
|||
size 31672 |
|||
oid sha256:0e4cd18406375999c2bee1c39ad439b37f9524485d6e247ab0f14d2eb90a65f3 |
|||
size 31256 |
|||
|
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:d28e405019add224bd0156332e16e152c6b3822de406c7d5a79cc78e15396a8f |
|||
size 3143 |
|||
oid sha256:fa25e5dbe84f942107a1c29f4f68ff2a73f497412ae91b6e60fc5464bc9b5f05 |
|||
size 3132 |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:bf2335642c6fd291befa0b203dbfb3387d99434369399b35aeea037c0f9eba45 |
|||
size 10474 |
|||
@ -1,3 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:6d21730b397705c2312383d1f7c3f614d2bc2daecf3f9b667f8cbf48a679b4da |
|||
size 59600 |
|||
oid sha256:e4217fe820af06a593903441f0719cab1ca650fd4de795f0e6808c4240a89819 |
|||
size 59646 |
|||
|
|||
@ -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. |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
ignore: |
|||
"src/ImageSharp/Common/Helpers/DebugGuard.cs" |
|||
|
|||
|
|||
@ -0,0 +1,4 @@ |
|||
#recipe Docs |
|||
Settings[Keys.Host] = "imagesharp.org"; |
|||
Settings[Keys.Title] = "Image Sharp"; |
|||
FileSystem.OutputPath = "./docs"; |
|||
@ -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 |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"projects": [ "src" ], |
|||
"sdk": { |
|||
"version": "1.0.0-preview2-003121" |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
Title: About This Project |
|||
--- |
|||
This project is awesome! |
|||
@ -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> |
|||
@ -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`
|
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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,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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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`
|
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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`
|
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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`
|
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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`
|
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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`
|
|||
@ -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" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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<T> but there are significant differences in it's functionalities and semantics:
|
|||
/// - It's not possible to use it with stack objects or pointers to unmanaged memory, only with managed arrays
|
|||
/// - It's possible to retrieve a reference to the array (<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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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<T> but there are significant differences in it's functionalities and semantics:
|
|||
/// - It's not possible to use it with stack objects or pointers to unmanaged memory, only with managed arrays
|
|||
/// - It's possible to retrieve a reference to the array (<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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue