Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  7.1
  4.  *
  5.  * Copyright (C) 1999-2008  Brian Paul   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.  * BRIAN PAUL 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 pixel.c
  28.  * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer)
  29.  */
  30.  
  31. #include "glheader.h"
  32. #include "bufferobj.h"
  33. #include "colormac.h"
  34. #include "context.h"
  35. #include "macros.h"
  36. #include "pixel.h"
  37. #include "mtypes.h"
  38. #include "main/dispatch.h"
  39.  
  40.  
  41. #if FEATURE_pixel_transfer
  42.  
  43.  
  44. /**********************************************************************/
  45. /*****                    glPixelZoom                             *****/
  46. /**********************************************************************/
  47.  
  48. static void GLAPIENTRY
  49. _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
  50. {
  51.    GET_CURRENT_CONTEXT(ctx);
  52.  
  53.    if (ctx->Pixel.ZoomX == xfactor &&
  54.        ctx->Pixel.ZoomY == yfactor)
  55.       return;
  56.  
  57.    FLUSH_VERTICES(ctx, _NEW_PIXEL);
  58.    ctx->Pixel.ZoomX = xfactor;
  59.    ctx->Pixel.ZoomY = yfactor;
  60. }
  61.  
  62.  
  63.  
  64. /**********************************************************************/
  65. /*****                         glPixelMap                         *****/
  66. /**********************************************************************/
  67.  
  68. /**
  69.  * Return pointer to a pixelmap by name.
  70.  */
  71. static struct gl_pixelmap *
  72. get_pixelmap(struct gl_context *ctx, GLenum map)
  73. {
  74.    switch (map) {
  75.    case GL_PIXEL_MAP_I_TO_I:
  76.       return &ctx->PixelMaps.ItoI;
  77.    case GL_PIXEL_MAP_S_TO_S:
  78.       return &ctx->PixelMaps.StoS;
  79.    case GL_PIXEL_MAP_I_TO_R:
  80.       return &ctx->PixelMaps.ItoR;
  81.    case GL_PIXEL_MAP_I_TO_G:
  82.       return &ctx->PixelMaps.ItoG;
  83.    case GL_PIXEL_MAP_I_TO_B:
  84.       return &ctx->PixelMaps.ItoB;
  85.    case GL_PIXEL_MAP_I_TO_A:
  86.       return &ctx->PixelMaps.ItoA;
  87.    case GL_PIXEL_MAP_R_TO_R:
  88.       return &ctx->PixelMaps.RtoR;
  89.    case GL_PIXEL_MAP_G_TO_G:
  90.       return &ctx->PixelMaps.GtoG;
  91.    case GL_PIXEL_MAP_B_TO_B:
  92.       return &ctx->PixelMaps.BtoB;
  93.    case GL_PIXEL_MAP_A_TO_A:
  94.       return &ctx->PixelMaps.AtoA;
  95.    default:
  96.       return NULL;
  97.    }
  98. }
  99.  
  100.  
  101. /**
  102.  * Helper routine used by the other _mesa_PixelMap() functions.
  103.  */
  104. static void
  105. store_pixelmap(struct gl_context *ctx, GLenum map, GLsizei mapsize,
  106.                const GLfloat *values)
  107. {
  108.    GLint i;
  109.    struct gl_pixelmap *pm = get_pixelmap(ctx, map);
  110.    if (!pm) {
  111.       _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)");
  112.       return;
  113.    }
  114.  
  115.    switch (map) {
  116.    case GL_PIXEL_MAP_S_TO_S:
  117.       /* special case */
  118.       ctx->PixelMaps.StoS.Size = mapsize;
  119.       for (i = 0; i < mapsize; i++) {
  120.          ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]);
  121.       }
  122.       break;
  123.    case GL_PIXEL_MAP_I_TO_I:
  124.       /* special case */
  125.       ctx->PixelMaps.ItoI.Size = mapsize;
  126.       for (i = 0; i < mapsize; i++) {
  127.          ctx->PixelMaps.ItoI.Map[i] = values[i];
  128.       }
  129.       break;
  130.    default:
  131.       /* general case */
  132.       pm->Size = mapsize;
  133.       for (i = 0; i < mapsize; i++) {
  134.          GLfloat val = CLAMP(values[i], 0.0F, 1.0F);
  135.          pm->Map[i] = val;
  136.          pm->Map8[i] = (GLint) (val * 255.0F);
  137.       }
  138.    }
  139. }
  140.  
  141.  
  142. /**
  143.  * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
  144.  */
  145. static GLboolean
  146. validate_pbo_access(struct gl_context *ctx, struct gl_pixelstore_attrib *pack,
  147.                     GLsizei mapsize, GLenum format, GLenum type,
  148.                     const GLvoid *ptr)
  149. {
  150.    GLboolean ok;
  151.  
  152.    /* Note, need to use DefaultPacking and Unpack's buffer object */
  153.    _mesa_reference_buffer_object(ctx,
  154.                                  &ctx->DefaultPacking.BufferObj,
  155.                                  pack->BufferObj);
  156.  
  157.    ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
  158.                                   format, type, ptr);
  159.  
  160.    /* restore */
  161.    _mesa_reference_buffer_object(ctx,
  162.                                  &ctx->DefaultPacking.BufferObj,
  163.                                  ctx->Shared->NullBufferObj);
  164.  
  165.    if (!ok) {
  166.       _mesa_error(ctx, GL_INVALID_OPERATION,
  167.                   "glPixelMap(invalid PBO access)");
  168.    }
  169.    return ok;
  170. }
  171.  
  172.  
  173. static void GLAPIENTRY
  174. _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
  175. {
  176.    GET_CURRENT_CONTEXT(ctx);
  177.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  178.  
  179.    /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
  180.    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
  181.       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  182.       return;
  183.    }
  184.  
  185.    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
  186.       /* test that mapsize is a power of two */
  187.       if (!_mesa_is_pow_two(mapsize)) {
  188.          _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  189.          return;
  190.       }
  191.    }
  192.  
  193.    FLUSH_VERTICES(ctx, _NEW_PIXEL);
  194.  
  195.    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
  196.                             GL_INTENSITY, GL_FLOAT, values)) {
  197.       return;
  198.    }
  199.  
  200.    values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
  201.    if (!values) {
  202.       if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
  203.          _mesa_error(ctx, GL_INVALID_OPERATION,
  204.                      "glPixelMapfv(PBO is mapped)");
  205.       }
  206.       return;
  207.    }
  208.  
  209.    store_pixelmap(ctx, map, mapsize, values);
  210.  
  211.    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
  212. }
  213.  
  214.  
  215. static void GLAPIENTRY
  216. _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
  217. {
  218.    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
  219.    GET_CURRENT_CONTEXT(ctx);
  220.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  221.  
  222.    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
  223.       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
  224.       return;
  225.    }
  226.  
  227.    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
  228.       /* test that mapsize is a power of two */
  229.       if (!_mesa_is_pow_two(mapsize)) {
  230.          _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
  231.          return;
  232.       }
  233.    }
  234.  
  235.    FLUSH_VERTICES(ctx, _NEW_PIXEL);
  236.  
  237.    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
  238.                             GL_INTENSITY, GL_UNSIGNED_INT, values)) {
  239.       return;
  240.    }
  241.  
  242.    values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
  243.    if (!values) {
  244.       if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
  245.          _mesa_error(ctx, GL_INVALID_OPERATION,
  246.                      "glPixelMapuiv(PBO is mapped)");
  247.       }
  248.       return;
  249.    }
  250.  
  251.    /* convert to floats */
  252.    if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
  253.       GLint i;
  254.       for (i = 0; i < mapsize; i++) {
  255.          fvalues[i] = (GLfloat) values[i];
  256.       }
  257.    }
  258.    else {
  259.       GLint i;
  260.       for (i = 0; i < mapsize; i++) {
  261.          fvalues[i] = UINT_TO_FLOAT( values[i] );
  262.       }
  263.    }
  264.  
  265.    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
  266.  
  267.    store_pixelmap(ctx, map, mapsize, fvalues);
  268. }
  269.  
  270.  
  271. static void GLAPIENTRY
  272. _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
  273. {
  274.    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
  275.    GET_CURRENT_CONTEXT(ctx);
  276.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  277.  
  278.    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
  279.       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
  280.       return;
  281.    }
  282.  
  283.    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
  284.       /* test that mapsize is a power of two */
  285.       if (!_mesa_is_pow_two(mapsize)) {
  286.          _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
  287.          return;
  288.       }
  289.    }
  290.  
  291.    FLUSH_VERTICES(ctx, _NEW_PIXEL);
  292.  
  293.    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
  294.                             GL_INTENSITY, GL_UNSIGNED_SHORT, values)) {
  295.       return;
  296.    }
  297.  
  298.    values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
  299.    if (!values) {
  300.       if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
  301.          _mesa_error(ctx, GL_INVALID_OPERATION,
  302.                      "glPixelMapusv(PBO is mapped)");
  303.       }
  304.       return;
  305.    }
  306.  
  307.    /* convert to floats */
  308.    if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
  309.       GLint i;
  310.       for (i = 0; i < mapsize; i++) {
  311.          fvalues[i] = (GLfloat) values[i];
  312.       }
  313.    }
  314.    else {
  315.       GLint i;
  316.       for (i = 0; i < mapsize; i++) {
  317.          fvalues[i] = USHORT_TO_FLOAT( values[i] );
  318.       }
  319.    }
  320.  
  321.    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
  322.  
  323.    store_pixelmap(ctx, map, mapsize, fvalues);
  324. }
  325.  
  326.  
  327. static void GLAPIENTRY
  328. _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
  329. {
  330.    GET_CURRENT_CONTEXT(ctx);
  331.    GLuint mapsize, i;
  332.    const struct gl_pixelmap *pm;
  333.  
  334.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  335.  
  336.    pm = get_pixelmap(ctx, map);
  337.    if (!pm) {
  338.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)");
  339.       return;
  340.    }
  341.  
  342.    mapsize = pm->Size;
  343.  
  344.    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
  345.                             GL_INTENSITY, GL_FLOAT, values)) {
  346.       return;
  347.    }
  348.  
  349.    values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
  350.    if (!values) {
  351.       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
  352.          _mesa_error(ctx, GL_INVALID_OPERATION,
  353.                      "glGetPixelMapfv(PBO is mapped)");
  354.       }
  355.       return;
  356.    }
  357.  
  358.    if (map == GL_PIXEL_MAP_S_TO_S) {
  359.       /* special case */
  360.       for (i = 0; i < mapsize; i++) {
  361.          values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i];
  362.       }
  363.    }
  364.    else {
  365.       memcpy(values, pm->Map, mapsize * sizeof(GLfloat));
  366.    }
  367.  
  368.    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
  369. }
  370.  
  371.  
  372. static void GLAPIENTRY
  373. _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
  374. {
  375.    GET_CURRENT_CONTEXT(ctx);
  376.    GLint mapsize, i;
  377.    const struct gl_pixelmap *pm;
  378.  
  379.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  380.  
  381.    pm = get_pixelmap(ctx, map);
  382.    if (!pm) {
  383.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
  384.       return;
  385.    }
  386.    mapsize = pm->Size;
  387.  
  388.    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
  389.                             GL_INTENSITY, GL_UNSIGNED_INT, values)) {
  390.       return;
  391.    }
  392.  
  393.    values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
  394.    if (!values) {
  395.       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
  396.          _mesa_error(ctx, GL_INVALID_OPERATION,
  397.                      "glGetPixelMapuiv(PBO is mapped)");
  398.       }
  399.       return;
  400.    }
  401.  
  402.    if (map == GL_PIXEL_MAP_S_TO_S) {
  403.       /* special case */
  404.       memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint));
  405.    }
  406.    else {
  407.       for (i = 0; i < mapsize; i++) {
  408.          values[i] = FLOAT_TO_UINT( pm->Map[i] );
  409.       }
  410.    }
  411.  
  412.    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
  413. }
  414.  
  415.  
  416. static void GLAPIENTRY
  417. _mesa_GetPixelMapusv( GLenum map, GLushort *values )
  418. {
  419.    GET_CURRENT_CONTEXT(ctx);
  420.    GLint mapsize, i;
  421.    const struct gl_pixelmap *pm;
  422.  
  423.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  424.  
  425.    pm = get_pixelmap(ctx, map);
  426.    if (!pm) {
  427.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
  428.       return;
  429.    }
  430.    mapsize = pm->Size;
  431.  
  432.    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
  433.                             GL_INTENSITY, GL_UNSIGNED_SHORT, values)) {
  434.       return;
  435.    }
  436.  
  437.    values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
  438.    if (!values) {
  439.       if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
  440.          _mesa_error(ctx, GL_INVALID_OPERATION,
  441.                      "glGetPixelMapusv(PBO is mapped)");
  442.       }
  443.       return;
  444.    }
  445.  
  446.    switch (map) {
  447.    /* special cases */
  448.    case GL_PIXEL_MAP_I_TO_I:
  449.       for (i = 0; i < mapsize; i++) {
  450.          values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.);
  451.       }
  452.       break;
  453.    case GL_PIXEL_MAP_S_TO_S:
  454.       for (i = 0; i < mapsize; i++) {
  455.          values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.);
  456.       }
  457.       break;
  458.    default:
  459.       for (i = 0; i < mapsize; i++) {
  460.          CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] );
  461.       }
  462.    }
  463.  
  464.    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
  465. }
  466.  
  467.  
  468.  
  469. /**********************************************************************/
  470. /*****                       glPixelTransfer                      *****/
  471. /**********************************************************************/
  472.  
  473.  
  474. /*
  475.  * Implements glPixelTransfer[fi] whether called immediately or from a
  476.  * display list.
  477.  */
  478. static void GLAPIENTRY
  479. _mesa_PixelTransferf( GLenum pname, GLfloat param )
  480. {
  481.    GET_CURRENT_CONTEXT(ctx);
  482.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  483.  
  484.    switch (pname) {
  485.       case GL_MAP_COLOR:
  486.          if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
  487.             return;
  488.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  489.          ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
  490.          break;
  491.       case GL_MAP_STENCIL:
  492.          if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
  493.             return;
  494.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  495.          ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
  496.          break;
  497.       case GL_INDEX_SHIFT:
  498.          if (ctx->Pixel.IndexShift == (GLint) param)
  499.             return;
  500.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  501.          ctx->Pixel.IndexShift = (GLint) param;
  502.          break;
  503.       case GL_INDEX_OFFSET:
  504.          if (ctx->Pixel.IndexOffset == (GLint) param)
  505.             return;
  506.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  507.          ctx->Pixel.IndexOffset = (GLint) param;
  508.          break;
  509.       case GL_RED_SCALE:
  510.          if (ctx->Pixel.RedScale == param)
  511.             return;
  512.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  513.          ctx->Pixel.RedScale = param;
  514.          break;
  515.       case GL_RED_BIAS:
  516.          if (ctx->Pixel.RedBias == param)
  517.             return;
  518.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  519.          ctx->Pixel.RedBias = param;
  520.          break;
  521.       case GL_GREEN_SCALE:
  522.          if (ctx->Pixel.GreenScale == param)
  523.             return;
  524.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  525.          ctx->Pixel.GreenScale = param;
  526.          break;
  527.       case GL_GREEN_BIAS:
  528.          if (ctx->Pixel.GreenBias == param)
  529.             return;
  530.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  531.          ctx->Pixel.GreenBias = param;
  532.          break;
  533.       case GL_BLUE_SCALE:
  534.          if (ctx->Pixel.BlueScale == param)
  535.             return;
  536.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  537.          ctx->Pixel.BlueScale = param;
  538.          break;
  539.       case GL_BLUE_BIAS:
  540.          if (ctx->Pixel.BlueBias == param)
  541.             return;
  542.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  543.          ctx->Pixel.BlueBias = param;
  544.          break;
  545.       case GL_ALPHA_SCALE:
  546.          if (ctx->Pixel.AlphaScale == param)
  547.             return;
  548.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  549.          ctx->Pixel.AlphaScale = param;
  550.          break;
  551.       case GL_ALPHA_BIAS:
  552.          if (ctx->Pixel.AlphaBias == param)
  553.             return;
  554.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  555.          ctx->Pixel.AlphaBias = param;
  556.          break;
  557.       case GL_DEPTH_SCALE:
  558.          if (ctx->Pixel.DepthScale == param)
  559.             return;
  560.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  561.          ctx->Pixel.DepthScale = param;
  562.          break;
  563.       case GL_DEPTH_BIAS:
  564.          if (ctx->Pixel.DepthBias == param)
  565.             return;
  566.          FLUSH_VERTICES(ctx, _NEW_PIXEL);
  567.          ctx->Pixel.DepthBias = param;
  568.          break;
  569.       default:
  570.          _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
  571.          return;
  572.    }
  573. }
  574.  
  575.  
  576. static void GLAPIENTRY
  577. _mesa_PixelTransferi( GLenum pname, GLint param )
  578. {
  579.    _mesa_PixelTransferf( pname, (GLfloat) param );
  580. }
  581.  
  582.  
  583.  
  584. /**********************************************************************/
  585. /*****                    State Management                        *****/
  586. /**********************************************************************/
  587.  
  588. /*
  589.  * Return a bitmask of IMAGE_*_BIT flags which to indicate which
  590.  * pixel transfer operations are enabled.
  591.  */
  592. static void
  593. update_image_transfer_state(struct gl_context *ctx)
  594. {
  595.    GLuint mask = 0;
  596.  
  597.    if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
  598.        ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
  599.        ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
  600.        ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
  601.       mask |= IMAGE_SCALE_BIAS_BIT;
  602.  
  603.    if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
  604.       mask |= IMAGE_SHIFT_OFFSET_BIT;
  605.  
  606.    if (ctx->Pixel.MapColorFlag)
  607.       mask |= IMAGE_MAP_COLOR_BIT;
  608.  
  609.    ctx->_ImageTransferState = mask;
  610. }
  611.  
  612.  
  613. /**
  614.  * Update mesa pixel transfer derived state.
  615.  */
  616. void _mesa_update_pixel( struct gl_context *ctx, GLuint new_state )
  617. {
  618.    if (new_state & _MESA_NEW_TRANSFER_STATE)
  619.       update_image_transfer_state(ctx);
  620. }
  621.  
  622.  
  623. void
  624. _mesa_init_pixel_dispatch(struct _glapi_table *disp)
  625. {
  626.    SET_GetPixelMapfv(disp, _mesa_GetPixelMapfv);
  627.    SET_GetPixelMapuiv(disp, _mesa_GetPixelMapuiv);
  628.    SET_GetPixelMapusv(disp, _mesa_GetPixelMapusv);
  629.    SET_PixelMapfv(disp, _mesa_PixelMapfv);
  630.    SET_PixelMapuiv(disp, _mesa_PixelMapuiv);
  631.    SET_PixelMapusv(disp, _mesa_PixelMapusv);
  632.    SET_PixelTransferf(disp, _mesa_PixelTransferf);
  633.    SET_PixelTransferi(disp, _mesa_PixelTransferi);
  634.    SET_PixelZoom(disp, _mesa_PixelZoom);
  635. }
  636.  
  637.  
  638. #endif /* FEATURE_pixel_transfer */
  639.  
  640.  
  641. /**********************************************************************/
  642. /*****                      Initialization                        *****/
  643. /**********************************************************************/
  644.  
  645. static void
  646. init_pixelmap(struct gl_pixelmap *map)
  647. {
  648.    map->Size = 1;
  649.    map->Map[0] = 0.0;
  650.    map->Map8[0] = 0;
  651. }
  652.  
  653.  
  654. /**
  655.  * Initialize the context's PIXEL attribute group.
  656.  */
  657. void
  658. _mesa_init_pixel( struct gl_context *ctx )
  659. {
  660.    /* Pixel group */
  661.    ctx->Pixel.RedBias = 0.0;
  662.    ctx->Pixel.RedScale = 1.0;
  663.    ctx->Pixel.GreenBias = 0.0;
  664.    ctx->Pixel.GreenScale = 1.0;
  665.    ctx->Pixel.BlueBias = 0.0;
  666.    ctx->Pixel.BlueScale = 1.0;
  667.    ctx->Pixel.AlphaBias = 0.0;
  668.    ctx->Pixel.AlphaScale = 1.0;
  669.    ctx->Pixel.DepthBias = 0.0;
  670.    ctx->Pixel.DepthScale = 1.0;
  671.    ctx->Pixel.IndexOffset = 0;
  672.    ctx->Pixel.IndexShift = 0;
  673.    ctx->Pixel.ZoomX = 1.0;
  674.    ctx->Pixel.ZoomY = 1.0;
  675.    ctx->Pixel.MapColorFlag = GL_FALSE;
  676.    ctx->Pixel.MapStencilFlag = GL_FALSE;
  677.    init_pixelmap(&ctx->PixelMaps.StoS);
  678.    init_pixelmap(&ctx->PixelMaps.ItoI);
  679.    init_pixelmap(&ctx->PixelMaps.ItoR);
  680.    init_pixelmap(&ctx->PixelMaps.ItoG);
  681.    init_pixelmap(&ctx->PixelMaps.ItoB);
  682.    init_pixelmap(&ctx->PixelMaps.ItoA);
  683.    init_pixelmap(&ctx->PixelMaps.RtoR);
  684.    init_pixelmap(&ctx->PixelMaps.GtoG);
  685.    init_pixelmap(&ctx->PixelMaps.BtoB);
  686.    init_pixelmap(&ctx->PixelMaps.AtoA);
  687.    /* GL_SGI_texture_color_table */
  688.    ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
  689.    ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
  690.  
  691.    if (ctx->Visual.doubleBufferMode) {
  692.       ctx->Pixel.ReadBuffer = GL_BACK;
  693.    }
  694.    else {
  695.       ctx->Pixel.ReadBuffer = GL_FRONT;
  696.    }
  697.  
  698.    /* Miscellaneous */
  699.    ctx->_ImageTransferState = 0;
  700. }
  701.