00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_COLOR_CONVERT_H
00010 #define GIL_COLOR_CONVERT_H
00011
00023
00024 #include "gil_config.hpp"
00025 #include "channel.hpp"
00026 #include "gray.hpp"
00027 #include "rgb.hpp"
00028 #include "rgba.hpp"
00029 #include "cmyk.hpp"
00030 #include "lab.hpp"
00031 #include "hsb.hpp"
00032
00033 #include "utilities.hpp"
00034 #include <functional>
00035
00036 ADOBE_GIL_NAMESPACE_BEGIN
00037
00043
00048
00050 template <typename P1, typename P2>
00051 inline void color_convert(const P1& src, P2& dst) {
00052 typedef typename channel_traits<typename P1::channel_t>::value_type T1;
00053 typedef typename channel_traits<typename P2::channel_t>::value_type T2;
00054 typedef typename P1::color_space_t::base C1;
00055 typedef typename P2::color_space_t::base C2;
00056 detail::_color_converter<T1,C1,T2,C2>()(src,dst);
00057 };
00058
00060 template <typename DST_P>
00061 struct color_converter {
00062 template <typename SRC_P> DST_P operator()(const SRC_P& src) {
00063 DST_P dst;
00064 color_convert(src,dst);
00065 return dst;
00066 }
00067 };
00068
00070
00071 namespace detail {
00072
00075 template <typename C, typename T1, typename T2>
00076 struct _color_converter<T1,C,T2,C> {
00077 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00078 transform_channels(src,dst,channel_converter<T1,T2>());
00079 }
00080 };
00081
00088 template <typename T> T inline rgb_to_luminance(T r, T g, T b) {
00089 return (T)(((boost::uint32_t(r)*4915 + boost::uint32_t(g)*9667 + boost::uint32_t(b)*1802) + 8192) >> 14);
00090 }
00091
00094 template <> bits32f inline rgb_to_luminance<bits32f>(bits32f r, bits32f g, bits32f b) {
00095 return r*0.3f + g*0.59f + b*0.11f + 0.5f;
00096 }
00097
00098
00101 template <typename T1, typename T2>
00102 struct _color_converter<T1,gray_t,T2,rgb_t> {
00103 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00104 dst.red=dst.green=dst.blue=channel_convert<T2>(src.gray);
00105 }
00106 };
00107
00110 template <typename T1, typename T2>
00111 struct _color_converter<T1,gray_t,T2,cmyk_t> {
00112 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00113 dst.cyan=dst.magenta=dst.yellow=0;
00114 dst.black=channel_convert<T2>(src.gray);
00115 }
00116 };
00117
00120 template <typename T1, typename T2>
00121 struct _color_converter<T1,rgb_t,T2,gray_t> {
00122 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00123 dst.gray=channel_convert<T2>(rgb_to_luminance(src.red, src.green, src.blue));
00124 }
00125 };
00126
00127
00135 template <typename T1, typename T2>
00136 struct _color_converter<T1,rgb_t,T2,cmyk_t> {
00137 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00138 dst.cyan=channel_invert(channel_convert<T2>(src.red));
00139 dst.magenta=channel_invert(channel_convert<T2>(src.green));
00140 dst.yellow=channel_invert(channel_convert<T2>(src.blue));
00141 dst.black=std::min(dst.cyan,std::min(dst.magenta,dst.yellow));
00142 float x=float(channel_max_value<T2>()-dst.black);
00143 if (x>0.0001f) {
00144 float x1=channel_max_value<T2>()/x;
00145 dst.cyan=(T2)((dst.cyan-dst.black)*x1);
00146 dst.magenta=(T2)((dst.magenta-dst.black)*x1);
00147 dst.yellow=(T2)((dst.yellow-dst.black)*x1);
00148 } else {
00149 dst.cyan=dst.magenta=dst.yellow=0;
00150 }
00151 }
00152 };
00153
00160 template <typename T1, typename T2>
00161 struct _color_converter<T1,cmyk_t,T2,rgb_t> {
00162 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00163 dst.red =channel_convert<T2>(channel_invert<T1>(std::min(channel_max_value<T1>(), T1(src.cyan*channel_invert(src.black) + src.black))));
00164 dst.green=channel_convert<T2>(channel_invert<T1>(std::min(channel_max_value<T1>(), T1(src.magenta*channel_invert(src.black) + src.black))));
00165 dst.blue =channel_convert<T2>(channel_invert<T1>(std::min(channel_max_value<T1>(), T1(src.yellow*channel_invert(src.black) + src.black))));
00166 }
00167 };
00168
00169
00174 template <typename T1, typename T2>
00175 struct _color_converter<T1,cmyk_t,T2,gray_t> {
00176 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00177 dst.gray=channel_convert<T2>(channel_multiply(channel_invert(rgb_to_luminance(src.cyan, src.magenta, src.yellow)), channel_invert(src.black)));
00178 }
00179 };
00180 }
00181
00184 template <typename DST_P>
00185 struct color_convert_deref_fn {
00186 typedef DST_P value_type;
00187 typedef value_type reference;
00188 typedef const value_type& const_reference;
00189 typedef value_type* pointer;
00190 typedef pointer const const_pointer;
00191
00192 typedef reference result_type;
00193
00194 template <typename I> reference operator()(const I& srcIt) const {
00195 return color_converter<DST_P>()(*srcIt);
00196 }
00197 };
00198
00199
00200 ADOBE_GIL_NAMESPACE_END
00201
00202 #endif
00203