Permalink
Browse files

Add overloads to BaseEffect that write the results back to the source…

… surface rather than requiring a destination surface.
  • Loading branch information...
1 parent 056a06a commit aff6e936a5475288539253e17178a964ad850de5 @jpobst jpobst committed Dec 25, 2012
@@ -24,6 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+using Pinta.ImageManipulation.UnaryPixelOperations;
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -33,6 +34,15 @@ namespace Pinta.ImageManipulation
public abstract class BaseEffect
{
/// <summary>
+ /// Render the effect on the specified surface.
+ /// </summary>
+ /// <param name="surface">Surface to use a the source and destination.</param>
+ public virtual void Render (ISurface surface)
+ {
+ Render (surface, surface.Bounds);
+ }
+
+ /// <summary>
/// Render the effect from the source surface to the destination surface.
/// </summary>
/// <param name="src">The source surface.</param>
@@ -46,6 +56,16 @@ public virtual void Render (ISurface src, ISurface dst)
}
/// <summary>
+ /// Render the effect on the specified surface within the specified rectangle of interest.
+ /// </summary>
+ /// <param name="surface">Surface to use a the source and destination.</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 surface, Rectangle roi)
+ {
+ RenderLoop (surface, roi, CancellationToken.None);
+ }
+
+ /// <summary>
/// Render the effect from the source surface to the destination surface.
/// </summary>
/// <param name="src">The source surface.</param>
@@ -56,24 +76,44 @@ public void Render (ISurface src, ISurface dst, Rectangle roi)
RenderLoop (src, dst, roi, CancellationToken.None);
}
+ public Task RenderAsync (ISurface surface)
+ {
+ return RenderAsync (surface, CancellationToken.None);
+ }
+
public Task RenderAsync (ISurface src, ISurface dst)
{
return RenderAsync (src, dst, CancellationToken.None);
}
+ public Task RenderAsync (ISurface surface, CancellationToken token)
+ {
+ return RenderAsync (surface, surface.Bounds, token);
+ }
+
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));
+ return RenderAsync (src, dst, src.Bounds, token);
+ }
+
+ public Task RenderAsync (ISurface surface, Rectangle roi)
+ {
+ return RenderAsync (surface, roi, CancellationToken.None);
}
public Task RenderAsync (ISurface src, ISurface dst, Rectangle roi)
{
return RenderAsync (src, dst, roi, CancellationToken.None);
}
+ public Task RenderAsync (ISurface surface, Rectangle roi, CancellationToken token)
+ {
+ return Task.Factory.StartNew (() => RenderLoop (surface, roi, token));
+ }
+
public Task RenderAsync (ISurface src, ISurface dst, Rectangle roi, CancellationToken token)
{
return Task.Factory.StartNew (() => RenderLoop (src, dst, roi, token));
@@ -101,6 +141,38 @@ protected virtual void RenderLoop (ISurface src, ISurface dst, Rectangle roi, Ca
dst.EndUpdate ();
}
+ protected unsafe virtual void RenderLoop (ISurface surface, Rectangle roi, CancellationToken token)
+ {
+ var dst = new ColorBgra[surface.Height * surface.Width];
+
+ fixed (ColorBgra* dst_ptr = dst) {
+ var dst_wrap = new ColorBgraArrayWrapper (dst_ptr, surface.Width, surface.Height);
+
+ surface.BeginUpdate ();
+ dst_wrap.BeginUpdate ();
+
+ if (Settings.SingleThreaded || roi.Height <= 1) {
+ for (var y = roi.Y; y <= roi.Bottom; ++y) {
+ if (token.IsCancellationRequested)
+ return;
+
+ RenderLine (surface, dst_wrap, new Rectangle (roi.X, y, roi.Width, 1));
+ }
+ } else {
+ ParallelExtensions.OrderedFor (roi.Y, roi.Bottom + 1, token, (y) => {
+ RenderLine (surface, dst_wrap, new Rectangle (roi.X, y, roi.Width, 1));
+ });
+ }
+
+ // Copy the result from our temp destination back into the source
+ var op = new IdentityOp ();
+ op.ApplyAsync (dst_wrap, surface, token).Wait ();
+
+ surface.EndUpdate ();
+ dst_wrap.EndUpdate ();
+ }
+ }
+
/// <summary>
/// Performs the actual work of rendering an effect. Do not call base.Render ().
/// </summary>
@@ -0,0 +1,58 @@
+//
+// ByteArrayWrapper.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;
+
+namespace Pinta.ImageManipulation
+{
+ public class ColorBgraArrayWrapper : BaseSurface
+ {
+ private unsafe ColorBgra* data_ptr;
+
+ public unsafe ColorBgraArrayWrapper (ColorBgra* data, int width, int height)
+ {
+ data_ptr = data;
+ this.height = height;
+ this.width = width;
+ }
+
+ protected unsafe override ColorBgra* data {
+ get { return data_ptr; }
+ }
+
+ public unsafe override int Stride {
+ get { return width * sizeof (ColorBgra*); }
+ }
+
+ public unsafe override void BeginUpdate ()
+ {
+ }
+
+ public override void EndUpdate ()
+ {
+ }
+ }
+}
@@ -39,6 +39,7 @@
<ItemGroup>
<Compile Include="BaseEffect.cs" />
<Compile Include="BaseSurface.cs" />
+ <Compile Include="ColorBgraArrayWrapper.cs" />
<Compile Include="Effects\AddNoiseEffect.cs" />
<Compile Include="Effects\BulgeEffect.cs" />
<Compile Include="Effects\CloudsEffect.cs" />
View
@@ -28,13 +28,11 @@ For example, if you are using System.Drawing, add Pinta.ImageManipulation.dll an
```csharp
var src_bitmap = new System.Drawing.Bitmap (@"C:\pic.png");
-var dst_bitmap = new System.Drawing.Bitmap (src_bitmap.Width, src_bitmap.Height);
var src_wrap = new BitmapWrapper (src_bitmap);
-var dst_wrap = new BitmapWrapper (dst_bitmap);
var blur = new GaussianBlurEffect ();
-await blur.RenderAsync (src_wrap, dst_wrap);
+await blur.RenderAsync (src_wrap);
-dst_bitmap.Save (@"C:\pic2.png");
+src_bitmap.Save (@"C:\pic2.png");
```

0 comments on commit aff6e93

Please sign in to comment.