Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 00025 #ifndef AGG_GAMMA_LUT_INCLUDED 00026 #define AGG_GAMMA_LUT_INCLUDED 00027 00028 #include <math.h> 00029 #include "agg_basics.h" 00030 00031 namespace agg 00032 { 00033 template<class LoResT=int8u, 00034 class HiResT=int8u, 00035 unsigned GammaShift=8, 00036 unsigned HiResShift=8> class gamma_lut 00037 { 00038 public: 00039 typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type; 00040 00041 enum gamma_scale_e 00042 { 00043 gamma_shift = GammaShift, 00044 gamma_size = 1 << gamma_shift, 00045 gamma_mask = gamma_size - 1 00046 }; 00047 00048 enum hi_res_scale_e 00049 { 00050 hi_res_shift = HiResShift, 00051 hi_res_size = 1 << hi_res_shift, 00052 hi_res_mask = hi_res_size - 1 00053 }; 00054 00055 ~gamma_lut() 00056 { 00057 pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size); 00058 pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size); 00059 } 00060 00061 gamma_lut() : 00062 m_gamma(1.0), 00063 m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), 00064 m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) 00065 { 00066 unsigned i; 00067 for(i = 0; i < gamma_size; i++) 00068 { 00069 m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift)); 00070 } 00071 00072 for(i = 0; i < hi_res_size; i++) 00073 { 00074 m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift)); 00075 } 00076 } 00077 00078 gamma_lut(double g) : 00079 m_gamma(1.0), 00080 m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), 00081 m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) 00082 { 00083 gamma(g); 00084 } 00085 00086 void gamma(double g) 00087 { 00088 m_gamma = g; 00089 00090 unsigned i; 00091 for(i = 0; i < gamma_size; i++) 00092 { 00093 m_dir_gamma[i] = (HiResT) 00094 uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask)); 00095 } 00096 00097 double inv_g = 1.0 / g; 00098 for(i = 0; i < hi_res_size; i++) 00099 { 00100 m_inv_gamma[i] = (LoResT) 00101 uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask)); 00102 } 00103 } 00104 00105 double gamma() const 00106 { 00107 return m_gamma; 00108 } 00109 00110 HiResT dir(LoResT v) const 00111 { 00112 return m_dir_gamma[unsigned(v)]; 00113 } 00114 00115 LoResT inv(HiResT v) const 00116 { 00117 return m_inv_gamma[unsigned(v)]; 00118 } 00119 00120 private: 00121 gamma_lut(const self_type&); 00122 const self_type& operator = (const self_type&); 00123 00124 double m_gamma; 00125 HiResT* m_dir_gamma; 00126 LoResT* m_inv_gamma; 00127 }; 00128 } 00129 00130 #endif