2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * \file pixeltransfer.c
27 * Pixel transfer operations (scale, bias, table lookups, etc)
33 * Apply scale and bias factors to an array of RGBA pixels.
36 _mesa_scale_and_bias_rgba(GLuint n
, GLfloat rgba
[][4],
37 GLfloat rScale
, GLfloat gScale
,
38 GLfloat bScale
, GLfloat aScale
,
39 GLfloat rBias
, GLfloat gBias
,
40 GLfloat bBias
, GLfloat aBias
)
42 if (rScale
!= 1.0 || rBias
!= 0.0) {
44 for (i
= 0; i
< n
; i
++) {
45 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * rScale
+ rBias
;
48 if (gScale
!= 1.0 || gBias
!= 0.0) {
50 for (i
= 0; i
< n
; i
++) {
51 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * gScale
+ gBias
;
54 if (bScale
!= 1.0 || bBias
!= 0.0) {
56 for (i
= 0; i
< n
; i
++) {
57 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * bScale
+ bBias
;
60 if (aScale
!= 1.0 || aBias
!= 0.0) {
62 for (i
= 0; i
< n
; i
++) {
63 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * aScale
+ aBias
;
70 * Apply pixel mapping to an array of floating point RGBA pixels.
73 _mesa_map_rgba( const struct gl_context
*ctx
, GLuint n
, GLfloat rgba
[][4] )
75 const GLfloat rscale
= (GLfloat
) (ctx
->PixelMaps
.RtoR
.Size
- 1);
76 const GLfloat gscale
= (GLfloat
) (ctx
->PixelMaps
.GtoG
.Size
- 1);
77 const GLfloat bscale
= (GLfloat
) (ctx
->PixelMaps
.BtoB
.Size
- 1);
78 const GLfloat ascale
= (GLfloat
) (ctx
->PixelMaps
.AtoA
.Size
- 1);
79 const GLfloat
*rMap
= ctx
->PixelMaps
.RtoR
.Map
;
80 const GLfloat
*gMap
= ctx
->PixelMaps
.GtoG
.Map
;
81 const GLfloat
*bMap
= ctx
->PixelMaps
.BtoB
.Map
;
82 const GLfloat
*aMap
= ctx
->PixelMaps
.AtoA
.Map
;
85 GLfloat r
= CLAMP(rgba
[i
][RCOMP
], 0.0F
, 1.0F
);
86 GLfloat g
= CLAMP(rgba
[i
][GCOMP
], 0.0F
, 1.0F
);
87 GLfloat b
= CLAMP(rgba
[i
][BCOMP
], 0.0F
, 1.0F
);
88 GLfloat a
= CLAMP(rgba
[i
][ACOMP
], 0.0F
, 1.0F
);
89 rgba
[i
][RCOMP
] = rMap
[IROUND(r
* rscale
)];
90 rgba
[i
][GCOMP
] = gMap
[IROUND(g
* gscale
)];
91 rgba
[i
][BCOMP
] = bMap
[IROUND(b
* bscale
)];
92 rgba
[i
][ACOMP
] = aMap
[IROUND(a
* ascale
)];
97 * Map color indexes to float rgba values.
100 _mesa_map_ci_to_rgba( const struct gl_context
*ctx
, GLuint n
,
101 const GLuint index
[], GLfloat rgba
[][4] )
103 GLuint rmask
= ctx
->PixelMaps
.ItoR
.Size
- 1;
104 GLuint gmask
= ctx
->PixelMaps
.ItoG
.Size
- 1;
105 GLuint bmask
= ctx
->PixelMaps
.ItoB
.Size
- 1;
106 GLuint amask
= ctx
->PixelMaps
.ItoA
.Size
- 1;
107 const GLfloat
*rMap
= ctx
->PixelMaps
.ItoR
.Map
;
108 const GLfloat
*gMap
= ctx
->PixelMaps
.ItoG
.Map
;
109 const GLfloat
*bMap
= ctx
->PixelMaps
.ItoB
.Map
;
110 const GLfloat
*aMap
= ctx
->PixelMaps
.ItoA
.Map
;
113 rgba
[i
][RCOMP
] = rMap
[index
[i
] & rmask
];
114 rgba
[i
][GCOMP
] = gMap
[index
[i
] & gmask
];
115 rgba
[i
][BCOMP
] = bMap
[index
[i
] & bmask
];
116 rgba
[i
][ACOMP
] = aMap
[index
[i
] & amask
];
122 * Map ubyte color indexes to ubyte/RGBA values.
125 _mesa_map_ci8_to_rgba8(const struct gl_context
*ctx
,
126 GLuint n
, const GLubyte index
[],
129 GLuint rmask
= ctx
->PixelMaps
.ItoR
.Size
- 1;
130 GLuint gmask
= ctx
->PixelMaps
.ItoG
.Size
- 1;
131 GLuint bmask
= ctx
->PixelMaps
.ItoB
.Size
- 1;
132 GLuint amask
= ctx
->PixelMaps
.ItoA
.Size
- 1;
133 const GLubyte
*rMap
= ctx
->PixelMaps
.ItoR
.Map8
;
134 const GLubyte
*gMap
= ctx
->PixelMaps
.ItoG
.Map8
;
135 const GLubyte
*bMap
= ctx
->PixelMaps
.ItoB
.Map8
;
136 const GLubyte
*aMap
= ctx
->PixelMaps
.ItoA
.Map8
;
139 rgba
[i
][RCOMP
] = rMap
[index
[i
] & rmask
];
140 rgba
[i
][GCOMP
] = gMap
[index
[i
] & gmask
];
141 rgba
[i
][BCOMP
] = bMap
[index
[i
] & bmask
];
142 rgba
[i
][ACOMP
] = aMap
[index
[i
] & amask
];
148 _mesa_scale_and_bias_depth(const struct gl_context
*ctx
, GLuint n
,
149 GLfloat depthValues
[])
151 const GLfloat scale
= ctx
->Pixel
.DepthScale
;
152 const GLfloat bias
= ctx
->Pixel
.DepthBias
;
154 for (i
= 0; i
< n
; i
++) {
155 GLfloat d
= depthValues
[i
] * scale
+ bias
;
156 depthValues
[i
] = CLAMP(d
, 0.0F
, 1.0F
);
162 _mesa_scale_and_bias_depth_uint(const struct gl_context
*ctx
, GLuint n
,
163 GLuint depthValues
[])
165 const GLdouble max
= (double) 0xffffffff;
166 const GLdouble scale
= ctx
->Pixel
.DepthScale
;
167 const GLdouble bias
= ctx
->Pixel
.DepthBias
* max
;
169 for (i
= 0; i
< n
; i
++) {
170 GLdouble d
= (GLdouble
) depthValues
[i
] * scale
+ bias
;
171 d
= CLAMP(d
, 0.0, max
);
172 depthValues
[i
] = (GLuint
) d
;
177 * Apply various pixel transfer operations to an array of RGBA pixels
178 * as indicated by the transferOps bitmask
181 _mesa_apply_rgba_transfer_ops(struct gl_context
*ctx
, GLbitfield transferOps
,
182 GLuint n
, GLfloat rgba
[][4])
185 if (transferOps
& IMAGE_SCALE_BIAS_BIT
) {
186 _mesa_scale_and_bias_rgba(n
, rgba
,
187 ctx
->Pixel
.RedScale
, ctx
->Pixel
.GreenScale
,
188 ctx
->Pixel
.BlueScale
, ctx
->Pixel
.AlphaScale
,
189 ctx
->Pixel
.RedBias
, ctx
->Pixel
.GreenBias
,
190 ctx
->Pixel
.BlueBias
, ctx
->Pixel
.AlphaBias
);
192 /* color map lookup */
193 if (transferOps
& IMAGE_MAP_COLOR_BIT
) {
194 _mesa_map_rgba( ctx
, n
, rgba
);
197 /* clamping to [0,1] */
198 if (transferOps
& IMAGE_CLAMP_BIT
) {
200 for (i
= 0; i
< n
; i
++) {
201 rgba
[i
][RCOMP
] = CLAMP(rgba
[i
][RCOMP
], 0.0F
, 1.0F
);
202 rgba
[i
][GCOMP
] = CLAMP(rgba
[i
][GCOMP
], 0.0F
, 1.0F
);
203 rgba
[i
][BCOMP
] = CLAMP(rgba
[i
][BCOMP
], 0.0F
, 1.0F
);
204 rgba
[i
][ACOMP
] = CLAMP(rgba
[i
][ACOMP
], 0.0F
, 1.0F
);
211 * Apply color index shift and offset to an array of pixels.
214 _mesa_shift_and_offset_ci(const struct gl_context
*ctx
,
215 GLuint n
, GLuint indexes
[])
217 GLint shift
= ctx
->Pixel
.IndexShift
;
218 GLint offset
= ctx
->Pixel
.IndexOffset
;
222 indexes
[i
] = (indexes
[i
] << shift
) + offset
;
225 else if (shift
< 0) {
228 indexes
[i
] = (indexes
[i
] >> shift
) + offset
;
233 indexes
[i
] = indexes
[i
] + offset
;
241 * Apply color index shift, offset and table lookup to an array
245 _mesa_apply_ci_transfer_ops(const struct gl_context
*ctx
,
246 GLbitfield transferOps
,
247 GLuint n
, GLuint indexes
[])
249 if (transferOps
& IMAGE_SHIFT_OFFSET_BIT
) {
250 _mesa_shift_and_offset_ci(ctx
, n
, indexes
);
252 if (transferOps
& IMAGE_MAP_COLOR_BIT
) {
253 const GLuint mask
= ctx
->PixelMaps
.ItoI
.Size
- 1;
255 for (i
= 0; i
< n
; i
++) {
256 const GLuint j
= indexes
[i
] & mask
;
257 indexes
[i
] = IROUND(ctx
->PixelMaps
.ItoI
.Map
[j
]);
264 * Apply stencil index shift, offset and table lookup to an array
268 _mesa_apply_stencil_transfer_ops(const struct gl_context
*ctx
, GLuint n
,
271 if (ctx
->Pixel
.IndexShift
!= 0 || ctx
->Pixel
.IndexOffset
!= 0) {
272 const GLint offset
= ctx
->Pixel
.IndexOffset
;
273 GLint shift
= ctx
->Pixel
.IndexShift
;
276 for (i
= 0; i
< n
; i
++) {
277 stencil
[i
] = (stencil
[i
] << shift
) + offset
;
280 else if (shift
< 0) {
282 for (i
= 0; i
< n
; i
++) {
283 stencil
[i
] = (stencil
[i
] >> shift
) + offset
;
287 for (i
= 0; i
< n
; i
++) {
288 stencil
[i
] = stencil
[i
] + offset
;
292 if (ctx
->Pixel
.MapStencilFlag
) {
293 GLuint mask
= ctx
->PixelMaps
.StoS
.Size
- 1;
295 for (i
= 0; i
< n
; i
++) {
296 stencil
[i
] = (GLubyte
) ctx
->PixelMaps
.StoS
.Map
[ stencil
[i
] & mask
];