1Extending 2========= 3 4.. contents:: 5 :local: 6 :depth: 2 7 8Overview 9-------- 10 11You can define your own pixel iterators, locators, image views, 12images, channel types, color spaces and algorithms. You can make 13virtual images that live on the disk, inside a jpeg file, somewhere on 14the internet, or even fully-synthetic images such as the Mandelbrot 15set. As long as they properly model the corresponding concepts, they 16will work with any existing GIL code. Most such extensions require no 17changes to the library and can thus be supplied in another module. 18 19Defining new color spaces 20------------------------- 21 22Each color space is in a separate file. To add a new color space, just 23copy one of the existing ones (like rgb.hpp) and change it 24accordingly. If you want color conversion support, you will have to 25provide methods to convert between it and the existing color spaces 26(see color_convert.h). For convenience you may want to provide useful 27typedefs for pixels, pointers, references and images with the new 28color space (see typedefs.h). 29 30Defining new channel types 31-------------------------- 32 33Most of the time you don't need to do anything special to use a new 34channel type. You can just use it: 35 36.. code-block:: cpp 37 38 typedef pixel<double,rgb_layout_t> rgb64_pixel_t; // 64 bit RGB pixel 39 typedef rgb64_pixel* rgb64_pixel_ptr_t;// pointer to 64-bit interleaved data 40 typedef image_type<double,rgb_layout_t>::type rgb64_image_t; // 64-bit interleaved image 41 42If you want to use your own channel class, you will need to provide a 43specialization of ``channel_traits`` for it (see channel.hpp). If you 44want to do conversion between your and existing channel types, you 45will need to provide an overload of ``channel_convert``. 46 47Overloading color conversion 48---------------------------- 49 50Suppose you want to provide your own color conversion. For example, 51you may want to implement higher quality color conversion using color 52profiles. Typically you may want to redefine color conversion only in 53some instances and default to GIL's color conversion in all other 54cases. Here is, for example, how to overload color conversion so that 55color conversion to gray inverts the result but everything else 56remains the same: 57 58.. code-block:: cpp 59 60 // make the default use GIL's default 61 template <typename SrcColorSpace, typename DstColorSpace> 62 struct my_color_converter_impl 63 : public default_color_converter_impl<SrcColorSpace,DstColorSpace> {}; 64 65 // provide specializations only for cases you care about 66 // (in this case, if the destination is grayscale, invert it) 67 template <typename SrcColorSpace> 68 struct my_color_converter_impl<SrcColorSpace,gray_t> 69 { 70 template <typename SrcP, typename DstP> // Model PixelConcept 71 void operator()(const SrcP& src, DstP& dst) const 72 { 73 default_color_converter_impl<SrcColorSpace,gray_t>()(src,dst); 74 get_color(dst,gray_color_t())=channel_invert(get_color(dst,gray_color_t())); 75 } 76 }; 77 78 // create a color converter object that dispatches to your own implementation 79 struct my_color_converter 80 { 81 template <typename SrcP, typename DstP> // Model PixelConcept 82 void operator()(const SrcP& src,DstP& dst) const 83 { 84 typedef typename color_space_type<SrcP>::type SrcColorSpace; 85 typedef typename color_space_type<DstP>::type DstColorSpace; 86 my_color_converter_impl<SrcColorSpace,DstColorSpace>()(src,dst); 87 } 88 }; 89 90GIL color conversion functions take the color converter as an 91optional parameter. You can pass your own color converter: 92 93.. code-block:: cpp 94 95 color_converted_view<gray8_pixel_t>(img_view,my_color_converter()); 96 97Defining new image views 98------------------------ 99 100You can provide your own pixel iterators, locators and views, 101overriding either the mechanism for getting from one pixel to the next 102or doing an arbitrary pixel transformation on dereference. For 103example, let's look at the implementation of ``color_converted_view`` 104(an image factory method that, given any image view, returns a new, 105otherwise identical view, except that color conversion is performed on 106pixel access). First we need to define a model of 107``PixelDereferenceAdaptorConcept``; a function object that will be 108called when we dereference a pixel iterator. It will call 109``color_convert`` to convert to the destination pixel type: 110 111.. code-block:: cpp 112 113 template <typename SrcConstRefP, // const reference to the source pixel 114 typename DstP> // Destination pixel value (models PixelValueConcept) 115 class color_convert_deref_fn 116 { 117 public: 118 typedef color_convert_deref_fn const_t; 119 typedef DstP value_type; 120 typedef value_type reference; // read-only dereferencing 121 typedef const value_type& const_reference; 122 typedef SrcConstRefP argument_type; 123 typedef reference result_type; 124 static bool constexpr is_mutable = false; 125 126 result_type operator()(argument_type srcP) const { 127 result_type dstP; 128 color_convert(srcP,dstP); 129 return dstP; 130 } 131 }; 132 133We then use the ``add_deref`` member struct of image views to construct the 134type of a view that invokes a given function object (``deref_t``) upon 135dereferencing. In our case, it performs color conversion: 136 137.. code-block:: cpp 138 139 template <typename SrcView, typename DstP> 140 struct color_converted_view_type 141 { 142 private: 143 typedef typename SrcView::const_t::reference src_pix_ref; // const reference to pixel in SrcView 144 typedef color_convert_deref_fn<src_pix_ref, DstP> deref_t; // the dereference adaptor that performs color conversion 145 typedef typename SrcView::template add_deref<deref_t> add_ref_t; 146 public: 147 typedef typename add_ref_t::type type; // the color converted view type 148 static type make(const SrcView& sv) { return add_ref_t::make(sv, deref_t()); } 149 }; 150 151Finally our ``color_converted_view`` code simply creates color-converted view 152from the source view: 153 154.. code-block:: cpp 155 156 template <typename DstP, typename View> inline 157 typename color_converted_view_type<View,DstP>::type color_convert_view(const View& src) 158 { 159 return color_converted_view_type<View,DstP>::make(src); 160 } 161 162(The actual color convert view transformation is slightly more 163complicated, as it takes an optional color conversion object, which 164allows users to specify their own color conversion methods). See the 165GIL tutorial for an example of creating a virtual image view that 166defines the Mandelbrot set. 167