pixeltransfer.c revision af69d88d
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27/** 28 * \file pixeltransfer.c 29 * Pixel transfer operations (scale, bias, table lookups, etc) 30 */ 31 32 33#include "glheader.h" 34#include "colormac.h" 35#include "pixeltransfer.h" 36#include "imports.h" 37#include "mtypes.h" 38 39 40/* 41 * Apply scale and bias factors to an array of RGBA pixels. 42 */ 43void 44_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4], 45 GLfloat rScale, GLfloat gScale, 46 GLfloat bScale, GLfloat aScale, 47 GLfloat rBias, GLfloat gBias, 48 GLfloat bBias, GLfloat aBias) 49{ 50 if (rScale != 1.0 || rBias != 0.0) { 51 GLuint i; 52 for (i = 0; i < n; i++) { 53 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias; 54 } 55 } 56 if (gScale != 1.0 || gBias != 0.0) { 57 GLuint i; 58 for (i = 0; i < n; i++) { 59 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias; 60 } 61 } 62 if (bScale != 1.0 || bBias != 0.0) { 63 GLuint i; 64 for (i = 0; i < n; i++) { 65 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias; 66 } 67 } 68 if (aScale != 1.0 || aBias != 0.0) { 69 GLuint i; 70 for (i = 0; i < n; i++) { 71 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias; 72 } 73 } 74} 75 76 77/* 78 * Apply pixel mapping to an array of floating point RGBA pixels. 79 */ 80void 81_mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] ) 82{ 83 const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1); 84 const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1); 85 const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1); 86 const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1); 87 const GLfloat *rMap = ctx->PixelMaps.RtoR.Map; 88 const GLfloat *gMap = ctx->PixelMaps.GtoG.Map; 89 const GLfloat *bMap = ctx->PixelMaps.BtoB.Map; 90 const GLfloat *aMap = ctx->PixelMaps.AtoA.Map; 91 GLuint i; 92 for (i=0;i<n;i++) { 93 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 94 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 95 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 96 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 97 rgba[i][RCOMP] = rMap[F_TO_I(r * rscale)]; 98 rgba[i][GCOMP] = gMap[F_TO_I(g * gscale)]; 99 rgba[i][BCOMP] = bMap[F_TO_I(b * bscale)]; 100 rgba[i][ACOMP] = aMap[F_TO_I(a * ascale)]; 101 } 102} 103 104/* 105 * Map color indexes to float rgba values. 106 */ 107void 108_mesa_map_ci_to_rgba( const struct gl_context *ctx, GLuint n, 109 const GLuint index[], GLfloat rgba[][4] ) 110{ 111 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1; 112 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1; 113 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1; 114 GLuint amask = ctx->PixelMaps.ItoA.Size - 1; 115 const GLfloat *rMap = ctx->PixelMaps.ItoR.Map; 116 const GLfloat *gMap = ctx->PixelMaps.ItoG.Map; 117 const GLfloat *bMap = ctx->PixelMaps.ItoB.Map; 118 const GLfloat *aMap = ctx->PixelMaps.ItoA.Map; 119 GLuint i; 120 for (i=0;i<n;i++) { 121 rgba[i][RCOMP] = rMap[index[i] & rmask]; 122 rgba[i][GCOMP] = gMap[index[i] & gmask]; 123 rgba[i][BCOMP] = bMap[index[i] & bmask]; 124 rgba[i][ACOMP] = aMap[index[i] & amask]; 125 } 126} 127 128 129void 130_mesa_scale_and_bias_depth(const struct gl_context *ctx, GLuint n, 131 GLfloat depthValues[]) 132{ 133 const GLfloat scale = ctx->Pixel.DepthScale; 134 const GLfloat bias = ctx->Pixel.DepthBias; 135 GLuint i; 136 for (i = 0; i < n; i++) { 137 GLfloat d = depthValues[i] * scale + bias; 138 depthValues[i] = CLAMP(d, 0.0F, 1.0F); 139 } 140} 141 142 143void 144_mesa_scale_and_bias_depth_uint(const struct gl_context *ctx, GLuint n, 145 GLuint depthValues[]) 146{ 147 const GLdouble max = (double) 0xffffffff; 148 const GLdouble scale = ctx->Pixel.DepthScale; 149 const GLdouble bias = ctx->Pixel.DepthBias * max; 150 GLuint i; 151 for (i = 0; i < n; i++) { 152 GLdouble d = (GLdouble) depthValues[i] * scale + bias; 153 d = CLAMP(d, 0.0, max); 154 depthValues[i] = (GLuint) d; 155 } 156} 157 158/** 159 * Apply various pixel transfer operations to an array of RGBA pixels 160 * as indicated by the transferOps bitmask 161 */ 162void 163_mesa_apply_rgba_transfer_ops(struct gl_context *ctx, GLbitfield transferOps, 164 GLuint n, GLfloat rgba[][4]) 165{ 166 /* scale & bias */ 167 if (transferOps & IMAGE_SCALE_BIAS_BIT) { 168 _mesa_scale_and_bias_rgba(n, rgba, 169 ctx->Pixel.RedScale, ctx->Pixel.GreenScale, 170 ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, 171 ctx->Pixel.RedBias, ctx->Pixel.GreenBias, 172 ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); 173 } 174 /* color map lookup */ 175 if (transferOps & IMAGE_MAP_COLOR_BIT) { 176 _mesa_map_rgba( ctx, n, rgba ); 177 } 178 179 /* clamping to [0,1] */ 180 if (transferOps & IMAGE_CLAMP_BIT) { 181 GLuint i; 182 for (i = 0; i < n; i++) { 183 rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 184 rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 185 rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 186 rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 187 } 188 } 189} 190 191 192/* 193 * Apply color index shift and offset to an array of pixels. 194 */ 195void 196_mesa_shift_and_offset_ci(const struct gl_context *ctx, 197 GLuint n, GLuint indexes[]) 198{ 199 GLint shift = ctx->Pixel.IndexShift; 200 GLint offset = ctx->Pixel.IndexOffset; 201 GLuint i; 202 if (shift > 0) { 203 for (i=0;i<n;i++) { 204 indexes[i] = (indexes[i] << shift) + offset; 205 } 206 } 207 else if (shift < 0) { 208 shift = -shift; 209 for (i=0;i<n;i++) { 210 indexes[i] = (indexes[i] >> shift) + offset; 211 } 212 } 213 else { 214 for (i=0;i<n;i++) { 215 indexes[i] = indexes[i] + offset; 216 } 217 } 218} 219 220 221 222/** 223 * Apply color index shift, offset and table lookup to an array 224 * of color indexes; 225 */ 226void 227_mesa_apply_ci_transfer_ops(const struct gl_context *ctx, 228 GLbitfield transferOps, 229 GLuint n, GLuint indexes[]) 230{ 231 if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { 232 _mesa_shift_and_offset_ci(ctx, n, indexes); 233 } 234 if (transferOps & IMAGE_MAP_COLOR_BIT) { 235 const GLuint mask = ctx->PixelMaps.ItoI.Size - 1; 236 GLuint i; 237 for (i = 0; i < n; i++) { 238 const GLuint j = indexes[i] & mask; 239 indexes[i] = F_TO_I(ctx->PixelMaps.ItoI.Map[j]); 240 } 241 } 242} 243 244 245/** 246 * Apply stencil index shift, offset and table lookup to an array 247 * of stencil values. 248 */ 249void 250_mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n, 251 GLubyte stencil[]) 252{ 253 if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) { 254 const GLint offset = ctx->Pixel.IndexOffset; 255 GLint shift = ctx->Pixel.IndexShift; 256 GLuint i; 257 if (shift > 0) { 258 for (i = 0; i < n; i++) { 259 stencil[i] = (stencil[i] << shift) + offset; 260 } 261 } 262 else if (shift < 0) { 263 shift = -shift; 264 for (i = 0; i < n; i++) { 265 stencil[i] = (stencil[i] >> shift) + offset; 266 } 267 } 268 else { 269 for (i = 0; i < n; i++) { 270 stencil[i] = stencil[i] + offset; 271 } 272 } 273 } 274 if (ctx->Pixel.MapStencilFlag) { 275 GLuint mask = ctx->PixelMaps.StoS.Size - 1; 276 GLuint i; 277 for (i = 0; i < n; i++) { 278 stencil[i] = (GLubyte) ctx->PixelMaps.StoS.Map[ stencil[i] & mask ]; 279 } 280 } 281} 282