123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
- <title>Dynamic images and image views - Boost.GIL documentation</title>
- <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <link rel="stylesheet" href="../_static/style.css" type="text/css" />
- <script type="text/javascript">
- var DOCUMENTATION_OPTIONS = {
- URL_ROOT: '../',
- VERSION: '',
- COLLAPSE_MODINDEX: false,
- FILE_SUFFIX: '.html'
- };
- </script>
- <script type="text/javascript" src="../_static/jquery.js"></script>
- <script type="text/javascript" src="../_static/underscore.js"></script>
- <script type="text/javascript" src="../_static/doctools.js"></script>
- <link rel="index" title="Index" href="../genindex.html" />
- <link rel="search" title="Search" href="../search.html" />
- <link rel="top" title="Boost.GIL documentation" href="../index.html" />
- <link rel="up" title="Design Guide" href="index.html" />
- <link rel="next" title="Metafunctions" href="metafunctions.html" />
- <link rel="prev" title="Image" href="image.html" />
- </head>
- <body>
- <div class="header">
- <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
- "header">
- <tr>
- <td valign="top" width="300">
- <h3><a href="../index.html"><img
- alt="C++ Boost" src="../_static/gil.png" border="0"></a></h3>
- </td>
- <td >
- <h1 align="center"><a href="../index.html"></a></h1>
- </td>
- <td>
- <div id="searchbox" style="display: none">
- <form class="search" action="../search.html" method="get">
- <input type="text" name="q" size="18" />
- <input type="submit" value="Search" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- </div>
- <script type="text/javascript">$('#searchbox').show(0);</script>
- </td>
- </tr>
- </table>
- </div>
- <hr/>
- <div class="content">
- <div class="navbar" style="text-align:right;">
-
-
- <a class="prev" title="Image" href="image.html"><img src="../_static/prev.png" alt="prev"/></a>
- <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
- <a class="next" title="Metafunctions" href="metafunctions.html"><img src="../_static/next.png" alt="next"/></a>
-
- </div>
-
- <div class="section" id="dynamic-images-and-image-views">
- <h1>Dynamic images and image views</h1>
- <p>The GIL extension called <code class="docutils literal"><span class="pre">dynamic_image</span></code> allows for images, image views
- or any GIL constructs to have their parameters defined at run time.</p>
- <p>The color space, channel depth, channel ordering, and interleaved/planar
- structure of an image are defined by the type of its template argument, which
- makes them compile-time bound. Often some of these parameters are available
- only at run time. Consider, for example, writing a module that opens the image
- at a given file path, rotates it and saves it back in its original color space
- and channel depth. How can we possibly write this using our generic image?
- What type is the image loading code supposed to return?</p>
- <p>Here is an example:</p>
- <div class="highlight-cpp"><div class="highlight"><pre><span class="cp">#include</span> <span class="cpf"><boost/gil/extension/dynamic_image/dynamic_image_all.hpp></span><span class="cp"></span>
- <span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="p">;</span>
- <span class="cp">#define ASSERT_SAME(A,B) static_assert(is_same< A,B >::value, "")</span>
- <span class="c1">// Define the set of allowed images</span>
- <span class="k">typedef</span> <span class="n">mpl</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">rgb8_image_t</span><span class="p">,</span> <span class="n">cmyk16_planar_image_t</span><span class="o">></span> <span class="n">my_images_t</span><span class="p">;</span>
- <span class="c1">// Create any_image class (or any_image_view) class</span>
- <span class="k">typedef</span> <span class="n">any_image</span><span class="o"><</span><span class="n">my_images_t</span><span class="o">></span> <span class="n">my_any_image_t</span><span class="p">;</span>
- <span class="c1">// Associated view types are available (equivalent to the ones in image_t)</span>
- <span class="k">typedef</span> <span class="n">any_image_view</span><span class="o"><</span><span class="n">mpl</span><span class="o">::</span><span class="n">vector2</span><span class="o"><</span><span class="n">rgb8_view_t</span><span class="p">,</span> <span class="n">cmyk16_planar_view_t</span> <span class="o">></span> <span class="o">></span> <span class="n">AV</span><span class="p">;</span>
- <span class="n">ASSERT_SAME</span><span class="p">(</span><span class="n">my_any_image_t</span><span class="o">::</span><span class="n">view_t</span><span class="p">,</span> <span class="n">AV</span><span class="p">);</span>
- <span class="k">typedef</span> <span class="n">any_image_view</span><span class="o"><</span><span class="n">mpl</span><span class="o">::</span><span class="n">vector2</span><span class="o"><</span><span class="n">rgb8c_view_t</span><span class="p">,</span> <span class="n">cmyk16c_planar_view_t</span><span class="o">></span> <span class="o">></span> <span class="n">CAV</span><span class="p">;</span>
- <span class="n">ASSERT_SAME</span><span class="p">(</span><span class="n">my_any_image_t</span><span class="o">::</span><span class="n">const_view_t</span><span class="p">,</span> <span class="n">CAV</span><span class="p">);</span>
- <span class="n">ASSERT_SAME</span><span class="p">(</span><span class="n">my_any_image_t</span><span class="o">::</span><span class="n">const_view_t</span><span class="p">,</span> <span class="n">my_any_image_t</span><span class="o">::</span><span class="n">view_t</span><span class="o">::</span><span class="n">const_t</span><span class="p">);</span>
- <span class="k">typedef</span> <span class="n">any_image_view</span><span class="o"><</span><span class="n">mpl</span><span class="o">::</span><span class="n">vector2</span><span class="o"><</span><span class="n">rgb8_step_view_t</span><span class="p">,</span> <span class="n">cmyk16_planar_step_view_t</span><span class="o">></span> <span class="o">></span> <span class="n">SAV</span><span class="p">;</span>
- <span class="n">ASSERT_SAME</span><span class="p">(</span><span class="k">typename</span> <span class="n">dynamic_x_step_type</span><span class="o"><</span><span class="n">my_any_image_t</span><span class="o">::</span><span class="n">view_t</span><span class="o">>::</span><span class="n">type</span><span class="p">,</span> <span class="n">SAV</span><span class="p">);</span>
- <span class="c1">// Assign it a concrete image at run time:</span>
- <span class="n">my_any_image_t</span> <span class="n">myImg</span> <span class="o">=</span> <span class="n">my_any_image_t</span><span class="p">(</span><span class="n">rgb8_image_t</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span><span class="mi">100</span><span class="p">));</span>
- <span class="c1">// Change it to another at run time. The previous image gets destroyed</span>
- <span class="n">myImg</span> <span class="o">=</span> <span class="n">cmyk16_planar_image_t</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span><span class="mi">100</span><span class="p">);</span>
- <span class="c1">// Assigning to an image not in the allowed set throws an exception</span>
- <span class="n">myImg</span> <span class="o">=</span> <span class="n">gray8_image_t</span><span class="p">();</span> <span class="c1">// will throw std::bad_cast</span>
- </pre></div>
- </div>
- <p>The <code class="docutils literal"><span class="pre">any_image</span></code> and <code class="docutils literal"><span class="pre">any_image_view</span></code> subclass from GIL <code class="docutils literal"><span class="pre">variant</span></code> class,
- which breaks down the instantiated type into a non-templated underlying base
- type and a unique instantiation type identifier. The underlying base instance
- is represented as a block of bytes.
- The block is large enough to hold the largest of the specified types.</p>
- <p>GIL variant is similar to <code class="docutils literal"><span class="pre">boost::variant</span></code> in spirit (hence we borrow the
- name from there) but it differs in several ways from the current boost
- implementation. Perhaps the biggest difference is that GIL variant always
- takes a single argument, which is a model of MPL Random Access Sequence
- enumerating the allowed types. Having a single interface allows GIL variant
- to be used easier in generic code. Synopsis:</p>
- <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">Types</span><span class="o">></span> <span class="c1">// models MPL Random Access Container</span>
- <span class="k">class</span> <span class="nc">variant</span>
- <span class="p">{</span>
- <span class="p">...</span> <span class="n">_bits</span><span class="p">;</span>
- <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">_index</span><span class="p">;</span>
- <span class="k">public</span><span class="o">:</span>
- <span class="k">typedef</span> <span class="n">Types</span> <span class="n">types_t</span><span class="p">;</span>
- <span class="n">variant</span><span class="p">();</span>
- <span class="n">variant</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o">&</span> <span class="n">v</span><span class="p">);</span>
- <span class="k">virtual</span> <span class="o">~</span><span class="n">variant</span><span class="p">();</span>
- <span class="n">variant</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o">&</span> <span class="n">v</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">TS</span><span class="o">></span> <span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">TS</span><span class="o">>&</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">TS</span><span class="o">>&</span> <span class="n">y</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">TS</span><span class="o">></span> <span class="k">friend</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">!=</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">TS</span><span class="o">>&</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">TS</span><span class="o">>&</span> <span class="n">y</span><span class="p">);</span>
- <span class="c1">// Construct/assign to type T. Throws std::bad_cast if T is not in Types</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">explicit</span> <span class="n">variant</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="n">variant</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="c1">// Construct/assign by swapping T with its current instance. Only possible if they are swappable</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">explicit</span> <span class="n">variant</span><span class="p">(</span><span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">do_swap</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="kt">void</span> <span class="n">move_in</span><span class="p">(</span><span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">static</span> <span class="kt">bool</span> <span class="n">has_type</span><span class="p">();</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">_dynamic_cast</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="n">T</span><span class="o">&</span> <span class="n">_dynamic_cast</span><span class="p">();</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="kt">bool</span> <span class="n">current_type_is</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="p">};</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">UOP</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types</span><span class="o">></span>
- <span class="n">UOP</span><span class="o">::</span><span class="n">result_type</span> <span class="n">apply_operation</span><span class="p">(</span><span class="n">variant</span><span class="o"><</span><span class="n">Types</span><span class="o">>&</span> <span class="n">v</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">UOP</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types</span><span class="o">></span>
- <span class="n">UOP</span><span class="o">::</span><span class="n">result_type</span> <span class="n">apply_operation</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types</span><span class="o">>&</span> <span class="n">v</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">BOP</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types2</span><span class="o">></span>
- <span class="n">BOP</span><span class="o">::</span><span class="n">result_type</span> <span class="n">apply_operation</span><span class="p">(</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types1</span><span class="o">>&</span> <span class="n">v1</span><span class="p">,</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types2</span><span class="o">>&</span> <span class="n">v2</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">BOP</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types2</span><span class="o">></span>
- <span class="n">BOP</span><span class="o">::</span><span class="n">result_type</span> <span class="n">apply_operation</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types1</span><span class="o">>&</span> <span class="n">v1</span><span class="p">,</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types2</span><span class="o">>&</span> <span class="n">v2</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">BOP</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types1</span><span class="p">,</span> <span class="k">typename</span> <span class="n">Types2</span><span class="o">></span>
- <span class="n">BOP</span><span class="o">::</span><span class="n">result_type</span> <span class="n">apply_operation</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types1</span><span class="o">>&</span> <span class="n">v1</span><span class="p">,</span> <span class="k">const</span> <span class="n">variant</span><span class="o"><</span><span class="n">Types2</span><span class="o">>&</span> <span class="n">v2</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
- </pre></div>
- </div>
- <p>GIL <code class="docutils literal"><span class="pre">any_image_view</span></code> and <code class="docutils literal"><span class="pre">any_image</span></code> are subclasses of <code class="docutils literal"><span class="pre">variant</span></code>:</p>
- <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">ImageViewTypes</span><span class="o">></span>
- <span class="k">class</span> <span class="nc">any_image_view</span> <span class="o">:</span> <span class="k">public</span> <span class="n">variant</span><span class="o"><</span><span class="n">ImageViewTypes</span><span class="o">></span>
- <span class="p">{</span>
- <span class="k">public</span><span class="o">:</span>
- <span class="k">typedef</span> <span class="p">...</span> <span class="n">const_t</span><span class="p">;</span> <span class="c1">// immutable equivalent of this</span>
- <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="kt">ptrdiff_t</span> <span class="n">x_coord_t</span><span class="p">;</span>
- <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="kt">ptrdiff_t</span> <span class="n">y_coord_t</span><span class="p">;</span>
- <span class="k">typedef</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="n">point_t</span><span class="p">;</span>
- <span class="n">any_image_view</span><span class="p">();</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">explicit</span> <span class="n">any_image_view</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="n">any_image_view</span><span class="p">(</span><span class="k">const</span> <span class="n">any_image_view</span><span class="o">&</span> <span class="n">v</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="n">any_image_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="n">any_image_view</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">any_image_view</span><span class="o">&</span> <span class="n">v</span><span class="p">);</span>
- <span class="c1">// parameters of the currently instantiated view</span>
- <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">num_channels</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="n">point_t</span> <span class="nf">dimensions</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="n">x_coord_t</span> <span class="nf">width</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="n">y_coord_t</span> <span class="nf">height</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="p">};</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">ImageTypes</span><span class="o">></span>
- <span class="k">class</span> <span class="nc">any_image</span> <span class="o">:</span> <span class="k">public</span> <span class="n">variant</span><span class="o"><</span><span class="n">ImageTypes</span><span class="o">></span>
- <span class="p">{</span>
- <span class="k">typedef</span> <span class="n">variant</span><span class="o"><</span><span class="n">ImageTypes</span><span class="o">></span> <span class="n">parent_t</span><span class="p">;</span>
- <span class="k">public</span><span class="o">:</span>
- <span class="k">typedef</span> <span class="p">...</span> <span class="n">const_view_t</span><span class="p">;</span>
- <span class="k">typedef</span> <span class="p">...</span> <span class="n">view_t</span><span class="p">;</span>
- <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="kt">ptrdiff_t</span> <span class="n">x_coord_t</span><span class="p">;</span>
- <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="kt">ptrdiff_t</span> <span class="n">y_coord_t</span><span class="p">;</span>
- <span class="k">typedef</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="n">point_t</span><span class="p">;</span>
- <span class="n">any_image</span><span class="p">();</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">explicit</span> <span class="n">any_image</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="k">explicit</span> <span class="n">any_image</span><span class="p">(</span><span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">do_swap</span><span class="p">);</span>
- <span class="n">any_image</span><span class="p">(</span><span class="k">const</span> <span class="n">any_image</span><span class="o">&</span> <span class="n">v</span><span class="p">);</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span> <span class="n">any_image</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&</span> <span class="n">obj</span><span class="p">);</span>
- <span class="n">any_image</span><span class="o">&</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="k">const</span> <span class="n">any_image</span><span class="o">&</span> <span class="n">v</span><span class="p">);</span>
- <span class="kt">void</span> <span class="nf">recreate</span><span class="p">(</span><span class="k">const</span> <span class="n">point_t</span><span class="o">&</span> <span class="n">dims</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">alignment</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>
- <span class="kt">void</span> <span class="nf">recreate</span><span class="p">(</span><span class="n">x_coord_t</span> <span class="n">width</span><span class="p">,</span> <span class="n">y_coord_t</span> <span class="n">height</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">alignment</span><span class="o">=</span><span class="mi">1</span><span class="p">);</span>
- <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">num_channels</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="n">point_t</span> <span class="nf">dimensions</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="n">x_coord_t</span> <span class="nf">width</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="n">y_coord_t</span> <span class="nf">height</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
- <span class="p">};</span>
- </pre></div>
- </div>
- <p>Operations are invoked on variants via <code class="docutils literal"><span class="pre">apply_operation</span></code> passing a
- function object to perform the operation. The code for every allowed
- type in the variant is instantiated and the appropriate instantiation
- is selected via a switch statement. Since image view algorithms
- typically have time complexity at least linear on the number of
- pixels, the single switch statement of image view variant adds
- practically no measurable performance overhead compared to templated
- image views.</p>
- <p>Variants behave like the underlying type. Their copy constructor will
- invoke the copy constructor of the underlying instance. Equality
- operator will check if the two instances are of the same type and then
- invoke their <code class="docutils literal"><span class="pre">operator==</span></code>, etc. The default constructor of a variant
- will default-construct the first type. That means that
- <code class="docutils literal"><span class="pre">any_image_view</span></code> has shallow default-constructor, copy-constructor,
- assignment and equality comparison, whereas <code class="docutils literal"><span class="pre">any_image</span></code> has deep
- ones.</p>
- <p>It is important to note that even though <code class="docutils literal"><span class="pre">any_image_view</span></code> and
- <code class="docutils literal"><span class="pre">any_image</span></code> resemble the static <code class="docutils literal"><span class="pre">image_view</span></code> and <code class="docutils literal"><span class="pre">image</span></code>, they
- do not model the full requirements of <code class="docutils literal"><span class="pre">ImageViewConcept</span></code> and
- <code class="docutils literal"><span class="pre">ImageConcept</span></code>. In particular they don’t provide access to the
- pixels. There is no “any_pixel” or “any_pixel_iterator” in GIL. Such
- constructs could be provided via the <code class="docutils literal"><span class="pre">variant</span></code> mechanism, but doing
- so would result in inefficient algorithms, since the type resolution
- would have to be performed per pixel. Image-level algorithms should be
- implemented via <code class="docutils literal"><span class="pre">apply_operation</span></code>. That said, many common operations
- are shared between the static and dynamic types. In addition, all of
- the image view transformations and many STL-like image view algorithms
- have overloads operating on <code class="docutils literal"><span class="pre">any_image_view</span></code>, as illustrated with
- <code class="docutils literal"><span class="pre">copy_pixels</span></code>:</p>
- <div class="highlight-cpp"><div class="highlight"><pre><span class="n">rgb8_view_t</span> <span class="nf">v1</span><span class="p">(...);</span> <span class="c1">// concrete image view</span>
- <span class="n">bgr8_view_t</span> <span class="nf">v2</span><span class="p">(...);</span> <span class="c1">// concrete image view compatible with v1 and of the same size</span>
- <span class="n">any_image_view</span><span class="o"><</span><span class="n">Types</span><span class="o">></span> <span class="n">av</span><span class="p">(...);</span> <span class="c1">// run-time specified image view</span>
- <span class="c1">// Copies the pixels from v1 into v2.</span>
- <span class="c1">// If the pixels are incompatible triggers compile error</span>
- <span class="n">copy_pixels</span><span class="p">(</span><span class="n">v1</span><span class="p">,</span><span class="n">v2</span><span class="p">);</span>
- <span class="c1">// The source or destination (or both) may be run-time instantiated.</span>
- <span class="c1">// If they happen to be incompatible, throws std::bad_cast</span>
- <span class="n">copy_pixels</span><span class="p">(</span><span class="n">v1</span><span class="p">,</span> <span class="n">av</span><span class="p">);</span>
- <span class="n">copy_pixels</span><span class="p">(</span><span class="n">av</span><span class="p">,</span> <span class="n">v2</span><span class="p">);</span>
- <span class="n">copy_pixels</span><span class="p">(</span><span class="n">av</span><span class="p">,</span> <span class="n">av</span><span class="p">);</span>
- </pre></div>
- </div>
- <p>By having algorithm overloads supporting dynamic constructs, we create
- a base upon which it is possible to write algorithms that can work
- with either compile-time or runtime images or views. The following
- code, for example, uses the GIL I/O extension to turn an image on disk
- upside down:</p>
- <div class="highlight-cpp"><div class="highlight"><pre><span class="cp">#include</span> <span class="cpf"><boost\gil\extension\io\jpeg_dynamic_io.hpp></span><span class="cp"></span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">Image</span><span class="o">></span> <span class="c1">// Could be rgb8_image_t or any_image<...></span>
- <span class="kt">void</span> <span class="n">save_180rot</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span> <span class="n">file_name</span><span class="p">)</span>
- <span class="p">{</span>
- <span class="n">Image</span> <span class="n">img</span><span class="p">;</span>
- <span class="n">jpeg_read_image</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="n">img</span><span class="p">);</span>
- <span class="n">jpeg_write_view</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="n">rotated180_view</span><span class="p">(</span><span class="n">view</span><span class="p">(</span><span class="n">img</span><span class="p">)));</span>
- <span class="p">}</span>
- </pre></div>
- </div>
- <p>It can be instantiated with either a compile-time or a runtime image
- because all functions it uses have overloads taking runtime
- constructs. For example, here is how <code class="docutils literal"><span class="pre">rotated180_view</span></code> is
- implemented:</p>
- <div class="highlight-cpp"><div class="highlight"><pre><span class="c1">// implementation using templated view</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">View</span><span class="o">></span>
- <span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o"><</span><span class="n">View</span><span class="o">>::</span><span class="n">type</span> <span class="n">rotated180_view</span><span class="p">(</span><span class="k">const</span> <span class="n">View</span><span class="o">&</span> <span class="n">src</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
- <span class="k">namespace</span> <span class="n">detail</span>
- <span class="p">{</span>
- <span class="c1">// the function, wrapped inside a function object</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">Result</span><span class="o">></span> <span class="k">struct</span> <span class="n">rotated180_view_fn</span>
- <span class="p">{</span>
- <span class="k">typedef</span> <span class="n">Result</span> <span class="n">result_type</span><span class="p">;</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">View</span><span class="o">></span> <span class="n">result_type</span> <span class="k">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">View</span><span class="o">&</span> <span class="n">src</span><span class="p">)</span> <span class="k">const</span>
- <span class="p">{</span>
- <span class="k">return</span> <span class="n">result_type</span><span class="p">(</span><span class="n">rotated180_view</span><span class="p">(</span><span class="n">src</span><span class="p">));</span>
- <span class="p">}</span>
- <span class="p">};</span>
- <span class="p">}</span>
- <span class="c1">// overloading of the function using variant. Takes and returns run-time bound view.</span>
- <span class="c1">// The returned view has a dynamic step</span>
- <span class="k">template</span> <span class="o"><</span><span class="k">typename</span> <span class="n">ViewTypes</span><span class="o">></span> <span class="kr">inline</span> <span class="c1">// Models MPL Random Access Container of models of ImageViewConcept</span>
- <span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o"><</span><span class="n">any_image_view</span><span class="o"><</span><span class="n">ViewTypes</span><span class="o">></span> <span class="o">>::</span><span class="n">type</span> <span class="n">rotated180_view</span><span class="p">(</span><span class="k">const</span> <span class="n">any_image_view</span><span class="o"><</span><span class="n">ViewTypes</span><span class="o">>&</span> <span class="n">src</span><span class="p">)</span>
- <span class="p">{</span>
- <span class="k">return</span> <span class="n">apply_operation</span><span class="p">(</span><span class="n">src</span><span class="p">,</span><span class="n">detail</span><span class="o">::</span><span class="n">rotated180_view_fn</span><span class="o"><</span><span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o"><</span><span class="n">any_image_view</span><span class="o"><</span><span class="n">ViewTypes</span><span class="o">></span> <span class="o">>::</span><span class="n">type</span><span class="o">></span><span class="p">());</span>
- <span class="p">}</span>
- </pre></div>
- </div>
- <p>Variants should be used with caution (especially algorithms that take
- more than one variant) because they instantiate the algorithm for
- every possible model that the variant can take. This can take a toll
- on compile time and executable size. Despite these limitations,
- <code class="docutils literal"><span class="pre">variant</span></code> is a powerful technique that allows us to combine the
- speed of compile-time resolution with the flexibility of run-time
- resolution. It allows us to treat images of different parameters
- uniformly as a collection and store them in the same container.</p>
- </div>
- <div class="navbar" style="text-align:right;">
-
-
- <a class="prev" title="Image" href="image.html"><img src="../_static/prev.png" alt="prev"/></a>
- <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
- <a class="next" title="Metafunctions" href="metafunctions.html"><img src="../_static/next.png" alt="next"/></a>
-
- </div>
- </div>
- <div class="footer" role="contentinfo">
- Last updated on 2019-12-10 00:12:10.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
- </div>
- </body>
- </html>
|