Go to the documentation of this file.00001 #ifndef vgui_range_map_txx_
00002 #define vgui_range_map_txx_
00003
00004 #include "vgui_range_map.h"
00005
00006 #include <vcl_cassert.h>
00007 #include <vcl_cmath.h>
00008 #include <vcl_limits.h>
00009
00010 template <class Type>
00011 void vgui_range_map<Type>::init_map_domain(const Type min, const Type max,
00012 long double& ratio)
00013 {
00014 assert(max>=min);
00015 assert(!vcl_numeric_limits<Type>::has_infinity ||
00016 (-min != vcl_numeric_limits<Type>::infinity() &&
00017 max != vcl_numeric_limits<Type>::infinity()));
00018 ratio = 1.0;
00019 if (max!=min)
00020 ratio = 1.0/(max - min);
00021 }
00022
00023
00024 template <class Type>
00025 void vgui_range_map<Type>::init()
00026 {
00027 if (n_components_==1)
00028 init_map_domain(Type(min_L_), Type(max_L_), ratio_L_);
00029 else if (n_components_==3||n_components_==4)
00030 {
00031 init_map_domain(Type(min_R_), Type(max_R_), ratio_R_);
00032 init_map_domain(Type(min_G_), Type(max_G_), ratio_G_);
00033 init_map_domain(Type(min_B_), Type(max_B_), ratio_B_);
00034 }
00035 if (n_components_==4)
00036 init_map_domain(Type(min_X_), Type(max_X_), ratio_X_);
00037 }
00038
00039
00040 template <class Type>
00041 vxl_byte vgui_range_map<Type>::
00042 map_pixel_byte(const Type pix, const Type min, const Type max,
00043 const float gamma, const long double ratio)
00044 {
00045 int num_bits = (sizeof(Type)*8);
00046 if (num_bits==1) {
00047 if (pix)
00048 return 255;
00049 else
00050 return 0;
00051 }
00052
00053 long double y = pix;
00054 y = (y < (long double)min) ? (long double)min : (y > (long double)max) ? (long double)max : y;
00055 if (invert_)
00056 y = (long double)max - y;
00057 else
00058 y -= (long double)min;
00059
00060
00061 y *= ratio;
00062
00063 if (gamma > 0 && gamma !=1)
00064 y = vcl_pow((long double)y, (long double)1/gamma);
00065 return static_cast<vxl_byte>((y*255.0) +0.5);
00066 }
00067
00068
00069 template <class Type>
00070 float vgui_range_map<Type>::
00071 map_pixel_float(const Type pix, const Type min, const Type max,
00072 const float gamma, const long double ratio)
00073 {
00074 int num_bits = (sizeof(Type)*8);
00075 if (num_bits==1) {
00076 if (pix)
00077 return 1.0f;
00078 else
00079 return 0.0f;
00080 }
00081
00082 long double y = pix;
00083 y = (y < (long double)min) ? (long double)min: (y > (long double)max) ? (long double)max : y;
00084 if (invert_)
00085 y = (long double)max - y;
00086 else
00087 y -= (long double)min;
00088
00089
00090 y *=ratio;
00091
00092 if (gamma > 0 && gamma!=1)
00093 y = vcl_pow((long double)y, (long double)1/gamma);
00094 return static_cast<float>(y);
00095 }
00096
00097 template <class Type>
00098 vbl_array_1d<vxl_byte> vgui_range_map<Type>::
00099 compute_byte_table(const Type min, const Type max, const float gamma,
00100 const long double ratio)
00101 {
00102 vbl_array_1d<vxl_byte> bmap(size_, 0);
00103
00104 if (!vcl_numeric_limits<Type>::is_signed)
00105 for (unsigned long i = 0; i < size_; i++)
00106 bmap[i] = map_pixel_byte(static_cast<Type>(i), min, max, gamma, ratio);
00107 else
00108 {
00109
00110 long mint = static_cast<long>(vcl_numeric_limits<Type>::min());
00111 long maxt = static_cast<long>(vcl_numeric_limits<Type>::max());
00112 long range = static_cast<long>(maxt-mint);
00113 for (long i = 0; i <= range; ++i)
00114 bmap[i] = map_pixel_byte(static_cast<Type>(i+mint), min, max,
00115 gamma, ratio);
00116 }
00117 return bmap;
00118 }
00119
00120
00121 template <class Type>
00122 vbl_array_1d<float> vgui_range_map<Type>::
00123 compute_float_table(const Type min, const Type max, const float gamma,
00124 const long double ratio)
00125 {
00126 vbl_array_1d<float> null;
00127 if (vcl_numeric_limits<Type>::is_signed)
00128 return null;
00129 vbl_array_1d<float> fmap(size_, 0);
00130 Type maxt = vcl_numeric_limits<Type>::max();
00131 for (unsigned int i = 0; i <= (unsigned int)maxt; ++i)
00132 fmap[i] = map_pixel_float(Type(i), min, max, gamma, ratio);
00133 return fmap;
00134 }
00135
00136 template <class Type>
00137 vgui_range_map<Type>::vgui_range_map(vgui_range_map_params const& rmp)
00138 : vgui_range_map_params(rmp)
00139 {
00140 this->init();
00141 mapable_ = true;
00142 table_mapable_ = true;
00143 int num_bits = (sizeof(Type)*8);
00144 if (num_bits==1 || num_bits>16 || !vcl_numeric_limits<Type>::is_integer)
00145 table_mapable_ = false;
00146
00147
00148
00149 if (table_mapable_)
00150 size_ = 1 << num_bits;
00151
00152
00153
00154 if (!table_mapable_)
00155 size_ = 0;
00156 }
00157
00158 template <class Type>
00159 vgui_range_map<Type>::~vgui_range_map()
00160 {
00161 }
00162
00163
00164
00165 template <class Type>
00166 int vgui_range_map<Type>::offset()
00167 {
00168 if (table_mapable_)
00169 return - (int)vcl_numeric_limits<Type>::min();
00170 else
00171 return 0;
00172 }
00173
00174 #undef VGUI_RANGE_MAP_INSTANTIATE
00175 #define VGUI_RANGE_MAP_INSTANTIATE(T) \
00176 template class vgui_range_map<T >
00177
00178 #endif // vgui_range_map_txx_