ivl 679
ivl/details/image/impl/color.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 #ifndef IVL_IMAGE_DETAILS_COLOR_HPP
00025 #define IVL_IMAGE_DETAILS_COLOR_HPP
00026 
00027 namespace ivl {
00028 
00029 enum color_space_type
00030 {
00031         other = 0, rgb = 3, rgba = 4
00032 };
00033 
00034 namespace image_details {
00035 
00036 template <enum color_space_type C>
00037 struct col_channels : public types::number<0> { };
00038 
00039 template <>
00040 struct col_channels<rgb> : public types::number<3> { };
00041 
00042 template <>
00043 struct col_channels<rgba> : public types::number<4> { };
00044 
00045 } /* namespace image_details */
00046 
00047 template<class T>
00048 struct color_values { };
00049 
00050 template<>
00051 struct color_values<unsigned char> {
00052         static unsigned char min()      { return 0; }
00053         static unsigned char max()      { return 255; }
00054 };
00055 
00056 template<>
00057 struct color_values<char> {
00058         static char min()       { return -128; }
00059         static char max()       { return 127; }
00060 };
00061 
00062 template<>
00063 struct color_values<short> {
00064         static short min()      { return 0; }
00065         static short max()      { return 255; }
00066 };
00067 
00068 template<>
00069 struct color_values<int> {
00070         static int min()        { return 0; }
00071         static int max()        { return 255; }
00072 };
00073 
00074 template<>
00075 struct color_values<double> {
00076         static double min()     { return 0.0; }
00077         static double max()     { return 1.0; }
00078 };
00079 
00080 template<>
00081 struct color_values<float> {
00082         static double min()     { return 0.0; }
00083         static double max()     { return 1.0; }
00084 };
00085 
00088 template<class T, int N = 0>
00089 class color
00090 : public
00091         types::t_if<types::t_expr<N != 0>,
00092                 array<T, data::fixed<N, data::color_naming> >,
00093                 array<T, tiny> >
00094         ::type
00095 {
00096 private:
00097         class not_a_type { };
00098 
00099         template <int CHAN>
00100         struct disable_chan
00101         {
00102                 typedef typename types::t_if<types::t_expr<(N > CHAN || N == 0)>,
00103                         types::code_word<>, not_a_type>::type type;
00104 
00105 
00106         };
00107 
00108         typedef typename types::t_if<types::t_expr<(N == 0)>,
00109                 types::code_word<>, not_a_type>::type disableifn;
00110 
00111         typedef typename types::t_if<types::t_expr<(N != 0)>,
00112                 types::code_word<>, not_a_type>::type disableif0;
00113 
00114         template<int N0, int K>
00115         struct try_resize
00116         {
00117                 try_resize(color& c)
00118                 {
00119                         CHECK(N == 0 || K == N, erange);
00120                 }
00121         };
00122         template<int K>
00123         struct try_resize<0, K>
00124         {
00125                 try_resize(color& c)
00126                 {
00127                         c.resize(K);
00128                 }
00129         };
00130 
00131         template <class K>
00132         struct disableift
00133         {
00134                 typedef typename types::t_if<types::t_eq<T, K>,
00135                 not_a_type, types::code_word<> >::type type;
00136         };
00137 
00138 protected:
00139 
00140 public:
00141         typedef typename
00142         types::t_if<types::t_expr<N != 0>,
00143                 array<T, data::fixed<N, data::color_naming> >,
00144                 array<T, tiny> >
00145         ::type base_class;
00146 
00147         /*used to be: types::t_if<types::t_expr<N != 0>,
00148                 fixed_array<T, N>, array<T, data::little > >
00149         ::type base_class;*/
00150 
00151         typedef color<T, N> this_type;
00152 
00153         static inline T min_val() { return color_values<T>::min(); }
00154         static inline T max_val() { return color_values<T>::max(); }
00155 
00156         color() { }
00157 
00158         color(T c0) { try_resize<N, 1>(*this); (*this)[0] = c0; }
00159 
00160         color(T c0, T c1) { try_resize<N, 2>(*this);
00161                 (*this)[0] = c0; (*this)[1] = c1; }
00162 
00163         color(T c0, T c1, T c2) { try_resize<N, 3>(*this);
00164                 (*this)[0] = c0; (*this)[1] = c1; (*this)[2] = c2; }
00165 
00166         color(T c0, T c1, T c2, T c3) { try_resize<N, 4>(*this);
00167                 (*this)[0] = c0; (*this)[1] = c1; (*this)[2] = c2; (*this)[3] = c3; }
00168 
00169 
00170         explicit color(size_t count,
00171         typename disableift<size_t>::type = typename disableift<size_t>::type())
00172         : base_class(count) { }
00173 
00174         explicit color(int count,
00175         typename disableift<int>::type = typename disableift<int>::type())
00176         : base_class(count) { }
00177 
00178         explicit color(long int count,
00179         typename disableift<long int>::type = typename disableift<long int>::type())
00180         : base_class(count) { }
00181 
00182         color(size_t count, const T& s,
00183         typename disableift<size_t>::type = typename disableift<size_t>::type())
00184         : base_class(count, s) { }
00185 
00186         template <class D>
00187         color(const array<size_t, D>& size, const T& s)
00188         : base_class(size[0], s) { }
00189 
00190         color(size_t count, const T* s)
00191         : base_class(count, s) { }
00192 
00193         color(const this_type& c) : base_class(c) { }
00194 
00195         template<class S>
00196         color(const array<T, S>& a, size_t n) : base_class(a, n) { }
00197 
00198         template<class S>
00199         color(const array<T, S>& a) : base_class(a) { }
00200 
00201         template<class S>
00202         color(size_t count, const array<T, S>& a) : base_class(count, a) { }
00203 
00204 
00205         const T& val(typename disable_chan<0>::type =
00206                 typename disable_chan<0>::type()) const
00207                 { return (*this)[0]; }
00208 
00209         T& val(typename disable_chan<0>::type =
00210                 typename disable_chan<0>::type())
00211                 { return (*this)[0]; }
00212 
00213 };
00214 
00215 template <class T, int N>
00216 color<T, 4> rgb2rgba(const color<T, N>& c)
00217 {
00218         color<T, 4> r;
00219         r[0] = c[0];
00220         r[1] = c[1];
00221         r[2] = c[2];
00222         r[3] = color<T, 4>::max_val();
00223         return r;
00224 }
00225 
00226 template <class T, int N>
00227 color<T, 3> rgba2rgb(const color<T, N>& c)
00228 {
00229         color<T, 3> r;
00230         r[0] = c[0];
00231         r[1] = c[1];
00232         r[2] = c[2];
00233         return r;
00234 }
00235 
00236 template <class T, enum color_space_type C>
00237 struct color_type
00238 {
00239         color_type() {}
00240         template<class X>
00241         color_type(const X& x) {}
00242 };
00243 
00244 template <class T, enum color_space_type C>
00245 inline
00246 color<T, int(image_details::col_channels<C>::value)> white(
00247         color_type<T, C> = 0)
00248 {
00249         enum { n = image_details::col_channels<C>::value };
00250         return color<T, n>(fixed_array<size_t, 1>(n == 0 ? 3 : n),
00251                 color<T, n>::max_val());
00252 }
00253 
00254 template <class T, enum color_space_type C>
00255 inline
00256 color<T, image_details::col_channels<C>::value> black(
00257         color_type<T, C> = 0)
00258 {
00259         enum { n = image_details::col_channels<C>::value };
00260         return color<T, n>(fixed_array<size_t, 1>(n == 0 ? 3 : n),
00261                 color<T, n>::min_val());
00262 }
00263 
00264 } /* namespace ivl */
00265 
00266 #endif // IVL_IMAGE_DETAILS_COLOR_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations