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[F_TO_I(r * rscale)]; 97 rgba[i][GCOMP] = gMap[F_TO_I(g * gscale)]; 98 rgba[i][BCOMP] = bMap[F_TO_I(b * bscale)]; 99 rgba[i][ACOMP] = aMap[F_TO_I(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 void 129 _mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n, 130 GLfloat depthValues[]) 131 { 132 const GLfloat scale = ctx->Pixel.DepthScale; 133 const GLfloat bias = ctx->Pixel.DepthBias; 134 GLuint i; 135 for (i = 0; i < n; i++) { 136 GLfloat d = depthValues[i] * scale + bias; 137 depthValues[i] = CLAMP(d, 0.0F, 1.0F); 138 } 139 } 140 141 142 void 143 _mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n, 144 GLuint depthValues[]) 145 { 146 const GLdouble max = (double) 0xffffffff; 147 const GLdouble scale = ctx->Pixel.DepthScale; 148 const GLdouble bias = ctx->Pixel.DepthBias * max; 149 GLuint i; 150 for (i = 0; i < n; i++) { 151 GLdouble d = (GLdouble) depthValues[i] * scale + bias; 152 d = CLAMP(d, 0.0, max); 153 depthValues[i] = (GLuint) d; 154 } 155 } 156 157 /** 158 * Apply various pixel transfer operations to an array of RGBA pixels 159 * as indicated by the transferOps bitmask 160 */ 161 void 162 _mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps, 163 GLuint n, GLfloat rgba[][4]) 164 { 165 /* scale & bias */ 166 if (transferOps & IMAGE_SCALE_BIAS_BIT) { 167 _mesa_scale_and_bias_rgba(n, rgba, 168 ctx->Pixel.RedScale, ctx->Pixel.GreenScale, 169 ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, 170 ctx->Pixel.RedBias, ctx->Pixel.GreenBias, 171 ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); 172 } 173 /* color map lookup */ 174 if (transferOps & IMAGE_MAP_COLOR_BIT) { 175 _mesa_map_rgba( ctx, n, rgba ); 176 } 177 178 /* clamping to [0,1] */ 179 if (transferOps & IMAGE_CLAMP_BIT) { 180 GLuint i; 181 for (i = 0; i < n; i++) { 182 rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 183 rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 184 rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 185 rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 186 } 187 } 188 } 189 190 191 /* 192 * Apply color index shift and offset to an array of pixels. 193 */ 194 void 195 _mesa_shift_and_offset_ci(const struct gl_context *ctx, 196 GLuint n, GLuint indexes[]) 197 { 198 GLint shift = ctx->Pixel.IndexShift; 199 GLint offset = ctx->Pixel.IndexOffset; 200 GLuint i; 201 if (shift > 0) { 202 for (i=0;i<n;i++) { 203 indexes[i] = (indexes[i] << shift) + offset; 204 } 205 } 206 else if (shift < 0) { 207 shift = -shift; 208 for (i=0;i<n;i++) { 209 indexes[i] = (indexes[i] >> shift) + offset; 210 } 211 } 212 else { 213 for (i=0;i<n;i++) { 214 indexes[i] = indexes[i] + offset; 215 } 216 } 217 } 218 219 220 221 /** 222 * Apply color index shift, offset and table lookup to an array 223 * of color indexes; 224 */ 225 void 226 _mesa_apply_ci_transfer_ops(const struct gl_context *ctx, 227 GLbitfield transferOps, 228 GLuint n, GLuint indexes[]) 229 { 230 if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { 231 _mesa_shift_and_offset_ci(ctx, n, indexes); 232 } 233 if (transferOps & IMAGE_MAP_COLOR_BIT) { 234 const GLuint mask = ctx->PixelMaps.ItoI.Size - 1; 235 GLuint i; 236 for (i = 0; i < n; i++) { 237 const GLuint j = indexes[i] & mask; 238 indexes[i] = F_TO_I(ctx->PixelMaps.ItoI.Map[j]); 239 } 240 } 241 } 242 243 244 /** 245 * Apply stencil index shift, offset and table lookup to an array 246 * of stencil values. 247 */ 248 void 249 _mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n, 250 GLubyte stencil[]) 251 { 252 if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) { 253 const GLint offset = ctx->Pixel.IndexOffset; 254 GLint shift = ctx->Pixel.IndexShift; 255 GLuint i; 256 if (shift > 0) { 257 for (i = 0; i < n; i++) { 258 stencil[i] = (stencil[i] << shift) + offset; 259 } 260 } 261 else if (shift < 0) { 262 shift = -shift; 263 for (i = 0; i < n; i++) { 264 stencil[i] = (stencil[i] >> shift) + offset; 265 } 266 } 267 else { 268 for (i = 0; i < n; i++) { 269 stencil[i] = stencil[i] + offset; 270 } 271 } 272 } 273 if (ctx->Pixel.MapStencilFlag) { 274 GLuint mask = ctx->PixelMaps.StoS.Size - 1; 275 GLuint i; 276 for (i = 0; i < n; i++) { 277 stencil[i] = (GLubyte) ctx->PixelMaps.StoS.Map[ stencil[i] & mask ]; 278 } 279 } 280 } 281