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