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-2007  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. #include "glheader.h"
  27. #include "bufferobj.h"
  28. #include "colortab.h"
  29. #include "context.h"
  30. #include "image.h"
  31. #include "macros.h"
  32. #include "pack.h"
  33. #include "state.h"
  34. #include "teximage.h"
  35. #include "texstate.h"
  36. #include "main/dispatch.h"
  37.  
  38.  
  39. #if FEATURE_colortable
  40.  
  41.  
  42. /**
  43.  * Given an internalFormat token passed to glColorTable,
  44.  * return the corresponding base format.
  45.  * Return -1 if invalid token.
  46.  */
  47. static GLint
  48. base_colortab_format( GLenum format )
  49. {
  50.    switch (format) {
  51.       case GL_ALPHA:
  52.       case GL_ALPHA4:
  53.       case GL_ALPHA8:
  54.       case GL_ALPHA12:
  55.       case GL_ALPHA16:
  56.          return GL_ALPHA;
  57.       case GL_LUMINANCE:
  58.       case GL_LUMINANCE4:
  59.       case GL_LUMINANCE8:
  60.       case GL_LUMINANCE12:
  61.       case GL_LUMINANCE16:
  62.          return GL_LUMINANCE;
  63.       case GL_LUMINANCE_ALPHA:
  64.       case GL_LUMINANCE4_ALPHA4:
  65.       case GL_LUMINANCE6_ALPHA2:
  66.       case GL_LUMINANCE8_ALPHA8:
  67.       case GL_LUMINANCE12_ALPHA4:
  68.       case GL_LUMINANCE12_ALPHA12:
  69.       case GL_LUMINANCE16_ALPHA16:
  70.          return GL_LUMINANCE_ALPHA;
  71.       case GL_INTENSITY:
  72.       case GL_INTENSITY4:
  73.       case GL_INTENSITY8:
  74.       case GL_INTENSITY12:
  75.       case GL_INTENSITY16:
  76.          return GL_INTENSITY;
  77.       case GL_RGB:
  78.       case GL_R3_G3_B2:
  79.       case GL_RGB4:
  80.       case GL_RGB5:
  81.       case GL_RGB8:
  82.       case GL_RGB10:
  83.       case GL_RGB12:
  84.       case GL_RGB16:
  85.          return GL_RGB;
  86.       case GL_RGBA:
  87.       case GL_RGBA2:
  88.       case GL_RGBA4:
  89.       case GL_RGB5_A1:
  90.       case GL_RGBA8:
  91.       case GL_RGB10_A2:
  92.       case GL_RGBA12:
  93.       case GL_RGBA16:
  94.          return GL_RGBA;
  95.       default:
  96.          return -1;  /* error */
  97.    }
  98. }
  99.  
  100.  
  101.  
  102. /**
  103.  * Examine table's format and set the component sizes accordingly.
  104.  */
  105. static void
  106. set_component_sizes( struct gl_color_table *table )
  107. {
  108.    /* assuming the ubyte table */
  109.    const GLubyte sz = 8;
  110.  
  111.    switch (table->_BaseFormat) {
  112.       case GL_ALPHA:
  113.          table->RedSize = 0;
  114.          table->GreenSize = 0;
  115.          table->BlueSize = 0;
  116.          table->AlphaSize = sz;
  117.          table->IntensitySize = 0;
  118.          table->LuminanceSize = 0;
  119.          break;
  120.       case GL_LUMINANCE:
  121.          table->RedSize = 0;
  122.          table->GreenSize = 0;
  123.          table->BlueSize = 0;
  124.          table->AlphaSize = 0;
  125.          table->IntensitySize = 0;
  126.          table->LuminanceSize = sz;
  127.          break;
  128.       case GL_LUMINANCE_ALPHA:
  129.          table->RedSize = 0;
  130.          table->GreenSize = 0;
  131.          table->BlueSize = 0;
  132.          table->AlphaSize = sz;
  133.          table->IntensitySize = 0;
  134.          table->LuminanceSize = sz;
  135.          break;
  136.       case GL_INTENSITY:
  137.          table->RedSize = 0;
  138.          table->GreenSize = 0;
  139.          table->BlueSize = 0;
  140.          table->AlphaSize = 0;
  141.          table->IntensitySize = sz;
  142.          table->LuminanceSize = 0;
  143.          break;
  144.       case GL_RGB:
  145.          table->RedSize = sz;
  146.          table->GreenSize = sz;
  147.          table->BlueSize = sz;
  148.          table->AlphaSize = 0;
  149.          table->IntensitySize = 0;
  150.          table->LuminanceSize = 0;
  151.          break;
  152.       case GL_RGBA:
  153.          table->RedSize = sz;
  154.          table->GreenSize = sz;
  155.          table->BlueSize = sz;
  156.          table->AlphaSize = sz;
  157.          table->IntensitySize = 0;
  158.          table->LuminanceSize = 0;
  159.          break;
  160.       default:
  161.          _mesa_problem(NULL, "unexpected format in set_component_sizes");
  162.    }
  163. }
  164.  
  165.  
  166.  
  167. /**
  168.  * Update/replace all or part of a color table.  Helper function
  169.  * used by _mesa_ColorTable() and _mesa_ColorSubTable().
  170.  * The table->Table buffer should already be allocated.
  171.  * \param start first entry to update
  172.  * \param count number of entries to update
  173.  * \param format format of user-provided table data
  174.  * \param type datatype of user-provided table data
  175.  * \param data user-provided table data
  176.  * \param [rgba]Scale - RGBA scale factors
  177.  * \param [rgba]Bias - RGBA bias factors
  178.  */
  179. static void
  180. store_colortable_entries(struct gl_context *ctx, struct gl_color_table *table,
  181.                          GLsizei start, GLsizei count,
  182.                          GLenum format, GLenum type, const GLvoid *data,
  183.                          GLfloat rScale, GLfloat rBias,
  184.                          GLfloat gScale, GLfloat gBias,
  185.                          GLfloat bScale, GLfloat bBias,
  186.                          GLfloat aScale, GLfloat aBias)
  187. {
  188.    data = _mesa_map_validate_pbo_source(ctx,
  189.                                         1, &ctx->Unpack, count, 1, 1,
  190.                                         format, type, data,
  191.                                         "glColor[Sub]Table");
  192.    if (!data)
  193.       return;
  194.  
  195.    {
  196.       /* convert user-provided data to GLfloat values */
  197.       GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4];
  198.       GLfloat *tableF;
  199.       GLint i;
  200.  
  201.       _mesa_unpack_color_span_float(ctx,
  202.                                     count,         /* number of pixels */
  203.                                     table->_BaseFormat, /* dest format */
  204.                                     tempTab,       /* dest address */
  205.                                     format, type,  /* src format/type */
  206.                                     data,          /* src data */
  207.                                     &ctx->Unpack,
  208.                                     IMAGE_CLAMP_BIT); /* transfer ops */
  209.  
  210.       /* the destination */
  211.       tableF = table->TableF;
  212.  
  213.       /* Apply scale & bias & clamp now */
  214.       switch (table->_BaseFormat) {
  215.          case GL_INTENSITY:
  216.             for (i = 0; i < count; i++) {
  217.                GLuint j = start + i;
  218.                tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
  219.             }
  220.             break;
  221.          case GL_LUMINANCE:
  222.             for (i = 0; i < count; i++) {
  223.                GLuint j = start + i;
  224.                tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
  225.             }
  226.             break;
  227.          case GL_ALPHA:
  228.             for (i = 0; i < count; i++) {
  229.                GLuint j = start + i;
  230.                tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F);
  231.             }
  232.             break;
  233.          case GL_LUMINANCE_ALPHA:
  234.             for (i = 0; i < count; i++) {
  235.                GLuint j = start + i;
  236.                tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F);
  237.                tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F);
  238.             }
  239.             break;
  240.          case GL_RGB:
  241.             for (i = 0; i < count; i++) {
  242.                GLuint j = start + i;
  243.                tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F);
  244.                tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F);
  245.                tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F);
  246.             }
  247.             break;
  248.          case GL_RGBA:
  249.             for (i = 0; i < count; i++) {
  250.                GLuint j = start + i;
  251.                tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F);
  252.                tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F);
  253.                tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F);
  254.                tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F);
  255.             }
  256.             break;
  257.          default:
  258.             _mesa_problem(ctx, "Bad format in store_colortable_entries");
  259.             return;
  260.          }
  261.    }
  262.  
  263.    /* update the ubyte table */
  264.    {
  265.       const GLint comps = _mesa_components_in_format(table->_BaseFormat);
  266.       const GLfloat *tableF = table->TableF + start * comps;
  267.       GLubyte *tableUB = table->TableUB + start * comps;
  268.       GLint i;
  269.       for (i = 0; i < count * comps; i++) {
  270.          CLAMPED_FLOAT_TO_UBYTE(tableUB[i], tableF[i]);
  271.       }
  272.    }
  273.  
  274.    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
  275. }
  276.  
  277.  
  278.  
  279. void GLAPIENTRY
  280. _mesa_ColorTable( GLenum target, GLenum internalFormat,
  281.                   GLsizei width, GLenum format, GLenum type,
  282.                   const GLvoid *data )
  283. {
  284.    static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
  285.    static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
  286.    GET_CURRENT_CONTEXT(ctx);
  287.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  288.    struct gl_texture_object *texObj = NULL;
  289.    struct gl_color_table *table = NULL;
  290.    GLboolean proxy = GL_FALSE;
  291.    GLint baseFormat;
  292.    const GLfloat *scale = one, *bias = zero;
  293.    GLint comps;
  294.  
  295.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
  296.  
  297.    switch (target) {
  298.       case GL_SHARED_TEXTURE_PALETTE_EXT:
  299.          table = &ctx->Texture.Palette;
  300.          break;
  301.       case GL_TEXTURE_COLOR_TABLE_SGI:
  302.          if (!ctx->Extensions.SGI_texture_color_table) {
  303.             _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
  304.             return;
  305.          }
  306.          table = &(texUnit->ColorTable);
  307.          scale = ctx->Pixel.TextureColorTableScale;
  308.          bias = ctx->Pixel.TextureColorTableBias;
  309.          break;
  310.       case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
  311.          if (!ctx->Extensions.SGI_texture_color_table) {
  312.             _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
  313.             return;
  314.          }
  315.          table = &(texUnit->ProxyColorTable);
  316.          proxy = GL_TRUE;
  317.          break;
  318.       default:
  319.          /* try texture targets */
  320.          {
  321.             struct gl_texture_object *texobj
  322.                = _mesa_select_tex_object(ctx, texUnit, target);
  323.             if (texobj) {
  324.                table = &texobj->Palette;
  325.                proxy = _mesa_is_proxy_texture(target);
  326.             }
  327.             else {
  328.                _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
  329.                return;
  330.             }
  331.          }
  332.    }
  333.  
  334.    assert(table);
  335.  
  336.    if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
  337.        format == GL_INTENSITY) {
  338.       _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)");
  339.       return;
  340.    }
  341.  
  342.    baseFormat = base_colortab_format(internalFormat);
  343.    if (baseFormat < 0) {
  344.       _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)");
  345.       return;
  346.    }
  347.  
  348.    if (width < 0 || (width != 0 && !_mesa_is_pow_two(width))) {
  349.       /* error */
  350.       if (proxy) {
  351.          table->Size = 0;
  352.          table->InternalFormat = (GLenum) 0;
  353.          table->_BaseFormat = (GLenum) 0;
  354.       }
  355.       else {
  356.          _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width);
  357.       }
  358.       return;
  359.    }
  360.  
  361.    if (width > (GLsizei) ctx->Const.MaxColorTableSize) {
  362.       if (proxy) {
  363.          table->Size = 0;
  364.          table->InternalFormat = (GLenum) 0;
  365.          table->_BaseFormat = (GLenum) 0;
  366.       }
  367.       else {
  368.          _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)");
  369.       }
  370.       return;
  371.    }
  372.  
  373.    table->Size = width;
  374.    table->InternalFormat = internalFormat;
  375.    table->_BaseFormat = (GLenum) baseFormat;
  376.  
  377.    comps = _mesa_components_in_format(table->_BaseFormat);
  378.    assert(comps > 0);  /* error should have been caught sooner */
  379.  
  380.    if (!proxy) {
  381.       _mesa_free_colortable_data(table);
  382.  
  383.       if (width > 0) {
  384.          table->TableF = (GLfloat *) malloc(comps * width * sizeof(GLfloat));
  385.          table->TableUB = (GLubyte *) malloc(comps * width * sizeof(GLubyte));
  386.  
  387.          if (!table->TableF || !table->TableUB) {
  388.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable");
  389.             return;
  390.          }
  391.  
  392.          store_colortable_entries(ctx, table,
  393.                                   0, width,  /* start, count */
  394.                                   format, type, data,
  395.                                   scale[0], bias[0],
  396.                                   scale[1], bias[1],
  397.                                   scale[2], bias[2],
  398.                                   scale[3], bias[3]);
  399.       }
  400.    } /* proxy */
  401.  
  402.    /* do this after the table's Type and Format are set */
  403.    set_component_sizes(table);
  404.  
  405.    if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
  406.       /* texture object palette, texObj==NULL means the shared palette */
  407.       if (ctx->Driver.UpdateTexturePalette) {
  408.          (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
  409.       }
  410.    }
  411.  
  412.    ctx->NewState |= _NEW_PIXEL;
  413. }
  414.  
  415.  
  416.  
  417. void GLAPIENTRY
  418. _mesa_ColorSubTable( GLenum target, GLsizei start,
  419.                      GLsizei count, GLenum format, GLenum type,
  420.                      const GLvoid *data )
  421. {
  422.    static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
  423.    static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
  424.    GET_CURRENT_CONTEXT(ctx);
  425.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  426.    struct gl_texture_object *texObj = NULL;
  427.    struct gl_color_table *table = NULL;
  428.    const GLfloat *scale = one, *bias = zero;
  429.  
  430.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  431.  
  432.    switch (target) {
  433.       case GL_SHARED_TEXTURE_PALETTE_EXT:
  434.          table = &ctx->Texture.Palette;
  435.          break;
  436.       case GL_TEXTURE_COLOR_TABLE_SGI:
  437.          if (!ctx->Extensions.SGI_texture_color_table) {
  438.             _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
  439.             return;
  440.          }
  441.          table = &(texUnit->ColorTable);
  442.          scale = ctx->Pixel.TextureColorTableScale;
  443.          bias = ctx->Pixel.TextureColorTableBias;
  444.          break;
  445.       default:
  446.          /* try texture targets */
  447.          texObj = _mesa_select_tex_object(ctx, texUnit, target);
  448.          if (texObj && !_mesa_is_proxy_texture(target)) {
  449.             table = &texObj->Palette;
  450.          }
  451.          else {
  452.             _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
  453.             return;
  454.          }
  455.    }
  456.  
  457.    assert(table);
  458.  
  459.    if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
  460.        format == GL_INTENSITY) {
  461.       _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)");
  462.       return;
  463.    }
  464.  
  465.    if (count < 1) {
  466.       _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
  467.       return;
  468.    }
  469.  
  470.    /* error should have been caught sooner */
  471.    assert(_mesa_components_in_format(table->_BaseFormat) > 0);
  472.  
  473.    if (start + count > (GLint) table->Size) {
  474.       _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
  475.       return;
  476.    }
  477.  
  478.    if (!table->TableF || !table->TableUB) {
  479.       /* a GL_OUT_OF_MEMORY error would have been recorded previously */
  480.       return;
  481.    }
  482.  
  483.    store_colortable_entries(ctx, table, start, count,
  484.                             format, type, data,
  485.                             scale[0], bias[0],
  486.                             scale[1], bias[1],
  487.                             scale[2], bias[2],
  488.                             scale[3], bias[3]);
  489.  
  490.    if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
  491.       /* per-texture object palette */
  492.       if (ctx->Driver.UpdateTexturePalette) {
  493.          (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
  494.       }
  495.    }
  496.  
  497.    ctx->NewState |= _NEW_PIXEL;
  498. }
  499.  
  500.  
  501.  
  502. static void GLAPIENTRY
  503. _mesa_CopyColorTable(GLenum target, GLenum internalformat,
  504.                      GLint x, GLint y, GLsizei width)
  505. {
  506.    GET_CURRENT_CONTEXT(ctx);
  507.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  508.  
  509.    if (!ctx->ReadBuffer->_ColorReadBuffer) {
  510.       return;      /* no readbuffer - OK */
  511.    }
  512.  
  513.    ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width );
  514. }
  515.  
  516.  
  517.  
  518. static void GLAPIENTRY
  519. _mesa_CopyColorSubTable(GLenum target, GLsizei start,
  520.                         GLint x, GLint y, GLsizei width)
  521. {
  522.    GET_CURRENT_CONTEXT(ctx);
  523.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  524.  
  525.    if (!ctx->ReadBuffer->_ColorReadBuffer) {
  526.       return;      /* no readbuffer - OK */
  527.    }
  528.  
  529.    ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width );
  530. }
  531.  
  532.  
  533.  
  534. static void GLAPIENTRY
  535. _mesa_GetColorTable( GLenum target, GLenum format,
  536.                      GLenum type, GLvoid *data )
  537. {
  538.    GET_CURRENT_CONTEXT(ctx);
  539.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  540.    struct gl_color_table *table = NULL;
  541.    GLfloat rgba[MAX_COLOR_TABLE_SIZE][4];
  542.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  543.  
  544.    if (ctx->NewState) {
  545.       _mesa_update_state(ctx);
  546.    }
  547.  
  548.    switch (target) {
  549.       case GL_SHARED_TEXTURE_PALETTE_EXT:
  550.          table = &ctx->Texture.Palette;
  551.          break;
  552.       case GL_TEXTURE_COLOR_TABLE_SGI:
  553.          if (!ctx->Extensions.SGI_texture_color_table) {
  554.             _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
  555.             return;
  556.          }
  557.          table = &(texUnit->ColorTable);
  558.          break;
  559.       default:
  560.          /* try texture targets */
  561.          {
  562.             struct gl_texture_object *texobj
  563.                = _mesa_select_tex_object(ctx, texUnit, target);
  564.             if (texobj && !_mesa_is_proxy_texture(target)) {
  565.                table = &texobj->Palette;
  566.             }
  567.             else {
  568.                _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
  569.                return;
  570.             }
  571.          }
  572.    }
  573.  
  574.    ASSERT(table);
  575.  
  576.    if (table->Size <= 0) {
  577.       return;
  578.    }
  579.  
  580.    switch (table->_BaseFormat) {
  581.    case GL_ALPHA:
  582.       {
  583.          GLuint i;
  584.          for (i = 0; i < table->Size; i++) {
  585.             rgba[i][RCOMP] = 0;
  586.             rgba[i][GCOMP] = 0;
  587.             rgba[i][BCOMP] = 0;
  588.             rgba[i][ACOMP] = table->TableF[i];
  589.          }
  590.       }
  591.       break;
  592.    case GL_LUMINANCE:
  593.       {
  594.          GLuint i;
  595.          for (i = 0; i < table->Size; i++) {
  596.             rgba[i][RCOMP] =
  597.             rgba[i][GCOMP] =
  598.             rgba[i][BCOMP] = table->TableF[i];
  599.             rgba[i][ACOMP] = 1.0F;
  600.          }
  601.       }
  602.       break;
  603.    case GL_LUMINANCE_ALPHA:
  604.       {
  605.          GLuint i;
  606.          for (i = 0; i < table->Size; i++) {
  607.             rgba[i][RCOMP] =
  608.             rgba[i][GCOMP] =
  609.             rgba[i][BCOMP] = table->TableF[i*2+0];
  610.             rgba[i][ACOMP] = table->TableF[i*2+1];
  611.          }
  612.       }
  613.       break;
  614.    case GL_INTENSITY:
  615.       {
  616.          GLuint i;
  617.          for (i = 0; i < table->Size; i++) {
  618.             rgba[i][RCOMP] =
  619.             rgba[i][GCOMP] =
  620.             rgba[i][BCOMP] =
  621.             rgba[i][ACOMP] = table->TableF[i];
  622.          }
  623.       }
  624.       break;
  625.    case GL_RGB:
  626.       {
  627.          GLuint i;
  628.          for (i = 0; i < table->Size; i++) {
  629.             rgba[i][RCOMP] = table->TableF[i*3+0];
  630.             rgba[i][GCOMP] = table->TableF[i*3+1];
  631.             rgba[i][BCOMP] = table->TableF[i*3+2];
  632.             rgba[i][ACOMP] = 1.0F;
  633.          }
  634.       }
  635.       break;
  636.    case GL_RGBA:
  637.       memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat));
  638.       break;
  639.    default:
  640.       _mesa_problem(ctx, "bad table format in glGetColorTable");
  641.       return;
  642.    }
  643.  
  644.    data = _mesa_map_validate_pbo_dest(ctx,
  645.                                       1, &ctx->Pack, table->Size, 1, 1,
  646.                                       format, type, data,
  647.                                       "glGetColorTable");
  648.    if (!data)
  649.       return;
  650.  
  651.    _mesa_pack_rgba_span_float(ctx, table->Size, rgba,
  652.                               format, type, data, &ctx->Pack, 0x0);
  653.  
  654.    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
  655. }
  656.  
  657.  
  658.  
  659. static void GLAPIENTRY
  660. _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
  661. {
  662.    GLfloat *scale, *bias;
  663.    GET_CURRENT_CONTEXT(ctx);
  664.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  665.  
  666.    switch (target) {
  667.    case GL_TEXTURE_COLOR_TABLE_SGI:
  668.       scale = ctx->Pixel.TextureColorTableScale;
  669.       bias  = ctx->Pixel.TextureColorTableBias;
  670.       break;
  671.    default:
  672.       _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
  673.       return;
  674.    }
  675.  
  676.    if (pname == GL_COLOR_TABLE_SCALE_SGI) {
  677.       COPY_4V(scale, params);
  678.    }
  679.    else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
  680.       COPY_4V(bias, params);
  681.    }
  682.    else {
  683.       _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
  684.       return;
  685.    }
  686.  
  687.    ctx->NewState |= _NEW_PIXEL;
  688. }
  689.  
  690.  
  691.  
  692. static void GLAPIENTRY
  693. _mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
  694. {
  695.    GLfloat fparams[4];
  696.    if (pname == GL_TEXTURE_COLOR_TABLE_SGI) {
  697.       /* four values */
  698.       fparams[0] = (GLfloat) params[0];
  699.       fparams[1] = (GLfloat) params[1];
  700.       fparams[2] = (GLfloat) params[2];
  701.       fparams[3] = (GLfloat) params[3];
  702.    }
  703.    else {
  704.       /* one values */
  705.       fparams[0] = (GLfloat) params[0];
  706.    }
  707.    _mesa_ColorTableParameterfv(target, pname, fparams);
  708. }
  709.  
  710.  
  711.  
  712. static void GLAPIENTRY
  713. _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
  714. {
  715.    GET_CURRENT_CONTEXT(ctx);
  716.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  717.    struct gl_color_table *table = NULL;
  718.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  719.  
  720.    switch (target) {
  721.       case GL_SHARED_TEXTURE_PALETTE_EXT:
  722.          table = &ctx->Texture.Palette;
  723.          break;
  724.       case GL_TEXTURE_COLOR_TABLE_SGI:
  725.          if (!ctx->Extensions.SGI_texture_color_table) {
  726.             _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
  727.             return;
  728.          }
  729.          table = &(texUnit->ColorTable);
  730.          if (pname == GL_COLOR_TABLE_SCALE_SGI) {
  731.             COPY_4V(params, ctx->Pixel.TextureColorTableScale);
  732.             return;
  733.          }
  734.          else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
  735.             COPY_4V(params, ctx->Pixel.TextureColorTableBias);
  736.             return;
  737.          }
  738.          break;
  739.       case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
  740.          if (!ctx->Extensions.SGI_texture_color_table) {
  741.             _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
  742.             return;
  743.          }
  744.          table = &(texUnit->ProxyColorTable);
  745.          break;
  746.       default:
  747.          /* try texture targets */
  748.          {
  749.             struct gl_texture_object *texobj
  750.                = _mesa_select_tex_object(ctx, texUnit, target);
  751.             if (texobj) {
  752.                table = &texobj->Palette;
  753.             }
  754.             else {
  755.                _mesa_error(ctx, GL_INVALID_ENUM,
  756.                            "glGetColorTableParameterfv(target)");
  757.                return;
  758.             }
  759.          }
  760.    }
  761.  
  762.    assert(table);
  763.  
  764.    switch (pname) {
  765.       case GL_COLOR_TABLE_FORMAT:
  766.          *params = (GLfloat) table->InternalFormat;
  767.          break;
  768.       case GL_COLOR_TABLE_WIDTH:
  769.          *params = (GLfloat) table->Size;
  770.          break;
  771.       case GL_COLOR_TABLE_RED_SIZE:
  772.          *params = (GLfloat) table->RedSize;
  773.          break;
  774.       case GL_COLOR_TABLE_GREEN_SIZE:
  775.          *params = (GLfloat) table->GreenSize;
  776.          break;
  777.       case GL_COLOR_TABLE_BLUE_SIZE:
  778.          *params = (GLfloat) table->BlueSize;
  779.          break;
  780.       case GL_COLOR_TABLE_ALPHA_SIZE:
  781.          *params = (GLfloat) table->AlphaSize;
  782.          break;
  783.       case GL_COLOR_TABLE_LUMINANCE_SIZE:
  784.          *params = (GLfloat) table->LuminanceSize;
  785.          break;
  786.       case GL_COLOR_TABLE_INTENSITY_SIZE:
  787.          *params = (GLfloat) table->IntensitySize;
  788.          break;
  789.       default:
  790.          _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" );
  791.          return;
  792.    }
  793. }
  794.  
  795.  
  796.  
  797. static void GLAPIENTRY
  798. _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
  799. {
  800.    GET_CURRENT_CONTEXT(ctx);
  801.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  802.    struct gl_color_table *table = NULL;
  803.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  804.  
  805.    switch (target) {
  806.       case GL_SHARED_TEXTURE_PALETTE_EXT:
  807.          table = &ctx->Texture.Palette;
  808.          break;
  809.       case GL_TEXTURE_COLOR_TABLE_SGI:
  810.          if (!ctx->Extensions.SGI_texture_color_table) {
  811.             _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
  812.             return;
  813.          }
  814.          table = &(texUnit->ColorTable);
  815.          if (pname == GL_COLOR_TABLE_SCALE_SGI) {
  816.             params[0] = (GLint) ctx->Pixel.TextureColorTableScale[0];
  817.             params[1] = (GLint) ctx->Pixel.TextureColorTableScale[1];
  818.             params[2] = (GLint) ctx->Pixel.TextureColorTableScale[2];
  819.             params[3] = (GLint) ctx->Pixel.TextureColorTableScale[3];
  820.             return;
  821.          }
  822.          else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
  823.             params[0] = (GLint) ctx->Pixel.TextureColorTableBias[0];
  824.             params[1] = (GLint) ctx->Pixel.TextureColorTableBias[1];
  825.             params[2] = (GLint) ctx->Pixel.TextureColorTableBias[2];
  826.             params[3] = (GLint) ctx->Pixel.TextureColorTableBias[3];
  827.             return;
  828.          }
  829.          break;
  830.       case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
  831.          if (!ctx->Extensions.SGI_texture_color_table) {
  832.             _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
  833.             return;
  834.          }
  835.          table = &(texUnit->ProxyColorTable);
  836.          break;
  837.       default:
  838.          /* Try texture targets */
  839.          {
  840.             struct gl_texture_object *texobj
  841.                = _mesa_select_tex_object(ctx, texUnit, target);
  842.             if (texobj) {
  843.                table = &texobj->Palette;
  844.             }
  845.             else {
  846.                _mesa_error(ctx, GL_INVALID_ENUM,
  847.                            "glGetColorTableParameteriv(target)");
  848.                return;
  849.             }
  850.          }
  851.    }
  852.  
  853.    assert(table);
  854.  
  855.    switch (pname) {
  856.       case GL_COLOR_TABLE_FORMAT:
  857.          *params = table->InternalFormat;
  858.          break;
  859.       case GL_COLOR_TABLE_WIDTH:
  860.          *params = table->Size;
  861.          break;
  862.       case GL_COLOR_TABLE_RED_SIZE:
  863.          *params = table->RedSize;
  864.          break;
  865.       case GL_COLOR_TABLE_GREEN_SIZE:
  866.          *params = table->GreenSize;
  867.          break;
  868.       case GL_COLOR_TABLE_BLUE_SIZE:
  869.          *params = table->BlueSize;
  870.          break;
  871.       case GL_COLOR_TABLE_ALPHA_SIZE:
  872.          *params = table->AlphaSize;
  873.          break;
  874.       case GL_COLOR_TABLE_LUMINANCE_SIZE:
  875.          *params = table->LuminanceSize;
  876.          break;
  877.       case GL_COLOR_TABLE_INTENSITY_SIZE:
  878.          *params = table->IntensitySize;
  879.          break;
  880.       default:
  881.          _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" );
  882.          return;
  883.    }
  884. }
  885.  
  886.  
  887. void
  888. _mesa_init_colortable_dispatch(struct _glapi_table *disp)
  889. {
  890.    SET_ColorSubTable(disp, _mesa_ColorSubTable);
  891.    SET_ColorTable(disp, _mesa_ColorTable);
  892.    SET_ColorTableParameterfv(disp, _mesa_ColorTableParameterfv);
  893.    SET_ColorTableParameteriv(disp, _mesa_ColorTableParameteriv);
  894.    SET_CopyColorSubTable(disp, _mesa_CopyColorSubTable);
  895.    SET_CopyColorTable(disp, _mesa_CopyColorTable);
  896.    SET_GetColorTable(disp, _mesa_GetColorTable);
  897.    SET_GetColorTableParameterfv(disp, _mesa_GetColorTableParameterfv);
  898.    SET_GetColorTableParameteriv(disp, _mesa_GetColorTableParameteriv);
  899. }
  900.  
  901.  
  902. #endif /* FEATURE_colortable */
  903.  
  904.  
  905. /**********************************************************************/
  906. /*****                      Initialization                        *****/
  907. /**********************************************************************/
  908.  
  909.  
  910. void
  911. _mesa_init_colortable( struct gl_color_table *p )
  912. {
  913.    p->TableF = NULL;
  914.    p->TableUB = NULL;
  915.    p->Size = 0;
  916.    p->InternalFormat = GL_RGBA;
  917. }
  918.  
  919.  
  920.  
  921. void
  922. _mesa_free_colortable_data( struct gl_color_table *p )
  923. {
  924.    if (p->TableF) {
  925.       free(p->TableF);
  926.       p->TableF = NULL;
  927.    }
  928.    if (p->TableUB) {
  929.       free(p->TableUB);
  930.       p->TableUB = NULL;
  931.    }
  932. }
  933.