Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial import.

  • Loading branch information...
commit d203da5baf5e5439a0d85f7ccf72e51eb2d0ae25 1 parent ea70090
@jpobst jpobst authored
Showing with 9,580 additions and 1 deletion.
  1. +22 −0 .gitignore
  2. +39 −0 Pinta.ImageManipulation.Cairo/CairoSurfaceWrapper.cs
  3. +62 −0 Pinta.ImageManipulation.Cairo/Pinta.ImageManipulation.Cairo.csproj
  4. +36 −0 Pinta.ImageManipulation.Cairo/Properties/AssemblyInfo.cs
  5. +41 −0 Pinta.ImageManipulation.System.Drawing/BitmapWrapper.cs
  6. +58 −0 Pinta.ImageManipulation.System.Drawing/Pinta.ImageManipulation.System.Drawing.csproj
  7. +36 −0 Pinta.ImageManipulation.System.Drawing/Properties/AssemblyInfo.cs
  8. +66 −0 Pinta.ImageManipulation.sln
  9. +137 −0 Pinta.ImageManipulation/BaseEffect.cs
  10. +76 −0 Pinta.ImageManipulation/BaseSurface.cs
  11. +145 −0 Pinta.ImageManipulation/Effects/AddNoiseEffect.cs
  12. +41 −0 Pinta.ImageManipulation/Effects/AutoLevelEffect.cs
  13. +33 −0 Pinta.ImageManipulation/Effects/BlackAndWhiteEffect.cs
  14. +121 −0 Pinta.ImageManipulation/Effects/BrightnessContrastEffect.cs
  15. +74 −0 Pinta.ImageManipulation/Effects/BulgeEffect.cs
  16. +166 −0 Pinta.ImageManipulation/Effects/CloudsEffect.cs
  17. +94 −0 Pinta.ImageManipulation/Effects/ColorDifferenceEffect.cs
  18. +80 −0 Pinta.ImageManipulation/Effects/CurvesEffect.cs
  19. +62 −0 Pinta.ImageManipulation/Effects/EdgeDetectEffect.cs
  20. +116 −0 Pinta.ImageManipulation/Effects/EmbossEffect.cs
  21. +89 −0 Pinta.ImageManipulation/Effects/FragmentEffect.cs
  22. +132 −0 Pinta.ImageManipulation/Effects/FrostedGlassEffect.cs
  23. +233 −0 Pinta.ImageManipulation/Effects/GaussianBlurEffect.cs
  24. +58 −0 Pinta.ImageManipulation/Effects/GlowEffect.cs
  25. +41 −0 Pinta.ImageManipulation/Effects/HueSaturationEffect.cs
  26. +139 −0 Pinta.ImageManipulation/Effects/InkSketchEffect.cs
  27. +26 −0 Pinta.ImageManipulation/Effects/InvertColorsEffect.cs
  28. +112 −0 Pinta.ImageManipulation/Effects/JuliaFractalEffect.cs
  29. +477 −0 Pinta.ImageManipulation/Effects/LocalHistogramEffect.cs
  30. +137 −0 Pinta.ImageManipulation/Effects/MandelbrotFractalEffect.cs
  31. +43 −0 Pinta.ImageManipulation/Effects/MedianEffect.cs
  32. +85 −0 Pinta.ImageManipulation/Effects/MotionBlurEffect.cs
  33. +148 −0 Pinta.ImageManipulation/Effects/OilPaintingEffect.cs
  34. +114 −0 Pinta.ImageManipulation/Effects/OutlineEffect.cs
  35. +68 −0 Pinta.ImageManipulation/Effects/PencilSketchEffect.cs
  36. +88 −0 Pinta.ImageManipulation/Effects/PixelateEffect.cs
  37. +41 −0 Pinta.ImageManipulation/Effects/PolarInversionEffect.cs
  38. +133 −0 Pinta.ImageManipulation/Effects/RadialBlurEffect.cs
  39. +36 −0 Pinta.ImageManipulation/Effects/RedEyeRemoveEffect.cs
  40. +67 −0 Pinta.ImageManipulation/Effects/ReduceNoiseEffect.cs
  41. +60 −0 Pinta.ImageManipulation/Effects/ReliefEffect.cs
  42. +33 −0 Pinta.ImageManipulation/Effects/SepiaEffect.cs
  43. +39 −0 Pinta.ImageManipulation/Effects/SharpenEffect.cs
  44. +102 −0 Pinta.ImageManipulation/Effects/SoftenPortraitEffect.cs
  45. +115 −0 Pinta.ImageManipulation/Effects/TileEffect.cs
  46. +106 −0 Pinta.ImageManipulation/Effects/TwistEffect.cs
  47. +69 −0 Pinta.ImageManipulation/Effects/UnfocusEffect.cs
  48. +167 −0 Pinta.ImageManipulation/Effects/WarpEffect.cs
  49. +103 −0 Pinta.ImageManipulation/Effects/ZoomBlurEffect.cs
  50. +48 −0 Pinta.ImageManipulation/Enumerations/BlendMode.cs
  51. +17 −0 Pinta.ImageManipulation/Enumerations/ColorTransferMode.cs
  52. +200 −0 Pinta.ImageManipulation/Histogram.cs
  53. +120 −0 Pinta.ImageManipulation/HistogramRGB.cs
  54. +50 −0 Pinta.ImageManipulation/ISurface.cs
  55. +52 −0 Pinta.ImageManipulation/ParallelExtensions.cs
  56. +142 −0 Pinta.ImageManipulation/Pinta.ImageManipulation.csproj
  57. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/AdditiveBlendOp.cs
  58. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/ColorBurnBlendOp.cs
  59. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/ColorDodgeBlendOp.cs
  60. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/DarkenBlendOp.cs
  61. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/DifferenceBlendOp.cs
  62. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/GlowBlendOp.cs
  63. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/LightenBlendOp.cs
  64. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/MultiplyBlendOp.cs
  65. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/NegationBlendOp.cs
  66. +83 −0 Pinta.ImageManipulation/PixelBlendOperations/NormalBlendOp.cs
  67. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/OverlayBlendOp.cs
  68. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/ReflectBlendOp.cs
  69. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/ScreenBlendOp.cs
  70. +36 −0 Pinta.ImageManipulation/PixelBlendOperations/XorBlendOp.cs
  71. +182 −0 Pinta.ImageManipulation/PixelOperations/BinaryPixelOp.cs
  72. +17 −0 Pinta.ImageManipulation/PixelOperations/PixelOp.cs
  73. +153 −0 Pinta.ImageManipulation/PixelOperations/UnaryPixelOp.cs
  74. +336 −0 Pinta.ImageManipulation/PixelOperations/UserBlendOp.cs
  75. +36 −0 Pinta.ImageManipulation/Properties/AssemblyInfo.cs
  76. +12 −0 Pinta.ImageManipulation/Settings.cs
  77. +119 −0 Pinta.ImageManipulation/SplineInterpolator.cs
  78. +702 −0 Pinta.ImageManipulation/Structs/ColorBgra.cs
  79. +189 −0 Pinta.ImageManipulation/Structs/HsvColor.cs
  80. +47 −0 Pinta.ImageManipulation/Structs/Point.cs
  81. +47 −0 Pinta.ImageManipulation/Structs/PointD.cs
  82. +110 −0 Pinta.ImageManipulation/Structs/Rectangle.cs
  83. +132 −0 Pinta.ImageManipulation/Structs/RgbColor.cs
  84. +58 −0 Pinta.ImageManipulation/Structs/Size.cs
  85. +27 −0 Pinta.ImageManipulation/UnaryPixelOperations/AverageChannelsOp.cs
  86. +48 −0 Pinta.ImageManipulation/UnaryPixelOperations/BlendConstantOp.cs
  87. +59 −0 Pinta.ImageManipulation/UnaryPixelOperations/ChannelCurveOp.cs
  88. +50 −0 Pinta.ImageManipulation/UnaryPixelOperations/ConstantOp.cs
  89. +53 −0 Pinta.ImageManipulation/UnaryPixelOperations/DesaturateOp.cs
  90. +64 −0 Pinta.ImageManipulation/UnaryPixelOperations/HueSaturationLightnessOp.cs
  91. +40 −0 Pinta.ImageManipulation/UnaryPixelOperations/IdentityOp.cs
  92. +25 −0 Pinta.ImageManipulation/UnaryPixelOperations/InvertOp.cs
  93. +25 −0 Pinta.ImageManipulation/UnaryPixelOperations/InvertWithAlphaOp.cs
  94. +310 −0 Pinta.ImageManipulation/UnaryPixelOperations/LevelOp.cs
  95. +37 −0 Pinta.ImageManipulation/UnaryPixelOperations/LuminosityCurveOp.cs
  96. +85 −0 Pinta.ImageManipulation/UnaryPixelOperations/PosterizePixelOp.cs
  97. +76 −0 Pinta.ImageManipulation/UnaryPixelOperations/RedEyeRemoveOp.cs
  98. +55 −0 Pinta.ImageManipulation/UnaryPixelOperations/SetAlphaChannelOp.cs
  99. +44 −0 Pinta.ImageManipulation/UnaryPixelOperations/SetAlphaChannelTo255Op.cs
  100. +56 −0 Pinta.ImageManipulation/UnaryPixelOperations/SetChannelOp.cs
  101. +331 −0 Pinta.ImageManipulation/Utility.cs
  102. +77 −0 Pinta.TestHarness/Pinta.TestHarness.csproj
  103. +113 −0 Pinta.TestHarness/Program.cs
  104. +36 −0 Pinta.TestHarness/Properties/AssemblyInfo.cs
  105. +3 −0  Pinta.TestHarness/app.config
  106. +39 −1 README.md
  107. +21 −0 license-mit.txt
  108. +20 −0 license-pdn.txt
View
22 .gitignore
@@ -0,0 +1,22 @@
+*.pidb
+*.suo
+*.userprefs
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+bin
+config.log
+config.status
+configure
+install-sh
+missing
+obj
+pinta
+pinta.pc
+intltool-extract.in
+intltool-merge.in
+intltool-update.in
+po/Makefile.in.in
+po/POTFILES
+po/stamp-it
View
39 Pinta.ImageManipulation.Cairo/CairoSurfaceWrapper.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Pinta.ImageManipulation
+{
+ public class CairoSurfaceWrapper : BaseSurface
+ {
+ private Cairo.ImageSurface surface;
+ private unsafe ImageManipulation.ColorBgra* data_ptr;
+
+ public unsafe CairoSurfaceWrapper (Cairo.ImageSurface surface)
+ {
+ this.surface = surface;
+ this.data_ptr = (ImageManipulation.ColorBgra*)surface.DataPtr;
+ height = surface.Height;
+ width = surface.Width;
+ }
+
+ protected unsafe override ImageManipulation.ColorBgra* data {
+ get { return data_ptr; }
+ }
+
+ public override int Stride {
+ get { return surface.Stride; }
+ }
+
+ public override void BeginUpdate ()
+ {
+ surface.Flush ();
+ }
+
+ public override void EndUpdate ()
+ {
+ surface.MarkDirty ();
+ }
+ }
+}
View
62 Pinta.ImageManipulation.Cairo/Pinta.ImageManipulation.Cairo.csproj
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{E189D463-7CFC-4049-B455-6A6499AB0F65}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Pinta.ImageManipulation.Cairo</RootNamespace>
+ <AssemblyName>Pinta.ImageManipulation.Cairo</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Mono.Cairo" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="CairoSurfaceWrapper.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Pinta.ImageManipulation\Pinta.ImageManipulation.csproj">
+ <Project>{f8df7505-b2e8-45cb-b7c4-b1a884bff582}</Project>
+ <Name>Pinta.ImageManipulation</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
36 Pinta.ImageManipulation.Cairo/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pinta.ImageManipulation.Cairo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Pinta.ImageManipulation.Cairo")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("849dfdaf-1ed3-4f72-88ea-d66bbfb7797b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
41 Pinta.ImageManipulation.System.Drawing/BitmapWrapper.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing.Imaging;
+
+namespace Pinta.ImageManipulation
+{
+ public class BitmapWrapper : BaseSurface
+ {
+ private System.Drawing.Bitmap surface;
+ private BitmapData bitmap_data;
+ private unsafe ImageManipulation.ColorBgra* data_ptr;
+
+ public unsafe BitmapWrapper (System.Drawing.Bitmap surface)
+ {
+ this.surface = surface;
+ height = surface.Height;
+ width = surface.Width;
+ }
+
+ protected unsafe override ImageManipulation.ColorBgra* data {
+ get { return data_ptr; }
+ }
+
+ public override int Stride {
+ get { return bitmap_data.Stride; }
+ }
+
+ public unsafe override void BeginUpdate ()
+ {
+ bitmap_data = surface.LockBits (new System.Drawing.Rectangle (0, 0, surface.Width, surface.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
+ data_ptr = (ImageManipulation.ColorBgra*)bitmap_data.Scan0;
+ }
+
+ public override void EndUpdate ()
+ {
+ surface.UnlockBits (bitmap_data);
+ }
+ }
+}
View
58 Pinta.ImageManipulation.System.Drawing/Pinta.ImageManipulation.System.Drawing.csproj
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{90A335A2-F419-4085-A297-4A1C47D2CE68}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Pinta.ImageManipulation.System.Drawing</RootNamespace>
+ <AssemblyName>Pinta.ImageManipulation.System.Drawing</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Drawing" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BitmapWrapper.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Pinta.ImageManipulation\Pinta.ImageManipulation.csproj">
+ <Project>{f8df7505-b2e8-45cb-b7c4-b1a884bff582}</Project>
+ <Name>Pinta.ImageManipulation</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
36 Pinta.ImageManipulation.System.Drawing/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pinta.ImageManipulation.System.Drawing")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Pinta.ImageManipulation.System.Drawing")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6bc0c026-2716-4af6-b604-5ac07bc1184d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
66 Pinta.ImageManipulation.sln
@@ -0,0 +1,66 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pinta.ImageManipulation", "Pinta.ImageManipulation\Pinta.ImageManipulation.csproj", "{F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pinta.TestHarness", "Pinta.TestHarness\Pinta.TestHarness.csproj", "{89BF2843-9D90-40B9-ABA7-84315C10A8CB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pinta.ImageManipulation.System.Drawing", "Pinta.ImageManipulation.System.Drawing\Pinta.ImageManipulation.System.Drawing.csproj", "{90A335A2-F419-4085-A297-4A1C47D2CE68}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pinta.ImageManipulation.Cairo", "Pinta.ImageManipulation.Cairo\Pinta.ImageManipulation.Cairo.csproj", "{E189D463-7CFC-4049-B455-6A6499AB0F65}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {F8DF7505-B2E8-45CB-B7C4-B1A884BFF582}.Release|x86.ActiveCfg = Release|Any CPU
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Debug|x86.ActiveCfg = Debug|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Debug|x86.Build.0 = Debug|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Release|Any CPU.ActiveCfg = Release|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Release|Mixed Platforms.Build.0 = Release|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Release|x86.ActiveCfg = Release|x86
+ {89BF2843-9D90-40B9-ABA7-84315C10A8CB}.Release|x86.Build.0 = Release|x86
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {90A335A2-F419-4085-A297-4A1C47D2CE68}.Release|x86.ActiveCfg = Release|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {E189D463-7CFC-4049-B455-6A6499AB0F65}.Release|x86.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
View
137 Pinta.ImageManipulation/BaseEffect.cs
@@ -0,0 +1,137 @@
+//
+// BaseEffect.cs
+//
+// Author:
+// Jonathan Pobst <monkey@jpobst.com>
+//
+// Copyright (c) 2010 Jonathan Pobst
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Pinta.ImageManipulation
+{
+ public abstract class BaseEffect
+ {
+ /// <summary>
+ /// Render the effect from the source surface to the destination surface.
+ /// </summary>
+ /// <param name="src">The source surface.</param>
+ /// <param name="dst">The destination surface.</param>
+ public virtual void Render (ISurface src, ISurface dst)
+ {
+ if (src.Bounds != dst.Bounds)
+ throw new InvalidOperationException ("Source and destination surfaces must be the same size.");
+
+ Render (src, dst, src.Bounds);
+ }
+
+ /// <summary>
+ /// Render the effect from the source surface to the destination surface.
+ /// </summary>
+ /// <param name="src">The source surface.</param>
+ /// <param name="dst">The destination surface.</param>
+ /// <param name="roi">A rectangle of interest (roi) specifying the area(s) to modify. Only these areas should be modified.</param>
+ public void Render (ISurface src, ISurface dst, Rectangle roi)
+ {
+ RenderLoop (src, dst, roi, CancellationToken.None);
+ }
+
+ public Task RenderAsync (ISurface src, ISurface dst)
+ {
+ return RenderAsync (src, dst, CancellationToken.None);
+ }
+
+ public Task RenderAsync (ISurface src, ISurface dst, CancellationToken token)
+ {
+ if (src.Bounds != dst.Bounds)
+ throw new InvalidOperationException ("Source and destination surfaces must be the same size.");
+
+ return Task.Factory.StartNew (() => RenderLoop (src, dst, src.Bounds, token));
+ }
+
+ public Task RenderAsync (ISurface src, ISurface dst, Rectangle roi)
+ {
+ return RenderAsync (src, dst, roi, CancellationToken.None);
+ }
+
+ public Task RenderAsync (ISurface src, ISurface dst, Rectangle roi, CancellationToken token)
+ {
+ return Task.Factory.StartNew (() => RenderLoop (src, dst, roi, token));
+ }
+
+ protected virtual void RenderLoop (ISurface src, ISurface dst, Rectangle roi, CancellationToken token)
+ {
+ if (Settings.SingleThreaded || roi.Height <= 1) {
+ for (var y = roi.Y; y <= roi.Bottom; ++y) {
+ if (token.IsCancellationRequested)
+ return;
+
+ RenderLine (src, dst, new Rectangle (roi.X, y, roi.Width, 1));
+ }
+ } else {
+ ParallelExtensions.OrderedFor (roi.Y, roi.Bottom + 1, token, (y) => {
+ RenderLine (src, dst, new Rectangle (roi.X, y, roi.Width, 1));
+ });
+ }
+ }
+
+ /// <summary>
+ /// Performs the actual work of rendering an effect. Do not call base.Render ().
+ /// </summary>
+ /// <param name="src">The source surface. DO NOT MODIFY.</param>
+ /// <param name="dst">The destination surface.</param>
+ /// <param name="roi">A rectangle of interest (roi) specifying the area to modify. Only these areas should be modified</param>
+ protected unsafe virtual void RenderLine (ISurface src, ISurface dst, Rectangle roi)
+ {
+ var srcPtr = src.GetPointAddress (roi.X, roi.Y);
+ var dstPtr = dst.GetPointAddress (roi.X, roi.Y);
+ Render (srcPtr, dstPtr, roi.Width);
+ }
+
+ /// <summary>
+ /// Performs the actual work of rendering an effect. This overload represent a single line of the image. Do not call base.Render ().
+ /// </summary>
+ /// <param name="src">The source surface. DO NOT MODIFY.</param>
+ /// <param name="dst">The destination surface.</param>
+ /// <param name="length">The number of pixels to render.</param>
+ protected unsafe virtual void Render (ColorBgra* src, ColorBgra* dst, int length)
+ {
+ while (length > 0) {
+ *dst = Render (*src);
+ ++dst;
+ ++src;
+ --length;
+ }
+ }
+
+ /// <summary>
+ /// Performs the actual work of rendering an effect. This overload represent a single pixel of the image.
+ /// </summary>
+ /// <param name="color">The color of the source surface pixel.</param>
+ /// <returns>The color to be used for the destination pixel.</returns>
+ protected virtual ColorBgra Render (ColorBgra color)
+ {
+ return color;
+ }
+ }
+}
View
76 Pinta.ImageManipulation/BaseSurface.cs
@@ -0,0 +1,76 @@
+//
+// BaseSurface.cs
+//
+// Author:
+// Jonathan Pobst <monkey@jpobst.com>
+//
+// Copyright (c) 2012 Jonathan Pobst
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Pinta.ImageManipulation
+{
+ public unsafe abstract class BaseSurface : ISurface
+ {
+ protected abstract ColorBgra* data { get; }
+ protected int height;
+ protected int width;
+
+ #region ISurface Members
+ public Rectangle Bounds { get { return new Rectangle (Point.Empty, Size); } }
+ public int Height { get { return height; } }
+ public Size Size { get { return new Size (height, width); } }
+ public abstract int Stride { get; }
+ public int Width { get { return width; } }
+
+ public virtual void BeginUpdate ()
+ {
+ }
+
+ public virtual void EndUpdate ()
+ {
+ }
+
+ public unsafe ColorBgra GetPoint (int x, int y)
+ {
+ return *(data + (x + (y * width)));
+ }
+
+ public unsafe ColorBgra* GetPointAddress (int x, int y)
+ {
+ return data + (x + (y * width));
+ }
+
+ public unsafe ColorBgra* GetPointAddress (Point point)
+ {
+ return data + (point.X + (point.Y * width));
+ }
+
+ public unsafe ColorBgra* GetRowAddress (int y)
+ {
+ return data + (y * width);
+ }
+ #endregion
+ }
+}
View
145 Pinta.ImageManipulation/Effects/AddNoiseEffect.cs
@@ -0,0 +1,145 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Hanh Pham <hanh.pham@gmx.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class AddNoiseEffect : BaseEffect
+ {
+ [ThreadStatic]
+ private static Random threadRand;
+ private const int tableSize = 16384;
+ private static int[] lookup;
+
+ private int intensity;
+ private int color_saturation;
+ private double coverage;
+
+ int dev;
+ int sat;
+
+ /// <summary>
+ /// Creates a new effect that will add noise to an image.
+ /// </summary>
+ /// <param name="intensity">The intensity of the effect. Valid range is 0 - 100.</param>
+ /// <param name="colorSaturation">The color saturation of the effect. Valid range is 0 - 400.</param>
+ /// <param name="coverage">The coverage density of the effect. Valid range is 0 - 100.</param>
+ public AddNoiseEffect (int intensity = 64, int colorSaturation = 100, double coverage = 100.0)
+ {
+ if (intensity < 0 || intensity > 100)
+ throw new ArgumentOutOfRangeException ("intensity");
+ if (colorSaturation < 0 || colorSaturation > 400)
+ throw new ArgumentOutOfRangeException ("colorSaturation");
+ if (coverage < 0 || coverage > 100)
+ throw new ArgumentOutOfRangeException ("coverage");
+
+ this.intensity = intensity;
+ this.color_saturation = colorSaturation;
+ this.coverage = coverage * 0.01;
+
+ dev = this.intensity * this.intensity / 4;
+ sat = this.color_saturation * 4096 / 100;
+
+ }
+
+ static AddNoiseEffect ()
+ {
+ InitLookup ();
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override unsafe void Render (ColorBgra* src, ColorBgra* dst, int length)
+ {
+ if (threadRand == null)
+ threadRand = new Random ();
+
+ var localLookup = lookup;
+
+ for (var x = 0; x < length; ++x) {
+ if (threadRand.NextDouble () > coverage) {
+ *dst = *src;
+ } else {
+ int r;
+ int g;
+ int b;
+ int i;
+
+ r = localLookup[threadRand.Next (tableSize)];
+ g = localLookup[threadRand.Next (tableSize)];
+ b = localLookup[threadRand.Next (tableSize)];
+
+ i = (4899 * r + 9618 * g + 1867 * b) >> 14;
+
+
+ r = i + (((r - i) * sat) >> 12);
+ g = i + (((g - i) * sat) >> 12);
+ b = i + (((b - i) * sat) >> 12);
+
+ dst->R = Utility.ClampToByte (src->R + ((r * dev + 32768) >> 16));
+ dst->G = Utility.ClampToByte (src->G + ((g * dev + 32768) >> 16));
+ dst->B = Utility.ClampToByte (src->B + ((b * dev + 32768) >> 16));
+ dst->A = src->A;
+ }
+
+ ++src;
+ ++dst;
+ }
+ }
+
+ private static double NormalCurve (double x, double scale)
+ {
+ return scale * Math.Exp (-x * x / 2);
+ }
+
+ private static void InitLookup ()
+ {
+ double l = 5;
+ double r = 10;
+ double scale = 50;
+ double sum = 0;
+
+ while (r - l > 0.0000001) {
+ sum = 0;
+ scale = (l + r) * 0.5;
+
+ for (var i = 0; i < tableSize; ++i) {
+ sum += NormalCurve (16.0 * ((double)i - tableSize / 2) / tableSize, scale);
+
+ if (sum > 1000000) {
+ break;
+ }
+ }
+
+ if (sum > tableSize) {
+ r = scale;
+ } else if (sum < tableSize) {
+ l = scale;
+ } else {
+ break;
+ }
+ }
+
+ lookup = new int[tableSize];
+ sum = 0;
+ int roundedSum = 0, lastRoundedSum;
+
+ for (var i = 0; i < tableSize; ++i) {
+ sum += NormalCurve (16.0 * ((double)i - tableSize / 2) / tableSize, scale);
+ lastRoundedSum = roundedSum;
+ roundedSum = (int)sum;
+
+ for (var j = lastRoundedSum; j < roundedSum; ++j) {
+ lookup[j] = (i - tableSize / 2) * 65536 / tableSize;
+ }
+ }
+ }
+ #endregion
+ }
+}
View
41 Pinta.ImageManipulation/Effects/AutoLevelEffect.cs
@@ -0,0 +1,41 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Jonathan Pobst <monkey@jpobst.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using Pinta.ImageManipulation.UnaryPixelOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class AutoLevelEffect : BaseEffect
+ {
+ private LevelOp op;
+
+ /// <summary>
+ /// Creates a new effect that will apply an automatic leveling to an image.
+ /// </summary>
+ public AutoLevelEffect ()
+ {
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ if (op == null) {
+ var histogram = new HistogramRgb ();
+ histogram.UpdateHistogram (src, src.Bounds);
+
+ op = histogram.MakeLevelsAuto ();
+ }
+
+ if (op.isValid)
+ op.Apply (src, dest, roi);
+ }
+ #endregion
+ }
+}
View
33 Pinta.ImageManipulation/Effects/BlackAndWhiteEffect.cs
@@ -0,0 +1,33 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Jonathan Pobst <monkey@jpobst.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using Pinta.ImageManipulation.UnaryPixelOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class BlackAndWhiteEffect : BaseEffect
+ {
+ private DesaturateOp op = new DesaturateOp ();
+
+ /// <summary>
+ /// Creates a new effect that will remove color from an image.
+ /// </summary>
+ public BlackAndWhiteEffect ()
+ {
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ op.Apply (src, dest, roi);
+ }
+ #endregion
+ }
+}
View
121 Pinta.ImageManipulation/Effects/BrightnessContrastEffect.cs
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Krzysztof Marecki <marecki.krzysztof@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class BrightnessContrastEffect : BaseEffect
+ {
+ private int brightness;
+ private int contrast;
+
+ private int divide;
+ private byte[] rgbTable;
+
+ /// <summary>
+ /// Creates a new effect that will adjust the brightness and contrast of an image.
+ /// </summary>
+ /// <param name="brightness">Desired brightness of the image. Valid range is -100 - 100.</param>
+ /// <param name="contrast">Desired contrast of the image. Valid range is -100 - 100.</param>
+ public BrightnessContrastEffect (int brightness = 0, int contrast = 0)
+ {
+ if (brightness < -100 || brightness > 100)
+ throw new ArgumentOutOfRangeException ("brightness");
+ if (contrast < -100 || contrast > 100)
+ throw new ArgumentOutOfRangeException ("contrast");
+
+ this.brightness = brightness;
+ this.contrast = contrast;
+
+ Calculate ();
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override unsafe void Render (ColorBgra* src, ColorBgra* dst, int length)
+ {
+ var srcRowPtr = src;
+ var dstRowPtr = dst;
+ var dstRowEndPtr = dstRowPtr + length;
+
+ if (divide == 0) {
+ while (dstRowPtr < dstRowEndPtr) {
+ var col = *srcRowPtr;
+ var i = col.GetIntensityByte ();
+ uint c = rgbTable[i];
+ dstRowPtr->Bgra = (col.Bgra & 0xff000000) | c | (c << 8) | (c << 16);
+
+ ++dstRowPtr;
+ ++srcRowPtr;
+ }
+ } else {
+ while (dstRowPtr < dstRowEndPtr) {
+ var col = *srcRowPtr;
+ var i = col.GetIntensityByte ();
+ var shiftIndex = i * 256;
+
+ col.R = rgbTable[shiftIndex + col.R];
+ col.G = rgbTable[shiftIndex + col.G];
+ col.B = rgbTable[shiftIndex + col.B];
+
+ *dstRowPtr = col;
+ ++dstRowPtr;
+ ++srcRowPtr;
+ }
+ }
+ }
+
+ private void Calculate ()
+ {
+ int multiply;
+
+ if (contrast < 0) {
+ multiply = contrast + 100;
+ divide = 100;
+ } else if (contrast > 0) {
+ multiply = 100;
+ divide = 100 - contrast;
+ } else {
+ multiply = 1;
+ divide = 1;
+ }
+
+ if (rgbTable == null)
+ rgbTable = new byte[65536];
+
+ if (divide == 0) {
+ for (var intensity = 0; intensity < 256; intensity++) {
+ if (intensity + brightness < 128)
+ rgbTable[intensity] = 0;
+ else
+ rgbTable[intensity] = 255;
+ }
+ } else if (divide == 100) {
+ for (var intensity = 0; intensity < 256; intensity++) {
+ var shift = (intensity - 127) * multiply / divide + 127 - intensity + brightness;
+
+ for (var col = 0; col < 256; ++col) {
+ var index = (intensity * 256) + col;
+ rgbTable[index] = Utility.ClampToByte (col + shift);
+ }
+ }
+ } else {
+ for (var intensity = 0; intensity < 256; ++intensity) {
+ var shift = (intensity - 127 + brightness) * multiply / divide + 127 - intensity;
+
+ for (var col = 0; col < 256; ++col) {
+ var index = (intensity * 256) + col;
+ rgbTable[index] = Utility.ClampToByte (col + shift);
+ }
+ }
+ }
+ }
+ #endregion
+ }
+}
View
74 Pinta.ImageManipulation/Effects/BulgeEffect.cs
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Olivier Dufour <olivier.duff@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class BulgeEffect : BaseEffect
+ {
+ private int amount;
+ private PointD offset;
+
+ /// <summary>
+ /// Creates a new effect that will add a bulge to an image at a specified point.
+ /// </summary>
+ /// <param name="amount">Amount to bulge. Valid range is -200 - 100.</param>
+ /// <param name="offset">Bulge origin point.</param>
+ public BulgeEffect (int amount = 45, PointD offset = new PointD ())
+ {
+ if (amount < -200 || amount > 100)
+ throw new ArgumentOutOfRangeException ("amount");
+
+ this.amount = amount;
+ this.offset = offset;
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected unsafe override void RenderLine (ISurface src, ISurface dst, Rectangle rect)
+ {
+ var bulge = (float)amount;
+
+ var hw = dst.Width / 2f;
+ var hh = dst.Height / 2f;
+ var maxrad = Math.Min (hw, hh);
+ var amt = bulge / 100f;
+
+ hh = hh + (float)offset.Y * hh;
+ hw = hw + (float)offset.X * hw;
+
+ for (var y = rect.Top; y <= rect.Bottom; y++) {
+ var dstPtr = dst.GetPointAddress (rect.Left, y);
+ var srcPtr = src.GetPointAddress (rect.Left, y);
+ var v = y - hh;
+
+ for (var x = rect.Left; x <= rect.Right; x++) {
+ var u = x - hw;
+ var r = (float)Math.Sqrt (u * u + v * v);
+ var rscale1 = (1f - (r / maxrad));
+
+ if (rscale1 > 0) {
+ var rscale2 = 1 - amt * rscale1 * rscale1;
+
+ var xp = u * rscale2;
+ var yp = v * rscale2;
+
+ *dstPtr = Utility.GetBilinearSampleClamped (src, xp + hw, yp + hh);
+ } else {
+ *dstPtr = *srcPtr;
+ }
+
+ ++dstPtr;
+ ++srcPtr;
+ }
+ }
+ }
+ #endregion
+ }
+}
View
166 Pinta.ImageManipulation/Effects/CloudsEffect.cs
@@ -0,0 +1,166 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Olivier Dufour <olivier.duff@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class CloudsEffect : BaseEffect
+ {
+ private int scale;
+ private int power;
+ private int seed;
+ private BlendMode blend_mode;
+ private ColorBgra from_color;
+ private ColorBgra to_color;
+ private UserBlendOp blend_op;
+
+ // This is so that repetition of the effect with CTRL+F actually shows up differently.
+ //private byte instanceSeed = unchecked ((byte)DateTime.Now.Ticks);
+ static private int[] permuteLookup = new int[512];
+
+ public CloudsEffect (int scale, int power, int seed, ColorBgra fromColor, ColorBgra toColor, BlendMode blendMode)
+ {
+ if (scale < 2 || scale > 1000)
+ throw new ArgumentOutOfRangeException ("scale");
+ if (power < 0 || power > 100)
+ throw new ArgumentOutOfRangeException ("radius");
+
+ this.scale = scale;
+ this.power = power;
+ this.seed = seed;
+ this.from_color = fromColor;
+ this.to_color = toColor;
+ this.blend_mode = blendMode;
+
+ blend_op = Utility.GetBlendModeOp (blend_mode);
+ }
+
+ static CloudsEffect ()
+ {
+ for (int i = 0; i < 256; i++) {
+ permuteLookup[256 + i] = permutationTable[i];
+ permuteLookup[i] = permutationTable[i];
+ }
+ }
+
+ #region Algorithm Code Ported From PDN
+ // Adapted to 2-D version in C# from 3-D version in Java from http://mrl.nyu.edu/~perlin/noise/
+ protected override void RenderLine (ISurface src, ISurface dst, Rectangle roi)
+ {
+ RenderClouds (dst, roi, scale, (byte)(seed), power / 100.0, from_color, to_color);
+ blend_op.Apply (src, dst, dst, roi);
+ }
+
+ private static double Fade (double t)
+ {
+ return t * t * t * (t * (t * 6 - 15) + 10);
+ }
+
+ private static double Grad (int hash, double x, double y)
+ {
+ int h = hash & 15;
+ double u = h < 8 ? x : y;
+ double v = h < 4 ? y : h == 12 || h == 14 ? x : 0;
+
+ return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
+ }
+
+ private static double Noise (byte ix, byte iy, double x, double y, byte seed)
+ {
+ double u = Fade (x);
+ double v = Fade (y);
+
+ int a = permuteLookup[ix + seed] + iy;
+ int aa = permuteLookup[a];
+ int ab = permuteLookup[a + 1];
+ int b = permuteLookup[ix + 1 + seed] + iy;
+ int ba = permuteLookup[b];
+ int bb = permuteLookup[b + 1];
+
+ double gradAA = Grad (permuteLookup[aa], x, y);
+ double gradBA = Grad (permuteLookup[ba], x - 1, y);
+
+ double edge1 = Utility.Lerp (gradAA, gradBA, u);
+
+ double gradAB = Grad (permuteLookup[ab], x, y - 1);
+ double gradBB = Grad (permuteLookup[bb], x - 1, y - 1);
+
+ double edge2 = Utility.Lerp (gradAB, gradBB, u);
+
+ return Utility.Lerp (edge1, edge2, v);
+ }
+
+ private unsafe static void RenderClouds (ISurface surface, Rectangle rect, int scale, byte seed, double power, ColorBgra colorFrom, ColorBgra colorTo)
+ {
+ int w = surface.Width;
+ int h = surface.Height;
+
+ for (int y = rect.Top; y <= rect.Bottom; ++y) {
+ ColorBgra* ptr = surface.GetPointAddress (rect.Left, y);
+ int dy = 2 * y - h;
+
+ for (int x = rect.Left; x <= rect.Right; ++x) {
+ int dx = 2 * x - w;
+ double val = 0;
+ double mult = 1;
+ int div = scale;
+
+ for (int i = 0; i < 12 && mult > 0.03 && div > 0; ++i) {
+ double dxr = 65536 + (double)dx / (double)div;
+ double dyr = 65536 + (double)dy / (double)div;
+
+ int dxd = (int)dxr;
+ int dyd = (int)dyr;
+
+ dxr -= dxd;
+ dyr -= dyd;
+
+ double noise = Noise (
+ unchecked ((byte)dxd),
+ unchecked ((byte)dyd),
+ dxr, //(double)dxr / div,
+ dyr, //(double)dyr / div,
+ (byte)(seed ^ i));
+
+ val += noise * mult;
+ div /= 2;
+ mult *= power;
+ }
+
+ *ptr = ColorBgra.Lerp (colorFrom, colorTo, (val + 1) / 2);
+ ++ptr;
+ }
+ }
+ }
+
+ static private int[] permutationTable = new int[]
+ {
+ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7,
+ 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6,
+ 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
+ 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171,
+ 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231,
+ 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245,
+ 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76,
+ 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86,
+ 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
+ 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47,
+ 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2,
+ 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39,
+ 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218,
+ 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162,
+ 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181,
+ 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150,
+ 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128,
+ 195, 78, 66, 215, 61, 156, 180
+ };
+ #endregion
+ }
+}
View
94 Pinta.ImageManipulation/Effects/ColorDifferenceEffect.cs
@@ -0,0 +1,94 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) Rick Brewster, Tom Jackson, and past contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ /// <summary>
+ /// ColorDifferenctEffect is a base class for my difference effects
+ /// that have floating point (double) convolution filters.
+ /// its architecture is just like ConvolutionFilterEffect, adding a
+ /// function (RenderColorDifferenceEffect) called from Render in each
+ /// derived class.
+ /// It is also limited to 3x3 kernels.
+ /// (Chris Crosetto)
+ /// </summary>
+ public abstract class ColorDifferenceEffect : BaseEffect
+ {
+ public unsafe void RenderColorDifferenceEffect (double[][] weights, ISurface src, ISurface dest, Rectangle rect)
+ {
+ var src_rect = src.Bounds;
+
+ // loop through each line of target rectangle
+ for (int y = rect.Y; y < rect.Y + rect.Height; ++y) {
+ int fyStart = 0;
+ int fyEnd = 3;
+
+ if (y == src_rect.Y)
+ fyStart = 1;
+ if (y == src_rect.Y + src_rect.Height - 1)
+ fyEnd = 2;
+
+ // loop through each point in the line
+ ColorBgra* dstPtr = dest.GetPointAddress (rect.X, y);
+
+ for (int x = rect.X; x < rect.X + rect.Width; ++x) {
+ int fxStart = 0;
+ int fxEnd = 3;
+
+ if (x == src_rect.X)
+ fxStart = 1;
+
+ if (x == src_rect.X + src_rect.Width - 1)
+ fxEnd = 2;
+
+ // loop through each weight
+ double rSum = 0.0;
+ double gSum = 0.0;
+ double bSum = 0.0;
+
+ for (int fy = fyStart; fy < fyEnd; ++fy) {
+ for (int fx = fxStart; fx < fxEnd; ++fx) {
+ double weight = weights[fy][fx];
+ ColorBgra c = src.GetPoint (x - 1 + fx, y - 1 + fy);
+
+ rSum += weight * (double)c.R;
+ gSum += weight * (double)c.G;
+ bSum += weight * (double)c.B;
+ }
+ }
+
+ int iRsum = (int)rSum;
+ int iGsum = (int)gSum;
+ int iBsum = (int)bSum;
+
+ if (iRsum > 255)
+ iRsum = 255;
+
+ if (iGsum > 255)
+ iGsum = 255;
+
+ if (iBsum > 255)
+ iBsum = 255;
+
+ if (iRsum < 0)
+ iRsum = 0;
+
+ if (iGsum < 0)
+ iGsum = 0;
+
+ if (iBsum < 0)
+ iBsum = 0;
+
+ *dstPtr = ColorBgra.FromBgra ((byte)iBsum, (byte)iGsum, (byte)iRsum, 255);
+ ++dstPtr;
+ }
+ }
+ }
+ }
+}
View
80 Pinta.ImageManipulation/Effects/CurvesEffect.cs
@@ -0,0 +1,80 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Krzysztof Marecki <marecki.krzysztof@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Pinta.ImageManipulation.UnaryPixelOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class CurvesEffect : BaseEffect
+ {
+ UnaryPixelOp op = null;
+
+ public CurvesEffect (SortedList<int, int>[] controlPoints, ColorTransferMode mode)
+ {
+ op = MakeUop (controlPoints, mode);
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ op.Apply (src, dest, roi);
+ }
+
+ private UnaryPixelOp MakeUop (SortedList<int, int>[] controlPoints, ColorTransferMode mode)
+ {
+ UnaryPixelOp op;
+ byte[][] transferCurves;
+ int entries;
+
+ switch (mode) {
+ case ColorTransferMode.Rgb:
+ var cc = new ChannelCurveOp ();
+ transferCurves = new byte[][] { cc.CurveR, cc.CurveG, cc.CurveB };
+ entries = 256;
+ op = cc;
+ break;
+
+ case ColorTransferMode.Luminosity:
+ var lc = new LuminosityCurveOp ();
+ transferCurves = new byte[][] { lc.Curve };
+ entries = 256;
+ op = lc;
+ break;
+
+ default:
+ throw new InvalidEnumArgumentException ();
+ }
+
+
+ int channels = transferCurves.Length;
+
+ for (int channel = 0; channel < channels; channel++) {
+ var channelControlPoints = controlPoints[channel];
+ var xa = channelControlPoints.Keys;
+ var ya = channelControlPoints.Values;
+ SplineInterpolator interpolator = new SplineInterpolator ();
+ int length = channelControlPoints.Count;
+
+ for (int i = 0; i < length; i++) {
+ interpolator.Add (xa[i], ya[i]);
+ }
+
+ for (int i = 0; i < entries; i++) {
+ transferCurves[channel][i] = Utility.ClampToByte (interpolator.Interpolate (i));
+ }
+ }
+
+ return op;
+ }
+ #endregion
+ }
+}
View
62 Pinta.ImageManipulation/Effects/EdgeDetectEffect.cs
@@ -0,0 +1,62 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Krzysztof Marecki <marecki.krzysztof@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class EdgeDetectEffect : ColorDifferenceEffect
+ {
+ private double[][] weights;
+ private double angle;
+
+ public EdgeDetectEffect (double angle)
+ {
+ this.angle = angle;
+
+ SetWeights ();
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override unsafe void RenderLine (ISurface src, ISurface dst, Rectangle roi)
+ {
+ base.RenderColorDifferenceEffect (weights, src, dst, roi);
+ }
+
+ private void SetWeights ()
+ {
+ weights = new double[3][];
+
+ for (int i = 0; i < this.weights.Length; ++i) {
+ this.weights[i] = new double[3];
+ }
+
+ // adjust and convert angle to radians
+ double r = (double)angle * 2.0 * Math.PI / 360.0;
+
+ // angle delta for each weight
+ double dr = Math.PI / 4.0;
+
+ // for r = 0 this builds an edge detect filter pointing straight left
+
+ this.weights[0][0] = Math.Cos (r + dr);
+ this.weights[0][1] = Math.Cos (r + 2.0 * dr);
+ this.weights[0][2] = Math.Cos (r + 3.0 * dr);
+
+ this.weights[1][0] = Math.Cos (r);
+ this.weights[1][1] = 0;
+ this.weights[1][2] = Math.Cos (r + 4.0 * dr);
+
+ this.weights[2][0] = Math.Cos (r - dr);
+ this.weights[2][1] = Math.Cos (r - 2.0 * dr);
+ this.weights[2][2] = Math.Cos (r - 3.0 * dr);
+ }
+ #endregion
+ }
+}
View
116 Pinta.ImageManipulation/Effects/EmbossEffect.cs
@@ -0,0 +1,116 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Marco Rolappe <m_rolappe@gmx.net> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class EmbossEffect : BaseEffect
+ {
+ private double angle;
+
+ public EmbossEffect (double angle)
+ {
+ if (angle < 0 || angle > 360)
+ throw new ArgumentOutOfRangeException ("angle");
+
+ this.angle = angle;
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected unsafe override void RenderLine (ISurface src, ISurface dst, Rectangle rect)
+ {
+ double[,] weights = Weights;
+
+ var srcWidth = src.Width;
+ var srcHeight = src.Height;
+
+ // loop through each line of target rectangle
+ for (int y = rect.Top; y <= rect.Bottom; ++y) {
+ int fyStart = 0;
+ int fyEnd = 3;
+
+ if (y == 0)
+ fyStart = 1;
+
+ if (y == srcHeight - 1)
+ fyEnd = 2;
+
+ // loop through each point in the line
+ ColorBgra* dstPtr = dst.GetPointAddress (rect.Left, y);
+
+ for (int x = rect.Left; x <= rect.Right; ++x) {
+ int fxStart = 0;
+ int fxEnd = 3;
+
+ if (x == 0)
+ fxStart = 1;
+
+ if (x == srcWidth - 1)
+ fxEnd = 2;
+
+ // loop through each weight
+ double sum = 0.0;
+
+ for (int fy = fyStart; fy < fyEnd; ++fy) {
+ for (int fx = fxStart; fx < fxEnd; ++fx) {
+ double weight = weights[fy, fx];
+ ColorBgra c = src.GetPoint (x - 1 + fx, y - 1 + fy);
+ double intensity = (double)c.GetIntensityByte ();
+ sum += weight * intensity;
+ }
+ }
+
+ int iSum = (int)sum;
+ iSum += 128;
+
+ if (iSum > 255)
+ iSum = 255;
+
+ if (iSum < 0)
+ iSum = 0;
+
+ *dstPtr = ColorBgra.FromBgra ((byte)iSum, (byte)iSum, (byte)iSum, 255);
+
+ ++dstPtr;
+ }
+ }
+ }
+
+ private double[,] Weights
+ {
+ get
+ {
+ // adjust and convert angle to radians
+ double r = (double)angle * 2.0 * Math.PI / 360.0;
+
+ // angle delta for each weight
+ double dr = Math.PI / 4.0;
+
+ // for r = 0 this builds an emboss filter pointing straight left
+ double[,] weights = new double[3, 3];
+
+ weights[0, 0] = Math.Cos (r + dr);
+ weights[0, 1] = Math.Cos (r + 2.0 * dr);
+ weights[0, 2] = Math.Cos (r + 3.0 * dr);
+
+ weights[1, 0] = Math.Cos (r);
+ weights[1, 1] = 0;
+ weights[1, 2] = Math.Cos (r + 4.0 * dr);
+
+ weights[2, 0] = Math.Cos (r - dr);
+ weights[2, 1] = Math.Cos (r - 2.0 * dr);
+ weights[2, 2] = Math.Cos (r - 3.0 * dr);
+
+ return weights;
+ }
+ }
+ #endregion
+ }
+}
View
89 Pinta.ImageManipulation/Effects/FragmentEffect.cs
@@ -0,0 +1,89 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Olivier Dufour <olivier.duff@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class FragmentEffect : BaseEffect
+ {
+ private int fragments;
+ private int distance;
+ private double rotation;
+
+ public FragmentEffect (int fragments, int distance, double rotation)
+ {
+ if (fragments < 2 || fragments > 50)
+ throw new ArgumentOutOfRangeException ("fragments");
+ if (distance < 0 || distance > 100)
+ throw new ArgumentOutOfRangeException ("distance");
+
+ this.fragments = fragments;
+ this.distance = distance;
+ this.rotation = rotation;
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected unsafe override void RenderLine (ISurface src, ISurface dst, Rectangle rect)
+ {
+ var pointOffsets = RecalcPointOffsets (fragments, rotation, distance);
+
+ int poLength = pointOffsets.Length;
+ Point* pointOffsetsPtr = stackalloc Point[poLength];
+
+ for (int i = 0; i < poLength; ++i)
+ pointOffsetsPtr[i] = pointOffsets[i];
+
+ ColorBgra* samples = stackalloc ColorBgra[poLength];
+
+ int src_width = src.Width;
+ int src_height = src.Height;
+
+ for (int y = rect.Top; y <= rect.Bottom; y++) {
+ ColorBgra* dstPtr = dst.GetPointAddress (rect.Left, y);
+
+ for (int x = rect.Left; x <= rect.Right; x++) {
+ int sampleCount = 0;
+
+ for (int i = 0; i < poLength; ++i) {
+ int u = x - pointOffsetsPtr[i].X;
+ int v = y - pointOffsetsPtr[i].Y;
+
+ if (u >= 0 && u < src_width && v >= 0 && v < src_height) {
+ samples[sampleCount] = src.GetPoint (u, v);
+ ++sampleCount;
+ }
+ }
+
+ *dstPtr = ColorBgra.Blend (samples, sampleCount);
+ ++dstPtr;
+ }
+ }
+ }
+
+ private Point[] RecalcPointOffsets (int fragments, double rotationAngle, int distance)
+ {
+ double pointStep = 2 * Math.PI / (double)fragments;
+ double rotationRadians = ((rotationAngle - 90.0) * Math.PI) / 180.0;
+
+ Point[] pointOffsets = new Point[fragments];
+
+ for (int i = 0; i < fragments; i++) {
+ double currentRadians = rotationRadians + (pointStep * i);
+
+ pointOffsets[i] = new Point (
+ (int)Math.Round (distance * -Math.Sin (currentRadians), MidpointRounding.AwayFromZero),
+ (int)Math.Round (distance * -Math.Cos (currentRadians), MidpointRounding.AwayFromZero));
+ }
+
+ return pointOffsets;
+ }
+ #endregion
+ }
+}
View
132 Pinta.ImageManipulation/Effects/FrostedGlassEffect.cs
@@ -0,0 +1,132 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Marco Rolappe <m_rolappe@gmx.net> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class FrostedGlassEffect : BaseEffect
+ {
+ private int amount;
+ private Random random = new Random ();
+
+ public FrostedGlassEffect (int amount)
+ {
+ if (amount < 1 || amount > 10)
+ throw new ArgumentOutOfRangeException ("amount");
+
+ this.amount = amount;
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected unsafe override void RenderLine (ISurface src, ISurface dst, Rectangle rect)
+ {
+ int width = src.Width;
+ int height = src.Height;
+ int r = amount;
+ Random localRandom = this.random;
+
+ int* intensityCount = stackalloc int[256];
+ uint* avgRed = stackalloc uint[256];
+ uint* avgGreen = stackalloc uint[256];
+ uint* avgBlue = stackalloc uint[256];
+ uint* avgAlpha = stackalloc uint[256];
+ byte* intensityChoices = stackalloc byte[(1 + (r * 2)) * (1 + (r * 2))];
+
+ int rectTop = rect.Top;
+ int rectBottom = rect.Bottom;
+ int rectLeft = rect.Left;
+ int rectRight = rect.Right;
+
+ for (int y = rectTop; y <= rectBottom; ++y) {
+ ColorBgra* dstPtr = dst.GetPointAddress (rect.Left, y);
+
+ int top = y - r;
+ int bottom = y + r + 1;
+
+ if (top < 0) {
+ top = 0;
+ }
+
+ if (bottom > height) {
+ bottom = height;
+ }
+
+ for (int x = rectLeft; x <= rectRight; ++x) {
+ int intensityChoicesIndex = 0;
+
+ for (int i = 0; i < 256; ++i) {
+ intensityCount[i] = 0;
+ avgRed[i] = 0;
+ avgGreen[i] = 0;
+ avgBlue[i] = 0;
+ avgAlpha[i] = 0;
+ }
+
+ int left = x - r;
+ int right = x + r + 1;
+
+ if (left < 0) {
+ left = 0;
+ }
+
+ if (right > width) {
+ right = width;
+ }
+
+ for (int j = top; j < bottom; ++j) {
+ if (j < 0 || j >= height) {
+ continue;
+ }
+
+ ColorBgra* srcPtr = src.GetPointAddress (left, j);
+
+ for (int i = left; i < right; ++i) {
+ byte intensity = srcPtr->GetIntensityByte ();
+
+ intensityChoices[intensityChoicesIndex] = intensity;
+ ++intensityChoicesIndex;
+
+ ++intensityCount[intensity];
+
+ avgRed[intensity] += srcPtr->R;
+ avgGreen[intensity] += srcPtr->G;
+ avgBlue[intensity] += srcPtr->B;
+ avgAlpha[intensity] += srcPtr->A;
+
+ ++srcPtr;
+ }
+ }
+
+ int randNum;
+
+ lock (localRandom) {
+ randNum = localRandom.Next (intensityChoicesIndex);
+ }
+
+ byte chosenIntensity = intensityChoices[randNum];
+
+ byte R = (byte)(avgRed[chosenIntensity] / intensityCount[chosenIntensity]);
+ byte G = (byte)(avgGreen[chosenIntensity] / intensityCount[chosenIntensity]);
+ byte B = (byte)(avgBlue[chosenIntensity] / intensityCount[chosenIntensity]);
+ byte A = (byte)(avgAlpha[chosenIntensity] / intensityCount[chosenIntensity]);
+
+ *dstPtr = ColorBgra.FromBgra (B, G, R, A);
+ ++dstPtr;
+
+ // prepare the array for the next loop iteration
+ for (int i = 0; i < intensityChoicesIndex; ++i) {
+ intensityChoices[i] = 0;
+ }
+ }
+ }
+ }
+ #endregion
+ }
+}
View
233 Pinta.ImageManipulation/Effects/GaussianBlurEffect.cs
@@ -0,0 +1,233 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Jonathan Pobst <monkey@jpobst.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class GaussianBlurEffect : BaseEffect
+ {
+ private int radius;
+ private int[] w;
+
+ public GaussianBlurEffect (int radius)
+ {
+ if (radius < 0 || radius > 200)
+ throw new ArgumentOutOfRangeException ("radius");
+
+ this.radius = radius;
+ w = CreateGaussianBlurRow (radius);
+ }
+
+ #region Algorithm Code Ported From PDN
+ public static int[] CreateGaussianBlurRow (int amount)
+ {
+ int size = 1 + (amount * 2);
+ int[] weights = new int[size];
+
+ for (int i = 0; i <= amount; ++i) {
+ // 1 + aa - aa + 2ai - ii
+ weights[i] = 16 * (i + 1);
+ weights[weights.Length - i - 1] = weights[i];
+ }
+
+ return weights;
+ }
+
+ protected unsafe override void RenderLine (ISurface src, ISurface dest, Rectangle rect)
+ {
+ if (radius == 0) {
+ // Copy src to dest
+ return;
+ }
+
+ int r = radius;
+ int wlen = w.Length;
+
+ int localStoreSize = wlen * 6 * sizeof (long);
+ byte* localStore = stackalloc byte[localStoreSize];
+ byte* p = localStore;
+
+ long* waSums = (long*)p;
+ p += wlen * sizeof (long);
+
+ long* wcSums = (long*)p;
+ p += wlen * sizeof (long);
+
+ long* aSums = (long*)p;
+ p += wlen * sizeof (long);
+
+ long* bSums = (long*)p;
+ p += wlen * sizeof (long);
+
+ long* gSums = (long*)p;
+ p += wlen * sizeof (long);
+
+ long* rSums = (long*)p;
+ p += wlen * sizeof (long);
+
+ int src_width = src.Width;
+ int src_height = src.Height;
+
+ if (rect.Height >= 1 && rect.Width >= 1) {
+ for (int y = rect.Top; y <= rect.Bottom; ++y) {
+ //Memory.SetToZero (localStore, (ulong)localStoreSize);
+
+ long waSum = 0;
+ long wcSum = 0;
+ long aSum = 0;
+ long bSum = 0;
+ long gSum = 0;
+ long rSum = 0;
+
+ ColorBgra* dstPtr = dest.GetPointAddress (rect.Left, y);
+
+ for (int wx = 0; wx < wlen; ++wx) {
+ int srcX = rect.Left + wx - r;
+ waSums[wx] = 0;
+ wcSums[wx] = 0;
+ aSums[wx] = 0;
+ bSums[wx] = 0;
+ gSums[wx] = 0;
+ rSums[wx] = 0;
+
+ if (srcX >= 0 && srcX < src_width) {
+ for (int wy = 0; wy < wlen; ++wy) {
+ int srcY = y + wy - r;
+
+ if (srcY >= 0 && srcY < src_height) {
+ ColorBgra c = src.GetPoint (srcX, srcY);
+ int wp = w[wy];
+
+ waSums[wx] += wp;
+ wp *= c.A + (c.A >> 7);
+ wcSums[wx] += wp;
+ wp >>= 8;
+
+ aSums[wx] += wp * c.A;
+ bSums[wx] += wp * c.B;
+ gSums[wx] += wp * c.G;
+ rSums[wx] += wp * c.R;
+ }
+ }
+
+ int wwx = w[wx];
+ waSum += wwx * waSums[wx];
+ wcSum += wwx * wcSums[wx];
+ aSum += wwx * aSums[wx];
+ bSum += wwx * bSums[wx];
+ gSum += wwx * gSums[wx];
+ rSum += wwx * rSums[wx];
+ }
+ }
+
+ wcSum >>= 8;
+
+ if (waSum == 0 || wcSum == 0) {
+ dstPtr->Bgra = 0;
+ } else {
+ int alpha = (int)(aSum / waSum);
+ int blue = (int)(bSum / wcSum);
+ int green = (int)(gSum / wcSum);
+ int red = (int)(rSum / wcSum);
+
+ dstPtr->Bgra = ColorBgra.BgraToUInt32 (blue, green, red, alpha);
+ }
+
+ ++dstPtr;
+
+ for (int x = rect.Left + 1; x <= rect.Right; ++x) {
+ for (int i = 0; i < wlen - 1; ++i) {
+ waSums[i] = waSums[i + 1];
+ wcSums[i] = wcSums[i + 1];
+ aSums[i] = aSums[i + 1];
+ bSums[i] = bSums[i + 1];
+ gSums[i] = gSums[i + 1];
+ rSums[i] = rSums[i + 1];
+ }
+
+ waSum = 0;
+ wcSum = 0;
+ aSum = 0;
+ bSum = 0;
+ gSum = 0;
+ rSum = 0;
+
+ int wx;
+ for (wx = 0; wx < wlen - 1; ++wx) {
+ long wwx = (long)w[wx];
+ waSum += wwx * waSums[wx];
+ wcSum += wwx * wcSums[wx];
+ aSum += wwx * aSums[wx];
+ bSum += wwx * bSums[wx];
+ gSum += wwx * gSums[wx];
+ rSum += wwx * rSums[wx];
+ }
+
+ wx = wlen - 1;
+
+ waSums[wx] = 0;
+ wcSums[wx] = 0;
+ aSums[wx] = 0;
+ bSums[wx] = 0;
+ gSums[wx] = 0;
+ rSums[wx] = 0;
+
+ int srcX = x + wx - r;
+
+ if (srcX >= 0 && srcX < src_width) {
+ for (int wy = 0; wy < wlen; ++wy) {
+ int srcY = y + wy - r;
+
+ if (srcY >= 0 && srcY < src_height) {
+ ColorBgra c = src.GetPoint (srcX, srcY);
+ int wp = w[wy];
+
+ waSums[wx] += wp;
+ wp *= c.A + (c.A >> 7);
+ wcSums[wx] += wp;
+ wp >>= 8;
+
+ aSums[wx] += wp * (long)c.A;
+ bSums[wx] += wp * (long)c.B;
+ gSums[wx] += wp * (long)c.G;
+ rSums[wx] += wp * (long)c.R;
+ }
+ }
+
+ int wr = w[wx];
+ waSum += (long)wr * waSums[wx];
+ wcSum += (long)wr * wcSums[wx];
+ aSum += (long)wr * aSums[wx];
+ bSum += (long)wr * bSums[wx];
+ gSum += (long)wr * gSums[wx];
+ rSum += (long)wr * rSums[wx];
+ }
+
+ wcSum >>= 8;
+
+ if (waSum == 0 || wcSum == 0) {
+ dstPtr->Bgra = 0;
+ } else {
+ int alpha = (int)(aSum / waSum);
+ int blue = (int)(bSum / wcSum);
+ int green = (int)(gSum / wcSum);
+ int red = (int)(rSum / wcSum);
+
+ dstPtr->Bgra = ColorBgra.BgraToUInt32 (blue, green, red, alpha);
+ }
+
+ ++dstPtr;
+ }
+ }
+ }
+ }
+ #endregion
+ }
+}
View
58 Pinta.ImageManipulation/Effects/GlowEffect.cs
@@ -0,0 +1,58 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Jonathan Pobst <monkey@jpobst.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using Pinta.ImageManipulation.PixelBlendOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class GlowEffect : BaseEffect
+ {
+ private int radius;
+ private int brightness;
+ private int contrast;
+
+ private GaussianBlurEffect blur_effect;
+ private BrightnessContrastEffect contrast_effect;
+ private ScreenBlendOp screen_op;
+
+ public GlowEffect (int radius, int brightness, int contrast)
+ {
+ if (radius < 1 || radius > 20)
+ throw new ArgumentOutOfRangeException ("radius");
+ if (brightness < -100 || brightness > 100)
+ throw new ArgumentOutOfRangeException ("brightness");
+ if (contrast < -100 || contrast > 100)
+ throw new ArgumentOutOfRangeException ("contrast");
+
+ this.radius = radius;
+ this.brightness = brightness;
+ this.contrast = contrast;
+
+ blur_effect = new GaussianBlurEffect (radius);
+ contrast_effect = new BrightnessContrastEffect (brightness, contrast);
+ screen_op = new ScreenBlendOp ();
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected unsafe override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ blur_effect.Render (src, dest, roi);
+ contrast_effect.Render (dest, dest, roi);
+
+ for (var y = roi.Top; y <= roi.Bottom; ++y) {
+ var dstPtr = dest.GetPointAddress (roi.Left, y);
+ var srcPtr = src.GetPointAddress (roi.Left, y);
+
+ screen_op.Apply (srcPtr, dstPtr, dstPtr, roi.Width);
+ }
+ }
+ #endregion
+ }
+}
View
41 Pinta.ImageManipulation/Effects/HueSaturationEffect.cs
@@ -0,0 +1,41 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Krzysztof Marecki <marecki.krzysztof@gmail.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using Pinta.ImageManipulation.UnaryPixelOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class HueSaturationEffect : BaseEffect
+ {
+ private UnaryPixelOp op;
+
+ public HueSaturationEffect (int hue, int saturation, int lightness)
+ {
+ if (hue < -180 || hue > 180)
+ throw new ArgumentOutOfRangeException ("hue");
+ if (saturation < 0 || saturation > 200)
+ throw new ArgumentOutOfRangeException ("saturation");
+ if (lightness < -100 || lightness > 100)
+ throw new ArgumentOutOfRangeException ("lightness");
+
+ if (hue == 0 && saturation == 100 && lightness == 0)
+ op = new IdentityOp ();
+ else
+ op = new HueSaturationLightnessOp (hue, saturation, lightness);
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ op.Apply (src, dest, roi);
+ }
+ #endregion
+ }
+}
View
139 Pinta.ImageManipulation/Effects/InkSketchEffect.cs
@@ -0,0 +1,139 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Jonathan Pobst <monkey@jpobst.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using System.Collections.Generic;
+using Pinta.ImageManipulation.UnaryPixelOperations;
+using Pinta.ImageManipulation.PixelBlendOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class InkSketchEffect : BaseEffect
+ {
+ private static readonly int[][] conv;
+ private const int size = 5;
+ private const int radius = (size - 1) / 2;
+
+ private GlowEffect glow_effect;
+ private DesaturateOp desaturate_op;
+ private DarkenBlendOp darken_op;
+
+ private int ink_outline;
+ private int coloring;
+
+ static InkSketchEffect ()
+ {
+ conv = new int[5][];
+
+ for (var i = 0; i < conv.Length; ++i)
+ conv[i] = new int[5];
+
+ conv[0] = new int[] { -1, -1, -1, -1, -1 };
+ conv[1] = new int[] { -1, -1, -1, -1, -1 };
+ conv[2] = new int[] { -1, -1, 30, -1, -1 };
+ conv[3] = new int[] { -1, -1, -1, -1, -1 };
+ conv[4] = new int[] { -1, -1, -5, -1, -1 };
+ }
+
+ public InkSketchEffect (int inkOutline, int coloring)
+ {
+ if (inkOutline < 0 || inkOutline > 99)
+ throw new ArgumentOutOfRangeException ("inkOutline");
+ if (coloring < 0 || coloring > 100)
+ throw new ArgumentOutOfRangeException ("coloring");
+
+ ink_outline = inkOutline;
+ this.coloring = coloring;
+
+ glow_effect = new GlowEffect (6, -(coloring - 50) * 2, -(coloring - 50) * 2);
+ desaturate_op = new DesaturateOp ();
+ darken_op = new DarkenBlendOp ();
+ }
+
+ #region Algorithm Code Ported From PDN
+ protected unsafe override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ // Glow backgound
+ glow_effect.Render (src, dest, roi);
+
+ // Create black outlines by finding the edges of objects
+ for (int y = roi.Top; y <= roi.Bottom; ++y) {
+ int top = y - radius;
+ int bottom = y + radius + 1;
+
+ if (top < 0) {
+ top = 0;
+ }
+
+ if (bottom > dest.Height) {
+ bottom = dest.Height;
+ }
+
+ ColorBgra* srcPtr = src.GetPointAddress (roi.X, y);
+ ColorBgra* dstPtr = dest.GetPointAddress (roi.X, y);
+
+ for (int x = roi.Left; x <= roi.Right; ++x) {
+ int left = x - radius;
+ int right = x + radius + 1;
+
+ if (left < 0) {
+ left = 0;
+ }
+
+ if (right > dest.Width) {
+ right = dest.Width;
+ }
+
+ int r = 0;
+ int g = 0;
+ int b = 0;
+
+ for (int v = top; v < bottom; v++) {
+ ColorBgra* pRow = src.GetRowAddress (v);
+ int j = v - y + radius;
+
+ for (int u = left; u < right; u++) {
+ int i1 = u - x + radius;
+ int w = conv[j][i1];
+
+ ColorBgra* pRef = pRow + u;
+
+ r += pRef->R * w;
+ g += pRef->G * w;
+ b += pRef->B * w;
+ }
+ }
+
+ ColorBgra topLayer = ColorBgra.FromBgr (
+ Utility.ClampToByte (b),
+ Utility.ClampToByte (g),
+ Utility.ClampToByte (r));
+
+ // Desaturate
+ topLayer = this.desaturate_op.Apply (topLayer);
+
+ // Adjust Brightness and Contrast
+ if (topLayer.R > (ink_outline * 255 / 100)) {
+ topLayer = ColorBgra.FromBgra (255, 255, 255, topLayer.A);
+ } else {
+ topLayer = ColorBgra.FromBgra (0, 0, 0, topLayer.A);
+ }
+
+ // Change Blend Mode to Darken
+ ColorBgra myPixel = this.darken_op.Apply (topLayer, *dstPtr);
+ *dstPtr = myPixel;
+
+ ++srcPtr;
+ ++dstPtr;
+ }
+ }
+ }
+ #endregion
+ }
+}
View
26 Pinta.ImageManipulation/Effects/InvertColorsEffect.cs
@@ -0,0 +1,26 @@
+/////////////////////////////////////////////////////////////////////////////////
+// Paint.NET //
+// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
+// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
+// See license-pdn.txt for full licensing and attribution details. //
+// //
+// Ported to Pinta by: Jonathan Pobst <monkey@jpobst.com> //
+/////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using Pinta.ImageManipulation.UnaryPixelOperations;
+
+namespace Pinta.ImageManipulation.Effects
+{
+ public class InvertColorsEffect : BaseEffect
+ {
+ private InvertOp op = new InvertOp ();
+
+ #region Algorithm Code Ported From PDN
+ protected override void RenderLine (ISurface src, ISurface dest, Rectangle roi)
+ {
+ op.Apply (src, dest, roi);
+ }
+ #endregion
+ }
+}
View
112 Pinta.ImageManipulation/Effects/JuliaFractalEffect.cs
@@ -0,0 +1,112 @@