Adobe Systems, Inc.

color_convert.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2006 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://opensource.adobe.com/licenses.html)
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 }   // namespace detail
00181 
00184 template <typename DST_P>
00185 struct color_convert_deref_fn {
00186     typedef DST_P               value_type;
00187     typedef value_type          reference;      // read-only dereferencing
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 

Copyright © 2006 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google