diff --git a/src/Greenshot.Gfx/BoxBlurUnmanaged.cs b/src/Greenshot.Gfx/BoxBlurUnmanaged.cs
index 661f05c33..a4174e7b2 100644
--- a/src/Greenshot.Gfx/BoxBlurUnmanaged.cs
+++ b/src/Greenshot.Gfx/BoxBlurUnmanaged.cs
@@ -18,7 +18,6 @@
// along with this program. If not, see .
using System;
-using System.Threading.Tasks;
using Greenshot.Gfx.Structs;
namespace Greenshot.Gfx
@@ -89,61 +88,61 @@ namespace Greenshot.Gfx
{
var halfRange = range / 2;
- Parallel.For(0, unmanagedBitmap.Height, y =>
+ for(var y = 0; y averages = stackalloc Bgr32[range];
- var r = 0;
- var g = 0;
- var b = 0;
- var hits = halfRange;
- for (var x = 0; x < halfRange; x++)
- {
- ref Bgr32 color = ref rgb32[x];
+ var rgb32 = unmanagedBitmap[y];
+ Span averages = stackalloc Bgr32[range];
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ var hits = halfRange;
+ for (var x = 0; x < halfRange; x++)
+ {
+ ref var color = ref rgb32[x];
+ r += color.R;
+ g += color.G;
+ b += color.B;
+ }
+ for (var x = 0; x < unmanagedBitmap.Width; x++)
+ {
+ var leftSide = x - halfRange - 1;
+ if (leftSide >= 0)
+ {
+ // Get value at the left side of range
+ ref var color = ref rgb32[leftSide];
+ r -= color.R;
+ g -= color.G;
+ b -= color.B;
+ hits--;
+ }
+
+ var rightSide = x + halfRange;
+ if (rightSide < unmanagedBitmap.Width)
+ {
+ ref var color = ref rgb32[rightSide];
r += color.R;
g += color.G;
b += color.B;
+ hits++;
}
- for (var x = 0; x < unmanagedBitmap.Width; x++)
+
+ ref var average = ref averages[x % range];
+ average.R = (byte)(r / hits);
+ average.G = (byte)(g / hits);
+ average.B = (byte)(b / hits);
+
+ if (leftSide < 0)
{
- var leftSide = x - halfRange - 1;
- if (leftSide >= 0)
- {
- // Get value at the left side of range
- ref Bgr32 color = ref rgb32[leftSide];
- r -= color.R;
- g -= color.G;
- b -= color.B;
- hits--;
- }
-
- var rightSide = x + halfRange;
- if (rightSide < unmanagedBitmap.Width)
- {
- ref Bgr32 color = ref rgb32[rightSide];
- r += color.R;
- g += color.G;
- b += color.B;
- hits++;
- }
-
- ref Bgr32 average = ref averages[x % range];
- average.R = (byte)(r / hits);
- average.G = (byte)(g / hits);
- average.B = (byte)(b / hits);
-
- if (leftSide >= 0)
- {
- // Now we can write the value from the calculated avarages
- var readLocation = (leftSide % range);
-
- rgb32[leftSide] = averages[readLocation];
- }
+ continue;
}
+
+ // Now we can write the value from the calculated averages
+ var readLocation = (leftSide % range);
+
+ rgb32[leftSide] = averages[readLocation];
}
- });
+ }
}
///
@@ -154,61 +153,61 @@ namespace Greenshot.Gfx
private static void BoxBlurVertical(UnmanagedBitmap unmanagedBitmap, int range)
{
var halfRange = range / 2;
- Parallel.For(0, unmanagedBitmap.Width, x =>
+ for(var x = 0; x averages = stackalloc Bgr32[range];
- var hits = 0;
- var r = 0;
- var g = 0;
- var b = 0;
- for (var y = 0; y < halfRange; y++)
+ var rgb32 = unmanagedBitmap.Span;
+ Span averages = stackalloc Bgr32[range];
+ var hits = 0;
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ for (var y = 0; y < halfRange; y++)
+ {
+ ref var color = ref rgb32[(y * unmanagedBitmap.Width) + x];
+ r += color.R;
+ g += color.G;
+ b += color.B;
+ hits++;
+ }
+ for (var y = 0; y < unmanagedBitmap.Height; y++)
+ {
+ var topSide = y - halfRange - 1;
+ if (topSide >= 0)
{
- ref Bgr32 color = ref rgb32[(y * unmanagedBitmap.Width) + x];
+ // Get value at the top side of range
+ ref var color = ref rgb32[x + (topSide * unmanagedBitmap.Width)];
+ r -= color.R;
+ g -= color.G;
+ b -= color.B;
+ hits--;
+ }
+
+ var bottomSide = y + halfRange;
+ if (bottomSide < unmanagedBitmap.Height)
+ {
+ ref var color = ref rgb32[x + (bottomSide * unmanagedBitmap.Width)];
r += color.R;
g += color.G;
b += color.B;
hits++;
}
- for (var y = 0; y < unmanagedBitmap.Height; y++)
+
+ ref var average = ref averages[y % range];
+ average.R = (byte)(r / hits);
+ average.G = (byte)(g / hits);
+ average.B = (byte)(b / hits);
+
+ if (topSide < 0)
{
- var topSide = y - halfRange - 1;
- if (topSide >= 0)
- {
- // Get value at the top side of range
- ref Bgr32 color = ref rgb32[x + (topSide * unmanagedBitmap.Width)];
- r -= color.R;
- g -= color.G;
- b -= color.B;
- hits--;
- }
-
- var bottomSide = y + halfRange;
- if (bottomSide < unmanagedBitmap.Height)
- {
- ref Bgr32 color = ref rgb32[x + (bottomSide * unmanagedBitmap.Width)];
- r += color.R;
- g += color.G;
- b += color.B;
- hits++;
- }
-
- ref Bgr32 average = ref averages[y % range];
- average.R = (byte)(r / hits);
- average.G = (byte)(g / hits);
- average.B = (byte)(b / hits);
-
- if (topSide >= 0)
- {
- // Write the value from the calculated avarages
- var readLocation = topSide % range;
-
- rgb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation];
- }
+ continue;
}
+
+ // Write the value from the calculated averages
+ var readLocation = topSide % range;
+
+ rgb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation];
}
- });
+ }
}
///
@@ -220,65 +219,65 @@ namespace Greenshot.Gfx
{
var halfRange = range / 2;
- Parallel.For(0, unmanagedBitmap.Height, y =>
+ for(var y = 0; y averages = stackalloc Bgra32[range];
- var a = 0;
- var r = 0;
- var g = 0;
- var b = 0;
- var hits = halfRange;
- for (var x = 0; x < halfRange; x++)
+ var argb32 = unmanagedBitmap[y];
+ Span averages = stackalloc Bgra32[range];
+ var a = 0;
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ var hits = halfRange;
+ for (var x = 0; x < halfRange; x++)
+ {
+ ref var color = ref argb32[x];
+ a += color.A;
+ r += color.R;
+ g += color.G;
+ b += color.B;
+ }
+ for (var x = 0; x < unmanagedBitmap.Width; x++)
+ {
+ var leftSide = x - halfRange - 1;
+ if (leftSide >= 0)
{
- ref Bgra32 color = ref argb32[x];
+ // Get value at the left side of range
+ ref var color = ref argb32[leftSide];
+ a -= color.A;
+ r -= color.R;
+ g -= color.G;
+ b -= color.B;
+ hits--;
+ }
+
+ var rightSide = x + halfRange;
+ if (rightSide < unmanagedBitmap.Width)
+ {
+ ref var color = ref argb32[rightSide];
a += color.A;
r += color.R;
g += color.G;
b += color.B;
+ hits++;
}
- for (var x = 0; x < unmanagedBitmap.Width; x++)
+
+ ref var average = ref averages[x % range];
+ average.A = (byte)(a / hits);
+ average.R = (byte)(r / hits);
+ average.G = (byte)(g / hits);
+ average.B = (byte)(b / hits);
+
+ if (leftSide < 0)
{
- var leftSide = x - halfRange - 1;
- if (leftSide >= 0)
- {
- // Get value at the left side of range
- ref Bgra32 color = ref argb32[leftSide];
- a -= color.A;
- r -= color.R;
- g -= color.G;
- b -= color.B;
- hits--;
- }
-
- var rightSide = x + halfRange;
- if (rightSide < unmanagedBitmap.Width)
- {
- ref Bgra32 color = ref argb32[rightSide];
- a += color.A;
- r += color.R;
- g += color.G;
- b += color.B;
- hits++;
- }
-
- ref Bgra32 average = ref averages[x % range];
- average.A = (byte)(a / hits);
- average.R = (byte)(r / hits);
- average.G = (byte)(g / hits);
- average.B = (byte)(b / hits);
-
- if (leftSide >= 0)
- {
- // Now we can write the value from the calculated avarages
- var readLocation = leftSide % range;
-
- argb32[leftSide] = averages[readLocation];
- }
+ continue;
}
+
+ // Now we can write the value from the calculated averages
+ var readLocation = leftSide % range;
+
+ argb32[leftSide] = averages[readLocation];
}
- });
+ }
}
///
@@ -289,67 +288,66 @@ namespace Greenshot.Gfx
private static void BoxBlurVertical(UnmanagedBitmap unmanagedBitmap, int range)
{
var halfRange = range / 2;
- Parallel.For(0, unmanagedBitmap.Width, x =>
+ for(var x = 0; x averages = stackalloc Bgra32[range];
+ var hits = 0;
+ var a = 0;
+ var r = 0;
+ var g = 0;
+ var b = 0;
+ for (var y = 0; y < halfRange; y++)
{
- var argb32 = unmanagedBitmap.Span;
- Span averages = stackalloc Bgra32[range];
- var hits = 0;
- var a = 0;
- var r = 0;
- var g = 0;
- var b = 0;
- for (var y = 0; y < halfRange; y++)
+ ref var color = ref argb32[x + (y * unmanagedBitmap.Width)];
+ a += color.A;
+ r += color.R;
+ g += color.G;
+ b += color.B;
+ hits++;
+ }
+ for (var y = 0; y < unmanagedBitmap.Height; y++)
+ {
+ var topSide = y - halfRange - 1;
+ if (topSide >= 0)
{
- ref Bgra32 color = ref argb32[x + (y * unmanagedBitmap.Width)];
+ // Get value at the top side of range
+ ref var color = ref argb32[x + (topSide * unmanagedBitmap.Width)];
+ a -= color.A;
+ r -= color.R;
+ g -= color.G;
+ b -= color.B;
+ hits--;
+ }
+
+ var bottomSide = y + halfRange;
+ if (bottomSide < unmanagedBitmap.Height)
+ {
+ ref var color = ref argb32[x + (bottomSide * unmanagedBitmap.Width)];
a += color.A;
r += color.R;
g += color.G;
b += color.B;
hits++;
}
- for (var y = 0; y < unmanagedBitmap.Height; y++)
+
+ ref var average = ref averages[(y % range)];
+ average.A = (byte)(a / hits);
+ average.R = (byte)(r / hits);
+ average.G = (byte)(g / hits);
+ average.B = (byte)(b / hits);
+
+ if (topSide < 0)
{
- var topSide = y - halfRange - 1;
- if (topSide >= 0)
- {
- // Get value at the top side of range
- ref Bgra32 color = ref argb32[x + (topSide * unmanagedBitmap.Width)];
- a -= color.A;
- r -= color.R;
- g -= color.G;
- b -= color.B;
- hits--;
- }
-
- var bottomSide = y + halfRange;
- if (bottomSide < unmanagedBitmap.Height)
- {
- ref Bgra32 color = ref argb32[x + (bottomSide * unmanagedBitmap.Width)];
- a += color.A;
- r += color.R;
- g += color.G;
- b += color.B;
- hits++;
- }
-
- ref Bgra32 average = ref averages[(y % range)];
- average.A = (byte)(a / hits);
- average.R = (byte)(r / hits);
- average.G = (byte)(g / hits);
- average.B = (byte)(b / hits);
-
- if (topSide >= 0)
- {
- // Write the value from the calculated avarages
- var readLocation = (topSide % range);
-
- argb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation];
- }
+ continue;
}
+
+ // Write the value from the calculated averages
+ var readLocation = (topSide % range);
+
+ argb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation];
}
- });
+ }
}
}
}
diff --git a/src/Greenshot.Gfx/ScaleXUnmanaged.cs b/src/Greenshot.Gfx/ScaleXUnmanaged.cs
index 02ac9fb28..3a12e4032 100644
--- a/src/Greenshot.Gfx/ScaleXUnmanaged.cs
+++ b/src/Greenshot.Gfx/ScaleXUnmanaged.cs
@@ -18,6 +18,7 @@
// along with this program. If not, see .
using System;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Greenshot.Gfx
@@ -44,45 +45,44 @@ namespace Greenshot.Gfx
var sourceWidth = sourceBitmap.Width;
var destinationWidth = destinationBitmap.Width;
- ReadOnlySpan sourceSpan = MemoryMarshal.Cast(sourceBitmap.Span);
- var destinationSpan = MemoryMarshal.Cast(destinationBitmap.Span);
+ ref var destinationPointer = ref Unsafe.As(ref destinationBitmap.Span.GetPinnableReference());
+ ref var sourcePointer = ref Unsafe.As(ref sourceBitmap.Span.GetPinnableReference());
for (var y = 0; y < sourceBitmap.Height; y++)
{
var sourceYOffset = y * sourceWidth;
var destinationYOffset = (y << 1) * destinationWidth;
for (var x = 0; x < sourceWidth; x++)
{
- var sourceOffset = sourceYOffset + x;
- ref readonly uint colorE = ref sourceSpan[sourceOffset];
+ ref var colorE = ref Unsafe.Add(ref sourcePointer, sourceYOffset + x);
- ref readonly uint colorB = ref colorE;
+ ref readonly var colorB = ref colorE;
if (y != 0)
{
- colorB = ref sourceSpan[sourceOffset - sourceWidth];
+ colorB = ref Unsafe.Subtract(ref colorE, sourceWidth);
}
- ref readonly uint colorH = ref colorE;
+ ref readonly var colorH = ref colorE;
if (y != sourceBitmap.Height - 1)
{
- colorH = ref sourceSpan[sourceOffset + sourceWidth];
+ colorH = ref Unsafe.Add(ref colorE, sourceWidth);
}
- ref readonly uint colorD = ref colorE;
+ ref readonly var colorD = ref colorE;
if (x > 0)
{
- colorD = ref sourceSpan[sourceOffset - 1];
+ colorD = ref Unsafe.Subtract(ref colorE, 1);
}
- ref readonly uint colorF = ref colorE;
+ ref readonly var colorF = ref colorE;
if (x < sourceBitmap.Width - 1)
{
- colorF = ref sourceSpan[sourceOffset + 1];
+ colorF = ref Unsafe.Add(ref colorE, 1);
}
- ref readonly uint colorE0 = ref colorE;
- ref readonly uint colorE1 = ref colorE;
- ref readonly uint colorE2 = ref colorE;
- ref readonly uint colorE3 = ref colorE;
+ ref readonly var colorE0 = ref colorE;
+ ref readonly var colorE1 = ref colorE;
+ ref readonly var colorE2 = ref colorE;
+ ref readonly var colorE3 = ref colorE;
if (colorB != colorH && colorD != colorF)
{
if (colorH == colorF)
@@ -102,17 +102,19 @@ namespace Greenshot.Gfx
colorE0 = ref colorD;
}
}
- var destinationOffset = (x << 1) + destinationYOffset;
- destinationSpan[destinationOffset + 1 + destinationWidth] = colorE3;
- destinationSpan[destinationOffset + destinationWidth] = colorE2;
- destinationSpan[destinationOffset + 1] = colorE1;
- destinationSpan[destinationOffset] = colorE0;
+
+ ref var destColorE0 = ref Unsafe.Add(ref destinationPointer, (x << 1) + destinationYOffset);
+ destColorE0 = colorE0;
+ Unsafe.Add(ref destColorE0, 1 + destinationWidth) = colorE3;
+ Unsafe.Add(ref destColorE0, destinationWidth) = colorE2;
+ Unsafe.Add(ref destColorE0, 1) = colorE1;
}
}
return destinationBitmap;
}
+
///
/// Use "Scale3x" algorithm to produce bitmap from the original.
/// Every pixel from input texture produces 6 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
@@ -128,133 +130,129 @@ namespace Greenshot.Gfx
// Create destination bitmap, where the scaled image is written to
var destinationBitmap = new UnmanagedBitmap(sourceBitmap.Width * 3, sourceBitmap.Height * 3);
- ReadOnlySpan sourceSpan = MemoryMarshal.Cast(sourceBitmap.Span);
- var destinationSpan = MemoryMarshal.Cast(destinationBitmap.Span);
-
var sourceWidth = sourceBitmap.Width;
var destinationWidth = destinationBitmap.Width;
- unchecked
+ ref var destinationPointer = ref Unsafe.As(ref destinationBitmap.Span.GetPinnableReference());
+ ref var sourcePointer = ref Unsafe.As(ref sourceBitmap.Span.GetPinnableReference());
+
+ for (var y = 0; y < sourceBitmap.Height; y++)
{
- for (var y = 0; y < sourceBitmap.Height; y++)
+ var sourceYOffset = y * sourceWidth;
+ var destinationYOffset = y * 3 * destinationWidth;
+ for (var x = 0; x < sourceWidth; x++)
{
- var sourceYOffset = y * sourceWidth;
- var destinationYOffset = y * 3 * destinationWidth;
- for (var x = 0; x < sourceWidth; x++)
+ ref var colorE = ref Unsafe.Add(ref sourcePointer, sourceYOffset + x);
+ ref readonly var colorA = ref colorE;
+ ref readonly var colorB = ref colorE;
+ ref readonly var colorC = ref colorE;
+ ref readonly var colorD = ref colorE;
+ ref readonly var colorF = ref colorE;
+ ref readonly var colorG = ref colorE;
+ ref readonly var colorH = ref colorE;
+ ref readonly var colorI = ref colorE;
+
+ if (y != 0 && x != 0)
{
- var sourceOffset = sourceYOffset + x;
- ref readonly uint colorE = ref sourceSpan[sourceOffset];
- ref readonly uint colorA = ref colorE;
- ref readonly uint colorB = ref colorE;
- ref readonly uint colorC = ref colorE;
- ref readonly uint colorD = ref colorE;
- ref readonly uint colorF = ref colorE;
- ref readonly uint colorG = ref colorE;
- ref readonly uint colorH = ref colorE;
- ref readonly uint colorI = ref colorE;
-
- if (y != 0 && x != 0)
- {
- colorA = ref sourceSpan[sourceOffset - 1 - sourceWidth];
- }
-
- if (y != 0)
- {
- colorB = ref sourceSpan[sourceOffset - sourceWidth];
- }
-
- if (x < sourceWidth - 1 && y != 0)
- {
- colorC = ref sourceSpan[sourceOffset + 1 - sourceWidth];
- }
-
- if (x != 0)
- {
- colorD = ref sourceSpan[sourceOffset - 1];
- }
-
- if (x < sourceWidth - 1)
- {
- colorF = ref sourceSpan[sourceOffset + 1];
- }
-
- if (x != 0 && y < sourceBitmap.Height - 1)
- {
- colorG = ref sourceSpan[sourceOffset - 1 + sourceWidth];
- }
-
- if (y < sourceBitmap.Height - 1)
- {
- colorH = ref sourceSpan[sourceOffset + sourceWidth];
- }
-
- if (x < sourceWidth - 1 && y < sourceBitmap.Height - 1)
- {
- colorI = ref sourceSpan[sourceOffset + 1 + sourceWidth];
- }
-
- ref readonly uint colorE0 = ref colorE;
- ref readonly uint colorE1 = ref colorE;
- ref readonly uint colorE2 = ref colorE;
- ref readonly uint colorE3 = ref colorE;
- ref readonly uint colorE4 = ref colorE;
- ref readonly uint colorE5 = ref colorE;
- ref readonly uint colorE6 = ref colorE;
- ref readonly uint colorE7 = ref colorE;
- ref readonly uint colorE8 = ref colorE;
- if (colorB != colorH && colorD != colorF)
- {
- if (colorH == colorF)
- {
- colorE8 = ref colorF;
- }
- if (colorD == colorH && colorE != colorI || colorH == colorF && colorE != colorG)
- {
- colorE7 = ref colorH;
- }
- if (colorD == colorH)
- {
- colorE6 = ref colorD;
- }
- if (colorB == colorF && colorE != colorI || colorH == colorF && colorE != colorC)
- {
- colorE5 = ref colorF;
- }
-
- if (colorD == colorB && colorE != colorG || colorD == colorH && colorE != colorA)
- {
- colorE3 = ref colorD;
- }
- if (colorB == colorF)
- {
- colorE2 = ref colorF;
- }
- if (colorD == colorB && colorE != colorC || colorB == colorF && colorE != colorA)
- {
- colorE1 = ref colorB;
- }
- if (colorD == colorB)
- {
- colorE0 = ref colorD;
- }
- }
-
- var destinationOffset = x * 3 + destinationYOffset;
-
- destinationSpan[destinationOffset] = colorE0;
- destinationSpan[destinationOffset + 1] = colorE1;
- destinationSpan[destinationOffset + 2] = colorE2;
-
- destinationOffset += destinationWidth;
- destinationSpan[destinationOffset] = colorE3;
- destinationSpan[destinationOffset + 1] = colorE4;
- destinationSpan[destinationOffset + 2] = colorE5;
-
- destinationOffset += destinationWidth;
- destinationSpan[destinationOffset] = colorE6;
- destinationSpan[destinationOffset + 1] = colorE7;
- destinationSpan[destinationOffset + 2] = colorE8;
+ colorA = ref Unsafe.Subtract(ref colorE, 1 + sourceWidth);
}
+
+ if (y != 0)
+ {
+ colorB = ref Unsafe.Subtract(ref colorE, sourceWidth);
+ }
+
+ if (x < sourceWidth - 1 && y != 0)
+ {
+ colorC = ref Unsafe.Subtract(ref colorE, sourceWidth - 1);
+ }
+
+ if (x != 0)
+ {
+ colorD = ref Unsafe.Subtract(ref colorE, 1);
+ }
+
+ if (x < sourceWidth - 1)
+ {
+ colorF = ref Unsafe.Add(ref colorE, 1);
+ }
+
+ if (x != 0 && y < sourceBitmap.Height - 1)
+ {
+ colorG = ref Unsafe.Add(ref colorE, sourceWidth - 1);
+ }
+
+ if (y < sourceBitmap.Height - 1)
+ {
+ colorH = ref Unsafe.Add(ref colorE, sourceWidth);
+ }
+
+ if (x < sourceWidth - 1 && y < sourceBitmap.Height - 1)
+ {
+ colorI = ref Unsafe.Add(ref colorE, sourceWidth + 1);
+ }
+
+ ref readonly var colorE0 = ref colorE;
+ ref readonly var colorE1 = ref colorE;
+ ref readonly var colorE2 = ref colorE;
+ ref readonly var colorE3 = ref colorE;
+ ref readonly var colorE4 = ref colorE;
+ ref readonly var colorE5 = ref colorE;
+ ref readonly var colorE6 = ref colorE;
+ ref readonly var colorE7 = ref colorE;
+ ref readonly var colorE8 = ref colorE;
+ if (colorB != colorH && colorD != colorF)
+ {
+ if (colorH == colorF)
+ {
+ colorE8 = ref colorF;
+ }
+ if (colorD == colorH && colorE != colorI || colorH == colorF && colorE != colorG)
+ {
+ colorE7 = ref colorH;
+ }
+ if (colorD == colorH)
+ {
+ colorE6 = ref colorD;
+ }
+ if (colorB == colorF && colorE != colorI || colorH == colorF && colorE != colorC)
+ {
+ colorE5 = ref colorF;
+ }
+
+ if (colorD == colorB && colorE != colorG || colorD == colorH && colorE != colorA)
+ {
+ colorE3 = ref colorD;
+ }
+ if (colorB == colorF)
+ {
+ colorE2 = ref colorF;
+ }
+ if (colorD == colorB && colorE != colorC || colorB == colorF && colorE != colorA)
+ {
+ colorE1 = ref colorB;
+ }
+ if (colorD == colorB)
+ {
+ colorE0 = ref colorD;
+ }
+ }
+
+ var destinationOffset = x * 3 + destinationYOffset;
+
+ Unsafe.Add(ref destinationPointer, destinationOffset) = colorE0;
+ Unsafe.Add(ref destinationPointer, destinationOffset + 1) = colorE1;
+ Unsafe.Add(ref destinationPointer, destinationOffset + 2) = colorE2;
+
+ destinationOffset += destinationWidth;
+ Unsafe.Add(ref destinationPointer, destinationOffset) = colorE3;
+ Unsafe.Add(ref destinationPointer, destinationOffset + 1) = colorE4;
+ Unsafe.Add(ref destinationPointer, destinationOffset + 2) = colorE5;
+
+ destinationOffset += destinationWidth;
+ Unsafe.Add(ref destinationPointer, destinationOffset) = colorE6;
+ Unsafe.Add(ref destinationPointer, destinationOffset + 1) = colorE7;
+ Unsafe.Add(ref destinationPointer, destinationOffset + 2) = colorE8;
}
}
diff --git a/src/Greenshot.PerformanceTests/GfxPerformance.cs b/src/Greenshot.PerformanceTests/GfxPerformance.cs
index d732a7a07..51146d1fc 100644
--- a/src/Greenshot.PerformanceTests/GfxPerformance.cs
+++ b/src/Greenshot.PerformanceTests/GfxPerformance.cs
@@ -21,8 +21,7 @@ namespace Greenshot.PerformanceTests
{
_unmanagedTestBitmap = new UnmanagedBitmap(400, 400);
_unmanagedTestBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0});
- using (var bitmap = _unmanagedTestBitmap.NativeBitmap)
- using (var graphics = Graphics.FromImage(bitmap))
+ using (var graphics = Graphics.FromImage(_unmanagedTestBitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
@@ -57,7 +56,7 @@ namespace Greenshot.PerformanceTests
}
}
- //[Benchmark]
+ [Benchmark]
public void Blur_FastBitmap()
{
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White))
@@ -71,14 +70,13 @@ namespace Greenshot.PerformanceTests
}
}
- //[Benchmark]
+ [Benchmark]
public void Blur_UnmanagedBitmap()
{
using (var unmanagedBitmap = new UnmanagedBitmap(400, 400))
{
unmanagedBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 });
- using (var bitmap = unmanagedBitmap.NativeBitmap)
- using (var graphics = Graphics.FromImage(bitmap))
+ using (var graphics = Graphics.FromImage(unmanagedBitmap.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
@@ -89,7 +87,7 @@ namespace Greenshot.PerformanceTests
}
- //[Benchmark]
+ [Benchmark]
public void Blur_Old()
{
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White))
@@ -121,19 +119,19 @@ namespace Greenshot.PerformanceTests
_unmanagedTestBitmap.Scale2XReference().Dispose();
}
- [Benchmark]
+ //[Benchmark]
public void Scale3x_FastBitmap()
{
ScaleX.Scale3X(_unmanagedTestBitmap).Dispose();
}
- [Benchmark]
+ //[Benchmark]
public void Scale3x_Unmanaged()
{
_unmanagedTestBitmap.Scale3X().Dispose();
}
- [Benchmark]
+ //[Benchmark]
public void Scale3x_Unmanaged_Reference()
{
_unmanagedTestBitmap.Scale3XReference().Dispose();
diff --git a/src/Greenshot.PerformanceTests/Program.cs b/src/Greenshot.PerformanceTests/Program.cs
index 0751610e9..bc15e4b61 100644
--- a/src/Greenshot.PerformanceTests/Program.cs
+++ b/src/Greenshot.PerformanceTests/Program.cs
@@ -30,8 +30,8 @@ namespace Greenshot.PerformanceTests
// ReSharper disable once UnusedParameter.Local
private static void Main(string[] args)
{
- //BenchmarkRunner.Run();
- BenchmarkRunner.Run();
+ BenchmarkRunner.Run();
+ //BenchmarkRunner.Run();
Console.ReadLine();
}
}
diff --git a/src/Greenshot.Tests/BlurTests.cs b/src/Greenshot.Tests/BlurTests.cs
index 3a35bf55a..3efab433b 100644
--- a/src/Greenshot.Tests/BlurTests.cs
+++ b/src/Greenshot.Tests/BlurTests.cs
@@ -70,19 +70,18 @@ namespace Greenshot.Tests
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
- BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10);
}
+ BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10);
bitmapOld.NativeBitmap.Save(@"old.png", ImageFormat.Png);
bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 });
- using (var bitmap = bitmapNew.NativeBitmap)
- using (var graphics = Graphics.FromImage(bitmap))
+ using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
- bitmapNew.ApplyBoxBlur(10);
- bitmap.Save(@"new.png", ImageFormat.Png);
}
+ bitmapNew.ApplyBoxBlur(10);
+ bitmapNew.NativeBitmap.Save(@"new.png", ImageFormat.Png);
Assert.True(bitmapOld.IsEqualTo(bitmapNew), "New blur doesn't compare to old.");
}
diff --git a/src/Greenshot.Tests/ScaleXTests.cs b/src/Greenshot.Tests/ScaleXTests.cs
index 86c69972e..742e0643e 100644
--- a/src/Greenshot.Tests/ScaleXTests.cs
+++ b/src/Greenshot.Tests/ScaleXTests.cs
@@ -37,7 +37,7 @@ namespace Greenshot.Tests
{
LogSettings.RegisterDefaultLogger(LogLevels.Verbose, testOutputHelper);
}
-
+
[Fact]
public void Test_Scale2X_UnmanagedBitmap()
{
@@ -50,8 +50,7 @@ namespace Greenshot.Tests
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0 });
- using (var bitmap = bitmapNew.NativeBitmap)
- using (var graphics = Graphics.FromImage(bitmap))
+ using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
@@ -78,13 +77,12 @@ namespace Greenshot.Tests
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
}
bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0 });
- using (var bitmap = bitmapNew.NativeBitmap)
- using (var graphics = Graphics.FromImage(bitmap))
+ using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap))
using (var pen = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340));
using (var scaledUnmanagedBitmap = bitmapNew.Scale3X())
- using (var scaledBitmap = ScaleX.Scale2X(bitmapOld))
+ using (var scaledBitmap = ScaleX.Scale3X(bitmapOld))
{
scaledUnmanagedBitmap.NativeBitmap.Save(@"new3x.png", ImageFormat.Png);
scaledBitmap.NativeBitmap.Save(@"old3x.png", ImageFormat.Png);