• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&#8217;t satisfy all the requirements of iterators. For example, they don&#8217;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">&lt;</span><span class="n">Regular</span> <span class="n">Loc</span><span class="o">&gt;</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">&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>
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">&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>
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">&lt;</span><span class="n">D</span><span class="o">&gt;::</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">&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>
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">&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>
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">&lt;</span><span class="n">type</span><span class="o">&gt;</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">&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>
109  <span class="p">};</span>
110
111  <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>
112  <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>
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">&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>
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">&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>
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">&amp;</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">&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>
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">&amp;</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">&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>
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">&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>
125  <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>
126  <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>
127<span class="p">};</span>
128
129<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>
130<span class="n">concept</span> <span class="nl">MutableRandomAccessNDLocatorConcept</span>
131    <span class="p">:</span> <span class="n">RandomAccessNDLocatorConcept</span><span class="o">&lt;</span><span class="n">Loc</span><span class="o">&gt;</span>
132<span class="p">{</span>
133  <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>
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">&lt;</span><span class="n">RandomAccessNDLocatorConcept</span> <span class="n">Loc</span><span class="o">&gt;</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">&lt;</span><span class="n">point_t</span><span class="o">&gt;</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">&lt;</span><span class="mi">0</span><span class="o">&gt;::</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">&lt;</span><span class="mi">1</span><span class="o">&gt;::</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">&lt;</span><span class="mi">0</span><span class="o">&gt;::</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">&lt;</span><span class="mi">1</span><span class="o">&gt;::</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&amp; 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&amp; loc, x_coord_t, y_coord_t, bool transposed=false);</span>
153
154  <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>
155  <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>
156  <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>
157  <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>
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">&amp;</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">&amp;</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">&amp;</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">&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>
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">&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>
172<span class="p">};</span>
173
174<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>
175    <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>
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">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
182<span class="p">{</span>
183  <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>
184      <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>
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">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
194<span class="p">{</span>
195  <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>
196      <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>
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">&lt;</span><span class="n">RandomAccess2DLocatorConcept</span> <span class="n">Loc</span><span class="o">&gt;</span>
204<span class="p">{</span>
205  <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>
206  <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>
207  <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>
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">&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>
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&lt;T&gt;</a></li>
220<li><a class="reference external" href="reference/structboost_1_1gil_1_1_has_transposed_type_concept.html">HasTransposedTypeConcept&lt;T&gt;</a></li>
221<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>
222<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>
223<li><a class="reference external" href="reference/structboost_1_1gil_1_1_random_access2_d_locator_concept.html">RandomAccess2DLocatorConcept&lt;Locator&gt;</a></li>
224<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>
225<li><a class="reference external" href="reference/structboost_1_1gil_1_1_pixel_locator_concept.html">PixelLocatorConcept&lt;Locator&gt;</a></li>
226<li><a class="reference external" href="reference/structboost_1_1gil_1_1_mutable_pixel_locator_concept.html">MutablePixelLocatorConcept&lt;Locator&gt;</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">&lt;</span><span class="k">typename</span> <span class="n">StepIterator</span><span class="o">&gt;</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&lt;T,C&gt;*</span></code> - for interleaved images</li>
255<li><code class="docutils literal"><span class="pre">planar_pixel_iterator&lt;T*,C&gt;</span></code> - for planar images</li>
256<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
257non-standard step)</li>
258<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
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&lt;XIterator&gt;</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&lt;memory_based_step_iterator&lt;XIterator&gt;</span> <span class="pre">&gt;</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">&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>
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&#8217;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 &#8220;carriage return&#8221;. Synopsis:</p>
319<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>
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">&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>
324
325  <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>
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>