xref: /haiku/headers/libs/agg/agg_gamma_lut.h (revision fef6144999c2fa611f59ee6ffe6dd7999501385c)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.2
3 // Copyright (C) 2002-2004 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         enum
31         {
32             gamma_shift = GammaShift,
33             gamma_size  = 1 << gamma_shift,
34             gamma_mask  = gamma_size - 1
35         };
36 
37         enum
38         {
39             hi_res_shift = HiResShift,
40             hi_res_size  = 1 << hi_res_shift,
41             hi_res_mask  = hi_res_size - 1
42         };
43 
44         ~gamma_lut()
45         {
46             delete [] m_inv_gamma;
47             delete [] m_dir_gamma;
48         }
49 
50         gamma_lut() :
51             m_gamma(1.0),
52             m_dir_gamma(new HiResT[gamma_size]),
53             m_inv_gamma(new LoResT[hi_res_size])
54         {
55             unsigned i;
56             for(i = 0; i < gamma_size; i++)
57             {
58                 m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift));
59             }
60 
61             for(i = 0; i < hi_res_size; i++)
62             {
63                 m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift));
64             }
65         }
66 
67         gamma_lut(double g) :
68             m_gamma(1.0),
69             m_dir_gamma(new HiResT[gamma_size]),
70             m_inv_gamma(new LoResT[hi_res_size])
71         {
72             gamma(g);
73         }
74 
75         void gamma(double g)
76         {
77             m_gamma = g;
78 
79             unsigned i;
80             for(i = 0; i < gamma_size; i++)
81             {
82                 m_dir_gamma[i] = (HiResT)(pow(double(i) / double(gamma_mask), m_gamma) * double(hi_res_mask) + 0.5);
83             }
84 
85             double inv_g = 1.0 / g;
86             for(i = 0; i < hi_res_size; i++)
87             {
88                 m_inv_gamma[i] = (LoResT)(pow(double(i) / double(hi_res_mask), inv_g) * double(gamma_mask) + 0.5);
89             }
90         }
91 
92         double gamma() const
93         {
94             return m_gamma;
95         }
96 
97         HiResT dir(LoResT v) const
98         {
99             return m_dir_gamma[unsigned(v)];
100         }
101 
102         LoResT inv(HiResT v) const
103         {
104             return m_inv_gamma[unsigned(v)];
105         }
106 
107     private:
108         double m_gamma;
109         HiResT* m_dir_gamma;
110         LoResT* m_inv_gamma;
111     };
112 }
113 
114 #endif
115