00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_CHANNEL_H
00010 #define GIL_CHANNEL_H
00011
00022
00023 #include "gil_config.hpp"
00024 #include <boost/cstdint.hpp>
00025 #include "utilities.hpp"
00026
00027 ADOBE_GIL_NAMESPACE_BEGIN
00028
00030
00031
00034 typedef boost::uint8_t bits8;
00036 typedef boost::uint16_t bits16;
00038 typedef float bits32f;
00040 typedef double bits64f;
00042
00045 template <typename T>
00046 struct channel_traits {
00047 typedef T value_type;
00048 typedef T& reference;
00049 typedef T* pointer;
00050 typedef const T& const_reference;
00051 typedef T const* const_pointer;
00052 BOOST_STATIC_CONSTANT(bool, is_mutable=true);
00053 };
00054
00056 template <typename T> struct channel_traits<T&> : public channel_traits<T> {};
00057
00059 template <typename T>
00060 struct channel_traits<const T> {
00061 typedef T value_type;
00062 typedef typename channel_traits<T>::const_reference reference;
00063 typedef typename channel_traits<T>::const_pointer pointer;
00064 typedef reference const_reference;
00065 typedef pointer const_pointer;
00066 BOOST_STATIC_CONSTANT(bool, is_mutable=false);
00067 };
00068
00070 template <typename T> struct channel_traits<const T&> : public channel_traits<const T> {};
00071
00072
00076
00078 template <typename T> T inline channel_min_value() { return std::numeric_limits<T>::min(); }
00079 template <typename T> T inline channel_max_value() { return std::numeric_limits<T>::max(); }
00080
00081 template<> inline bits8 channel_min_value<bits8>() { return 0; }
00082 template<> inline bits8 channel_max_value<bits8>() { return 255; }
00083
00084 template<> inline bits16 channel_min_value<bits16>() { return 0; }
00085 template<> inline bits16 channel_max_value<bits16>() { return 32768; }
00086
00087 template<> inline bits32f channel_min_value<bits32f>() { return 0.0f; }
00088 template<> inline bits32f channel_max_value<bits32f>() { return 1.0f; }
00090
00091
00095
00098 template <typename dstT, typename srcT>
00099 inline dstT _channel_convert(srcT val);
00100
00101
00102 template <>
00103 inline bits8 _channel_convert<bits8>(bits8 b) { return b; }
00104
00105 template <>
00106 inline bits8 _channel_convert<bits8>(bits16 s) { return static_cast<bits8>(s/257); }
00107
00108 template <>
00109 inline bits8 _channel_convert<bits8>(bits32f f) { return static_cast<bits8>(f*255); }
00110
00111 template <>
00112 inline bits8 _channel_convert<bits8>(bits64f d) { return static_cast<bits8>(d*255); }
00113
00114
00115 template <>
00116 inline bits16 _channel_convert<bits16>(bits8 b) { return b*(bits16)257; }
00117
00118 template <>
00119 inline bits16 _channel_convert<bits16>(bits16 s) { return s; }
00120
00121 template <>
00122 inline bits16 _channel_convert<bits16>(bits32f f) { return static_cast<bits16>(f*32768); }
00123
00124 template <>
00125 inline bits16 _channel_convert<bits16>(bits64f d) { return static_cast<bits16>(d*32768); }
00126
00127
00128 template <>
00129 inline bits32f _channel_convert<bits32f>(bits8 b) { return b/255.0f; }
00130
00131 template <>
00132 inline bits32f _channel_convert<bits32f>(bits16 s) { return s/32768.0f; }
00133
00134 template <>
00135 inline bits32f _channel_convert<bits32f>(bits32f f) { return f; }
00136
00137 template <>
00138 inline bits32f _channel_convert<bits32f>(bits64f d) { return (bits32f)d; }
00139
00140
00141 template <>
00142 inline bits64f _channel_convert<bits64f>(bits8 b) { return b/(bits64f)255.0; }
00143
00144 template <>
00145 inline bits64f _channel_convert<bits64f>(bits16 s) { return s/(bits64f)32768.0; }
00146
00147 template <>
00148 inline bits64f _channel_convert<bits64f>(bits32f f) { return (bits64f)f; }
00149
00150 template <>
00151 inline bits64f _channel_convert<bits64f>(bits64f d) { return d; }
00152
00153 template <typename dstT, typename srcT>
00154 inline typename channel_traits<dstT>::value_type channel_convert(srcT val) {
00155 return _channel_convert<typename channel_traits<dstT>::value_type>(val);
00156 }
00157
00158 template <typename srcT, typename dstT>
00159 struct channel_converter {
00160 inline dstT operator()(srcT src) const { return channel_convert<dstT>(src); }
00161 };
00162
00164
00165 namespace detail {
00167 inline boost::uint32_t div255(boost::uint32_t in) { boost::uint32_t tmp=in+128; return (tmp + (tmp>>8))>>8; }
00168
00170 inline boost::uint32_t div32768(boost::uint32_t in) { return (in+16384)>>15; }
00171 }
00172
00176
00178
00179 template <typename T>
00180 inline T channel_multiply(T a, T b) { std::exception("channel_multiply is not implemented for this channel type"); }
00181
00182 inline bits8 channel_multiply(bits8 a, bits8 b) {
00183 return bits8(detail::div255(boost::uint32_t(a) * boost::uint32_t(b)));
00184 }
00185
00186 inline bits16 channel_multiply(bits16 a, bits16 b) {
00187 return bits16(detail::div32768(boost::uint32_t(a) * boost::uint32_t(b)));
00188 }
00189
00190 inline bits32f channel_multiply(bits32f a, bits32f b) { return a*b; }
00191
00192 inline bits64f channel_multiply(bits64f a, bits64f b) { return a*b; }
00194
00195
00199
00201 template <typename T>
00202 inline T channel_invert(T x) { return channel_max_value<T>()-x + channel_min_value<T>(); }
00204
00205
00206 ADOBE_GIL_NAMESPACE_END
00207
00208 #endif