more updates
[synfig.git] / synfig-core / trunk / src / synfig / gamma.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file gamma.cpp
3 **      \brief Template File
4 **
5 **      $Id: gamma.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "gamma.h"
32 #include <cmath>
33 #include <algorithm>
34 #endif
35
36 /* === U S I N G =========================================================== */
37
38 using namespace std;
39 //using namespace etl;
40 using namespace sinfg;
41
42 /* === M A C R O S ========================================================= */
43
44 /* === G L O B A L S ======================================================= */
45
46 /* === P R O C E D U R E S ================================================= */
47
48 /* === M E T H O D S ======================================================= */
49
50 void
51 Gamma::set_gamma(float x)
52 {
53         gamma_r=gamma_g=gamma_b=x;
54         int i;
55         red_blue_level=1.0f;
56         for(i=0;i<65536;i++)
57         {
58                 float f(float(i)/65536.0f);
59                 f=pow(f,gamma_r);
60                 table_r_U16_to_U8[i]=table_g_U16_to_U8[i]=table_b_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
61         }
62
63         for(i=0;i<256;i++)
64                 table_r_U8_to_F32[i]=table_g_U8_to_F32[i]=table_b_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_r);
65 }
66
67
68 void
69 Gamma::refresh_gamma_r()
70 {
71         int i;
72 //      const float scalar(min(red_blue_level,1.0f));
73         const float scalar(1.0f);
74         for(i=0;i<65536;i++)
75         {
76                 float f(float(i)/65536.0f);
77                 f=pow(f,gamma_r)*scalar;
78                 table_r_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
79         }
80
81         for(i=0;i<256;i++)
82                 table_r_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_r)*scalar;
83 }
84
85 void
86 Gamma::refresh_gamma_g()
87 {
88         int i;
89 //      const float scalar(sqrt(min(red_blue_level,2.0f-red_blue_level)));
90         const float scalar(1.0f);
91         for(i=0;i<65536;i++)
92         {
93                 float f(float(i)/65536.0f);
94                 f=pow(f,gamma_g)*scalar;
95                 table_g_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
96         }
97         for(i=0;i<256;i++)
98                 table_g_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_g)*scalar;
99 }
100
101 void
102 Gamma::refresh_gamma_b()
103 {
104         int i;
105 //      const float scalar(min(2.0f-red_blue_level,1.0f));
106         const float scalar(1.0f);
107         for(i=0;i<65536;i++)
108         {
109                 float f(float(i)/65536.0f);
110                 f=pow(f,gamma_b)*scalar;
111                 table_b_U16_to_U8[i]=(unsigned char)(f*(255.0f-(black_level*255))+0.5f + black_level*255.0f);
112         }
113         for(i=0;i<256;i++)
114                 table_b_U8_to_F32[i]=pow((float(i)/255.0f)*(1.0f-black_level)+black_level,gamma_b)*scalar;
115 }
116
117 void
118 Gamma::set_gamma_r(float x)
119 {
120         // If the gamma hasn't changed, then don't recompute the tables
121         if(x==gamma_r) return;
122
123         gamma_r=x;
124         refresh_gamma_r();
125 }
126
127 void
128 Gamma::set_gamma_g(float x)
129 {
130         // If the gamma hasn't changed, then don't recompute the tables
131         if(x==gamma_g) return;
132
133         gamma_g=x;
134         refresh_gamma_g();
135 }
136
137 void
138 Gamma::set_gamma_b(float x)
139 {
140         // If the gamma hasn't changed, then don't recompute the tables
141         if(x==gamma_b) return;
142
143         gamma_b=x;
144         refresh_gamma_b();
145 }
146
147 void
148 Gamma::set_black_level(float x)
149 {
150         // If the black_level hasn't changed, then don't recompute the tables
151         if(x==black_level) return;
152
153         black_level=x;
154         
155         // Rebuild tables
156         refresh_gamma_r();
157         refresh_gamma_g();
158         refresh_gamma_b();
159 }
160
161 void
162 Gamma::set_red_blue_level(float x)
163 {
164         // If the black_level hasn't changed, then don't recompute the tables
165         if(x==red_blue_level) return;
166
167         red_blue_level=x;
168         
169         // Rebuild tables
170         refresh_gamma_r();
171         refresh_gamma_g();
172         refresh_gamma_b();
173 }
174
175 void
176 Gamma::set_all(float r, float g, float b, float black, float red_blue)
177 {
178         // If nothing has changed, then don't recompute the tables
179         if(gamma_r==r && gamma_g==g && gamma_b==b && black_level==black && red_blue_level==red_blue)
180                 return;
181         
182         gamma_r=r;
183         gamma_g=g;
184         gamma_b=b;
185         black_level=black;
186         red_blue_level=red_blue;
187
188         // Rebuild tables
189         refresh_gamma_r();
190         refresh_gamma_g();
191         refresh_gamma_b();
192 }