ivl 679
|
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