00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_RGBA_H
00010 #define GIL_RGBA_H
00011
00019
00020 #include "gil_config.hpp"
00021 #include <boost/type_traits.hpp>
00022
00023 ADOBE_GIL_NAMESPACE_BEGIN
00024
00025
00026 template <typename T, typename C> struct pixel;
00027 namespace detail { template <typename T, typename C> struct color_base; }
00028 template <typename IC, typename C> struct planar_ptr;
00029 template <typename IC, typename C> struct planar_ptr_base;
00030
00034
00037 struct rgba_t {
00038 typedef rgba_t base;
00039 BOOST_STATIC_CONSTANT(int, num_channels=4);
00040 };
00041
00044 struct argb_t : public rgba_t {};
00045
00048 struct abgr_t : public rgba_t {};
00049
00052 struct bgra_t : public rgba_t {};
00053
00054 namespace detail {
00064 template <typename T>
00065 struct color_base<T,rgba_t> : public homogeneous_color_base<T> {
00066 T red,green,blue,alpha;
00067
00068 color_base() {}
00069 color_base(T v0, T v1, T v2, T v3) : red(v0), green(v1), blue(v2), alpha(v3) {}
00070 template <typename T1, typename C1> color_base(const color_base<T1,C1>& c) : red(c.red), green(c.green), blue(c.blue), alpha(c.alpha) {}
00071 template <typename T1, typename C1> color_base( color_base<T1,C1>& c) : red(c.red), green(c.green), blue(c.blue), alpha(c.alpha) {}
00072 };
00073
00082 template <typename T>
00083 struct color_base<T,argb_t> : public homogeneous_color_base<T> {
00084 T alpha,red,green,blue;
00085
00086 color_base() {}
00087 color_base(T v0, T v1, T v2, T v3) : alpha(v0), red(v1), green(v2), blue(v3) {}
00088 template <typename T1, typename C1> color_base(const color_base<T1,C1>& c) : alpha(c.alpha),red(c.red),green(c.green),blue(c.blue) {}
00089 };
00090
00099 template <typename T>
00100 struct color_base<T,abgr_t> : public homogeneous_color_base<T> {
00101 T alpha,blue,green,red;
00102
00103 color_base() {}
00104 color_base(T v0, T v1, T v2, T v3) : alpha(v0), red(v1), green(v2), blue(v3) {}
00105 template <typename T1, typename C1> color_base(const color_base<T1,C1>& c) : alpha(c.alpha),red(c.red),green(c.green),blue(c.blue) {}
00106 };
00107
00116 template <typename T>
00117 struct color_base<T,bgra_t> : public homogeneous_color_base<T> {
00118 T blue,green,red,alpha;
00119
00120 color_base() {}
00121 color_base(T v0, T v1, T v2, T v3) : alpha(v0), red(v1), green(v2), blue(v3) {}
00122 template <typename T1, typename C1> color_base(const color_base<T1,C1>& c) : alpha(c.alpha),red(c.red),green(c.green),blue(c.blue) {}
00123 };
00124
00125 }
00126 ADOBE_GIL_NAMESPACE_END
00127
00128 #include "pixel_iterator.hpp"
00129
00130
00131 ADOBE_GIL_NAMESPACE_BEGIN
00132
00136
00143 template <typename IC>
00144 struct planar_ptr<IC,rgba_t> : public planar_ptr_base<IC,rgba_t> {
00145 typedef planar_ptr_base<IC,rgba_t> parent_t;
00146 typedef typename parent_t::value_type value_type;
00147 typedef typename parent_t::reference reference;
00148 typedef typename parent_t::color_space_t color_space_t;
00149
00150 planar_ptr() : parent_t(0,0,0,0) {}
00151 planar_ptr(IC ir, IC ig, IC ib, IC ia) : parent_t(ir,ig,ib,ia) {}
00152
00153 template <typename IC1,typename C1> planar_ptr(const planar_ptr<IC1,C1>& ptr) : parent_t(ptr) {}
00154 template <typename IC1,typename C1> planar_ptr& operator=(const planar_ptr<IC1,C1>& ptr) { parent_t::operator=(ptr); return *this; }
00155
00159 template <typename P> planar_ptr(P* pix) :
00160 parent_t(&pix->template semantic_channel<0>(),&pix->template semantic_channel<1>(), &pix->template semantic_channel<2>(), &pix->template semantic_channel<3>()) {
00161 boost::function_requires<PixelsCompatibleConcept<P,value_type> >();
00162 }
00163
00164 template <typename P> planar_ptr& operator=(P* pix) {
00165 boost::function_requires<PixelsCompatibleConcept<P,value_type> >();
00166 this->template semantic_channel<0>()=&pix->template semantic_channel<0>();
00167 this->template semantic_channel<1>()=&pix->template semantic_channel<1>();
00168 this->template semantic_channel<2>()=&pix->template semantic_channel<2>();
00169 this->template semantic_channel<3>()=&pix->template semantic_channel<3>();
00170 return *this;
00171 }
00172
00173 reference dereference() const { return reference(*(this->template semantic_channel<0>()),
00174 *(this->template semantic_channel<1>()),
00175 *(this->template semantic_channel<2>()),
00176 *(this->template semantic_channel<3>())); }
00177 };
00178
00181 template <typename IC>
00182 inline planar_ref<typename std::iterator_traits<IC>::reference,rgba_t> byte_advanced_ref(const planar_ptr_base<IC,rgba_t>& p, std::ptrdiff_t byteDiff) {
00183 return planar_ref<typename std::iterator_traits<IC>::reference,rgba_t>(*byte_advanced(p.red, byteDiff), *byte_advanced(p.green, byteDiff),
00184 *byte_advanced(p.blue, byteDiff), *byte_advanced(p.alpha, byteDiff));
00185 }
00186
00187 template <typename T> T alpha(const pixel<T, rgba_t>& p) { return p.alpha; }
00188
00189
00190 template <typename dstT, typename srcT> inline typename channel_traits<dstT>::value_type channel_convert(srcT val);
00191 template <typename srcT, typename dstT> struct channel_converter;
00192
00193 namespace detail {
00196 template <typename C1, typename T1, typename T2>
00197 struct _color_converter<T1,C1,T2,rgba_t> {
00198 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00199 pixel<T2,rgb_t> tmp;
00200 _color_converter<T1,C1,T2,rgb_t>()(src,tmp);
00201 dst.red=tmp.red;
00202 dst.green=tmp.green;
00203 dst.blue=tmp.blue;
00204 dst.alpha=channel_convert<T2>(alpha(src));
00205 }
00206 };
00207
00214 template <typename C2, typename T1, typename T2>
00215 struct _color_converter<T1,rgba_t,T2,C2> {
00216 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00217 _color_converter<T1,rgb_t,T2,C2>()(
00218 pixel<T1,rgb_t>(channel_multiply(src.red,src.alpha), channel_multiply(src.green,src.alpha), channel_multiply(src.blue,src.alpha))
00219 ,dst);
00220 }
00221 };
00222
00225 template <typename T1, typename T2>
00226 struct _color_converter<T1,rgba_t,T2,rgba_t> {
00227 template <typename P1, typename P2> void operator()(const P1& src, P2& dst) {
00228 transform_channels(src,dst,channel_converter<T1,T2>());
00229 }
00230 };
00231 }
00232
00233 namespace detail {
00234 template <typename CS,int N> struct channel_accessor;
00235
00237 template <>
00238 struct channel_accessor<rgba_t,0> {
00239 template <typename P> typename P::template kth_element_t<0>::reference operator()( P& p) const {return p.red;}
00240 template <typename P> typename P::template kth_element_t<0>::const_reference operator()(const P& p) const {return p.red;}
00241 };
00242
00244 template <>
00245 struct channel_accessor<rgba_t,1> {
00246 template <typename P> typename P::template kth_element_t<1>::reference operator()( P& p) const {return p.green;}
00247 template <typename P> typename P::template kth_element_t<1>::const_reference operator()(const P& p) const {return p.green;}
00248 };
00249
00251 template <>
00252 struct channel_accessor<rgba_t,2> {
00253 template <typename P> typename P::template kth_element_t<2>::reference operator()( P& p) const {return p.blue;}
00254 template <typename P> typename P::template kth_element_t<2>::const_reference operator()(const P& p) const {return p.blue;}
00255 };
00256
00258 template <>
00259 struct channel_accessor<rgba_t,3> {
00260 template <typename P> typename P::template kth_element_t<3>::reference operator()( P& p) const {return p.alpha;}
00261 template <typename P> typename P::template kth_element_t<3>::const_reference operator()(const P& p) const {return p.alpha;}
00262 };
00263
00265 template <>
00266 struct channel_accessor<argb_t,0> {
00267 template <typename P> typename P::template kth_element_t<0>::reference operator()( P& p) const {return p.alpha;}
00268 template <typename P> typename P::template kth_element_t<0>::const_reference operator()(const P& p) const {return p.alpha;}
00269 };
00270
00272 template <>
00273 struct channel_accessor<argb_t,1> {
00274 template <typename P> typename P::template kth_element_t<1>::reference operator()( P& p) const {return p.red;}
00275 template <typename P> typename P::template kth_element_t<1>::const_reference operator()(const P& p) const {return p.red;}
00276 };
00277
00279 template <>
00280 struct channel_accessor<argb_t,2> {
00281 template <typename P> typename P::template kth_element_t<2>::reference operator()( P& p) const {return p.green;}
00282 template <typename P> typename P::template kth_element_t<2>::const_reference operator()(const P& p) const {return p.green;}
00283 };
00284
00286 template <>
00287 struct channel_accessor<argb_t,3> {
00288 template <typename P> typename P::template kth_element_t<3>::reference operator()( P& p) const {return p.blue;}
00289 template <typename P> typename P::template kth_element_t<3>::const_reference operator()(const P& p) const {return p.blue;}
00290 };
00291
00292
00293
00295 template <>
00296 struct channel_accessor<bgra_t,0> {
00297 template <typename P> typename P::template kth_element_t<0>::reference operator()( P& p) const {return p.blue;}
00298 template <typename P> typename P::template kth_element_t<0>::const_reference operator()(const P& p) const {return p.blue;}
00299 };
00300
00302 template <>
00303 struct channel_accessor<bgra_t,1> {
00304 template <typename P> typename P::template kth_element_t<1>::reference operator()( P& p) const {return p.green;}
00305 template <typename P> typename P::template kth_element_t<1>::const_reference operator()(const P& p) const {return p.green;}
00306 };
00307
00309 template <>
00310 struct channel_accessor<bgra_t,2> {
00311 template <typename P> typename P::template kth_element_t<2>::reference operator()( P& p) const {return p.red;}
00312 template <typename P> typename P::template kth_element_t<2>::const_reference operator()(const P& p) const {return p.red;}
00313 };
00314
00316 template <>
00317 struct channel_accessor<bgra_t,3> {
00318 template <typename P> typename P::template kth_element_t<3>::reference operator()( P& p) const {return p.alpha;}
00319 template <typename P> typename P::template kth_element_t<3>::const_reference operator()(const P& p) const {return p.alpha;}
00320 };
00321
00322
00324 template <>
00325 struct channel_accessor<abgr_t,0> {
00326 template <typename P> typename P::template kth_element_t<0>::reference operator()( P& p) const {return p.alpha;}
00327 template <typename P> typename P::template kth_element_t<0>::const_reference operator()(const P& p) const {return p.alpha;}
00328 };
00329
00331 template <>
00332 struct channel_accessor<abgr_t,1> {
00333 template <typename P> typename P::template kth_element_t<1>::reference operator()( P& p) const {return p.blue;}
00334 template <typename P> typename P::template kth_element_t<1>::const_reference operator()(const P& p) const {return p.blue;}
00335 };
00336
00338 template <>
00339 struct channel_accessor<abgr_t,2> {
00340 template <typename P> typename P::template kth_element_t<2>::reference operator()( P& p) const {return p.green;}
00341 template <typename P> typename P::template kth_element_t<2>::const_reference operator()(const P& p) const {return p.green;}
00342 };
00343
00345 template <>
00346 struct channel_accessor<abgr_t,3> {
00347 template <typename P> typename P::template kth_element_t<3>::reference operator()( P& p) const {return p.red;}
00348 template <typename P> typename P::template kth_element_t<3>::const_reference operator()(const P& p) const {return p.red;}
00349 };
00350
00351 }
00352 ADOBE_GIL_NAMESPACE_END
00353
00354 #endif