Mercurial > sdl-ios-xcode
annotate src/video/SDL_gamma.c @ 571:8e3ce997621c
Date: Thu, 16 Jan 2003 13:48:31 +0200
From: "Mike Gorchak"
Subject: All QNX patches
whole patches concerning QNX. Almost all code has been rewritten by Julian
and me. Added initial support for hw overlays in QNX and many many others
fixes.
P.S. This patches has been reviewed by Dave Rempel from QSSL and included in
SDL 1.2.5 distribution, which coming on 3rd party CD for newest 6.2.1
version of QNX, which will be available soon.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 20 Jan 2003 01:38:37 +0000 |
parents | f6ffac90895c |
children | 37bb90b3d976 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
152
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Gamma correction support */ | |
29 | |
30 #define USE_MATH_H /* Used for calculating gamma ramps */ | |
31 | |
32 #ifdef USE_MATH_H | |
33 #include <math.h> | |
34 #endif | |
35 #include <stdlib.h> | |
152 | 36 #include <string.h> |
0 | 37 |
38 #include "SDL_error.h" | |
39 #include "SDL_sysvideo.h" | |
40 | |
41 #ifdef USE_MATH_H | |
42 static void CalculateGammaRamp(float gamma, Uint16 *ramp) | |
43 { | |
44 int i; | |
45 | |
46 /* 0.0 gamma is all black */ | |
47 if ( gamma <= 0.0 ) { | |
48 for ( i=0; i<256; ++i ) { | |
49 ramp[i] = 0; | |
50 } | |
51 return; | |
52 } else | |
53 /* 1.0 gamma is identity */ | |
54 if ( gamma == 1.0 ) { | |
55 for ( i=0; i<256; ++i ) { | |
56 ramp[i] = (i << 8) | i; | |
57 } | |
58 return; | |
59 } else | |
60 /* Calculate a real gamma ramp */ | |
61 { int value; | |
62 gamma = 1.0f / gamma; | |
63 for ( i=0; i<256; ++i ) { | |
64 value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5); | |
65 if ( value > 65535 ) { | |
66 value = 65535; | |
67 } | |
68 ramp[i] = (Uint16)value; | |
69 } | |
70 } | |
71 } | |
72 static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp) | |
73 { | |
74 /* The following is adapted from a post by Garrett Bass on OpenGL | |
75 Gamedev list, March 4, 2000. | |
76 */ | |
77 float sum = 0.0; | |
78 int i, count = 0; | |
79 | |
80 *gamma = 1.0; | |
81 for ( i = 1; i < 256; ++i ) { | |
82 if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { | |
83 double B = (double)i / 256.0; | |
84 double A = ramp[i] / 65535.0; | |
85 sum += (float) ( log(A) / log(B) ); | |
86 count++; | |
87 } | |
88 } | |
89 if ( count && sum ) { | |
90 *gamma = 1.0f / (sum / count); | |
91 } | |
92 } | |
93 #endif /* USE_MATH_H */ | |
94 | |
95 int SDL_SetGamma(float red, float green, float blue) | |
96 { | |
97 int succeeded; | |
98 SDL_VideoDevice *video = current_video; | |
99 SDL_VideoDevice *this = current_video; | |
100 | |
101 succeeded = -1; | |
102 #ifdef USE_MATH_H | |
103 /* Prefer using SetGammaRamp(), as it's more flexible */ | |
104 { | |
105 Uint16 ramp[3][256]; | |
106 | |
107 CalculateGammaRamp(red, ramp[0]); | |
108 CalculateGammaRamp(green, ramp[1]); | |
109 CalculateGammaRamp(blue, ramp[2]); | |
110 succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]); | |
111 } | |
112 #else | |
113 SDL_SetError("Gamma correction not supported"); | |
114 #endif | |
115 if ( (succeeded < 0) && video->SetGamma ) { | |
116 SDL_ClearError(); | |
117 succeeded = video->SetGamma(this, red, green, blue); | |
118 } | |
119 return succeeded; | |
120 } | |
121 | |
122 /* Calculating the gamma by integrating the gamma ramps isn't exact, | |
123 so this function isn't officially supported. | |
124 */ | |
125 int SDL_GetGamma(float *red, float *green, float *blue) | |
126 { | |
127 int succeeded; | |
128 SDL_VideoDevice *video = current_video; | |
129 SDL_VideoDevice *this = current_video; | |
130 | |
131 succeeded = -1; | |
132 #ifdef USE_MATH_H | |
133 /* Prefer using GetGammaRamp(), as it's more flexible */ | |
134 { | |
135 Uint16 ramp[3][256]; | |
136 | |
137 succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]); | |
138 if ( succeeded >= 0 ) { | |
139 CalculateGammaFromRamp(red, ramp[0]); | |
140 CalculateGammaFromRamp(green, ramp[1]); | |
141 CalculateGammaFromRamp(blue, ramp[2]); | |
142 } | |
143 } | |
144 #else | |
145 SDL_SetError("Gamma correction not supported"); | |
146 #endif | |
147 if ( (succeeded < 0) && video->GetGamma ) { | |
148 SDL_ClearError(); | |
149 succeeded = video->GetGamma(this, red, green, blue); | |
150 } | |
151 return succeeded; | |
152 } | |
153 | |
154 int SDL_SetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) | |
155 { | |
156 int succeeded; | |
157 SDL_VideoDevice *video = current_video; | |
158 SDL_VideoDevice *this = current_video; | |
159 SDL_Surface *screen = SDL_PublicSurface; | |
160 | |
161 /* Verify the screen parameter */ | |
162 if ( !screen ) { | |
163 SDL_SetError("No video mode has been set"); | |
164 return -1; | |
165 } | |
166 | |
167 /* Lazily allocate the gamma tables */ | |
168 if ( ! video->gamma ) { | |
169 SDL_GetGammaRamp(0, 0, 0); | |
170 } | |
171 | |
172 /* Fill the gamma table with the new values */ | |
173 if ( red ) { | |
174 memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma)); | |
175 } | |
176 if ( green ) { | |
177 memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma)); | |
178 } | |
179 if ( blue ) { | |
180 memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma)); | |
181 } | |
182 | |
183 /* Gamma correction always possible on split palettes */ | |
184 if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { | |
185 SDL_Palette *pal = screen->format->palette; | |
186 | |
187 /* If physical palette has been set independently, use it */ | |
188 if(video->physpal) | |
189 pal = video->physpal; | |
190 | |
191 SDL_SetPalette(screen, SDL_PHYSPAL, | |
192 pal->colors, 0, pal->ncolors); | |
193 return 0; | |
194 } | |
195 | |
196 /* Try to set the gamma ramp in the driver */ | |
197 succeeded = -1; | |
198 if ( video->SetGammaRamp ) { | |
199 succeeded = video->SetGammaRamp(this, video->gamma); | |
200 } else { | |
201 SDL_SetError("Gamma ramp manipulation not supported"); | |
202 } | |
203 return succeeded; | |
204 } | |
205 | |
206 int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) | |
207 { | |
208 SDL_VideoDevice *video = current_video; | |
209 SDL_VideoDevice *this = current_video; | |
210 | |
211 /* Lazily allocate the gamma table */ | |
212 if ( ! video->gamma ) { | |
213 video->gamma = malloc(3*256*sizeof(*video->gamma)); | |
214 if ( ! video->gamma ) { | |
215 SDL_OutOfMemory(); | |
216 return -1; | |
217 } | |
218 if ( video->GetGammaRamp ) { | |
219 /* Get the real hardware gamma */ | |
220 video->GetGammaRamp(this, video->gamma); | |
221 } else { | |
222 /* Assume an identity gamma */ | |
223 int i; | |
224 for ( i=0; i<256; ++i ) { | |
225 video->gamma[0*256+i] = (i << 8) | i; | |
226 video->gamma[1*256+i] = (i << 8) | i; | |
227 video->gamma[2*256+i] = (i << 8) | i; | |
228 } | |
229 } | |
230 } | |
231 | |
232 /* Just copy from our internal table */ | |
233 if ( red ) { | |
234 memcpy(red, &video->gamma[0*256], 256*sizeof(*red)); | |
235 } | |
236 if ( green ) { | |
237 memcpy(green, &video->gamma[1*256], 256*sizeof(*green)); | |
238 } | |
239 if ( blue ) { | |
240 memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue)); | |
241 } | |
242 return 0; | |
243 } |