Boost GIL


color_convert.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3 
4  Use, modification and distribution are subject to the Boost Software License,
5  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6  http://www.boost.org/LICENSE_1_0.txt).
7 
8  See http://opensource.adobe.com/gil for most recent version including documentation.
9 */
10 /*************************************************************************************************/
11 
12 #ifndef GIL_COLOR_CONVERT_HPP
13 #define GIL_COLOR_CONVERT_HPP
14 
26 
27 #include <functional>
28 
29 #include <boost/config.hpp>
30 
31 #include "gil_config.hpp"
32 #include "channel_algorithm.hpp"
33 #include "pixel.hpp"
34 #include "gray.hpp"
35 #include "rgb.hpp"
36 #include "rgba.hpp"
37 #include "cmyk.hpp"
38 #include "metafunctions.hpp"
39 #include "utilities.hpp"
40 #include "color_base_algorithm.hpp"
41 
42 namespace boost { namespace gil {
43 
44 // Forward-declare
45 template <typename P> struct channel_type;
46 
52 
55 template <typename C1, typename C2>
57 
60 template <typename C>
62  template <typename P1, typename P2>
63  void operator()(const P1& src, P2& dst) const {
64  static_for_each(src,dst,default_channel_converter());
65  }
66 };
67 
68 namespace detail {
69 
71 
72 // The default implementation of to_luminance uses float0..1 as the intermediate channel type
73 template <typename RedChannel, typename GreenChannel, typename BlueChannel, typename GrayChannelValue>
75  GrayChannelValue operator()(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) const {
76  return channel_convert<GrayChannelValue>(float32_t(
77  channel_convert<float32_t>(red )*0.30f +
78  channel_convert<float32_t>(green)*0.59f +
79  channel_convert<float32_t>(blue )*0.11f) );
80  }
81 };
82 
83 // performance specialization for unsigned char
84 template <typename GrayChannelValue>
85 struct rgb_to_luminance_fn<uint8_t,uint8_t,uint8_t, GrayChannelValue> {
86  GrayChannelValue operator()(uint8_t red, uint8_t green, uint8_t blue) const {
87  return channel_convert<GrayChannelValue>(uint8_t(
88  ((uint32_t(red )*4915 + uint32_t(green)*9667 + uint32_t(blue )*1802) + 8192) >> 14));
89  }
90 };
91 
92 template <typename GrayChannel, typename RedChannel, typename GreenChannel, typename BlueChannel>
93 typename channel_traits<GrayChannel>::value_type rgb_to_luminance(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) {
94  return rgb_to_luminance_fn<RedChannel,GreenChannel,BlueChannel,
95  typename channel_traits<GrayChannel>::value_type>()(red,green,blue);
96 }
97 
98 } // namespace detail
99 
102 template <>
103 struct default_color_converter_impl<gray_t,rgb_t> {
104  template <typename P1, typename P2>
105  void operator()(const P1& src, P2& dst) const {
106  get_color(dst,red_t()) =
107  channel_convert<typename color_element_type<P2, red_t >::type>(get_color(src,gray_color_t()));
108  get_color(dst,green_t())=
109  channel_convert<typename color_element_type<P2, green_t>::type>(get_color(src,gray_color_t()));
110  get_color(dst,blue_t()) =
111  channel_convert<typename color_element_type<P2, blue_t >::type>(get_color(src,gray_color_t()));
112  }
113 };
114 
117 template <>
118 struct default_color_converter_impl<gray_t,cmyk_t> {
119  template <typename P1, typename P2>
120  void operator()(const P1& src, P2& dst) const {
121  get_color(dst,cyan_t())=
123  get_color(dst,magenta_t())=
125  get_color(dst,yellow_t())=
127  get_color(dst,black_t())=
128  channel_convert<typename color_element_type<P2, black_t >::type>(get_color(src,gray_color_t()));
129  }
130 };
131 
134 template <>
135 struct default_color_converter_impl<rgb_t,gray_t> {
136  template <typename P1, typename P2>
137  void operator()(const P1& src, P2& dst) const {
138  get_color(dst,gray_color_t()) =
139  detail::rgb_to_luminance<typename color_element_type<P2,gray_color_t>::type>(
140  get_color(src,red_t()), get_color(src,green_t()), get_color(src,blue_t())
141  );
142  }
143 };
144 
145 
153 template <>
154 struct default_color_converter_impl<rgb_t,cmyk_t> {
155  template <typename P1, typename P2>
156  void operator()(const P1& src, P2& dst) const {
157  typedef typename channel_type<P2>::type T2;
158  get_color(dst,cyan_t()) = channel_invert(channel_convert<T2>(get_color(src,red_t()))); // c = 1 - r
159  get_color(dst,magenta_t()) = channel_invert(channel_convert<T2>(get_color(src,green_t()))); // m = 1 - g
160  get_color(dst,yellow_t()) = channel_invert(channel_convert<T2>(get_color(src,blue_t()))); // y = 1 - b
161  get_color(dst,black_t()) = (std::min)(get_color(dst,cyan_t()),
162  (std::min)(get_color(dst,magenta_t()),
163  get_color(dst,yellow_t()))); // k = minimum(c, m, y)
164  T2 x = channel_traits<T2>::max_value()-get_color(dst,black_t()); // x = 1 - k
165  if (x>0.0001f) {
166  float x1 = channel_traits<T2>::max_value()/float(x);
167  get_color(dst,cyan_t()) = (T2)((get_color(dst,cyan_t()) - get_color(dst,black_t()))*x1); // c = (c - k) / x
168  get_color(dst,magenta_t()) = (T2)((get_color(dst,magenta_t()) - get_color(dst,black_t()))*x1); // m = (m - k) / x
169  get_color(dst,yellow_t()) = (T2)((get_color(dst,yellow_t()) - get_color(dst,black_t()))*x1); // y = (y - k) / x
170  } else {
171  get_color(dst,cyan_t())=get_color(dst,magenta_t())=get_color(dst,yellow_t())=0;
172  }
173  }
174 };
175 
182 template <>
183 struct default_color_converter_impl<cmyk_t,rgb_t> {
184  template <typename P1, typename P2>
185  void operator()(const P1& src, P2& dst) const {
186  typedef typename channel_type<P1>::type T1;
187  get_color(dst,red_t()) =
188  channel_convert<typename color_element_type<P2,red_t>::type>(
189  channel_invert<T1>(
190  (std::min)(channel_traits<T1>::max_value(),
192  get_color(dst,green_t())=
193  channel_convert<typename color_element_type<P2,green_t>::type>(
194  channel_invert<T1>(
195  (std::min)(channel_traits<T1>::max_value(),
197  get_color(dst,blue_t()) =
198  channel_convert<typename color_element_type<P2,blue_t>::type>(
199  channel_invert<T1>(
200  (std::min)(channel_traits<T1>::max_value(),
202  }
203 };
204 
205 
210 template <>
211 struct default_color_converter_impl<cmyk_t,gray_t> {
212  template <typename P1, typename P2>
213  void operator()(const P1& src, P2& dst) const {
214  get_color(dst,gray_color_t())=
215  channel_convert<typename color_element_type<P2,gray_t>::type>(
218  detail::rgb_to_luminance<typename color_element_type<P1,black_t>::type>(
219  get_color(src,cyan_t()),
220  get_color(src,magenta_t()),
221  get_color(src,yellow_t())
222  )
223  ),
224  channel_invert(get_color(src,black_t()))));
225  }
226 };
227 
228 namespace detail {
229 template <typename Pixel>
230 typename channel_type<Pixel>::type alpha_or_max_impl(const Pixel& p, mpl::true_) {
231  return get_color(p,alpha_t());
232 }
233 template <typename Pixel>
234 typename channel_type<Pixel>::type alpha_or_max_impl(const Pixel& , mpl::false_) {
235  return channel_traits<typename channel_type<Pixel>::type>::max_value();
236 }
237 } // namespace detail
238 
239 // Returns max_value if the pixel has no alpha channel. Otherwise returns the alpha.
240 template <typename Pixel>
241 typename channel_type<Pixel>::type alpha_or_max(const Pixel& p) {
242  return detail::alpha_or_max_impl(p, mpl::contains<typename color_space_type<Pixel>::type,alpha_t>());
243 }
244 
245 
248 template <typename C1>
249 struct default_color_converter_impl<C1,rgba_t> {
250  template <typename P1, typename P2>
251  void operator()(const P1& src, P2& dst) const {
252  typedef typename channel_type<P2>::type T2;
255  get_color(dst,red_t()) =get_color(tmp,red_t());
256  get_color(dst,green_t())=get_color(tmp,green_t());
257  get_color(dst,blue_t()) =get_color(tmp,blue_t());
258  get_color(dst,alpha_t())=channel_convert<T2>(alpha_or_max(src));
259  }
260 };
261 
268 template <typename C2>
269 struct default_color_converter_impl<rgba_t,C2> {
270  template <typename P1, typename P2>
271  void operator()(const P1& src, P2& dst) const {
272  typedef typename channel_type<P1>::type T1;
277  ,dst);
278  }
279 };
280 
283 template <>
284 struct default_color_converter_impl<rgba_t,rgba_t> {
285  template <typename P1, typename P2>
286  void operator()(const P1& src, P2& dst) const {
287  static_for_each(src,dst,default_channel_converter());
288  }
289 };
290 
294 
298  template <typename SrcP, typename DstP>
299  void operator()(const SrcP& src,DstP& dst) const {
300  typedef typename color_space_type<SrcP>::type SrcColorSpace;
301  typedef typename color_space_type<DstP>::type DstColorSpace;
303  }
304 };
305 
310 template <typename SrcP, typename DstP>
311 inline void color_convert(const SrcP& src, DstP& dst) {
312  default_color_converter()(src,dst);
313 }
314 
315 } } // namespace boost::gil
316 
317 #endif
Magenta.
Definition: cmyk.hpp:42
channel_traits< Channel >::value_type channel_invert(Channel x)
Default implementation. Provide overloads for performance.
Definition: channel_algorithm.hpp:532
Support for grayscale color space and variants.
pixel related algorithms
Represents a pixel value (a container of channels). Models: HomogeneousColorBaseValueConcept, PixelValueConcept, HomogeneousPixelBasedConcept.
Definition: metafunctions.hpp:44
Yellow.
Definition: cmyk.hpp:45
metafunctions that construct types or return type properties
channel_traits< Channel >::value_type channel_multiply(Channel a, Channel b)
A function multiplying two channels. result = a * b / max_value.
Definition: channel_algorithm.hpp:510
color_element_reference_type< ColorBase, Color >::type get_color(ColorBase &cb, Color=Color())
Mutable accessor to the element associated with a given color name.
Definition: color_base_algorithm.hpp:185
scoped_channel_value< float, float_point_zero< float >, float_point_one< float >> float32_t
32-bit floating point channel type with range [0.0f ... 1.0f]. Models ChannelValueConcept ...
Definition: typedefs.hpp:130
Green.
Definition: rgb.hpp:40
Same as channel_converter, except it takes the destination channel by reference, which allows us to m...
Definition: channel_algorithm.hpp:429
Support for CMYK color space and variants.
Alpha.
Definition: rgba.hpp:33
Color Convertion function object. To be specialized for every src/dst color space.
Definition: color_convert.hpp:56
Blue.
Definition: rgb.hpp:43
Traits for channels. Contains the following members:
Definition: channel.hpp:114
void color_convert(const SrcP &src, DstP &dst)
helper function for converting one pixel to another using GIL default color-converters where ScrP mod...
Definition: color_convert.hpp:311
red * .3 + green * .59 + blue * .11 + .5
Definition: color_convert.hpp:74
Black.
Definition: cmyk.hpp:48
GIL configuration file.
Red.
Definition: rgb.hpp:37
Gray.
Definition: gray.hpp:34
Cyan.
Definition: cmyk.hpp:39
Channel algorithms.
class for color-converting one pixel to another
Definition: color_convert.hpp:297
pixel class and related utilities
Support for RGB color space and variants.
Support for RGBA color space and variants.
Various utilities not specific to the image library. Some are non-standard STL extensions or generic ...