Mercurial > sdl-ios-xcode
comparison src/video/SDL_gamma.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | 97d0966f4bf7 |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 /* Gamma correction support */ | 24 /* Gamma correction support */ |
25 | 25 |
26 #ifdef HAVE_MATH_H | 26 #ifdef HAVE_MATH_H |
27 #include <math.h> /* Used for calculating gamma ramps */ | 27 #include <math.h> /* Used for calculating gamma ramps */ |
28 #else | 28 #else |
29 /* Math routines from uClibc: http://www.uclibc.org */ | 29 /* Math routines from uClibc: http://www.uclibc.org */ |
30 #include "math_private.h" | 30 #include "math_private.h" |
31 #include "e_sqrt.h" | 31 #include "e_sqrt.h" |
32 #include "e_pow.h" | 32 #include "e_pow.h" |
36 #endif | 36 #endif |
37 | 37 |
38 #include "SDL_sysvideo.h" | 38 #include "SDL_sysvideo.h" |
39 | 39 |
40 | 40 |
41 static void CalculateGammaRamp(float gamma, Uint16 *ramp) | 41 static void |
42 { | 42 CalculateGammaRamp (float gamma, Uint16 * ramp) |
43 int i; | 43 { |
44 | 44 int i; |
45 /* 0.0 gamma is all black */ | 45 |
46 if ( gamma <= 0.0f ) { | 46 /* 0.0 gamma is all black */ |
47 for ( i=0; i<256; ++i ) { | 47 if (gamma <= 0.0f) { |
48 ramp[i] = 0; | 48 for (i = 0; i < 256; ++i) { |
49 } | 49 ramp[i] = 0; |
50 return; | 50 } |
51 } else | 51 return; |
52 /* 1.0 gamma is identity */ | 52 } else |
53 if ( gamma >= 1.0f ) { | 53 /* 1.0 gamma is identity */ |
54 for ( i=0; i<256; ++i ) { | 54 if (gamma >= 1.0f) { |
55 ramp[i] = (i << 8) | i; | 55 for (i = 0; i < 256; ++i) { |
56 } | 56 ramp[i] = (i << 8) | i; |
57 return; | 57 } |
58 } else | 58 return; |
59 /* Calculate a real gamma ramp */ | 59 } else |
60 { int value; | 60 /* Calculate a real gamma ramp */ |
61 gamma = 1.0f / gamma; | 61 { |
62 for ( i=0; i<256; ++i ) { | 62 int value; |
63 value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5); | 63 gamma = 1.0f / gamma; |
64 if ( value > 65535 ) { | 64 for (i = 0; i < 256; ++i) { |
65 value = 65535; | 65 value = (int) (pow ((double) i / 256.0, gamma) * 65535.0 + 0.5); |
66 } | 66 if (value > 65535) { |
67 ramp[i] = (Uint16)value; | 67 value = 65535; |
68 } | 68 } |
69 } | 69 ramp[i] = (Uint16) value; |
70 } | 70 } |
71 static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp) | 71 } |
72 { | 72 } |
73 /* The following is adapted from a post by Garrett Bass on OpenGL | 73 static void |
74 Gamedev list, March 4, 2000. | 74 CalculateGammaFromRamp (float *gamma, Uint16 * ramp) |
75 */ | 75 { |
76 float sum = 0.0f; | 76 /* The following is adapted from a post by Garrett Bass on OpenGL |
77 int i, count = 0; | 77 Gamedev list, March 4, 2000. |
78 | 78 */ |
79 *gamma = 1.0; | 79 float sum = 0.0f; |
80 for ( i = 1; i < 256; ++i ) { | 80 int i, count = 0; |
81 if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { | 81 |
82 double B = (double)i / 256.0; | 82 *gamma = 1.0; |
83 double A = ramp[i] / 65535.0; | 83 for (i = 1; i < 256; ++i) { |
84 sum += (float) ( log(A) / log(B) ); | 84 if ((ramp[i] != 0) && (ramp[i] != 65535)) { |
85 count++; | 85 double B = (double) i / 256.0; |
86 } | 86 double A = ramp[i] / 65535.0; |
87 } | 87 sum += (float) (log (A) / log (B)); |
88 if ( count && sum > 0.0f ) { | 88 count++; |
89 *gamma = 1.0f / (sum / count); | 89 } |
90 } | 90 } |
91 } | 91 if (count && sum > 0.0f) { |
92 | 92 *gamma = 1.0f / (sum / count); |
93 int SDL_SetGamma(float red, float green, float blue) | 93 } |
94 { | 94 } |
95 int succeeded; | 95 |
96 SDL_VideoDevice *video = current_video; | 96 int |
97 SDL_VideoDevice *this = current_video; | 97 SDL_SetGamma (float red, float green, float blue) |
98 | 98 { |
99 succeeded = -1; | 99 SDL_VideoDevice *_this = SDL_GetVideoDevice (); |
100 /* Prefer using SetGammaRamp(), as it's more flexible */ | 100 int succeeded; |
101 { | 101 |
102 Uint16 ramp[3][256]; | 102 succeeded = -1; |
103 | 103 /* Prefer using SetGammaRamp(), as it's more flexible */ |
104 CalculateGammaRamp(red, ramp[0]); | 104 { |
105 CalculateGammaRamp(green, ramp[1]); | 105 Uint16 ramp[3][256]; |
106 CalculateGammaRamp(blue, ramp[2]); | 106 |
107 succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]); | 107 CalculateGammaRamp (red, ramp[0]); |
108 } | 108 CalculateGammaRamp (green, ramp[1]); |
109 if ( (succeeded < 0) && video->SetGamma ) { | 109 CalculateGammaRamp (blue, ramp[2]); |
110 SDL_ClearError(); | 110 succeeded = SDL_SetGammaRamp (ramp[0], ramp[1], ramp[2]); |
111 succeeded = video->SetGamma(this, red, green, blue); | 111 } |
112 } | 112 if ((succeeded < 0) && _this->SetGamma) { |
113 return succeeded; | 113 SDL_ClearError (); |
114 succeeded = _this->SetGamma (_this, red, green, blue); | |
115 } | |
116 return succeeded; | |
114 } | 117 } |
115 | 118 |
116 /* Calculating the gamma by integrating the gamma ramps isn't exact, | 119 /* Calculating the gamma by integrating the gamma ramps isn't exact, |
117 so this function isn't officially supported. | 120 so this function isn't officially supported. |
118 */ | 121 */ |
119 int SDL_GetGamma(float *red, float *green, float *blue) | 122 int |
120 { | 123 SDL_GetGamma (float *red, float *green, float *blue) |
121 int succeeded; | 124 { |
122 SDL_VideoDevice *video = current_video; | 125 SDL_VideoDevice *_this = SDL_GetVideoDevice (); |
123 SDL_VideoDevice *this = current_video; | 126 int succeeded; |
124 | 127 |
125 succeeded = -1; | 128 succeeded = -1; |
126 /* Prefer using GetGammaRamp(), as it's more flexible */ | 129 /* Prefer using GetGammaRamp(), as it's more flexible */ |
127 { | 130 { |
128 Uint16 ramp[3][256]; | 131 Uint16 ramp[3][256]; |
129 | 132 |
130 succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]); | 133 succeeded = SDL_GetGammaRamp (ramp[0], ramp[1], ramp[2]); |
131 if ( succeeded >= 0 ) { | 134 if (succeeded >= 0) { |
132 CalculateGammaFromRamp(red, ramp[0]); | 135 CalculateGammaFromRamp (red, ramp[0]); |
133 CalculateGammaFromRamp(green, ramp[1]); | 136 CalculateGammaFromRamp (green, ramp[1]); |
134 CalculateGammaFromRamp(blue, ramp[2]); | 137 CalculateGammaFromRamp (blue, ramp[2]); |
135 } | 138 } |
136 } | 139 } |
137 if ( (succeeded < 0) && video->GetGamma ) { | 140 if ((succeeded < 0) && _this->GetGamma) { |
138 SDL_ClearError(); | 141 SDL_ClearError (); |
139 succeeded = video->GetGamma(this, red, green, blue); | 142 succeeded = _this->GetGamma (_this, red, green, blue); |
140 } | 143 } |
141 return succeeded; | 144 return succeeded; |
142 } | 145 } |
143 | 146 |
144 int SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue) | 147 int |
145 { | 148 SDL_SetGammaRamp (const Uint16 * red, const Uint16 * green, |
146 int succeeded; | 149 const Uint16 * blue) |
147 SDL_VideoDevice *video = current_video; | 150 { |
148 SDL_VideoDevice *this = current_video; | 151 SDL_VideoDevice *_this = SDL_GetVideoDevice (); |
149 SDL_Surface *screen = SDL_PublicSurface; | 152 int succeeded; |
150 | 153 SDL_Surface *screen = SDL_PublicSurface; |
151 /* Verify the screen parameter */ | 154 |
152 if ( !screen ) { | 155 /* Verify the screen parameter */ |
153 SDL_SetError("No video mode has been set"); | 156 if (!screen) { |
154 return -1; | 157 SDL_SetError ("No video mode has been set"); |
155 } | 158 return -1; |
156 | 159 } |
157 /* Lazily allocate the gamma tables */ | 160 |
158 if ( ! video->gamma ) { | 161 /* Lazily allocate the gamma tables */ |
159 SDL_GetGammaRamp(0, 0, 0); | 162 if (!SDL_CurrentWindow.gamma) { |
160 } | 163 SDL_GetGammaRamp (0, 0, 0); |
161 | 164 } |
162 /* Fill the gamma table with the new values */ | 165 |
163 if ( red ) { | 166 /* Fill the gamma table with the new values */ |
164 SDL_memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma)); | 167 if (red) { |
165 } | 168 SDL_memcpy (&SDL_CurrentWindow.gamma[0 * 256], red, |
166 if ( green ) { | 169 256 * sizeof (*SDL_CurrentWindow.gamma)); |
167 SDL_memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma)); | 170 } |
168 } | 171 if (green) { |
169 if ( blue ) { | 172 SDL_memcpy (&SDL_CurrentWindow.gamma[1 * 256], green, |
170 SDL_memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma)); | 173 256 * sizeof (*SDL_CurrentWindow.gamma)); |
171 } | 174 } |
172 | 175 if (blue) { |
173 /* Gamma correction always possible on split palettes */ | 176 SDL_memcpy (&SDL_CurrentWindow.gamma[2 * 256], blue, |
174 if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { | 177 256 * sizeof (*SDL_CurrentWindow.gamma)); |
175 SDL_Palette *pal = screen->format->palette; | 178 } |
176 | 179 |
177 /* If physical palette has been set independently, use it */ | 180 /* Try to set the gamma ramp in the driver */ |
178 if(video->physpal) | 181 succeeded = -1; |
179 pal = video->physpal; | 182 if (_this->SetGammaRamp) { |
180 | 183 succeeded = _this->SetGammaRamp (_this, SDL_CurrentWindow.gamma); |
181 SDL_SetPalette(screen, SDL_PHYSPAL, | 184 } else { |
182 pal->colors, 0, pal->ncolors); | 185 SDL_SetError ("Gamma ramp manipulation not supported"); |
183 return 0; | 186 } |
184 } | 187 return succeeded; |
185 | 188 } |
186 /* Try to set the gamma ramp in the driver */ | 189 |
187 succeeded = -1; | 190 int |
188 if ( video->SetGammaRamp ) { | 191 SDL_GetGammaRamp (Uint16 * red, Uint16 * green, Uint16 * blue) |
189 succeeded = video->SetGammaRamp(this, video->gamma); | 192 { |
190 } else { | 193 SDL_VideoDevice *_this = SDL_GetVideoDevice (); |
191 SDL_SetError("Gamma ramp manipulation not supported"); | 194 |
192 } | 195 /* Lazily allocate the gamma table */ |
193 return succeeded; | 196 if (!SDL_CurrentWindow.gamma) { |
194 } | 197 SDL_CurrentWindow.gamma = |
195 | 198 SDL_malloc (3 * 256 * sizeof (*SDL_CurrentWindow.gamma)); |
196 int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) | 199 if (!SDL_CurrentWindow.gamma) { |
197 { | 200 SDL_OutOfMemory (); |
198 SDL_VideoDevice *video = current_video; | 201 return -1; |
199 SDL_VideoDevice *this = current_video; | 202 } |
200 | 203 if (_this->GetGammaRamp) { |
201 /* Lazily allocate the gamma table */ | 204 /* Get the real hardware gamma */ |
202 if ( ! video->gamma ) { | 205 _this->GetGammaRamp (_this, SDL_CurrentWindow.gamma); |
203 video->gamma = SDL_malloc(3*256*sizeof(*video->gamma)); | 206 } else { |
204 if ( ! video->gamma ) { | 207 /* Assume an identity gamma */ |
205 SDL_OutOfMemory(); | 208 int i; |
206 return -1; | 209 for (i = 0; i < 256; ++i) { |
207 } | 210 SDL_CurrentWindow.gamma[0 * 256 + i] = (i << 8) | i; |
208 if ( video->GetGammaRamp ) { | 211 SDL_CurrentWindow.gamma[1 * 256 + i] = (i << 8) | i; |
209 /* Get the real hardware gamma */ | 212 SDL_CurrentWindow.gamma[2 * 256 + i] = (i << 8) | i; |
210 video->GetGammaRamp(this, video->gamma); | 213 } |
211 } else { | 214 } |
212 /* Assume an identity gamma */ | 215 } |
213 int i; | 216 |
214 for ( i=0; i<256; ++i ) { | 217 /* Just copy from our internal table */ |
215 video->gamma[0*256+i] = (i << 8) | i; | 218 if (red) { |
216 video->gamma[1*256+i] = (i << 8) | i; | 219 SDL_memcpy (red, &SDL_CurrentWindow.gamma[0 * 256], |
217 video->gamma[2*256+i] = (i << 8) | i; | 220 256 * sizeof (*red)); |
218 } | 221 } |
219 } | 222 if (green) { |
220 } | 223 SDL_memcpy (green, &SDL_CurrentWindow.gamma[1 * 256], |
221 | 224 256 * sizeof (*green)); |
222 /* Just copy from our internal table */ | 225 } |
223 if ( red ) { | 226 if (blue) { |
224 SDL_memcpy(red, &video->gamma[0*256], 256*sizeof(*red)); | 227 SDL_memcpy (blue, &SDL_CurrentWindow.gamma[2 * 256], |
225 } | 228 256 * sizeof (*blue)); |
226 if ( green ) { | 229 } |
227 SDL_memcpy(green, &video->gamma[1*256], 256*sizeof(*green)); | 230 return 0; |
228 } | 231 } |
229 if ( blue ) { | 232 |
230 SDL_memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue)); | 233 /* vi: set ts=4 sw=4 expandtab: */ |
231 } | |
232 return 0; | |
233 } |