Metafunctions ============= .. contents:: :local: :depth: 2 Overview -------- Flexibility comes at a price. GIL types can be very long and hard to read. To address this problem, GIL provides typedefs to refer to any standard image, pixel iterator, pixel locator, pixel reference or pixel value. They follow this pattern:: *ColorSpace* + *BitDepth* + ["s|f"] + ["c"] + ["_planar"] + ["_step"] + *ClassType* + "_t" where *ColorSpace* also indicates the ordering of components. Examples are ``rgb``, ``bgr``, ``cmyk``, ``rgba``. *BitDepth* can be, for example, ``8``,``16``,``32``. By default the bits are unsigned integral type. Append ``s`` to the bit depth to indicate signed integral, or ``f`` to indicate floating point. ``c`` indicates object whose associated pixel reference is immutable. ``_planar`` indicates planar organization (as opposed to interleaved). ``_step`` indicates the type has a dynamic step and *ClassType* is ``_image`` (image, using a standard allocator), ``_view`` (image view), ``_loc`` (pixel locator), ``_ptr`` (pixel iterator), ``_ref`` (pixel reference), ``_pixel`` (pixel value). Here are examples: .. code-block:: cpp bgr8_image_t i; // 8-bit unsigned (unsigned char) interleaved BGR image cmyk16_pixel_t; x; // 16-bit unsigned (unsigned short) CMYK pixel value; cmyk16sc_planar_ref_t p(x); // const reference to a 16-bit signed integral (signed short) planar CMYK pixel x. rgb32f_planar_step_ptr_t ii; // step iterator to a floating point 32-bit (float) planar RGB pixel. Homogeneous memory-based images ------------------------------- GIL provides the metafunctions that return the types of standard homogeneous memory-based GIL constructs given a channel type, a layout, and whether the construct is planar, has a step along the X direction, and is mutable: .. code-block:: cpp template struct pixel_reference_type { typedef ... type; }; template struct pixel_value_type { typedef ... type; }; template struct iterator_type { typedef ... type; }; template struct locator_type { typedef ... type; }; template struct view_type { typedef ... type; }; template > struct image_type { typedef ... type; }; template > struct packed_image_type { typedef ... type; }; template > struct bit_aligned_image_type { typedef ... type; }; Packed and bit-aligned images ----------------------------- There are also helper metafunctions to construct packed and bit-aligned images with up to five channels: .. code-block:: cpp template > struct packed_image1_type { typedef ... type; }; template > struct packed_image2_type { typedef ... type; }; template > struct packed_image3_type { typedef ... type; }; template > struct packed_image4_type { typedef ... type; }; template > struct packed_image5_type { typedef ... type; }; template > struct bit_aligned_image1_type { typedef ... type; }; template > struct bit_aligned_image2_type { typedef ... type; }; template > struct bit_aligned_image3_type { typedef ... type; }; template > struct bit_aligned_image4_type { typedef ... type; }; template > struct bit_aligned_image5_type { typedef ... type; }; Iterators and views ------------------- Here ``ChannelValue`` models ``ChannelValueConcept``. We don't need ``IsYStep`` because GIL's memory-based locator and view already allow the vertical step to be specified dynamically. Iterators and views can be constructed from a pixel type: .. code-block:: cpp template struct iterator_type_from_pixel { typedef ... type; }; template struct view_type_from_pixel { typedef ... type; }; Using a heterogeneous pixel type will result in heterogeneous iterators and views. Types can also be constructed from horizontal iterator: .. code-block:: cpp template struct type_from_x_iterator { typedef ... step_iterator_t; typedef ... xy_locator_t; typedef ... view_t; }; Pixel components ---------------- You can get pixel-related types of any pixel-based GIL constructs (pixels, iterators, locators and views) using the following metafunctions provided by ``PixelBasedConcept``, ``HomogeneousPixelBasedConcept`` and metafunctions built on top of them: .. code-block:: cpp template struct color_space_type { typedef ... type; }; template struct channel_mapping_type { typedef ... type; }; template struct is_planar { typedef ... type; }; // Defined by homogeneous constructs template struct channel_type { typedef ... type; }; template struct num_channels { typedef ... type; }; Deriving and manipulating existing types ---------------------------------------- There are metafunctions to construct the type of a construct from an existing type by changing one or more of its properties: .. code-block:: cpp template struct derived_pixel_reference_type { typedef ... type; // Models PixelConcept }; template struct derived_iterator_type { typedef ... type; // Models PixelIteratorConcept }; template struct derived_view_type { typedef ... type; // Models ImageViewConcept }; template struct derived_image_type { typedef ... type; // Models ImageConcept }; You can replace one or more of its properties and use ``boost::use_default`` for the rest. In this case ``IsPlanar``, ``IsStep`` and ``IsMutable`` are MPL boolean constants. For example, here is how to create the type of a view just like ``View``, but being grayscale and planar: .. code-block:: cpp using VT = typename derived_view_type::type; Type traits ----------- These are metafunctions, some of which return integral types which can be evaluated like this: .. code-block:: cpp static_assert(is_planar::value == true, ""); GIL also supports type analysis metafunctions of the form: .. code-block:: cpp [pixel_reference/iterator/locator/view/image] + "_is_" + [basic/mutable/step] For example: .. code-block:: cpp if (view_is_mutable::value) { ... } A *basic* GIL construct is a memory-based construct that uses the built-in GIL classes and does not have any function object to invoke upon dereferencing. For example, a simple planar or interleaved, step or non-step RGB image view is basic, but a color converted view or a virtual view is not.