Generic Image Library: color_convert.hpp Source File

###  | #  |

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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>
56 struct default_color_converter_impl {};
57
60 template <typename C>
61 struct default_color_converter_impl<C,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>
74 struct rgb_to_luminance_fn {
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())=
122 channel_traits<typename color_element_type<P2, cyan_t >::type>::min_value();
123 get_color(dst,magenta_t())=
124 channel_traits<typename color_element_type<P2, magenta_t>::type>::min_value();
125 get_color(dst,yellow_t())=
126 channel_traits<typename color_element_type<P2, yellow_t >::type>::min_value();
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(),
191 T1(channel_multiply(get_color(src,cyan_t()),channel_invert(get_color(src,black_t())))+get_color(src,black_t())))));
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(),
196 T1(channel_multiply(get_color(src,magenta_t()),channel_invert(get_color(src,black_t())))+get_color(src,black_t())))));
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(),
201 T1(channel_multiply(get_color(src,yellow_t()),channel_invert(get_color(src,black_t())))+get_color(src,black_t())))));
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>(
216 channel_multiply(
217 channel_invert(
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;
253 pixel<T2,rgb_layout_t> tmp;
254 default_color_converter_impl<C1,rgb_t>()(src,tmp);
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;
273 default_color_converter_impl<rgb_t,C2>()(
274 pixel<T1,rgb_layout_t>(channel_multiply(get_color(src,red_t()), get_color(src,alpha_t())),
275 channel_multiply(get_color(src,green_t()),get_color(src,alpha_t())),
276 channel_multiply(get_color(src,blue_t()), get_color(src,alpha_t())))
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
297 struct default_color_converter {
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;
302 default_color_converter_impl<SrcColorSpace,DstColorSpace>()(src,dst);
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
boost::gil::magenta_t
Magenta.
Definition: cmyk.hpp:42
boost::gil::channel_invert
channel_traits< Channel >::value_type channel_invert(Channel x)
Default implementation. Provide overloads for performance.
Definition: channel_algorithm.hpp:532
gray.hpp
Support for grayscale color space and variants.
color_base_algorithm.hpp
pixel related algorithms
boost::gil::pixel
Represents a pixel value (a container of channels). Models: HomogeneousColorBaseValueConcept, PixelValueConcept, HomogeneousPixelBasedConcept.
Definition: metafunctions.hpp:44
boost::gil::yellow_t
Yellow.
Definition: cmyk.hpp:45
metafunctions.hpp
metafunctions that construct types or return type properties
boost::gil::channel_multiply
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
boost::gil::get_color
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
boost::gil::float32_t
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
boost::gil::green_t
Green.
Definition: rgb.hpp:40
boost::gil::default_channel_converter
Same as channel_converter, except it takes the destination channel by reference, which allows us to m...
Definition: channel_algorithm.hpp:429
cmyk.hpp
Support for CMYK color space and variants.
boost::gil::alpha_t
Alpha.
Definition: rgba.hpp:33
boost::gil::default_color_converter_impl
Color Convertion function object. To be specialized for every src/dst color space.
Definition: color_convert.hpp:56
boost::gil::blue_t
Blue.
Definition: rgb.hpp:43
boost::gil::channel_traits
Traits for channels. Contains the following members:
Definition: channel.hpp:114
boost::gil::color_convert
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
boost::gil::detail::rgb_to_luminance_fn
red * .3 + green * .59 + blue * .11 + .5
Definition: color_convert.hpp:74
boost::gil::black_t
Black.
Definition: cmyk.hpp:48
gil_config.hpp
GIL configuration file.
boost::gil::red_t
Red.
Definition: rgb.hpp:37
boost::gil::gray_color_t
Gray.
Definition: gray.hpp:34
boost::gil::cyan_t
Cyan.
Definition: cmyk.hpp:39
channel_algorithm.hpp
Channel algorithms.
boost::gil::default_color_converter
class for color-converting one pixel to another
Definition: color_convert.hpp:297
pixel.hpp
pixel class and related utilities
rgb.hpp
Support for RGB color space and variants.
rgba.hpp
Support for RGBA color space and variants.
utilities.hpp
Various utilities not specific to the image library. Some are non-standard STL extensions or generic ...