From 585d49513d9471640d22308aeadeb765884d1d51 Mon Sep 17 00:00:00 2001 From: Jmerk523 <47197320+Jmerk523@users.noreply.github.com> Date: Sat, 27 Apr 2019 14:01:45 -0700 Subject: [PATCH 1/2] Fix StackOverflowException in ZhangSuenSkeletonization for large images Limited stack size may cause a StackOverflowException for large stackalloc. Replace usage with native memory --- .../Filters/Other/ZhangSuenSkeletonization.cs | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs b/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs index c35aef166..671e50739 100644 --- a/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs +++ b/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs @@ -29,8 +29,11 @@ namespace Accord.Imaging.Filters using Accord.Imaging; using Accord.Imaging.Filters; using System.Collections.Generic; + using System; using System.Drawing; using System.Drawing.Imaging; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; /// /// Zhang-Suen skeletonization filter. @@ -150,39 +153,50 @@ protected override unsafe void ProcessFilter(UnmanagedImage source, UnmanagedIma // do the job var dst0 = (byte*)destination.ImageData.ToPointer(); - var del0 = stackalloc byte[delSize]; for (var i = 0; i < delSize; i++) del0[i] = 0xFF; - bool endOfAlgorithm; + IntPtr delPtr = IntPtr.Zero; + RuntimeHelpers.PrepareConstrainedRegions(); + try + { + delPtr = Marshal.AllocHGlobal(delSize); + var del0 = (byte*)delPtr.ToPointer(); for (var i = 0; i < delSize; i++) del0[i] = 0xFF; + + bool endOfAlgorithm; - do + do + { + endOfAlgorithm = true; + + // Setp 1 + Process(startX, startY, stopX, stopY, + dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstStride, dstOffset, + del0, + new[] { 1, 3, 5, 3, 5, 7 }, + ref endOfAlgorithm); + + // Deletion + delete(startX, startY, stopX, stopY, + dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstOffset, + del0); + + // Setp 2 + Process(startX, startY, stopX, stopY, + dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstStride, dstOffset, + del0, + new[] { 1, 3, 7, 1, 5, 7 }, + ref endOfAlgorithm); + + // Deletion + delete(startX, startY, stopX, stopY, + dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstOffset, + del0); + + } while (!endOfAlgorithm); + } + finally { - endOfAlgorithm = true; - - // Setp 1 - Process(startX, startY, stopX, stopY, - dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstStride, dstOffset, - del0, - new[] { 1, 3, 5, 3, 5, 7 }, - ref endOfAlgorithm); - - // Deletion - delete(startX, startY, stopX, stopY, - dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstOffset, - del0); - - // Setp 2 - Process(startX, startY, stopX, stopY, - dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstStride, dstOffset, - del0, - new[] { 1, 3, 7, 1, 5, 7 }, - ref endOfAlgorithm); - - // Deletion - delete(startX, startY, stopX, stopY, - dst0 + (rect.Top + 1) * dstStride + rect.Left + 1, dstOffset, - del0); - - } while (!endOfAlgorithm); + Marshal.FreeHGlobal(delPtr); + } #region Set colors From 26b2c46d97787e259d959b1f689757c0dc7bee66 Mon Sep 17 00:00:00 2001 From: Jmerk523 <47197320+Jmerk523@users.noreply.github.com> Date: Sat, 27 Apr 2019 14:14:47 -0700 Subject: [PATCH 2/2] Correct using statement ordering --- .../AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs b/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs index 671e50739..32bfaa184 100644 --- a/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs +++ b/Sources/Accord.Imaging/AForge.Imaging/Filters/Other/ZhangSuenSkeletonization.cs @@ -28,8 +28,8 @@ namespace Accord.Imaging.Filters { using Accord.Imaging; using Accord.Imaging.Filters; - using System.Collections.Generic; using System; + using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.CompilerServices;