/ src / modules / MeasureTool / MeasureToolCore / EdgeDetection.cpp
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  }