EdgeDetection.cpp
1 #include "pch.h" 2 3 #include "constants.h" 4 #include "EdgeDetection.h" 5 6 template<bool PerChannel, 7 bool IsX, 8 bool Increment> 9 inline long FindEdge(const BGRATextureView& texture, const POINT centerPoint, const uint8_t tolerance) 10 { 11 using namespace consts; 12 13 const size_t maxDim = IsX ? texture.width : texture.height; 14 15 long x = std::clamp<long>(centerPoint.x, 1, static_cast<long>(texture.width - 2)); 16 long y = std::clamp<long>(centerPoint.y, 1, static_cast<long>(texture.height - 2)); 17 18 const uint32_t startPixel = texture.GetPixel(x, y); 19 while (true) 20 { 21 long oldX = x; 22 long oldY = y; 23 if constexpr (IsX) 24 { 25 if constexpr (Increment) 26 { 27 if (++x == maxDim) 28 break; 29 } 30 else 31 { 32 if (--x == 0) 33 break; 34 } 35 } 36 else 37 { 38 if constexpr (Increment) 39 { 40 if (++y == maxDim) 41 break; 42 } 43 else 44 { 45 if (--y == 0) 46 break; 47 } 48 } 49 50 const uint32_t nextPixel = texture.GetPixel(x, y); 51 if (!texture.PixelsClose<PerChannel>(startPixel, nextPixel, tolerance)) 52 { 53 return IsX ? oldX : oldY; 54 } 55 } 56 57 return Increment ? static_cast<long>(IsX ? texture.width : texture.height) - 1 : 0; 58 } 59 60 template<bool PerChannel> 61 inline RECT DetectEdgesInternal(const BGRATextureView& texture, 62 const POINT centerPoint, 63 const uint8_t tolerance) 64 { 65 return RECT{ .left = FindEdge<PerChannel, 66 true, 67 false>(texture, centerPoint, tolerance), 68 .top = FindEdge<PerChannel, 69 false, 70 false>(texture, centerPoint, tolerance), 71 .right = FindEdge<PerChannel, 72 true, 73 true>(texture, centerPoint, tolerance), 74 .bottom = FindEdge<PerChannel, 75 false, 76 true>(texture, centerPoint, tolerance) }; 77 } 78 79 RECT DetectEdges(const BGRATextureView& texture, 80 const POINT centerPoint, 81 const bool perChannel, 82 const uint8_t tolerance) 83 { 84 auto function = perChannel ? &DetectEdgesInternal<true> : DetectEdgesInternal<false>; 85 86 return function(texture, centerPoint, tolerance); 87 }