dynamic_image.html 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  6. <title>Dynamic images and image views - Boost.GIL documentation</title>
  7. <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
  8. <link rel="stylesheet" href="../_static/style.css" type="text/css" />
  9. <script type="text/javascript">
  10. var DOCUMENTATION_OPTIONS = {
  11. URL_ROOT: '../',
  12. VERSION: '',
  13. COLLAPSE_MODINDEX: false,
  14. FILE_SUFFIX: '.html'
  15. };
  16. </script>
  17. <script type="text/javascript" src="../_static/jquery.js"></script>
  18. <script type="text/javascript" src="../_static/underscore.js"></script>
  19. <script type="text/javascript" src="../_static/doctools.js"></script>
  20. <link rel="index" title="Index" href="../genindex.html" />
  21. <link rel="search" title="Search" href="../search.html" />
  22. <link rel="top" title="Boost.GIL documentation" href="../index.html" />
  23. <link rel="up" title="Design Guide" href="index.html" />
  24. <link rel="next" title="Metafunctions" href="metafunctions.html" />
  25. <link rel="prev" title="Image" href="image.html" />
  26. </head>
  27. <body>
  28. <div class="header">
  29. <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
  30. "header">
  31. <tr>
  32. <td valign="top" width="300">
  33. <h3><a href="../index.html"><img
  34. alt="C++ Boost" src="../_static/gil.png" border="0"></a></h3>
  35. </td>
  36. <td >
  37. <h1 align="center"><a href="../index.html"></a></h1>
  38. </td>
  39. <td>
  40. <div id="searchbox" style="display: none">
  41. <form class="search" action="../search.html" method="get">
  42. <input type="text" name="q" size="18" />
  43. <input type="submit" value="Search" />
  44. <input type="hidden" name="check_keywords" value="yes" />
  45. <input type="hidden" name="area" value="default" />
  46. </form>
  47. </div>
  48. <script type="text/javascript">$('#searchbox').show(0);</script>
  49. </td>
  50. </tr>
  51. </table>
  52. </div>
  53. <hr/>
  54. <div class="content">
  55. <div class="navbar" style="text-align:right;">
  56. <a class="prev" title="Image" href="image.html"><img src="../_static/prev.png" alt="prev"/></a>
  57. <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
  58. <a class="next" title="Metafunctions" href="metafunctions.html"><img src="../_static/next.png" alt="next"/></a>
  59. </div>
  60. <div class="section" id="dynamic-images-and-image-views">
  61. <h1>Dynamic images and image views</h1>
  62. <p>The GIL extension called <code class="docutils literal"><span class="pre">dynamic_image</span></code> allows for images, image views
  63. or any GIL constructs to have their parameters defined at run time.</p>
  64. <p>The color space, channel depth, channel ordering, and interleaved/planar
  65. structure of an image are defined by the type of its template argument, which
  66. makes them compile-time bound. Often some of these parameters are available
  67. only at run time. Consider, for example, writing a module that opens the image
  68. at a given file path, rotates it and saves it back in its original color space
  69. and channel depth. How can we possibly write this using our generic image?
  70. What type is the image loading code supposed to return?</p>
  71. <p>Here is an example:</p>
  72. <div class="highlight-cpp"><div class="highlight"><pre><span class="cp">#include</span> <span class="cpf">&lt;boost/gil/extension/dynamic_image/dynamic_image_all.hpp&gt;</span><span class="cp"></span>
  73. <span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="p">;</span>
  74. <span class="cp">#define ASSERT_SAME(A,B) static_assert(is_same&lt; A,B &gt;::value, &quot;&quot;)</span>
  75. <span class="c1">// Define the set of allowed images</span>
  76. <span class="k">typedef</span> <span class="n">mpl</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">rgb8_image_t</span><span class="p">,</span> <span class="n">cmyk16_planar_image_t</span><span class="o">&gt;</span> <span class="n">my_images_t</span><span class="p">;</span>
  77. <span class="c1">// Create any_image class (or any_image_view) class</span>
  78. <span class="k">typedef</span> <span class="n">any_image</span><span class="o">&lt;</span><span class="n">my_images_t</span><span class="o">&gt;</span> <span class="n">my_any_image_t</span><span class="p">;</span>
  79. <span class="c1">// Associated view types are available (equivalent to the ones in image_t)</span>
  80. <span class="k">typedef</span> <span class="n">any_image_view</span><span class="o">&lt;</span><span class="n">mpl</span><span class="o">::</span><span class="n">vector2</span><span class="o">&lt;</span><span class="n">rgb8_view_t</span><span class="p">,</span> <span class="n">cmyk16_planar_view_t</span> <span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">AV</span><span class="p">;</span>
  81. <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>
  82. <span class="k">typedef</span> <span class="n">any_image_view</span><span class="o">&lt;</span><span class="n">mpl</span><span class="o">::</span><span class="n">vector2</span><span class="o">&lt;</span><span class="n">rgb8c_view_t</span><span class="p">,</span> <span class="n">cmyk16c_planar_view_t</span><span class="o">&gt;</span> <span class="o">&gt;</span> <span class="n">CAV</span><span class="p">;</span>
  83. <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>
  84. <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>
  85. <span class="k">typedef</span> <span class="n">any_image_view</span><span class="o">&lt;</span><span class="n">mpl</span><span class="o">::</span><span class="n">vector2</span><span class="o">&lt;</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">&gt;</span> <span class="o">&gt;</span> <span class="n">SAV</span><span class="p">;</span>
  86. <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">&lt;</span><span class="n">my_any_image_t</span><span class="o">::</span><span class="n">view_t</span><span class="o">&gt;::</span><span class="n">type</span><span class="p">,</span> <span class="n">SAV</span><span class="p">);</span>
  87. <span class="c1">// Assign it a concrete image at run time:</span>
  88. <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>
  89. <span class="c1">// Change it to another at run time. The previous image gets destroyed</span>
  90. <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>
  91. <span class="c1">// Assigning to an image not in the allowed set throws an exception</span>
  92. <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>
  93. </pre></div>
  94. </div>
  95. <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,
  96. which breaks down the instantiated type into a non-templated underlying base
  97. type and a unique instantiation type identifier. The underlying base instance
  98. is represented as a block of bytes.
  99. The block is large enough to hold the largest of the specified types.</p>
  100. <p>GIL variant is similar to <code class="docutils literal"><span class="pre">boost::variant</span></code> in spirit (hence we borrow the
  101. name from there) but it differs in several ways from the current boost
  102. implementation. Perhaps the biggest difference is that GIL variant always
  103. takes a single argument, which is a model of MPL Random Access Sequence
  104. enumerating the allowed types. Having a single interface allows GIL variant
  105. to be used easier in generic code. Synopsis:</p>
  106. <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">Types</span><span class="o">&gt;</span> <span class="c1">// models MPL Random Access Container</span>
  107. <span class="k">class</span> <span class="nc">variant</span>
  108. <span class="p">{</span>
  109. <span class="p">...</span> <span class="n">_bits</span><span class="p">;</span>
  110. <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">_index</span><span class="p">;</span>
  111. <span class="k">public</span><span class="o">:</span>
  112. <span class="k">typedef</span> <span class="n">Types</span> <span class="n">types_t</span><span class="p">;</span>
  113. <span class="n">variant</span><span class="p">();</span>
  114. <span class="n">variant</span><span class="p">(</span><span class="k">const</span> <span class="n">variant</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">);</span>
  115. <span class="k">virtual</span> <span class="o">~</span><span class="n">variant</span><span class="p">();</span>
  116. <span class="n">variant</span><span class="o">&amp;</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">&amp;</span> <span class="n">v</span><span class="p">);</span>
  117. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">TS</span><span class="o">&gt;</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">&lt;</span><span class="n">TS</span><span class="o">&gt;&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="n">variant</span><span class="o">&lt;</span><span class="n">TS</span><span class="o">&gt;&amp;</span> <span class="n">y</span><span class="p">);</span>
  118. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">TS</span><span class="o">&gt;</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">&lt;</span><span class="n">TS</span><span class="o">&gt;&amp;</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="n">variant</span><span class="o">&lt;</span><span class="n">TS</span><span class="o">&gt;&amp;</span> <span class="n">y</span><span class="p">);</span>
  119. <span class="c1">// Construct/assign to type T. Throws std::bad_cast if T is not in Types</span>
  120. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</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">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  121. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">variant</span><span class="o">&amp;</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">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  122. <span class="c1">// Construct/assign by swapping T with its current instance. Only possible if they are swappable</span>
  123. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="k">explicit</span> <span class="n">variant</span><span class="p">(</span><span class="n">T</span><span class="o">&amp;</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>
  124. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="kt">void</span> <span class="n">move_in</span><span class="p">(</span><span class="n">T</span><span class="o">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  125. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="k">static</span> <span class="kt">bool</span> <span class="n">has_type</span><span class="p">();</span>
  126. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">_dynamic_cast</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
  127. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">_dynamic_cast</span><span class="p">();</span>
  128. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</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>
  129. <span class="p">};</span>
  130. <span class="k">template</span> <span class="o">&lt;</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">&gt;</span>
  131. <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">&lt;</span><span class="n">Types</span><span class="o">&gt;&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
  132. <span class="k">template</span> <span class="o">&lt;</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">&gt;</span>
  133. <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">&lt;</span><span class="n">Types</span><span class="o">&gt;&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
  134. <span class="k">template</span> <span class="o">&lt;</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">&gt;</span>
  135. <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">&lt;</span><span class="n">Types1</span><span class="o">&gt;&amp;</span> <span class="n">v1</span><span class="p">,</span> <span class="n">variant</span><span class="o">&lt;</span><span class="n">Types2</span><span class="o">&gt;&amp;</span> <span class="n">v2</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
  136. <span class="k">template</span> <span class="o">&lt;</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">&gt;</span>
  137. <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">&lt;</span><span class="n">Types1</span><span class="o">&gt;&amp;</span> <span class="n">v1</span><span class="p">,</span> <span class="n">variant</span><span class="o">&lt;</span><span class="n">Types2</span><span class="o">&gt;&amp;</span> <span class="n">v2</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
  138. <span class="k">template</span> <span class="o">&lt;</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">&gt;</span>
  139. <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">&lt;</span><span class="n">Types1</span><span class="o">&gt;&amp;</span> <span class="n">v1</span><span class="p">,</span> <span class="k">const</span> <span class="n">variant</span><span class="o">&lt;</span><span class="n">Types2</span><span class="o">&gt;&amp;</span> <span class="n">v2</span><span class="p">,</span> <span class="n">UOP</span> <span class="n">op</span><span class="p">);</span>
  140. </pre></div>
  141. </div>
  142. <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>
  143. <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">ImageViewTypes</span><span class="o">&gt;</span>
  144. <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">&lt;</span><span class="n">ImageViewTypes</span><span class="o">&gt;</span>
  145. <span class="p">{</span>
  146. <span class="k">public</span><span class="o">:</span>
  147. <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>
  148. <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>
  149. <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>
  150. <span class="k">typedef</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="n">point_t</span><span class="p">;</span>
  151. <span class="n">any_image_view</span><span class="p">();</span>
  152. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</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">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  153. <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">&amp;</span> <span class="n">v</span><span class="p">);</span>
  154. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">any_image_view</span><span class="o">&amp;</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">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  155. <span class="n">any_image_view</span><span class="o">&amp;</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">&amp;</span> <span class="n">v</span><span class="p">);</span>
  156. <span class="c1">// parameters of the currently instantiated view</span>
  157. <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>
  158. <span class="n">point_t</span> <span class="nf">dimensions</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
  159. <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>
  160. <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>
  161. <span class="p">};</span>
  162. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">ImageTypes</span><span class="o">&gt;</span>
  163. <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">&lt;</span><span class="n">ImageTypes</span><span class="o">&gt;</span>
  164. <span class="p">{</span>
  165. <span class="k">typedef</span> <span class="n">variant</span><span class="o">&lt;</span><span class="n">ImageTypes</span><span class="o">&gt;</span> <span class="n">parent_t</span><span class="p">;</span>
  166. <span class="k">public</span><span class="o">:</span>
  167. <span class="k">typedef</span> <span class="p">...</span> <span class="n">const_view_t</span><span class="p">;</span>
  168. <span class="k">typedef</span> <span class="p">...</span> <span class="n">view_t</span><span class="p">;</span>
  169. <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>
  170. <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>
  171. <span class="k">typedef</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="n">point_t</span><span class="p">;</span>
  172. <span class="n">any_image</span><span class="p">();</span>
  173. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</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">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  174. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="k">explicit</span> <span class="n">any_image</span><span class="p">(</span><span class="n">T</span><span class="o">&amp;</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>
  175. <span class="n">any_image</span><span class="p">(</span><span class="k">const</span> <span class="n">any_image</span><span class="o">&amp;</span> <span class="n">v</span><span class="p">);</span>
  176. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="n">any_image</span><span class="o">&amp;</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">&amp;</span> <span class="n">obj</span><span class="p">);</span>
  177. <span class="n">any_image</span><span class="o">&amp;</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">&amp;</span> <span class="n">v</span><span class="p">);</span>
  178. <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">&amp;</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>
  179. <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>
  180. <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>
  181. <span class="n">point_t</span> <span class="nf">dimensions</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
  182. <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>
  183. <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>
  184. <span class="p">};</span>
  185. </pre></div>
  186. </div>
  187. <p>Operations are invoked on variants via <code class="docutils literal"><span class="pre">apply_operation</span></code> passing a
  188. function object to perform the operation. The code for every allowed
  189. type in the variant is instantiated and the appropriate instantiation
  190. is selected via a switch statement. Since image view algorithms
  191. typically have time complexity at least linear on the number of
  192. pixels, the single switch statement of image view variant adds
  193. practically no measurable performance overhead compared to templated
  194. image views.</p>
  195. <p>Variants behave like the underlying type. Their copy constructor will
  196. invoke the copy constructor of the underlying instance. Equality
  197. operator will check if the two instances are of the same type and then
  198. invoke their <code class="docutils literal"><span class="pre">operator==</span></code>, etc. The default constructor of a variant
  199. will default-construct the first type. That means that
  200. <code class="docutils literal"><span class="pre">any_image_view</span></code> has shallow default-constructor, copy-constructor,
  201. assignment and equality comparison, whereas <code class="docutils literal"><span class="pre">any_image</span></code> has deep
  202. ones.</p>
  203. <p>It is important to note that even though <code class="docutils literal"><span class="pre">any_image_view</span></code> and
  204. <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
  205. do not model the full requirements of <code class="docutils literal"><span class="pre">ImageViewConcept</span></code> and
  206. <code class="docutils literal"><span class="pre">ImageConcept</span></code>. In particular they don&#8217;t provide access to the
  207. pixels. There is no &#8220;any_pixel&#8221; or &#8220;any_pixel_iterator&#8221; in GIL. Such
  208. constructs could be provided via the <code class="docutils literal"><span class="pre">variant</span></code> mechanism, but doing
  209. so would result in inefficient algorithms, since the type resolution
  210. would have to be performed per pixel. Image-level algorithms should be
  211. implemented via <code class="docutils literal"><span class="pre">apply_operation</span></code>. That said, many common operations
  212. are shared between the static and dynamic types. In addition, all of
  213. the image view transformations and many STL-like image view algorithms
  214. have overloads operating on <code class="docutils literal"><span class="pre">any_image_view</span></code>, as illustrated with
  215. <code class="docutils literal"><span class="pre">copy_pixels</span></code>:</p>
  216. <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>
  217. <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>
  218. <span class="n">any_image_view</span><span class="o">&lt;</span><span class="n">Types</span><span class="o">&gt;</span> <span class="n">av</span><span class="p">(...);</span> <span class="c1">// run-time specified image view</span>
  219. <span class="c1">// Copies the pixels from v1 into v2.</span>
  220. <span class="c1">// If the pixels are incompatible triggers compile error</span>
  221. <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>
  222. <span class="c1">// The source or destination (or both) may be run-time instantiated.</span>
  223. <span class="c1">// If they happen to be incompatible, throws std::bad_cast</span>
  224. <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>
  225. <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>
  226. <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>
  227. </pre></div>
  228. </div>
  229. <p>By having algorithm overloads supporting dynamic constructs, we create
  230. a base upon which it is possible to write algorithms that can work
  231. with either compile-time or runtime images or views. The following
  232. code, for example, uses the GIL I/O extension to turn an image on disk
  233. upside down:</p>
  234. <div class="highlight-cpp"><div class="highlight"><pre><span class="cp">#include</span> <span class="cpf">&lt;boost\gil\extension\io\jpeg_dynamic_io.hpp&gt;</span><span class="cp"></span>
  235. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Image</span><span class="o">&gt;</span> <span class="c1">// Could be rgb8_image_t or any_image&lt;...&gt;</span>
  236. <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">&amp;</span> <span class="n">file_name</span><span class="p">)</span>
  237. <span class="p">{</span>
  238. <span class="n">Image</span> <span class="n">img</span><span class="p">;</span>
  239. <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>
  240. <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>
  241. <span class="p">}</span>
  242. </pre></div>
  243. </div>
  244. <p>It can be instantiated with either a compile-time or a runtime image
  245. because all functions it uses have overloads taking runtime
  246. constructs. For example, here is how <code class="docutils literal"><span class="pre">rotated180_view</span></code> is
  247. implemented:</p>
  248. <div class="highlight-cpp"><div class="highlight"><pre><span class="c1">// implementation using templated view</span>
  249. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</span>
  250. <span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o">&lt;</span><span class="n">View</span><span class="o">&gt;::</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">&amp;</span> <span class="n">src</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
  251. <span class="k">namespace</span> <span class="n">detail</span>
  252. <span class="p">{</span>
  253. <span class="c1">// the function, wrapped inside a function object</span>
  254. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Result</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">rotated180_view_fn</span>
  255. <span class="p">{</span>
  256. <span class="k">typedef</span> <span class="n">Result</span> <span class="n">result_type</span><span class="p">;</span>
  257. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">View</span><span class="o">&gt;</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">&amp;</span> <span class="n">src</span><span class="p">)</span> <span class="k">const</span>
  258. <span class="p">{</span>
  259. <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>
  260. <span class="p">}</span>
  261. <span class="p">};</span>
  262. <span class="p">}</span>
  263. <span class="c1">// overloading of the function using variant. Takes and returns run-time bound view.</span>
  264. <span class="c1">// The returned view has a dynamic step</span>
  265. <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">ViewTypes</span><span class="o">&gt;</span> <span class="kr">inline</span> <span class="c1">// Models MPL Random Access Container of models of ImageViewConcept</span>
  266. <span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o">&lt;</span><span class="n">any_image_view</span><span class="o">&lt;</span><span class="n">ViewTypes</span><span class="o">&gt;</span> <span class="o">&gt;::</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">&lt;</span><span class="n">ViewTypes</span><span class="o">&gt;&amp;</span> <span class="n">src</span><span class="p">)</span>
  267. <span class="p">{</span>
  268. <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">&lt;</span><span class="k">typename</span> <span class="n">dynamic_xy_step_type</span><span class="o">&lt;</span><span class="n">any_image_view</span><span class="o">&lt;</span><span class="n">ViewTypes</span><span class="o">&gt;</span> <span class="o">&gt;::</span><span class="n">type</span><span class="o">&gt;</span><span class="p">());</span>
  269. <span class="p">}</span>
  270. </pre></div>
  271. </div>
  272. <p>Variants should be used with caution (especially algorithms that take
  273. more than one variant) because they instantiate the algorithm for
  274. every possible model that the variant can take. This can take a toll
  275. on compile time and executable size. Despite these limitations,
  276. <code class="docutils literal"><span class="pre">variant</span></code> is a powerful technique that allows us to combine the
  277. speed of compile-time resolution with the flexibility of run-time
  278. resolution. It allows us to treat images of different parameters
  279. uniformly as a collection and store them in the same container.</p>
  280. </div>
  281. <div class="navbar" style="text-align:right;">
  282. <a class="prev" title="Image" href="image.html"><img src="../_static/prev.png" alt="prev"/></a>
  283. <a class="up" title="Design Guide" href="index.html"><img src="../_static/up.png" alt="up"/></a>
  284. <a class="next" title="Metafunctions" href="metafunctions.html"><img src="../_static/next.png" alt="next"/></a>
  285. </div>
  286. </div>
  287. <div class="footer" role="contentinfo">
  288. Last updated on 2019-12-10 00:12:10.
  289. Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6.
  290. </div>
  291. </body>
  292. </html>