1Metafunctions 2============= 3 4.. contents:: 5 :local: 6 :depth: 2 7 8Overview 9-------- 10 11Flexibility comes at a price. GIL types can be very long and hard to read. 12To address this problem, GIL provides typedefs to refer to any standard image, 13pixel iterator, pixel locator, pixel reference or pixel value. 14 15They follow this pattern:: 16 17 *ColorSpace* + *BitDepth* + ["s|f"] + ["c"] + ["_planar"] + ["_step"] + *ClassType* + "_t" 18 19where *ColorSpace* also indicates the ordering of components. 20 21Examples are ``rgb``, ``bgr``, ``cmyk``, ``rgba``. *BitDepth* can be, for 22example, ``8``,``16``,``32``. By default the bits are unsigned integral type. 23Append ``s`` to the bit depth to indicate signed integral, or ``f`` to 24indicate floating point. ``c`` indicates object whose associated pixel 25reference is immutable. ``_planar`` indicates planar organization (as opposed 26to interleaved). ``_step`` indicates the type has a dynamic step and 27*ClassType* is ``_image`` (image, using a standard allocator), ``_view`` 28(image view), ``_loc`` (pixel locator), ``_ptr`` (pixel iterator), ``_ref`` 29(pixel reference), ``_pixel`` (pixel value). 30 31Here are examples: 32 33.. code-block:: cpp 34 35 bgr8_image_t i; // 8-bit unsigned (unsigned char) interleaved BGR image 36 cmyk16_pixel_t; x; // 16-bit unsigned (unsigned short) CMYK pixel value; 37 cmyk16sc_planar_ref_t p(x); // const reference to a 16-bit signed integral (signed short) planar CMYK pixel x. 38 rgb32f_planar_step_ptr_t ii; // step iterator to a floating point 32-bit (float) planar RGB pixel. 39 40Homogeneous memory-based images 41------------------------------- 42 43GIL provides the metafunctions that return the types of standard 44homogeneous memory-based GIL constructs given a channel type, a 45layout, and whether the construct is planar, has a step along the X 46direction, and is mutable: 47 48.. code-block:: cpp 49 50 template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsMutable=true> 51 struct pixel_reference_type { typedef ... type; }; 52 53 template <typename Channel, typename Layout> 54 struct pixel_value_type { typedef ... type; }; 55 56 template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> 57 struct iterator_type { typedef ... type; }; 58 59 template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsXStep=false, bool IsMutable=true> 60 struct locator_type { typedef ... type; }; 61 62 template <typename ChannelValue, typename Layout, bool IsPlanar=false, bool IsXStep=false, bool IsMutable=true> 63 struct view_type { typedef ... type; }; 64 65 template <typename ChannelValue, typename Layout, bool IsPlanar=false, typename Alloc=std::allocator<unsigned char> > 66 struct image_type { typedef ... type; }; 67 68 template <typename BitField, typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> > 69 struct packed_image_type { typedef ... type; }; 70 71 template <typename ChannelBitSizeVector, typename Layout, typename Alloc=std::allocator<unsigned char> > 72 struct bit_aligned_image_type { typedef ... type; }; 73 74Packed and bit-aligned images 75----------------------------- 76 77There are also helper metafunctions to construct packed and 78bit-aligned images with up to five channels: 79 80.. code-block:: cpp 81 82 template <typename BitField, unsigned Size1, 83 typename Layout, typename Alloc=std::allocator<unsigned char> > 84 struct packed_image1_type { typedef ... type; }; 85 86 template <typename BitField, unsigned Size1, unsigned Size2, 87 typename Layout, typename Alloc=std::allocator<unsigned char> > 88 struct packed_image2_type { typedef ... type; }; 89 90 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, 91 typename Layout, typename Alloc=std::allocator<unsigned char> > 92 struct packed_image3_type { typedef ... type; }; 93 94 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, 95 typename Layout, typename Alloc=std::allocator<unsigned char> > 96 struct packed_image4_type { typedef ... type; }; 97 98 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, 99 typename Layout, typename Alloc=std::allocator<unsigned char> > 100 struct packed_image5_type { typedef ... type; }; 101 102 template <unsigned Size1, 103 typename Layout, typename Alloc=std::allocator<unsigned char> > 104 struct bit_aligned_image1_type { typedef ... type; }; 105 106 template <unsigned Size1, unsigned Size2, 107 typename Layout, typename Alloc=std::allocator<unsigned char> > 108 struct bit_aligned_image2_type { typedef ... type; }; 109 110 template <unsigned Size1, unsigned Size2, unsigned Size3, 111 typename Layout, typename Alloc=std::allocator<unsigned char> > 112 struct bit_aligned_image3_type { typedef ... type; }; 113 114 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, 115 typename Layout, typename Alloc=std::allocator<unsigned char> > 116 struct bit_aligned_image4_type { typedef ... type; }; 117 118 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4, unsigned Size5, 119 typename Layout, typename Alloc=std::allocator<unsigned char> > 120 struct bit_aligned_image5_type { typedef ... type; }; 121 122Iterators and views 123------------------- 124 125Here ``ChannelValue`` models ``ChannelValueConcept``. We don't need 126``IsYStep`` because GIL's memory-based locator and view already allow 127the vertical step to be specified dynamically. Iterators and views can 128be constructed from a pixel type: 129 130.. code-block:: cpp 131 132 template <typename Pixel, bool IsPlanar=false, bool IsStep=false, bool IsMutable=true> 133 struct iterator_type_from_pixel { typedef ... type; }; 134 135 template <typename Pixel, bool IsPlanar=false, bool IsStepX=false, bool IsMutable=true> 136 struct view_type_from_pixel { typedef ... type; }; 137 138Using a heterogeneous pixel type will result in heterogeneous iterators and 139views. Types can also be constructed from horizontal iterator: 140 141.. code-block:: cpp 142 143 template <typename XIterator> 144 struct type_from_x_iterator 145 { 146 typedef ... step_iterator_t; 147 typedef ... xy_locator_t; 148 typedef ... view_t; 149 }; 150 151Pixel components 152---------------- 153 154You can get pixel-related types of any pixel-based GIL constructs (pixels, 155iterators, locators and views) using the following metafunctions provided by 156``PixelBasedConcept``, ``HomogeneousPixelBasedConcept`` and metafunctions 157built on top of them: 158 159.. code-block:: cpp 160 161 template <typename T> struct color_space_type { typedef ... type; }; 162 template <typename T> struct channel_mapping_type { typedef ... type; }; 163 template <typename T> struct is_planar { typedef ... type; }; 164 165 // Defined by homogeneous constructs 166 template <typename T> struct channel_type { typedef ... type; }; 167 template <typename T> struct num_channels { typedef ... type; }; 168 169Deriving and manipulating existing types 170---------------------------------------- 171 172There are metafunctions to construct the type of a construct from an existing 173type by changing one or more of its properties: 174 175.. code-block:: cpp 176 177 template <typename PixelReference, 178 typename ChannelValue, typename Layout, typename IsPlanar, typename IsMutable> 179 struct derived_pixel_reference_type 180 { 181 typedef ... type; // Models PixelConcept 182 }; 183 184 template <typename Iterator, 185 typename ChannelValue, typename Layout, typename IsPlanar, typename IsStep, typename IsMutable> 186 struct derived_iterator_type 187 { 188 typedef ... type; // Models PixelIteratorConcept 189 }; 190 191 template <typename View, 192 typename ChannelValue, typename Layout, typename IsPlanar, typename IsXStep, typename IsMutable> 193 struct derived_view_type 194 { 195 typedef ... type; // Models ImageViewConcept 196 }; 197 198 template <typename Image, 199 typename ChannelValue, typename Layout, typename IsPlanar> 200 struct derived_image_type 201 { 202 typedef ... type; // Models ImageConcept 203 }; 204 205You can replace one or more of its properties and use ``boost::use_default`` 206for the rest. In this case ``IsPlanar``, ``IsStep`` and ``IsMutable`` are 207MPL boolean constants. For example, here is how to create the type of a view 208just like ``View``, but being grayscale and planar: 209 210.. code-block:: cpp 211 212 using VT = typename derived_view_type<View, boost::use_default, gray_t, mpl::true_>::type; 213 214Type traits 215----------- 216 217These are metafunctions, some of which return integral types which can be 218evaluated like this: 219 220.. code-block:: cpp 221 222 static_assert(is_planar<rgb8_planar_view_t>::value == true, ""); 223 224GIL also supports type analysis metafunctions of the form: 225 226.. code-block:: cpp 227 228 [pixel_reference/iterator/locator/view/image] + "_is_" + [basic/mutable/step] 229 230For example: 231 232.. code-block:: cpp 233 234 if (view_is_mutable<View>::value) 235 { 236 ... 237 } 238 239A *basic* GIL construct is a memory-based construct that uses the built-in GIL 240classes and does not have any function object to invoke upon dereferencing. 241For example, a simple planar or interleaved, step or non-step RGB image view 242is basic, but a color converted view or a virtual view is not. 243