core/vgui/vgui_range_map.h
Go to the documentation of this file.
00001 // This is core/vgui/vgui_range_map.h
00002 #ifndef vgui_range_map_h
00003 #define vgui_range_map_h
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author  J.L. Mundy
00010 // \brief A mapping from pixels to 8 bit display range
00011 //
00012 //  Supports pixel look-up table mapping for contrast adjustment
00013 //  and other interactive controls of the image display range
00014 //  A key application is producing usable display of 16 bit pixels
00015 //  Can be used to interactively window the dynamic range of 8 bit pixels
00016 //  or to display signed char or signed short.
00017 //
00018 //  For byte and short pixel types, the mapping is implemented using
00019 //  a look-up table.
00020 //
00021 //  When mapping can be done by a look_up table, there are two
00022 //  table types available (* = [L,R,G,B,A]):
00023 //     ::*map()  - rmap[in_pixel]->vxl_byte
00024 //     ::f*map() - frmap[in_pixe]->float
00025 //
00026 //     *map is used to map the image pixels during conversion to
00027 //     display pixels carried out by vgui_section_buffer. The range of
00028 //     this map is [0 256], which is the unclamped range in vgui_pixel.
00029 //
00030 //     *fmap is used to directly map image pixels using the OpenGL
00031 //     glPixelMapf() mapping function. The best form for a glPixelMap
00032 //     is an array of floats on the range [0,1] and is provided by frmap.
00033 //
00034 // For pixel types with a larger dynamic range than can
00035 // be stored in a table, the pixel conversion is done on the fly, using
00036 // the ::map_pixel(in_pixel) method. This function is applied in
00037 // vgui_section_buffer during pixel conversion.
00038 //
00039 // The gamma  mapping function is defined as,
00040 //                  y = (x)^(1/gamma)
00041 // which accounts for the standard photometric gamma correction.
00042 // Note on Gamma (by Joel Savaric 1998):
00043 // 1/gamma is used to be consistent with other software like Photoshop,
00044 // Paintshop pro, GIMP or xv, that raise to the power of 1/gamma when
00045 // making gamma correction. Gamma correction is considered to be a
00046 // correction of the hardware setting. Monitors raise the input voltage to a
00047 // power of gamma (generally gamma=1.7 or 2.5) When you want to correct the
00048 // gamma of the monitor your raise to the power of 1/gamma.
00049 // (for more detail see http://www.cgsd.com/papers/gamma.html)
00050 //
00051 // The map can also be inverted, i.e. swapping dark and light intensity values,
00052 //                  in = max(in)-in;
00053 //
00054 // The map is recomputed whenever the domain limits, gamma or invert parameters
00055 // are changed.
00056 //
00057 // Notes:
00058 //
00059 //   In GUI applications, the dynamic mouse motion pixel display should show
00060 //   the source pixel values before mapping, not the frame buffer values.
00061 //
00062 //   The current scheme can easily be extended to full color support if the
00063 //   need arises. The number of maps has to be extended to three
00064 //   (four with an alpha channel or multi-spectras) as well as
00065 //   increasing the number of mapping parameters.
00066 //
00067 // \verbatim
00068 //  Modifications
00069 //   <none>
00070 // \endverbatim
00071 #include <vxl_config.h>
00072 #include <vbl/vbl_array_1d.h>
00073 #include <vgui/vgui_range_map_params.h>
00074 
00075 template <class Type>
00076 class vgui_range_map : public vgui_range_map_params
00077 {
00078  public:
00079   vgui_range_map(vgui_range_map_params const& rmp);
00080   ~vgui_range_map();
00081 
00082   //: Is the pixel type mapable at all
00083   bool mapable() const {return mapable_;}
00084 
00085   //: Is the pixel type mapable by a lookup table
00086   bool table_mapable() const {return table_mapable_;}
00087 
00088   //: Get the number of elements in the mapping tables
00089   unsigned map_size() const {return size_;}
00090 
00091   // get the software range maps (byte range)
00092 
00093   //: Luminance map
00094   vbl_array_1d<vxl_byte> Lmap() {return this->compute_byte_table(Type(min_L_), Type(max_L_), gamma_L_, ratio_L_);}
00095   //: Red Channel map
00096   vbl_array_1d<vxl_byte> Rmap() {return this->compute_byte_table(Type(min_R_), Type(max_R_), gamma_R_, ratio_R_);}
00097   //: Green Channel map
00098   vbl_array_1d<vxl_byte> Gmap() {return this->compute_byte_table(Type(min_G_), Type(max_G_), gamma_G_, ratio_G_);}
00099   //: Blue Channel map
00100   vbl_array_1d<vxl_byte> Bmap() {return this->compute_byte_table(Type(min_B_), Type(max_B_), gamma_B_, ratio_B_);}
00101   //: Alpha or Infrared Channel map
00102   vbl_array_1d<vxl_byte> Xmap() {return this->compute_byte_table(Type(min_X_), Type(max_X_), gamma_X_, ratio_X_);}
00103 
00104   // get the OpenGL hardware range maps (float [0, 1] range)
00105 
00106   //: Luminance hardware map
00107   vbl_array_1d<float> fLmap() {return this->compute_float_table(Type(min_L_), Type(max_L_), gamma_L_, ratio_L_);}
00108   //: Red channel hardware map
00109   vbl_array_1d<float> fRmap() {return this->compute_float_table(Type(min_R_), Type(max_R_), gamma_R_, ratio_R_);}
00110   //: Green channel hardware map
00111   vbl_array_1d<float> fGmap() {return this->compute_float_table(Type(min_G_), Type(max_G_), gamma_G_, ratio_G_);}
00112   //: Blue channel hardware map
00113   vbl_array_1d<float> fBmap() {return this->compute_float_table(Type(min_B_), Type(max_B_), gamma_B_, ratio_B_);}
00114   //: Alpha or Infrared channel hardware map
00115   vbl_array_1d<float> fXmap() {return this->compute_float_table(Type(min_X_), Type(max_X_), gamma_X_, ratio_X_);}
00116 
00117   //: Luminance computed map
00118   vxl_byte map_L_pixel(const Type pix) {return this->map_pixel_byte(pix, Type(min_L_), Type(max_L_), gamma_L_, ratio_L_);}
00119   //: Red channel computed map
00120   vxl_byte map_R_pixel(const Type pix) {return this->map_pixel_byte(pix, Type(min_R_), Type(max_R_), gamma_R_, ratio_R_);}
00121   //: Green channel computed map
00122   vxl_byte map_G_pixel(const Type pix) {return this->map_pixel_byte(pix, Type(min_G_), Type(max_G_), gamma_G_, ratio_G_);}
00123   //: Blue channel computed map
00124   vxl_byte map_B_pixel(const Type pix) {return this->map_pixel_byte(pix, Type(min_B_), Type(max_B_), gamma_B_, ratio_B_);}
00125   //: Alpha or Infrared channel computed map
00126   vxl_byte map_X_pixel(const Type pix) {return this->map_pixel_byte(pix, Type(min_X_), Type(max_X_), gamma_X_, ratio_X_);}
00127 
00128   //: offset for potentially signed table index. Zero for unsigned, -maxval for signed.
00129   int offset();
00130 
00131  private:
00132   vgui_range_map();//never use this
00133   //:
00134   void init();
00135 
00136   //: Initialize the domain - sanity check and compute ratio_
00137   void init_map_domain(const Type min, const Type max,
00138                        long double& ratio);
00139 
00140   //: Map a pixel from Type to vxl_byte
00141   vxl_byte map_pixel_byte(const Type pix, const Type min, const Type max,
00142                           const float gamma, const long double ratio);
00143   //: Map the pixel to the range [0f 1f];
00144   float map_pixel_float(const Type pix, const Type min, const Type max,
00145                         const float gamma, const long double ratio);
00146 
00147   //: Initialize the byte mapping table
00148   vbl_array_1d<vxl_byte> compute_byte_table(const Type min, const Type max,
00149                                             const float gamma,
00150                                             const long double ratio);
00151 
00152   //: Initialize the float mapping table
00153   vbl_array_1d<float> compute_float_table(const Type min, const Type max,
00154                                           const float gamma,
00155                                           const long double ratio);
00156 
00157   bool mapable_;           //!< input pixel type can be mapped
00158   bool table_mapable_;     //!< input pixel type can be mapped by a table.
00159   unsigned size_;          //!< number of elements in the map
00160   long double ratio_L_;    //!< scale for computed Luminance mapping
00161   long double ratio_R_;    //!< scale for computed red channel mapping
00162   long double ratio_G_;    //!< scale for computed green channel mapping
00163   long double ratio_B_;    //!< scale for computed blue channel mapping
00164   long double ratio_X_;    //!< scale for computed alpha or IR channel mapping
00165 };
00166 
00167 #define VGUI_RANGE_MAP_INSTANTIATE(T) extern "please include vgui/vgui_range_map.txx first"
00168 
00169 #endif //vgui_range_map_h