pixel_locator.html 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <title>Pixel Locator - Boost.GIL documentation</title>
  7. <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
  8. <link rel="stylesheet" href="../_static/style.css" type="text/css" />
  9. <script type="text/javascript">
  10. var DOCUMENTATION_OPTIONS = {
  11. URL_ROOT: '../',
  12. VERSION: '',
  13. COLLAPSE_MODINDEX: false,
  14. FILE_SUFFIX: '.html'
  15. };
  16. </script>
  17. <script type="text/javascript" src="../_static/jquery.js"></script>
  18. <script type="text/javascript" src="../_static/underscore.js"></script>
  19. <script type="text/javascript" src="../_static/doctools.js"></script>
  20. <link rel="index" title="Index" href="../genindex.html" />
  21. <link rel="search" title="Search" href="../search.html" />
  22. <link rel="top" title="Boost.GIL documentation" href="../index.html" />
  23. <link rel="up" title="Design Guide" href="index.html" />
  24. <link rel="next" title="Image View" href="image_view.html" />
  25. <link rel="prev" title="Pixel Iterator" href="pixel_iterator.html" />
  26. </head>
  27. <body>
  28. <div class="header">
  29. <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
  30. "header">
  31. <tr>
  32. <td valign="top" width="300">
  33. <h3><a href="../index.html"><img
  34. alt="C++ Boost" src="../_static/gil.png" border="0"></a></h3>
  35. </td>
  36. <td >
  37. <h1 align="center"><a href="../index.html"></a></h1>
  38. </td>
  39. <td>
  40. <div id="searchbox" style="display: none">
  41. <form class="search" action="../search.html" method="get">
  42. <input type="text" name="q" size="18" />
  43. <input type="submit" value="Search" />
  44. <input type="hidden" name="check_keywords" value="yes" />
  45. <input type="hidden" name="area" value="default" />
  46. </form>
  47. </div>
  48. <script type="text/javascript">$('#searchbox').show(0);</script>
  49. </td>
  50. </tr>
  51. </table>
  52. </div>
  53. <hr/>
  54. <div class="content">
  55. <div class="navbar" style="text-align:right;">
  56. <a class="prev" title="Pixel Iterator" href="pixel_iterator.html"><img src="../_static/prev.png" alt="prev"/></a>
  57. <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
  58. <a class="next" title="Image View" href="image_view.html"><img src="../_static/next.png" alt="next"/></a>
  59. </div>
  60. <div class="section" id="pixel-locator">
  61. <h1>Pixel Locator</h1>
  62. <div class="contents local topic" id="contents">
  63. <ul class="simple">
  64. <li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
  65. <li><a class="reference internal" href="#models" id="id2">Models</a></li>
  66. <li><a class="reference internal" href="#iterator-over-2d-image" id="id3">Iterator over 2D image</a></li>
  67. </ul>
  68. </div>
  69. <div class="section" id="overview">
  70. <h2><a class="toc-backref" href="#id1">Overview</a></h2>
  71. <p>A Locator allows for navigation in two or more dimensions. Locators are
  72. N-dimensional iterators in spirit, but we use a different name because they
  73. don&#8217;t satisfy all the requirements of iterators. For example, they don&#8217;t
  74. supply increment and decrement operators because it is unclear which dimension
  75. the operators should advance along.
  76. N-dimensional locators model the following concept:</p>
  77. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">concept</span> <span class="n">RandomAccessNDLocatorConcept</span><span class="o">&lt;</span><span class="n">Regular</span> <span class="n">Loc</span><span class="o">&gt;</span>
  78. <span class="p">{</span>
  79. <span class="k">typename</span> <span class="n">value_type</span><span class="p">;</span> <span class="c1">// value over which the locator navigates</span>
  80. <span class="k">typename</span> <span class="n">reference</span><span class="p">;</span> <span class="c1">// result of dereferencing</span>
  81. <span class="k">typename</span> <span class="n">difference_type</span><span class="p">;</span> <span class="n">where</span> <span class="n">PointNDConcept</span><span class="o">&lt;</span><span class="n">difference_type</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// return value of operator-.</span>
  82. <span class="k">typename</span> <span class="n">const_t</span><span class="p">;</span> <span class="c1">// same as Loc, but operating over immutable values</span>
  83. <span class="k">typename</span> <span class="n">cached_location_t</span><span class="p">;</span> <span class="c1">// type to store relative location (for efficient repeated access)</span>
  84. <span class="k">typename</span> <span class="n">point_t</span> <span class="o">=</span> <span class="n">difference_type</span><span class="p">;</span>
  85. <span class="k">static</span> <span class="k">const</span> <span class="kt">size_t</span> <span class="n">num_dimensions</span><span class="p">;</span> <span class="c1">// dimensionality of the locator</span>
  86. <span class="n">where</span> <span class="n">num_dimensions</span> <span class="o">=</span> <span class="n">point_t</span><span class="o">::</span><span class="n">num_dimensions</span><span class="p">;</span>
  87. <span class="c1">// The difference_type and iterator type along each dimension. The iterators may only differ in</span>
  88. <span class="c1">// difference_type. Their value_type must be the same as Loc::value_type</span>
  89. <span class="k">template</span> <span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">D</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">axis</span> <span class="p">{</span>
  90. <span class="k">typename</span> <span class="n">coord_t</span> <span class="o">=</span> <span class="n">point_t</span><span class="o">::</span><span class="n">axis</span><span class="o">&lt;</span><span class="n">D</span><span class="o">&gt;::</span><span class="n">coord_t</span><span class="p">;</span>
  91. <span class="k">typename</span> <span class="n">iterator</span><span class="p">;</span> <span class="n">where</span> <span class="n">RandomAccessTraversalConcept</span><span class="o">&lt;</span><span class="n">iterator</span><span class="o">&gt;</span><span class="p">;</span> <span class="c1">// iterator along D-th axis.</span>
  92. <span class="n">where</span> <span class="n">iterator</span><span class="o">::</span><span class="n">value_type</span> <span class="o">==</span> <span class="n">value_type</span><span class="p">;</span>
  93. <span class="p">};</span>
  94. <span class="c1">// Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing</span>
  95. <span class="k">template</span> <span class="o">&lt;</span><span class="n">PixelDereferenceAdaptorConcept</span> <span class="n">Deref</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">add_deref</span> <span class="p">{</span>
  96. <span class="k">typename</span> <span class="n">type</span><span class="p">;</span> <span class="n">where</span> <span class="n">RandomAccessNDLocatorConcept</span><span class="o">&lt;</span><span class="n">type</span><span class="o">&gt;</span><span class="p">;</span>
  97. <span class="k">static</span> <span class="n">type</span> <span class="nf">make</span><span class="p">(</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span> <span class="n">loc</span><span class="p">,</span> <span class="k">const</span> <span class="n">Deref</span><span class="o">&amp;</span> <span class="n">deref</span><span class="p">);</span>
  98. <span class="p">};</span>
  99. <span class="n">Loc</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">+=</span><span class="p">(</span><span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">);</span>
  100. <span class="n">Loc</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">-=</span><span class="p">(</span><span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">);</span>
  101. <span class="n">Loc</span> <span class="k">operator</span><span class="o">+</span><span class="p">(</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">);</span>
  102. <span class="n">Loc</span> <span class="k">operator</span><span class="o">-</span><span class="p">(</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">);</span>
  103. <span class="n">reference</span> <span class="k">operator</span><span class="o">*</span><span class="p">(</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span><span class="p">);</span>
  104. <span class="n">reference</span> <span class="k">operator</span><span class="p">[](</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span> <span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">);</span>
  105. <span class="c1">// Storing relative location for faster repeated access and accessing it</span>
  106. <span class="n">cached_location_t</span> <span class="n">Loc</span><span class="o">::</span><span class="n">cache_location</span><span class="p">(</span><span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  107. <span class="n">reference</span> <span class="k">operator</span><span class="p">[](</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span><span class="k">const</span> <span class="n">cached_location_t</span><span class="o">&amp;</span><span class="p">);</span>
  108. <span class="c1">// Accessing iterators along a given dimension at the current location or at a given offset</span>
  109. <span class="k">template</span> <span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">D</span><span class="o">&gt;</span> <span class="n">axis</span><span class="o">&lt;</span><span class="n">D</span><span class="o">&gt;::</span><span class="n">iterator</span><span class="o">&amp;</span> <span class="n">Loc</span><span class="o">::</span><span class="n">axis_iterator</span><span class="p">();</span>
  110. <span class="k">template</span> <span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">D</span><span class="o">&gt;</span> <span class="n">axis</span><span class="o">&lt;</span><span class="n">D</span><span class="o">&gt;::</span><span class="n">iterator</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">Loc</span><span class="o">::</span><span class="n">axis_iterator</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
  111. <span class="k">template</span> <span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">D</span><span class="o">&gt;</span> <span class="n">axis</span><span class="o">&lt;</span><span class="n">D</span><span class="o">&gt;::</span><span class="n">iterator</span> <span class="n">Loc</span><span class="o">::</span><span class="n">axis_iterator</span><span class="p">(</span><span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  112. <span class="p">};</span>
  113. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Loc</span><span class="o">&gt;</span>
  114. <span class="n">concept</span> <span class="nl">MutableRandomAccessNDLocatorConcept</span>
  115. <span class="p">:</span> <span class="n">RandomAccessNDLocatorConcept</span><span class="o">&lt;</span><span class="n">Loc</span><span class="o">&gt;</span>
  116. <span class="p">{</span>
  117. <span class="n">where</span> <span class="n">Mutable</span><span class="o">&lt;</span><span class="n">reference</span><span class="o">&gt;</span><span class="p">;</span>
  118. <span class="p">};</span>
  119. </pre></div>
  120. </div>
  121. <p>Two-dimensional locators have additional requirements:</p>
  122. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">concept</span> <span class="n">RandomAccess2DLocatorConcept</span><span class="o">&lt;</span><span class="n">RandomAccessNDLocatorConcept</span> <span class="n">Loc</span><span class="o">&gt;</span>
  123. <span class="p">{</span>
  124. <span class="n">where</span> <span class="n">num_dimensions</span><span class="o">==</span><span class="mi">2</span><span class="p">;</span>
  125. <span class="n">where</span> <span class="n">Point2DConcept</span><span class="o">&lt;</span><span class="n">point_t</span><span class="o">&gt;</span><span class="p">;</span>
  126. <span class="k">typename</span> <span class="n">x_iterator</span> <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;::</span><span class="n">iterator</span><span class="p">;</span>
  127. <span class="k">typename</span> <span class="n">y_iterator</span> <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;::</span><span class="n">iterator</span><span class="p">;</span>
  128. <span class="k">typename</span> <span class="n">x_coord_t</span> <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;::</span><span class="n">coord_t</span><span class="p">;</span>
  129. <span class="k">typename</span> <span class="n">y_coord_t</span> <span class="o">=</span> <span class="n">axis</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;::</span><span class="n">coord_t</span><span class="p">;</span>
  130. <span class="c1">// Only available to locators that have dynamic step in Y</span>
  131. <span class="c1">//Loc::Loc(const Loc&amp; loc, y_coord_t);</span>
  132. <span class="c1">// Only available to locators that have dynamic step in X and Y</span>
  133. <span class="c1">//Loc::Loc(const Loc&amp; loc, x_coord_t, y_coord_t, bool transposed=false);</span>
  134. <span class="n">x_iterator</span><span class="o">&amp;</span> <span class="n">Loc</span><span class="o">::</span><span class="n">x</span><span class="p">();</span>
  135. <span class="n">x_iterator</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">Loc</span><span class="o">::</span><span class="n">x</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
  136. <span class="n">y_iterator</span><span class="o">&amp;</span> <span class="n">Loc</span><span class="o">::</span><span class="n">y</span><span class="p">();</span>
  137. <span class="n">y_iterator</span> <span class="k">const</span><span class="o">&amp;</span> <span class="n">Loc</span><span class="o">::</span><span class="n">y</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
  138. <span class="n">x_iterator</span> <span class="n">Loc</span><span class="o">::</span><span class="n">x_at</span><span class="p">(</span><span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  139. <span class="n">y_iterator</span> <span class="n">Loc</span><span class="o">::</span><span class="n">y_at</span><span class="p">(</span><span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  140. <span class="n">Loc</span> <span class="n">Loc</span><span class="o">::</span><span class="n">xy_at</span><span class="p">(</span><span class="k">const</span> <span class="n">difference_type</span><span class="o">&amp;</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  141. <span class="c1">// x/y versions of all methods that can take difference type</span>
  142. <span class="n">x_iterator</span> <span class="n">Loc</span><span class="o">::</span><span class="n">x_at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span> <span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  143. <span class="n">y_iterator</span> <span class="n">Loc</span><span class="o">::</span><span class="n">y_at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span> <span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  144. <span class="n">Loc</span> <span class="n">Loc</span><span class="o">::</span><span class="n">xy_at</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span> <span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  145. <span class="n">reference</span> <span class="nf">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">x_coord_t</span><span class="p">,</span> <span class="n">y_coord_t</span><span class="p">);</span>
  146. <span class="n">cached_location_t</span> <span class="n">Loc</span><span class="o">::</span><span class="n">cache_location</span><span class="p">(</span><span class="n">x_coord_t</span><span class="p">,</span> <span class="n">y_coord_t</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  147. <span class="kt">bool</span> <span class="n">Loc</span><span class="o">::</span><span class="n">is_1d_traversable</span><span class="p">(</span><span class="n">x_coord_t</span> <span class="n">width</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  148. <span class="n">y_coord_t</span> <span class="n">Loc</span><span class="o">::</span><span class="n">y_distance_to</span><span class="p">(</span><span class="k">const</span> <span class="n">Loc</span><span class="o">&amp;</span> <span class="n">loc2</span><span class="p">,</span> <span class="n">x_coord_t</span> <span class="n">x_diff</span><span class="p">)</span> <span class="k">const</span><span class="p">;</span>
  149. <span class="p">};</span>
  150. <span class="n">concept</span> <span class="n">MutableRandomAccess2DLocatorConcept</span><span class="o">&lt;</span><span class="n">RandomAccess2DLocatorConcept</span> <span class="n">Loc</span><span class="o">&gt;</span>
  151. <span class="o">:</span> <span class="n">MutableRandomAccessNDLocatorConcept</span><span class="o">&lt;</span><span class="n">Loc</span><span class="o">&gt;</span> <span class="p">{};</span>
  152. </pre></div>
  153. </div>
  154. <p>2D locators can have a dynamic step not just horizontally, but
  155. vertically. This gives rise to the Y equivalent of
  156. <code class="docutils literal"><span class="pre">HasDynamicXStepTypeConcept</span></code>:</p>
  157. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">concept</span> <span class="n">HasDynamicYStepTypeConcept</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
  158. <span class="p">{</span>
  159. <span class="k">typename</span> <span class="n">dynamic_y_step_type</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
  160. <span class="n">where</span> <span class="n">Metafunction</span><span class="o">&lt;</span><span class="n">dynamic_y_step_type</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">;</span>
  161. <span class="p">};</span>
  162. </pre></div>
  163. </div>
  164. <p>All locators and image views that GIL provides model
  165. <code class="docutils literal"><span class="pre">HasDynamicYStepTypeConcept</span></code>.</p>
  166. <p>Sometimes it is necessary to swap the meaning of X and Y for a given locator
  167. or image view type (for example, GIL provides a function to transpose an image
  168. view). Such locators and views must be transposable:</p>
  169. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">concept</span> <span class="n">HasTransposedTypeConcept</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
  170. <span class="p">{</span>
  171. <span class="k">typename</span> <span class="n">transposed_type</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
  172. <span class="n">where</span> <span class="n">Metafunction</span><span class="o">&lt;</span><span class="n">transposed_type</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">&gt;</span><span class="p">;</span>
  173. <span class="p">};</span>
  174. </pre></div>
  175. </div>
  176. <p>All GIL provided locators and views model <code class="docutils literal"><span class="pre">HasTransposedTypeConcept</span></code>.</p>
  177. <p>The locators GIL uses operate over models of <code class="docutils literal"><span class="pre">PixelConcept</span></code> and their x and
  178. y dimension types are the same. They model the following concept:</p>
  179. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">concept</span> <span class="n">PixelLocatorConcept</span><span class="o">&lt;</span><span class="n">RandomAccess2DLocatorConcept</span> <span class="n">Loc</span><span class="o">&gt;</span>
  180. <span class="p">{</span>
  181. <span class="n">where</span> <span class="n">PixelValueConcept</span><span class="o">&lt;</span><span class="n">value_type</span><span class="o">&gt;</span><span class="p">;</span>
  182. <span class="n">where</span> <span class="n">PixelIteratorConcept</span><span class="o">&lt;</span><span class="n">x_iterator</span><span class="o">&gt;</span><span class="p">;</span>
  183. <span class="n">where</span> <span class="n">PixelIteratorConcept</span><span class="o">&lt;</span><span class="n">y_iterator</span><span class="o">&gt;</span><span class="p">;</span>
  184. <span class="n">where</span> <span class="n">x_coord_t</span> <span class="o">==</span> <span class="n">y_coord_t</span><span class="p">;</span>
  185. <span class="k">typename</span> <span class="n">coord_t</span> <span class="o">=</span> <span class="n">x_coord_t</span><span class="p">;</span>
  186. <span class="p">};</span>
  187. <span class="n">concept</span> <span class="n">MutablePixelLocatorConcept</span><span class="o">&lt;</span><span class="n">PixelLocatorConcept</span> <span class="n">Loc</span><span class="o">&gt;</span> <span class="o">:</span> <span class="n">MutableRandomAccess2DLocatorConcept</span><span class="o">&lt;</span><span class="n">Loc</span><span class="o">&gt;</span> <span class="p">{};</span>
  188. </pre></div>
  189. </div>
  190. <div class="admonition seealso">
  191. <p class="first admonition-title">See also</p>
  192. <ul class="last simple">
  193. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_has_dynamic_y_step_type_concept.html">HasDynamicYStepTypeConcept&lt;T&gt;</a></li>
  194. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_has_transposed_type_concept.html">HasTransposedTypeConcept&lt;T&gt;</a></li>
  195. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_random_access_n_d_locator_concept.html">RandomAccessNDLocatorConcept&lt;Locator&gt;</a></li>
  196. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_random_access_n_d_locator_concept.html">MutableRandomAccessNDLocatorConcept&lt;Locator&gt;</a></li>
  197. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_random_access2_d_locator_concept.html">RandomAccess2DLocatorConcept&lt;Locator&gt;</a></li>
  198. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_random_access2_d_locator_concept.html">MutableRandomAccess2DLocatorConcept&lt;Locator&gt;</a></li>
  199. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_pixel_locator_concept.html">PixelLocatorConcept&lt;Locator&gt;</a></li>
  200. <li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_pixel_locator_concept.html">MutablePixelLocatorConcept&lt;Locator&gt;</a></li>
  201. </ul>
  202. </div>
  203. </div>
  204. <div class="section" id="models">
  205. <h2><a class="toc-backref" href="#id2">Models</a></h2>
  206. <p>GIL provides two models of <code class="docutils literal"><span class="pre">PixelLocatorConcept</span></code> - a memory-based locator,
  207. <code class="docutils literal"><span class="pre">memory_based_2d_locator</span></code> and a virtual locator <code class="docutils literal"><span class="pre">virtual_2d_locator</span></code>.</p>
  208. <p>The <code class="docutils literal"><span class="pre">memory_based_2d_locator</span></code> is a locator over planar or interleaved images
  209. that have their pixels in memory. It takes a model of <code class="docutils literal"><span class="pre">StepIteratorConcept</span></code>
  210. over pixels as a template parameter. (When instantiated with a model of
  211. <code class="docutils literal"><span class="pre">MutableStepIteratorConcept</span></code>, it models <code class="docutils literal"><span class="pre">MutablePixelLocatorConcept</span></code>).</p>
  212. <div class="highlight-cpp"><div class="highlight"><pre><span class="c1">// StepIterator models StepIteratorConcept, MemoryBasedIteratorConcept</span>
  213. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">StepIterator</span><span class="o">&gt;</span>
  214. <span class="k">class</span> <span class="nc">memory_based_2d_locator</span><span class="p">;</span>
  215. </pre></div>
  216. </div>
  217. <p>The step of <code class="docutils literal"><span class="pre">StepIterator</span></code> must be the number of memory units (bytes or
  218. bits) per row (thus it must be memunit advanceable). The class
  219. <code class="docutils literal"><span class="pre">memory_based_2d_locator</span></code> is a wrapper around <code class="docutils literal"><span class="pre">StepIterator</span></code> and uses it
  220. to navigate vertically, while its base iterator is used to navigate
  221. horizontally.</p>
  222. <p>Combining fundamental iterator and step iterator allows us to create locators
  223. that describe complex pixel memory organizations. First, we have a choice of
  224. iterator to use for horizontal direction, i.e. for iterating over the pixels
  225. on the same row. Using the fundamental and step iterators gives us four
  226. choices:</p>
  227. <ul class="simple">
  228. <li><code class="docutils literal"><span class="pre">pixel&lt;T,C&gt;*</span></code> - for interleaved images</li>
  229. <li><code class="docutils literal"><span class="pre">planar_pixel_iterator&lt;T*,C&gt;</span></code> - for planar images</li>
  230. <li><code class="docutils literal"><span class="pre">memory_based_step_iterator&lt;pixel&lt;T,C&gt;*&gt;</span></code> - for interleaved images with
  231. non-standard step)</li>
  232. <li><code class="docutils literal"><span class="pre">memory_based_step_iterator&lt;planar_pixel_iterator&lt;T*,C&gt;</span> <span class="pre">&gt;</span></code> - for planar
  233. images with non-standard step</li>
  234. </ul>
  235. <p>Of course, one could provide their own custom x-iterator. One such example
  236. described later is an iterator adaptor that performs color conversion when
  237. dereferenced.</p>
  238. <p>Given a horizontal iterator <code class="docutils literal"><span class="pre">XIterator</span></code>, we could choose the <code class="docutils literal"><span class="pre">y-iterator</span></code>,
  239. the iterator that moves along a column, as
  240. <code class="docutils literal"><span class="pre">memory_based_step_iterator&lt;XIterator&gt;</span></code> with a step equal to the number of
  241. memory units (bytes or bits) per row. Again, one is free to provide their own
  242. y-iterator.</p>
  243. <p>Then we can instantiate
  244. <code class="docutils literal"><span class="pre">memory_based_2d_locator&lt;memory_based_step_iterator&lt;XIterator&gt;</span> <span class="pre">&gt;</span></code> to obtain
  245. a 2D pixel locator, as the diagram indicates:</p>
  246. <img alt="../_images/pixel_locator.gif" src="../_images/pixel_locator.gif" />
  247. <p>The <code class="docutils literal"><span class="pre">memory_based_2d_locator</span></code> also offers <cite>cached_location_t</cite> as mechanism
  248. to store relative locations for optimized repeated access of neighborhood
  249. pixels. The 2D coordinates of relative locations are cached as 1-dimensional
  250. raw byte offsets. This provides efficient access if a neighboring locations
  251. relative to a given locator are read or written frequently (e.g. in filters).</p>
  252. <p>The <code class="docutils literal"><span class="pre">virtual_2d_locator</span></code> is a locator that is instantiated with a function
  253. object invoked upon dereferencing a pixel. It returns the value of a pixel
  254. given its X,Y coordinates. Virtual locators can be used to implement virtual
  255. image views that can model any user-defined function. See the GIL tutorial for
  256. an example of using virtual locators to create a view of the Mandelbrot set.</p>
  257. <p>Both the virtual and the memory-based locators subclass from
  258. <code class="docutils literal"><span class="pre">pixel_2d_locator_base</span></code>, a base class that provides most of the interface
  259. required by <code class="docutils literal"><span class="pre">PixelLocatorConcept</span></code>. Users may find this base class useful if
  260. they need to provide other models of <code class="docutils literal"><span class="pre">PixelLocatorConcept</span></code>.</p>
  261. <p>Here is some sample code using locators:</p>
  262. <div class="highlight-cpp"><div class="highlight"><pre><span class="n">loc</span><span class="o">=</span><span class="n">img</span><span class="p">.</span><span class="n">xy_at</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">);</span> <span class="c1">// start at pixel (x=10,y=10)</span>
  263. <span class="n">above</span><span class="o">=</span><span class="n">loc</span><span class="p">.</span><span class="n">cache_location</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// remember relative locations of neighbors above and below</span>
  264. <span class="n">below</span><span class="o">=</span><span class="n">loc</span><span class="p">.</span><span class="n">cache_location</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
  265. <span class="o">++</span><span class="n">loc</span><span class="p">.</span><span class="n">x</span><span class="p">();</span> <span class="c1">// move to (11,10)</span>
  266. <span class="n">loc</span><span class="p">.</span><span class="n">y</span><span class="p">()</span><span class="o">+=</span><span class="mi">15</span><span class="p">;</span> <span class="c1">// move to (11,25)</span>
  267. <span class="n">loc</span><span class="o">-=</span><span class="n">point</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">ptrdiff_t</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span><span class="c1">// move to (10,24)</span>
  268. <span class="o">*</span><span class="n">loc</span><span class="o">=</span><span class="p">(</span><span class="n">loc</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">loc</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span> <span class="c1">// set pixel (10,24) to the average of (10,23) and (10,25) (grayscale pixels only)</span>
  269. <span class="o">*</span><span class="n">loc</span><span class="o">=</span><span class="p">(</span><span class="n">loc</span><span class="p">[</span><span class="n">above</span><span class="p">]</span><span class="o">+</span><span class="n">loc</span><span class="p">[</span><span class="n">below</span><span class="p">])</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span> <span class="c1">// the same, but faster using cached relative neighbor locations</span>
  270. </pre></div>
  271. </div>
  272. <p>The standard GIL locators are fast and lightweight objects. For example, the
  273. locator for a simple interleaved image consists of one raw pointer to the
  274. pixel location plus one integer for the row size in bytes, for a total of
  275. 8 bytes. <code class="docutils literal"><span class="pre">++loc.x()</span></code> amounts to incrementing a raw pointer (or N pointers
  276. for planar images). Computing 2D offsets is slower as it requires
  277. multiplication and addition. Filters, for example, need to access the same
  278. neighbors for every pixel in the image, in which case the relative positions
  279. can be cached into a raw byte difference using <code class="docutils literal"><span class="pre">cache_location</span></code>.
  280. In the above example <code class="docutils literal"><span class="pre">loc[above]</span></code> for simple interleaved images amounts to a
  281. raw array index operator.</p>
  282. </div>
  283. <div class="section" id="iterator-over-2d-image">
  284. <h2><a class="toc-backref" href="#id3">Iterator over 2D image</a></h2>
  285. <p>Sometimes we want to perform the same, location-independent operation
  286. over all pixels of an image. In such a case it is useful to represent
  287. the pixels as a one-dimensional array. GIL&#8217;s <code class="docutils literal"><span class="pre">iterator_from_2d</span></code> is a
  288. random access traversal iterator that visits all pixels in an image in
  289. the natural memory-friendly order left-to-right inside
  290. top-to-bottom. It takes a locator, the width of the image and the
  291. current X position. This is sufficient information for it to determine
  292. when to do a &#8220;carriage return&#8221;. Synopsis:</p>
  293. <div class="highlight-cpp"><div class="highlight"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Locator</span><span class="o">&gt;</span> <span class="c1">// Models PixelLocatorConcept</span>
  294. <span class="k">class</span> <span class="nc">iterator_from_2d</span>
  295. <span class="p">{</span>
  296. <span class="k">public</span><span class="o">:</span>
  297. <span class="n">iterator_from_2d</span><span class="p">(</span><span class="k">const</span> <span class="n">Locator</span><span class="o">&amp;</span> <span class="n">loc</span><span class="p">,</span> <span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">width</span><span class="p">);</span>
  298. <span class="n">iterator_from_2d</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">++</span><span class="p">();</span> <span class="c1">// if (++_x&lt;_width) ++_p.x(); else _p+=point_t(-_width,1);</span>
  299. <span class="p">...</span>
  300. <span class="k">private</span><span class="o">:</span>
  301. <span class="kt">int</span> <span class="n">_x</span><span class="p">,</span> <span class="n">_width</span><span class="p">;</span>
  302. <span class="n">Locator</span> <span class="n">_p</span><span class="p">;</span>
  303. <span class="p">};</span>
  304. </pre></div>
  305. </div>
  306. <p>Iterating through the pixels in an image using <code class="docutils literal"><span class="pre">iterator_from_2d</span></code> is slower
  307. than going through all rows and using the x-iterator at each row. This is
  308. because two comparisons are done per iteration step - one for the end
  309. condition of the loop using the iterators, and one inside
  310. <code class="docutils literal"><span class="pre">iterator_from_2d::operator++</span></code> to determine whether we are at the end of a
  311. row. For fast operations, such as pixel copy, this second check adds about
  312. 15% performance delay (measured for interleaved images on Intel platform).
  313. GIL overrides some STL algorithms, such as <code class="docutils literal"><span class="pre">std::copy</span></code> and <code class="docutils literal"><span class="pre">std::fill</span></code>,
  314. when invoked with <code class="docutils literal"><span class="pre">iterator_from_2d</span></code>-s, to go through each row using their
  315. base x-iterators, and, if the image has no padding (i.e.
  316. <code class="docutils literal"><span class="pre">iterator_from_2d::is_1d_traversable()</span></code> returns true) to simply iterate
  317. using the x-iterators directly.</p>
  318. </div>
  319. </div>
  320. <div class="navbar" style="text-align:right;">
  321. <a class="prev" title="Pixel Iterator" href="pixel_iterator.html"><img src="../_static/prev.png" alt="prev"/></a>
  322. <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
  323. <a class="next" title="Image View" href="image_view.html"><img src="../_static/next.png" alt="next"/></a>
  324. </div>
  325. </div>
  326. <div class="footer" role="contentinfo">
  327. Last updated on 2019-12-10 00:12:10.
  328. Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
  329. </div>
  330. </body>
  331. </html>