1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry - Version 2.4 3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 4 // 5 // Permission to copy, use, modify, sell and distribute this software 6 // is granted provided this copyright notice appears in all copies. 7 // This software is provided "as is" without express or implied 8 // warranty, and with no claim as to its suitability for any purpose. 9 // 10 //---------------------------------------------------------------------------- 11 // Contact: mcseem@antigrain.com 12 // mcseemagg@yahoo.com 13 // http://www.antigrain.com 14 //---------------------------------------------------------------------------- 15 16 #ifndef AGG_GAMMA_LUT_INCLUDED 17 #define AGG_GAMMA_LUT_INCLUDED 18 19 #include <math.h> 20 #include "agg_basics.h" 21 22 namespace agg 23 { 24 template<class LoResT=int8u, 25 class HiResT=int8u, 26 unsigned GammaShift=8, 27 unsigned HiResShift=8> class gamma_lut 28 { 29 public: 30 typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type; 31 32 enum gamma_scale_e 33 { 34 gamma_shift = GammaShift, 35 gamma_size = 1 << gamma_shift, 36 gamma_mask = gamma_size - 1 37 }; 38 39 enum hi_res_scale_e 40 { 41 hi_res_shift = HiResShift, 42 hi_res_size = 1 << hi_res_shift, 43 hi_res_mask = hi_res_size - 1 44 }; 45 ~gamma_lut()46 ~gamma_lut() 47 { 48 pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size); 49 pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size); 50 } 51 gamma_lut()52 gamma_lut() : 53 m_gamma(1.0), 54 m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), 55 m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) 56 { 57 unsigned i; 58 for(i = 0; i < gamma_size; i++) 59 { 60 m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift)); 61 } 62 63 for(i = 0; i < hi_res_size; i++) 64 { 65 m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift)); 66 } 67 } 68 gamma_lut(double g)69 gamma_lut(double g) : 70 m_gamma(1.0), 71 m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), 72 m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) 73 { 74 gamma(g); 75 } 76 gamma(double g)77 void gamma(double g) 78 { 79 m_gamma = g; 80 81 unsigned i; 82 for(i = 0; i < gamma_size; i++) 83 { 84 m_dir_gamma[i] = (HiResT) 85 uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask)); 86 } 87 88 double inv_g = 1.0 / g; 89 for(i = 0; i < hi_res_size; i++) 90 { 91 m_inv_gamma[i] = (LoResT) 92 uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask)); 93 } 94 } 95 gamma()96 double gamma() const 97 { 98 return m_gamma; 99 } 100 dir(LoResT v)101 HiResT dir(LoResT v) const 102 { 103 return m_dir_gamma[unsigned(v)]; 104 } 105 inv(HiResT v)106 LoResT inv(HiResT v) const 107 { 108 return m_inv_gamma[unsigned(v)]; 109 } 110 111 private: 112 gamma_lut(const self_type&); 113 const self_type& operator = (const self_type&); 114 115 double m_gamma; 116 HiResT* m_dir_gamma; 117 LoResT* m_inv_gamma; 118 }; 119 } 120 121 #endif 122