[[MESA]
[reactos.git] / reactos / dll / opengl / mesa / src / mesa / main / pixeltransfer.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file pixeltransfer.c
28 * Pixel transfer operations (scale, bias, table lookups, etc)
29 */
30
31
32 #include "glheader.h"
33 #include "colormac.h"
34 #include "pixeltransfer.h"
35 #include "imports.h"
36 #include "mtypes.h"
37
38
39 /*
40 * Apply scale and bias factors to an array of RGBA pixels.
41 */
42 void
43 _mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
44 GLfloat rScale, GLfloat gScale,
45 GLfloat bScale, GLfloat aScale,
46 GLfloat rBias, GLfloat gBias,
47 GLfloat bBias, GLfloat aBias)
48 {
49 if (rScale != 1.0 || rBias != 0.0) {
50 GLuint i;
51 for (i = 0; i < n; i++) {
52 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
53 }
54 }
55 if (gScale != 1.0 || gBias != 0.0) {
56 GLuint i;
57 for (i = 0; i < n; i++) {
58 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
59 }
60 }
61 if (bScale != 1.0 || bBias != 0.0) {
62 GLuint i;
63 for (i = 0; i < n; i++) {
64 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
65 }
66 }
67 if (aScale != 1.0 || aBias != 0.0) {
68 GLuint i;
69 for (i = 0; i < n; i++) {
70 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
71 }
72 }
73 }
74
75
76 /*
77 * Apply pixel mapping to an array of floating point RGBA pixels.
78 */
79 void
80 _mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] )
81 {
82 const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1);
83 const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1);
84 const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1);
85 const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1);
86 const GLfloat *rMap = ctx->PixelMaps.RtoR.Map;
87 const GLfloat *gMap = ctx->PixelMaps.GtoG.Map;
88 const GLfloat *bMap = ctx->PixelMaps.BtoB.Map;
89 const GLfloat *aMap = ctx->PixelMaps.AtoA.Map;
90 GLuint i;
91 for (i=0;i<n;i++) {
92 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
93 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
94 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
95 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
96 rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
97 rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
98 rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
99 rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
100 }
101 }
102
103 /*
104 * Map color indexes to float rgba values.
105 */
106 void
107 _mesa_map_ci_to_rgba( const struct gl_context *ctx, GLuint n,
108 const GLuint index[], GLfloat rgba[][4] )
109 {
110 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
111 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
112 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
113 GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
114 const GLfloat *rMap = ctx->PixelMaps.ItoR.Map;
115 const GLfloat *gMap = ctx->PixelMaps.ItoG.Map;
116 const GLfloat *bMap = ctx->PixelMaps.ItoB.Map;
117 const GLfloat *aMap = ctx->PixelMaps.ItoA.Map;
118 GLuint i;
119 for (i=0;i<n;i++) {
120 rgba[i][RCOMP] = rMap[index[i] & rmask];
121 rgba[i][GCOMP] = gMap[index[i] & gmask];
122 rgba[i][BCOMP] = bMap[index[i] & bmask];
123 rgba[i][ACOMP] = aMap[index[i] & amask];
124 }
125 }
126
127
128 /**
129 * Map ubyte color indexes to ubyte/RGBA values.
130 */
131 void
132 _mesa_map_ci8_to_rgba8(const struct gl_context *ctx,
133 GLuint n, const GLubyte index[],
134 GLubyte rgba[][4])
135 {
136 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
137 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
138 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
139 GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
140 const GLubyte *rMap = ctx->PixelMaps.ItoR.Map8;
141 const GLubyte *gMap = ctx->PixelMaps.ItoG.Map8;
142 const GLubyte *bMap = ctx->PixelMaps.ItoB.Map8;
143 const GLubyte *aMap = ctx->PixelMaps.ItoA.Map8;
144 GLuint i;
145 for (i=0;i<n;i++) {
146 rgba[i][RCOMP] = rMap[index[i] & rmask];
147 rgba[i][GCOMP] = gMap[index[i] & gmask];
148 rgba[i][BCOMP] = bMap[index[i] & bmask];
149 rgba[i][ACOMP] = aMap[index[i] & amask];
150 }
151 }
152
153
154 void
155 _mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n,
156 GLfloat depthValues[])
157 {
158 const GLfloat scale = ctx->Pixel.DepthScale;
159 const GLfloat bias = ctx->Pixel.DepthBias;
160 GLuint i;
161 for (i = 0; i < n; i++) {
162 GLfloat d = depthValues[i] * scale + bias;
163 depthValues[i] = CLAMP(d, 0.0F, 1.0F);
164 }
165 }
166
167
168 void
169 _mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n,
170 GLuint depthValues[])
171 {
172 const GLdouble max = (double) 0xffffffff;
173 const GLdouble scale = ctx->Pixel.DepthScale;
174 const GLdouble bias = ctx->Pixel.DepthBias * max;
175 GLuint i;
176 for (i = 0; i < n; i++) {
177 GLdouble d = (GLdouble) depthValues[i] * scale + bias;
178 d = CLAMP(d, 0.0, max);
179 depthValues[i] = (GLuint) d;
180 }
181 }
182
183 /**
184 * Apply various pixel transfer operations to an array of RGBA pixels
185 * as indicated by the transferOps bitmask
186 */
187 void
188 _mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps,
189 GLuint n, GLfloat rgba[][4])
190 {
191 /* scale & bias */
192 if (transferOps & IMAGE_SCALE_BIAS_BIT) {
193 _mesa_scale_and_bias_rgba(n, rgba,
194 ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
195 ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
196 ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
197 ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
198 }
199 /* color map lookup */
200 if (transferOps & IMAGE_MAP_COLOR_BIT) {
201 _mesa_map_rgba( ctx, n, rgba );
202 }
203
204 /* clamping to [0,1] */
205 if (transferOps & IMAGE_CLAMP_BIT) {
206 GLuint i;
207 for (i = 0; i < n; i++) {
208 rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
209 rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
210 rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
211 rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
212 }
213 }
214 }
215
216
217 /*
218 * Apply color index shift and offset to an array of pixels.
219 */
220 void
221 _mesa_shift_and_offset_ci(const struct gl_context *ctx,
222 GLuint n, GLuint indexes[])
223 {
224 GLint shift = ctx->Pixel.IndexShift;
225 GLint offset = ctx->Pixel.IndexOffset;
226 GLuint i;
227 if (shift > 0) {
228 for (i=0;i<n;i++) {
229 indexes[i] = (indexes[i] << shift) + offset;
230 }
231 }
232 else if (shift < 0) {
233 shift = -shift;
234 for (i=0;i<n;i++) {
235 indexes[i] = (indexes[i] >> shift) + offset;
236 }
237 }
238 else {
239 for (i=0;i<n;i++) {
240 indexes[i] = indexes[i] + offset;
241 }
242 }
243 }
244
245
246
247 /**
248 * Apply color index shift, offset and table lookup to an array
249 * of color indexes;
250 */
251 void
252 _mesa_apply_ci_transfer_ops(const struct gl_context *ctx,
253 GLbitfield transferOps,
254 GLuint n, GLuint indexes[])
255 {
256 if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
257 _mesa_shift_and_offset_ci(ctx, n, indexes);
258 }
259 if (transferOps & IMAGE_MAP_COLOR_BIT) {
260 const GLuint mask = ctx->PixelMaps.ItoI.Size - 1;
261 GLuint i;
262 for (i = 0; i < n; i++) {
263 const GLuint j = indexes[i] & mask;
264 indexes[i] = IROUND(ctx->PixelMaps.ItoI.Map[j]);
265 }
266 }
267 }
268
269
270 /**
271 * Apply stencil index shift, offset and table lookup to an array
272 * of stencil values.
273 */
274 void
275 _mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n,
276 GLubyte stencil[])
277 {
278 if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
279 const GLint offset = ctx->Pixel.IndexOffset;
280 GLint shift = ctx->Pixel.IndexShift;
281 GLuint i;
282 if (shift > 0) {
283 for (i = 0; i < n; i++) {
284 stencil[i] = (stencil[i] << shift) + offset;
285 }
286 }
287 else if (shift < 0) {
288 shift = -shift;
289 for (i = 0; i < n; i++) {
290 stencil[i] = (stencil[i] >> shift) + offset;
291 }
292 }
293 else {
294 for (i = 0; i < n; i++) {
295 stencil[i] = stencil[i] + offset;
296 }
297 }
298 }
299 if (ctx->Pixel.MapStencilFlag) {
300 GLuint mask = ctx->PixelMaps.StoS.Size - 1;
301 GLuint i;
302 for (i = 0; i < n; i++) {
303 stencil[i] = (GLubyte) ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
304 }
305 }
306 }