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