home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / pixel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  25.0 KB  |  992 lines

  1. /* $Id: pixel.c,v 1.8 1997/07/24 01:23:44 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.4
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: pixel.c,v $
  26.  * Revision 1.8  1997/07/24 01:23:44  brianp
  27.  * changed precompiled header symbol from PCH to PC_HEADER
  28.  *
  29.  * Revision 1.7  1997/05/28 03:26:02  brianp
  30.  * added precompiled header (PCH) support
  31.  *
  32.  * Revision 1.6  1997/02/09 20:05:03  brianp
  33.  * new arguments for gl_pixel_addr_in_image()
  34.  *
  35.  * Revision 1.5  1997/02/09 18:52:37  brianp
  36.  * added GL_EXT_texture3D support
  37.  *
  38.  * Revision 1.4  1996/11/06 04:09:37  brianp
  39.  * added a missing return after a gl_error() call
  40.  *
  41.  * Revision 1.3  1996/09/26 22:35:10  brianp
  42.  * fixed a few compiler warnings from IRIX 6 -n32 and -64 compiler
  43.  *
  44.  * Revision 1.2  1996/09/15 14:18:55  brianp
  45.  * now use GLframebuffer and GLvisual
  46.  *
  47.  * Revision 1.1  1996/09/13 01:38:16  brianp
  48.  * Initial revision
  49.  *
  50.  */
  51.  
  52.  
  53. /*
  54.  * glPixelStore, glPixelTransfer, glPixelMap, glPixelZoom, etc.
  55.  */
  56.  
  57.  
  58. #ifdef PC_HEADER
  59. #include "all.h"
  60. #else
  61. #include <assert.h>
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include <string.h>
  65. #include "context.h"
  66. #include "dlist.h"
  67. #include "macros.h"
  68. #include "pixel.h"
  69. #include "image.h"
  70. #include "span.h"
  71. #include "stencil.h"
  72. #include "types.h"
  73. #endif
  74.  
  75.  
  76.  
  77. /*
  78.  * Determine if we can use the optimized glDrawPixels function.
  79.  */
  80. static void update_drawpixels_state( GLcontext *ctx )
  81. {
  82.    if (ctx->Visual->RGBAflag==GL_TRUE &&
  83.        ctx->Visual->EightBitColor &&
  84.        ctx->Pixel.RedBias==0.0   && ctx->Pixel.RedScale==1.0 &&
  85.        ctx->Pixel.GreenBias==0.0 && ctx->Pixel.GreenScale==1.0 &&
  86.        ctx->Pixel.BlueBias==0.0  && ctx->Pixel.BlueScale==1.0 &&
  87.        ctx->Pixel.AlphaBias==0.0 && ctx->Pixel.AlphaScale==1.0 &&
  88.        ctx->Pixel.MapColorFlag==GL_FALSE &&
  89.        ctx->Pixel.ZoomX==1.0 && ctx->Pixel.ZoomY==1.0 &&
  90. /*       ctx->Unpack.Alignment==4 &&*/
  91.        ctx->Unpack.RowLength==0 &&
  92.        ctx->Unpack.SkipPixels==0 &&
  93.        ctx->Unpack.SkipRows==0 &&
  94.        ctx->Unpack.SwapBytes==0 &&
  95.        ctx->Unpack.LsbFirst==0) {
  96.       ctx->FastDrawPixels = GL_TRUE;
  97.    }
  98.    else {
  99.       ctx->FastDrawPixels = GL_FALSE;
  100.    }
  101. }
  102.  
  103.  
  104.  
  105.  
  106. /**********************************************************************/
  107. /*****                    glPixelZoom                             *****/
  108. /**********************************************************************/
  109.  
  110.  
  111.  
  112. void gl_PixelZoom( GLcontext *ctx, GLfloat xfactor, GLfloat yfactor )
  113. {
  114.    if (INSIDE_BEGIN_END(ctx)) {
  115.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelZoom" );
  116.       return;
  117.    }
  118.    ctx->Pixel.ZoomX = xfactor;
  119.    ctx->Pixel.ZoomY = yfactor;
  120.    update_drawpixels_state( ctx );
  121. }
  122.  
  123.  
  124.  
  125.  
  126. /*
  127.  * Write a span of pixels to the frame buffer while applying a pixel zoom.
  128.  * This is only used by glDrawPixels and glCopyPixels.
  129.  * Input:  n - number of pixels in input row
  130.  *         x, y - destination of the span
  131.  *         z - depth values for the span
  132.  *         red, green, blue, alpha - array of colors
  133.  *         y0 - location of first row in the image we're drawing.
  134.  */
  135. void
  136. gl_write_zoomed_color_span( GLcontext *ctx,
  137.                             GLuint n, GLint x, GLint y, const GLdepth z[],
  138.                             const GLubyte red[], const GLubyte green[],
  139.                             const GLubyte blue[], const GLubyte alpha[],
  140.                             GLint y0 )
  141. {
  142.    GLint m;
  143.    GLint r0, r1, row, r;
  144.    GLint i, j, skipcol;
  145.    GLubyte zred[MAX_WIDTH], zgreen[MAX_WIDTH];  /* zoomed pixel colors */
  146.    GLubyte zblue[MAX_WIDTH], zalpha[MAX_WIDTH];
  147.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  148.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  149.  
  150.    /* compute width of output row */
  151.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  152.    if (m==0) {
  153.       return;
  154.    }
  155.    if (ctx->Pixel.ZoomX<0.0) {
  156.       /* adjust x coordinate for left/right mirroring */
  157.       x = x - m;
  158.    }
  159.  
  160.    /* compute which rows to draw */
  161.    row = y-y0;
  162.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  163.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  164.    if (r0==r1) {
  165.       return;
  166.    }
  167.    else if (r1<r0) {
  168.       GLint rtmp = r1;
  169.       r1 = r0;
  170.       r0 = rtmp;
  171.    }
  172.  
  173.    /* return early if r0...r1 is above or below window */
  174.    if (r0<0 && r1<0) {
  175.       /* below window */
  176.       return;
  177.    }
  178.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  179.       /* above window */
  180.       return;
  181.    }
  182.  
  183.    /* check if left edge is outside window */
  184.    skipcol = 0;
  185.    if (x<0) {
  186.       skipcol = -x;
  187.       m += x;
  188.    }
  189.    /* make sure span isn't too long or short */
  190.    if (m>maxwidth) {
  191.       m = maxwidth;
  192.    }
  193.    else if (m<=0) {
  194.       return;
  195.    }
  196.  
  197.    assert( m <= MAX_WIDTH );
  198.  
  199.    /* zoom the span horizontally */
  200.    if (ctx->Pixel.ZoomX==-1.0F) {
  201.       /* n==m */
  202.       for (j=0;j<m;j++) {
  203.          i = n - (j+skipcol) - 1;
  204.          zred[j]   = red[i];
  205.          zgreen[j] = green[i];
  206.          zblue[j]  = blue[i];
  207.          zalpha[j] = alpha[i];
  208.          zdepth[j] = z[i];
  209.       }
  210.    }
  211.    else {
  212.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  213.       for (j=0;j<m;j++) {
  214.          i = (j+skipcol) * xscale;
  215.          if (i<0)  i = n + i - 1;
  216.          zred[j]   = red[i];
  217.          zgreen[j] = green[i];
  218.          zblue[j]  = blue[i];
  219.          zalpha[j] = alpha[i];
  220.          zdepth[j] = z[i];
  221.       }
  222.    }
  223.  
  224.    /* write the span */
  225.    for (r=r0; r<r1; r++) {
  226.       gl_write_color_span( ctx, m, x+skipcol, r, zdepth,
  227.                            zred, zgreen, zblue, zalpha, GL_BITMAP );
  228.    }
  229. }
  230.  
  231.  
  232.  
  233. /*
  234.  * As above, but write CI pixels.
  235.  */
  236. void
  237. gl_write_zoomed_index_span( GLcontext *ctx,
  238.                             GLuint n, GLint x, GLint y, const GLdepth z[],
  239.                             const GLuint indexes[], GLint y0 )
  240. {
  241.    GLint m;
  242.    GLint r0, r1, row, r;
  243.    GLint i, j, skipcol;
  244.    GLuint zindexes[MAX_WIDTH];  /* zoomed color indexes */
  245.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  246.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  247.  
  248.    /* compute width of output row */
  249.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  250.    if (m==0) {
  251.       return;
  252.    }
  253.    if (ctx->Pixel.ZoomX<0.0) {
  254.       /* adjust x coordinate for left/right mirroring */
  255.       x = x - m;
  256.    }
  257.  
  258.    /* compute which rows to draw */
  259.    row = y-y0;
  260.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  261.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  262.    if (r0==r1) {
  263.       return;
  264.    }
  265.    else if (r1<r0) {
  266.       GLint rtmp = r1;
  267.       r1 = r0;
  268.       r0 = rtmp;
  269.    }
  270.  
  271.    /* return early if r0...r1 is above or below window */
  272.    if (r0<0 && r1<0) {
  273.       /* below window */
  274.       return;
  275.    }
  276.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  277.       /* above window */
  278.       return;
  279.    }
  280.  
  281.    /* check if left edge is outside window */
  282.    skipcol = 0;
  283.    if (x<0) {
  284.       skipcol = -x;
  285.       m += x;
  286.    }
  287.    /* make sure span isn't too long or short */
  288.    if (m>maxwidth) {
  289.       m = maxwidth;
  290.    }
  291.    else if (m<=0) {
  292.       return;
  293.    }
  294.  
  295.    assert( m <= MAX_WIDTH );
  296.  
  297.    /* zoom the span horizontally */
  298.    if (ctx->Pixel.ZoomX==-1.0F) {
  299.       /* n==m */
  300.       for (j=0;j<m;j++) {
  301.          i = n - (j+skipcol) - 1;
  302.          zindexes[j] = indexes[i];
  303.          zdepth[j]   = z[i];
  304.       }
  305.    }
  306.    else {
  307.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  308.       for (j=0;j<m;j++) {
  309.          i = (j+skipcol) * xscale;
  310.          if (i<0)  i = n + i - 1;
  311.          zindexes[j] = indexes[i];
  312.          zdepth[j] = z[i];
  313.       }
  314.    }
  315.  
  316.    /* write the span */
  317.    for (r=r0; r<r1; r++) {
  318.       gl_write_index_span( ctx, m, x+skipcol, r, zdepth, zindexes, GL_BITMAP );
  319.    }
  320. }
  321.  
  322.  
  323.  
  324. /*
  325.  * As above, but write stencil values.
  326.  */
  327. void
  328. gl_write_zoomed_stencil_span( GLcontext *ctx,
  329.                               GLuint n, GLint x, GLint y,
  330.                               const GLubyte stencil[], GLint y0 )
  331. {
  332.    GLint m;
  333.    GLint r0, r1, row, r;
  334.    GLint i, j, skipcol;
  335.    GLubyte zstencil[MAX_WIDTH];  /* zoomed stencil values */
  336.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  337.  
  338.    /* compute width of output row */
  339.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  340.    if (m==0) {
  341.       return;
  342.    }
  343.    if (ctx->Pixel.ZoomX<0.0) {
  344.       /* adjust x coordinate for left/right mirroring */
  345.       x = x - m;
  346.    }
  347.  
  348.    /* compute which rows to draw */
  349.    row = y-y0;
  350.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  351.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  352.    if (r0==r1) {
  353.       return;
  354.    }
  355.    else if (r1<r0) {
  356.       GLint rtmp = r1;
  357.       r1 = r0;
  358.       r0 = rtmp;
  359.    }
  360.  
  361.    /* return early if r0...r1 is above or below window */
  362.    if (r0<0 && r1<0) {
  363.       /* below window */
  364.       return;
  365.    }
  366.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  367.       /* above window */
  368.       return;
  369.    }
  370.  
  371.    /* check if left edge is outside window */
  372.    skipcol = 0;
  373.    if (x<0) {
  374.       skipcol = -x;
  375.       m += x;
  376.    }
  377.    /* make sure span isn't too long or short */
  378.    if (m>maxwidth) {
  379.       m = maxwidth;
  380.    }
  381.    else if (m<=0) {
  382.       return;
  383.    }
  384.  
  385.    assert( m <= MAX_WIDTH );
  386.  
  387.    /* zoom the span horizontally */
  388.    if (ctx->Pixel.ZoomX==-1.0F) {
  389.       /* n==m */
  390.       for (j=0;j<m;j++) {
  391.          i = n - (j+skipcol) - 1;
  392.          zstencil[j] = stencil[i];
  393.       }
  394.    }
  395.    else {
  396.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  397.       for (j=0;j<m;j++) {
  398.          i = (j+skipcol) * xscale;
  399.          if (i<0)  i = n + i - 1;
  400.          zstencil[j] = stencil[i];
  401.       }
  402.    }
  403.  
  404.    /* write the span */
  405.    for (r=r0; r<r1; r++) {
  406.       gl_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
  407.    }
  408. }
  409.  
  410.  
  411.  
  412.  
  413. /**********************************************************************/
  414. /*****                    glPixelStore                            *****/
  415. /**********************************************************************/
  416.  
  417.  
  418. void gl_PixelStorei( GLcontext *ctx, GLenum pname, GLint param )
  419. {
  420.    /* NOTE: this call can't be compiled into the display list */
  421.  
  422.    if (INSIDE_BEGIN_END(ctx)) {
  423.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelStore" );
  424.       return;
  425.    }
  426.  
  427.    switch (pname) {
  428.       case GL_PACK_SWAP_BYTES:
  429.          ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
  430.      break;
  431.       case GL_PACK_LSB_FIRST:
  432.          ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
  433.      break;
  434.       case GL_PACK_ROW_LENGTH:
  435.      if (param<0) {
  436.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  437.      }
  438.      else {
  439.         ctx->Pack.RowLength = param;
  440.      }
  441.      break;
  442.       case GL_PACK_SKIP_PIXELS:
  443.      if (param<0) {
  444.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  445.      }
  446.      else {
  447.         ctx->Pack.SkipPixels = param;
  448.      }
  449.      break;
  450.       case GL_PACK_SKIP_ROWS:
  451.      if (param<0) {
  452.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  453.      }
  454.      else {
  455.         ctx->Pack.SkipRows = param;
  456.      }
  457.      break;
  458.       case GL_PACK_ALIGNMENT:
  459.          if (param==1 || param==2 || param==4 || param==8) {
  460.         ctx->Pack.Alignment = param;
  461.      }
  462.      else {
  463.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  464.      }
  465.      break;
  466.       case GL_UNPACK_SWAP_BYTES:
  467.      ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
  468.          break;
  469.       case GL_UNPACK_LSB_FIRST:
  470.      ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
  471.      break;
  472.       case GL_UNPACK_ROW_LENGTH:
  473.      if (param<0) {
  474.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  475.      }
  476.      else {
  477.         ctx->Unpack.RowLength = param;
  478.      }
  479.      break;
  480.       case GL_UNPACK_SKIP_PIXELS:
  481.      if (param<0) {
  482.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  483.      }
  484.      else {
  485.         ctx->Unpack.SkipPixels = param;
  486.      }
  487.      break;
  488.       case GL_UNPACK_SKIP_ROWS:
  489.      if (param<0) {
  490.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  491.      }
  492.      else {
  493.         ctx->Unpack.SkipRows = param;
  494.      }
  495.      break;
  496.       case GL_UNPACK_ALIGNMENT:
  497.          if (param==1 || param==2 || param==4 || param==8) {
  498.         ctx->Unpack.Alignment = param;
  499.      }
  500.      else {
  501.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
  502.      }
  503.      break;
  504.       default:
  505.      gl_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
  506.    }
  507.    update_drawpixels_state( ctx );
  508. }
  509.  
  510.  
  511.  
  512.  
  513.  
  514. /**********************************************************************/
  515. /*****                         glPixelMap                         *****/
  516. /**********************************************************************/
  517.  
  518.  
  519.  
  520. void gl_PixelMapfv( GLcontext *ctx,
  521.                     GLenum map, GLint mapsize, const GLfloat *values )
  522. {
  523.    GLuint i;
  524.  
  525.    if (INSIDE_BEGIN_END(ctx)) {
  526.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelMapfv" );
  527.       return;
  528.    }
  529.  
  530.    if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
  531.       gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  532.       return;
  533.    }
  534.  
  535.    if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
  536.       /* test that mapsize is a power of two */
  537.       GLuint p;
  538.       GLboolean ok = GL_FALSE;
  539.       for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
  540.      if ( (p&mapsize) == p ) {
  541.         ok = GL_TRUE;
  542.         break;
  543.      }
  544.       }
  545.       if (!ok) {
  546.      gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  547.          return;
  548.       }
  549.    }
  550.  
  551.    switch (map) {
  552.       case GL_PIXEL_MAP_S_TO_S:
  553.          ctx->Pixel.MapStoSsize = mapsize;
  554.          for (i=0;i<mapsize;i++) {
  555.         ctx->Pixel.MapStoS[i] = (GLint) values[i];
  556.      }
  557.      break;
  558.       case GL_PIXEL_MAP_I_TO_I:
  559.          ctx->Pixel.MapItoIsize = mapsize;
  560.          for (i=0;i<mapsize;i++) {
  561.         ctx->Pixel.MapItoI[i] = (GLint) values[i];
  562.      }
  563.      break;
  564.       case GL_PIXEL_MAP_I_TO_R:
  565.          ctx->Pixel.MapItoRsize = mapsize;
  566.          for (i=0;i<mapsize;i++) {
  567.         ctx->Pixel.MapItoR[i] = CLAMP( values[i], 0.0, 1.0 );
  568.      }
  569.      break;
  570.       case GL_PIXEL_MAP_I_TO_G:
  571.          ctx->Pixel.MapItoGsize = mapsize;
  572.          for (i=0;i<mapsize;i++) {
  573.         ctx->Pixel.MapItoG[i] = CLAMP( values[i], 0.0, 1.0 );
  574.      }
  575.      break;
  576.       case GL_PIXEL_MAP_I_TO_B:
  577.          ctx->Pixel.MapItoBsize = mapsize;
  578.          for (i=0;i<mapsize;i++) {
  579.         ctx->Pixel.MapItoB[i] = CLAMP( values[i], 0.0, 1.0 );
  580.      }
  581.      break;
  582.       case GL_PIXEL_MAP_I_TO_A:
  583.          ctx->Pixel.MapItoAsize = mapsize;
  584.          for (i=0;i<mapsize;i++) {
  585.         ctx->Pixel.MapItoA[i] = CLAMP( values[i], 0.0, 1.0 );
  586.      }
  587.      break;
  588.       case GL_PIXEL_MAP_R_TO_R:
  589.          ctx->Pixel.MapRtoRsize = mapsize;
  590.          for (i=0;i<mapsize;i++) {
  591.         ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
  592.      }
  593.      break;
  594.       case GL_PIXEL_MAP_G_TO_G:
  595.          ctx->Pixel.MapGtoGsize = mapsize;
  596.          for (i=0;i<mapsize;i++) {
  597.         ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
  598.      }
  599.      break;
  600.       case GL_PIXEL_MAP_B_TO_B:
  601.          ctx->Pixel.MapBtoBsize = mapsize;
  602.          for (i=0;i<mapsize;i++) {
  603.         ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
  604.      }
  605.      break;
  606.       case GL_PIXEL_MAP_A_TO_A:
  607.          ctx->Pixel.MapAtoAsize = mapsize;
  608.          for (i=0;i<mapsize;i++) {
  609.         ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
  610.      }
  611.      break;
  612.       default:
  613.          gl_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
  614.    }
  615. }
  616.  
  617.  
  618.  
  619.  
  620.  
  621. void gl_GetPixelMapfv( GLcontext *ctx, GLenum map, GLfloat *values )
  622. {
  623.    GLuint i;
  624.  
  625.    if (INSIDE_BEGIN_END(ctx)) {
  626.       gl_error( ctx, GL_INVALID_OPERATION, "glGetPixelMapfv" );
  627.       return;
  628.    }
  629.    switch (map) {
  630.       case GL_PIXEL_MAP_I_TO_I:
  631.          for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
  632.         values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
  633.      }
  634.      break;
  635.       case GL_PIXEL_MAP_S_TO_S:
  636.          for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
  637.         values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
  638.      }
  639.      break;
  640.       case GL_PIXEL_MAP_I_TO_R:
  641.          MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
  642.      break;
  643.       case GL_PIXEL_MAP_I_TO_G:
  644.          MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
  645.      break;
  646.       case GL_PIXEL_MAP_I_TO_B:
  647.          MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
  648.      break;
  649.       case GL_PIXEL_MAP_I_TO_A:
  650.          MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
  651.      break;
  652.       case GL_PIXEL_MAP_R_TO_R:
  653.          MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
  654.      break;
  655.       case GL_PIXEL_MAP_G_TO_G:
  656.          MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
  657.      break;
  658.       case GL_PIXEL_MAP_B_TO_B:
  659.          MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
  660.      break;
  661.       case GL_PIXEL_MAP_A_TO_A:
  662.          MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
  663.      break;
  664.       default:
  665.          gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
  666.    }
  667. }
  668.  
  669.  
  670. void gl_GetPixelMapuiv( GLcontext *ctx, GLenum map, GLuint *values )
  671. {
  672.    GLuint i;
  673.  
  674.    if (INSIDE_BEGIN_END(ctx)) {
  675.       gl_error( ctx, GL_INVALID_OPERATION, "glGetPixelMapfv" );
  676.       return;
  677.    }
  678.    switch (map) {
  679.       case GL_PIXEL_MAP_I_TO_I:
  680.          MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
  681.      break;
  682.       case GL_PIXEL_MAP_S_TO_S:
  683.          MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
  684.      break;
  685.       case GL_PIXEL_MAP_I_TO_R:
  686.      for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
  687.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
  688.      }
  689.      break;
  690.       case GL_PIXEL_MAP_I_TO_G:
  691.      for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
  692.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
  693.      }
  694.      break;
  695.       case GL_PIXEL_MAP_I_TO_B:
  696.      for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
  697.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
  698.      }
  699.      break;
  700.       case GL_PIXEL_MAP_I_TO_A:
  701.      for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
  702.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
  703.      }
  704.      break;
  705.       case GL_PIXEL_MAP_R_TO_R:
  706.      for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
  707.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
  708.      }
  709.      break;
  710.       case GL_PIXEL_MAP_G_TO_G:
  711.      for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
  712.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
  713.      }
  714.      break;
  715.       case GL_PIXEL_MAP_B_TO_B:
  716.      for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
  717.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
  718.      }
  719.      break;
  720.       case GL_PIXEL_MAP_A_TO_A:
  721.      for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
  722.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
  723.      }
  724.      break;
  725.       default:
  726.          gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
  727.    }
  728. }
  729.  
  730.  
  731. void gl_GetPixelMapusv( GLcontext *ctx, GLenum map, GLushort *values )
  732. {
  733.    GLuint i;
  734.  
  735.    if (INSIDE_BEGIN_END(ctx)) {
  736.       gl_error( ctx, GL_INVALID_OPERATION, "glGetPixelMapfv" );
  737.       return;
  738.    }
  739.    switch (map) {
  740.       case GL_PIXEL_MAP_I_TO_I:
  741.      for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
  742.         values[i] = (GLushort) ctx->Pixel.MapItoI[i];
  743.      }
  744.      break;
  745.       case GL_PIXEL_MAP_S_TO_S:
  746.      for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
  747.         values[i] = (GLushort) ctx->Pixel.MapStoS[i];
  748.      }
  749.      break;
  750.       case GL_PIXEL_MAP_I_TO_R:
  751.      for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
  752.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
  753.      }
  754.      break;
  755.       case GL_PIXEL_MAP_I_TO_G:
  756.      for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
  757.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
  758.      }
  759.      break;
  760.       case GL_PIXEL_MAP_I_TO_B:
  761.      for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
  762.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
  763.      }
  764.      break;
  765.       case GL_PIXEL_MAP_I_TO_A:
  766.      for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
  767.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
  768.      }
  769.      break;
  770.       case GL_PIXEL_MAP_R_TO_R:
  771.      for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
  772.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
  773.      }
  774.      break;
  775.       case GL_PIXEL_MAP_G_TO_G:
  776.      for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
  777.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
  778.      }
  779.      break;
  780.       case GL_PIXEL_MAP_B_TO_B:
  781.      for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
  782.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
  783.      }
  784.      break;
  785.       case GL_PIXEL_MAP_A_TO_A:
  786.      for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
  787.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
  788.      }
  789.      break;
  790.       default:
  791.          gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
  792.    }
  793. }
  794.  
  795.  
  796.  
  797. /**********************************************************************/
  798. /*****                       glPixelTransfer                      *****/
  799. /**********************************************************************/
  800.  
  801.  
  802. /*
  803.  * Implements glPixelTransfer[fi] whether called immediately or from a
  804.  * display list.
  805.  */
  806. void gl_PixelTransferf( GLcontext *ctx, GLenum pname, GLfloat param )
  807. {
  808.    if (INSIDE_BEGIN_END(ctx)) {
  809.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelTransfer" );
  810.       return;
  811.    }
  812.  
  813.    switch (pname) {
  814.       case GL_MAP_COLOR:
  815.          ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
  816.      break;
  817.       case GL_MAP_STENCIL:
  818.          ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
  819.      break;
  820.       case GL_INDEX_SHIFT:
  821.          ctx->Pixel.IndexShift = (GLint) param;
  822.      break;
  823.       case GL_INDEX_OFFSET:
  824.          ctx->Pixel.IndexOffset = (GLint) param;
  825.      break;
  826.       case GL_RED_SCALE:
  827.          ctx->Pixel.RedScale = param;
  828.      break;
  829.       case GL_RED_BIAS:
  830.          ctx->Pixel.RedBias = param;
  831.      break;
  832.       case GL_GREEN_SCALE:
  833.          ctx->Pixel.GreenScale = param;
  834.      break;
  835.       case GL_GREEN_BIAS:
  836.          ctx->Pixel.GreenBias = param;
  837.      break;
  838.       case GL_BLUE_SCALE:
  839.          ctx->Pixel.BlueScale = param;
  840.      break;
  841.       case GL_BLUE_BIAS:
  842.          ctx->Pixel.BlueBias = param;
  843.      break;
  844.       case GL_ALPHA_SCALE:
  845.          ctx->Pixel.AlphaScale = param;
  846.      break;
  847.       case GL_ALPHA_BIAS:
  848.          ctx->Pixel.AlphaBias = param;
  849.      break;
  850.       case GL_DEPTH_SCALE:
  851.          ctx->Pixel.DepthScale = param;
  852.      break;
  853.       case GL_DEPTH_BIAS:
  854.          ctx->Pixel.DepthBias = param;
  855.      break;
  856.       default:
  857.          gl_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
  858.          return;
  859.    }
  860.    update_drawpixels_state( ctx );
  861. }
  862.  
  863.  
  864.  
  865.  
  866.  
  867. /**********************************************************************/
  868. /*****                 Pixel packing/unpacking                    *****/
  869. /**********************************************************************/
  870.  
  871.  
  872.  
  873. /*
  874.  * Unpack a 2-D pixel array/image.  The unpacked format will be con-
  875.  * tiguous (no "empty" bytes) with byte/bit swapping applied as needed.
  876.  * Input:  same as glDrawPixels
  877.  * Output:  pointer to block of pixel data in same format and type as input
  878.  *          or NULL if error.
  879.  */
  880. GLvoid *gl_unpack_pixels( GLcontext *ctx,
  881.                           GLsizei width, GLsizei height,\
  882.                           GLenum format, GLenum type,
  883.                           const GLvoid *pixels )
  884. {
  885.    GLint s, n;
  886.  
  887.    s = gl_sizeof_type( type );
  888.    if (s<0) {
  889.       gl_error( ctx, GL_INVALID_ENUM, "internal error in gl_unpack(type)" );
  890.       return NULL;
  891.    }
  892.  
  893.    n = gl_components_in_format( format );
  894.    if (n<0) {
  895.       gl_error( ctx, GL_INVALID_ENUM, "gl_unpack_pixels(format)" );
  896.       return NULL;
  897.    }
  898.  
  899.    if (type==GL_BITMAP) {
  900.       /* BITMAP data */
  901.       GLint bytes, i, width_in_bytes;
  902.       GLubyte *buffer, *dst;
  903.       GLvoid *src;
  904.  
  905.       /* Alloc dest storage */
  906.       bytes = CEILING( width * height , 8 );
  907.       buffer = (GLubyte *) malloc( bytes );
  908.       if (!buffer) {
  909.      return NULL;
  910.       }
  911.  
  912.       /* Copy/unpack pixel data to buffer */
  913.       width_in_bytes = CEILING( width, 8 );
  914.       dst = buffer;
  915.       for (i=0;i<height;i++) {
  916.          src = gl_pixel_addr_in_image( &ctx->Unpack, pixels, width, height,
  917.                                        format, type, 0, i, 0 );
  918.          if (!src) {
  919.             free(buffer);
  920.             return NULL;
  921.          }
  922.      MEMCPY( dst, src, width_in_bytes );
  923.      dst += width_in_bytes;
  924.       }
  925.  
  926.       /* Bit flipping */
  927.       if (ctx->Unpack.LsbFirst) {
  928.      gl_flip_bytes( buffer, bytes );
  929.       }
  930.       return (GLvoid *) buffer;
  931.    }
  932.    else {
  933.       /* Non-BITMAP data */
  934.       GLint width_in_bytes, bytes, i;
  935.       GLubyte *buffer, *dst;
  936.       GLvoid *src;
  937.  
  938.       width_in_bytes = width * n * s;
  939.  
  940.       /* Alloc dest storage */
  941.       bytes = height * width_in_bytes;
  942.       buffer = (GLubyte *) malloc( bytes );
  943.       if (!buffer) {
  944.      return NULL;
  945.       }
  946.  
  947.       /* Copy/unpack pixel data to buffer */
  948.       dst = buffer;
  949.       for (i=0;i<height;i++) {
  950.          src = gl_pixel_addr_in_image( &ctx->Unpack, pixels, width, height,
  951.                                        format, type, 0, i, 0 );
  952.          if (!src) {
  953.             free(buffer);
  954.             return NULL;
  955.          }
  956.      MEMCPY( dst, src, width_in_bytes );
  957.      dst += width_in_bytes;
  958.       }
  959.  
  960.       /* Byte swapping */
  961.       if (ctx->Unpack.SwapBytes && s>1) {
  962.      if (s==2) {
  963.         gl_swap2( (GLushort *) buffer, bytes/2 );
  964.      }
  965.      else if (s==4) {
  966.         gl_swap4( (GLuint *) buffer, bytes/4 );
  967.      }
  968.       }
  969.       return (GLvoid *) buffer;
  970.    }
  971. }
  972.  
  973.  
  974.  
  975.  
  976. /*
  977.    if (s>=a) {
  978.       k = n * l;
  979.    }
  980.    else {  *s<a*
  981.       k = (a/s) * ceil( s*n*l / a );
  982.    }
  983.  
  984.    s = size in bytes of a single component
  985.    a = alignment
  986.    n = number of components in a pixel
  987.    l = number of pixels in a row
  988.  
  989.    k = number of components or indices between first pixel in each row in mem.
  990. */
  991.  
  992.