home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / pixel.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  30KB  |  1,238 lines

  1. /* $Id: pixel.c,v 1.18 1996/04/15 14:12:48 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  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.18  1996/04/15  14:12:48  brianp
  27.  * inserted missing CC.Pixel.Map?to?size assignments
  28.  *
  29.  * Revision 1.17  1996/02/14  15:40:15  brianp
  30.  * replaced ABS with ABSF
  31.  *
  32.  * Revision 1.16  1996/01/22  15:33:10  brianp
  33.  * check if zoomed span length is <=0, per Frederic Devernay
  34.  * check for CC.EightBitColor in update_drawpixels_state()
  35.  *
  36.  * Revision 1.15  1996/01/19  19:16:33  brianp
  37.  * fixed pixel zoom problems, per Frederic Devernay
  38.  *
  39.  * Revision 1.14  1995/12/19  16:42:44  brianp
  40.  * added gl_pixel_transfer()
  41.  *
  42.  * Revision 1.13  1995/12/18  17:26:35  brianp
  43.  * use new GLdepth datatype
  44.  *
  45.  * Revision 1.12  1995/11/30  00:19:31  brianp
  46.  * include stdio.h
  47.  *
  48.  * Revision 1.11  1995/11/17  14:30:41  brianp
  49.  * in gl_write_zoomed_*() limit spans to MAX_WIDTH, removed mallocs/frees
  50.  *
  51.  * Revision 1.10  1995/10/16  15:26:34  brianp
  52.  * added gl_write_zoomed_stencil_span
  53.  *
  54.  * Revision 1.9  1995/10/14  16:28:56  brianp
  55.  * added glPixelZoom support
  56.  *
  57.  * Revision 1.8  1995/09/15  18:39:07  brianp
  58.  * added update_drawpixels_state()
  59.  *
  60.  * Revision 1.7  1995/08/01  20:53:50  brianp
  61.  * added gl_save_pixelzoom()
  62.  *
  63.  * Revision 1.6  1995/07/24  20:35:20  brianp
  64.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  65.  *
  66.  * Revision 1.5  1995/05/29  21:22:42  brianp
  67.  * added glGetPixelMap*() functions
  68.  *
  69.  * Revision 1.4  1995/05/22  21:02:41  brianp
  70.  * Release 1.2
  71.  *
  72.  * Revision 1.3  1995/05/12  16:57:22  brianp
  73.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  74.  *
  75.  * Revision 1.2  1995/03/04  19:29:44  brianp
  76.  * 1.1 beta revision
  77.  *
  78.  * Revision 1.1  1995/02/24  14:25:08  brianp
  79.  * Initial revision
  80.  *
  81.  */
  82.  
  83.  
  84. /*
  85.  * glPixelStore, glPixelTransfer, glPixelMap, glPixelZoom, etc.
  86.  */
  87.  
  88.  
  89.  
  90. #include <assert.h>
  91. #include <stdio.h>
  92. #include <stdlib.h>
  93. #include <string.h>
  94. #include "context.h"
  95. #include "list.h"
  96. #include "macros.h"
  97. #include "pixel.h"
  98. #include "span.h"
  99. #include "stencil.h"
  100.  
  101.  
  102.  
  103.  
  104. /*
  105.  * Determine if we can use the optimized glDrawPixels function.
  106.  */
  107. static void update_drawpixels_state( void )
  108. {
  109.    if (CC.RGBAflag==GL_TRUE &&
  110.        CC.EightBitColor &&
  111.        CC.Pixel.RedBias==0.0   && CC.Pixel.RedScale==1.0 &&
  112.        CC.Pixel.GreenBias==0.0 && CC.Pixel.GreenScale==1.0 &&
  113.        CC.Pixel.BlueBias==0.0  && CC.Pixel.BlueScale==1.0 &&
  114.        CC.Pixel.AlphaBias==0.0 && CC.Pixel.AlphaScale==1.0 &&
  115.        CC.Pixel.MapColorFlag==GL_FALSE &&
  116.        CC.Pixel.ZoomX==1.0 && CC.Pixel.ZoomY==1.0 &&
  117. /*       CC.UnpackAlignment==4 &&*/
  118.        CC.UnpackRowLength==0 &&
  119.        CC.UnpackSkipPixels==0 &&
  120.        CC.UnpackSkipRows==0 &&
  121.        CC.UnpackSwapBytes==0 &&
  122.        CC.UnpackLSBFirst==0) {
  123.       CC.FastDrawPixels = GL_TRUE;
  124.    }
  125.    else {
  126.       CC.FastDrawPixels = GL_FALSE;
  127.    }
  128. }
  129.  
  130.  
  131.  
  132.  
  133. /**********************************************************************/
  134. /*****                    glPixelZoom                             *****/
  135. /**********************************************************************/
  136.  
  137.  
  138. /*
  139.  * Write a span of pixels to the frame buffer while applying a pixel zoom.
  140.  * This is only used by glDrawPixels and glCopyPixels.
  141.  * Input:  n - number of pixels in input row
  142.  *         x, y - destination of the span
  143.  *         z - depth values for the span
  144.  *         red, green, blue, alpha - array of colors
  145.  *         y0 - location of first row in the image we're drawing.
  146.  */
  147. void
  148. gl_write_zoomed_color_span( GLuint n, GLint x, GLint y, const GLdepth z[],
  149.                             const GLubyte red[], const GLubyte green[],
  150.                             const GLubyte blue[], const GLubyte alpha[],
  151.                             GLint y0 )
  152. {
  153.    GLint m;
  154.    GLint r0, r1, row, r;
  155.    GLint i, j, skipcol;
  156.    GLubyte zred[MAX_WIDTH], zgreen[MAX_WIDTH];  /* zoomed pixel colors */
  157.    GLubyte zblue[MAX_WIDTH], zalpha[MAX_WIDTH];
  158.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  159.    GLint maxwidth = MIN2( CC.BufferWidth, MAX_WIDTH );
  160.  
  161.    /* compute width of output row */
  162.    m = (GLint) ABSF( n * CC.Pixel.ZoomX );
  163.    if (m==0) {
  164.       return;
  165.    }
  166.    if (CC.Pixel.ZoomX<0.0) {
  167.       /* adjust x coordinate for left/right mirroring */
  168.       x = x - m;
  169.    }
  170.  
  171.    /* compute which rows to draw */
  172.    row = y-y0;
  173.    r0 = y0 + (GLint) (row * CC.Pixel.ZoomY);
  174.    r1 = y0 + (GLint) ((row+1) * CC.Pixel.ZoomY);
  175.    if (r0==r1) {
  176.       return;
  177.    }
  178.    else if (r1<r0) {
  179.       GLint rtmp = r1;
  180.       r1 = r0;
  181.       r0 = rtmp;
  182.    }
  183.  
  184.    /* return early if r0...r1 is above or below window */
  185.    if (r0<0 && r1<0) {
  186.       /* below window */
  187.       return;
  188.    }
  189.    if (r0>=CC.BufferHeight && r1>=CC.BufferHeight) {
  190.       /* above window */
  191.       return;
  192.    }
  193.  
  194.    /* check if left edge is outside window */
  195.    skipcol = 0;
  196.    if (x<0) {
  197.       skipcol = -x;
  198.       m += x;
  199.    }
  200.    /* make sure span isn't too long or short */
  201.    if (m>maxwidth) {
  202.       m = maxwidth;
  203.    }
  204.    else if (m<=0) {
  205.       return;
  206.    }
  207.  
  208.    assert( m <= MAX_WIDTH );
  209.  
  210.    /* zoom the span horizontally */
  211.    if (CC.Pixel.ZoomX==-1.0F) {
  212.       /* n==m */
  213.       for (j=0;j<m;j++) {
  214.          i = n - (j+skipcol) - 1;
  215.          zred[j]   = red[i];
  216.          zgreen[j] = green[i];
  217.          zblue[j]  = blue[i];
  218.          zalpha[j] = alpha[i];
  219.          zdepth[j] = z[i];
  220.       }
  221.    }
  222.    else {
  223.       GLfloat xscale = 1.0F / CC.Pixel.ZoomX;
  224.       for (j=0;j<m;j++) {
  225.          i = (j+skipcol) * xscale;
  226.          if (i<0)  i = n + i - 1;
  227.          zred[j]   = red[i];
  228.          zgreen[j] = green[i];
  229.          zblue[j]  = blue[i];
  230.          zalpha[j] = alpha[i];
  231.          zdepth[j] = z[i];
  232.       }
  233.    }
  234.  
  235.    /* write the span */
  236.    for (r=r0; r<r1; r++) {
  237.       gl_write_color_span( m, x+skipcol, r, zdepth,
  238.                            zred, zgreen, zblue, zalpha, GL_BITMAP );
  239.    }
  240. }
  241.  
  242.  
  243.  
  244. /*
  245.  * As above, but write CI pixels.
  246.  */
  247. void
  248. gl_write_zoomed_index_span( GLuint n, GLint x, GLint y, const GLdepth z[],
  249.                             const GLuint indexes[], GLint y0 )
  250. {
  251.    GLint m;
  252.    GLint r0, r1, row, r;
  253.    GLint i, j, skipcol;
  254.    GLuint zindexes[MAX_WIDTH];  /* zoomed color indexes */
  255.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  256.    GLint maxwidth = MIN2( CC.BufferWidth, MAX_WIDTH );
  257.  
  258.    /* compute width of output row */
  259.    m = (GLint) ABSF( n * CC.Pixel.ZoomX );
  260.    if (m==0) {
  261.       return;
  262.    }
  263.    if (CC.Pixel.ZoomX<0.0) {
  264.       /* adjust x coordinate for left/right mirroring */
  265.       x = x - m;
  266.    }
  267.  
  268.    /* compute which rows to draw */
  269.    row = y-y0;
  270.    r0 = y0 + (GLint) (row * CC.Pixel.ZoomY);
  271.    r1 = y0 + (GLint) ((row+1) * CC.Pixel.ZoomY);
  272.    if (r0==r1) {
  273.       return;
  274.    }
  275.    else if (r1<r0) {
  276.       GLint rtmp = r1;
  277.       r1 = r0;
  278.       r0 = rtmp;
  279.    }
  280.  
  281.    /* return early if r0...r1 is above or below window */
  282.    if (r0<0 && r1<0) {
  283.       /* below window */
  284.       return;
  285.    }
  286.    if (r0>=CC.BufferHeight && r1>=CC.BufferHeight) {
  287.       /* above window */
  288.       return;
  289.    }
  290.  
  291.    /* check if left edge is outside window */
  292.    skipcol = 0;
  293.    if (x<0) {
  294.       skipcol = -x;
  295.       m += x;
  296.    }
  297.    /* make sure span isn't too long or short */
  298.    if (m>maxwidth) {
  299.       m = maxwidth;
  300.    }
  301.    else if (m<=0) {
  302.       return;
  303.    }
  304.  
  305.    assert( m <= MAX_WIDTH );
  306.  
  307.    /* zoom the span horizontally */
  308.    if (CC.Pixel.ZoomX==-1.0F) {
  309.       /* n==m */
  310.       for (j=0;j<m;j++) {
  311.          i = n - (j+skipcol) - 1;
  312.          zindexes[j] = indexes[i];
  313.          zdepth[j]   = z[i];
  314.       }
  315.    }
  316.    else {
  317.       GLfloat xscale = 1.0F / CC.Pixel.ZoomX;
  318.       for (j=0;j<m;j++) {
  319.          i = (j+skipcol) * xscale;
  320.          if (i<0)  i = n + i - 1;
  321.          zindexes[j] = indexes[i];
  322.          zdepth[j] = z[i];
  323.       }
  324.    }
  325.  
  326.    /* write the span */
  327.    for (r=r0; r<r1; r++) {
  328.       gl_write_index_span( m, x+skipcol, r, zdepth, zindexes, GL_BITMAP );
  329.    }
  330. }
  331.  
  332.  
  333.  
  334. /*
  335.  * As above, but write stencil values.
  336.  */
  337. void
  338. gl_write_zoomed_stencil_span( GLuint n, GLint x, GLint y,
  339.                               const GLubyte stencil[], GLint y0 )
  340. {
  341.    GLint m;
  342.    GLint r0, r1, row, r;
  343.    GLint i, j, skipcol;
  344.    GLubyte zstencil[MAX_WIDTH];  /* zoomed stencil values */
  345.    GLint maxwidth = MIN2( CC.BufferWidth, MAX_WIDTH );
  346.  
  347.    /* compute width of output row */
  348.    m = (GLint) ABSF( n * CC.Pixel.ZoomX );
  349.    if (m==0) {
  350.       return;
  351.    }
  352.    if (CC.Pixel.ZoomX<0.0) {
  353.       /* adjust x coordinate for left/right mirroring */
  354.       x = x - m;
  355.    }
  356.  
  357.    /* compute which rows to draw */
  358.    row = y-y0;
  359.    r0 = y0 + (GLint) (row * CC.Pixel.ZoomY);
  360.    r1 = y0 + (GLint) ((row+1) * CC.Pixel.ZoomY);
  361.    if (r0==r1) {
  362.       return;
  363.    }
  364.    else if (r1<r0) {
  365.       GLint rtmp = r1;
  366.       r1 = r0;
  367.       r0 = rtmp;
  368.    }
  369.  
  370.    /* return early if r0...r1 is above or below window */
  371.    if (r0<0 && r1<0) {
  372.       /* below window */
  373.       return;
  374.    }
  375.    if (r0>=CC.BufferHeight && r1>=CC.BufferHeight) {
  376.       /* above window */
  377.       return;
  378.    }
  379.  
  380.    /* check if left edge is outside window */
  381.    skipcol = 0;
  382.    if (x<0) {
  383.       skipcol = -x;
  384.       m += x;
  385.    }
  386.    /* make sure span isn't too long or short */
  387.    if (m>maxwidth) {
  388.       m = maxwidth;
  389.    }
  390.    else if (m<=0) {
  391.       return;
  392.    }
  393.  
  394.    assert( m <= MAX_WIDTH );
  395.  
  396.    /* zoom the span horizontally */
  397.    if (CC.Pixel.ZoomX==-1.0F) {
  398.       /* n==m */
  399.       for (j=0;j<m;j++) {
  400.          i = n - (j+skipcol) - 1;
  401.          zstencil[j] = stencil[i];
  402.       }
  403.    }
  404.    else {
  405.       GLfloat xscale = 1.0F / CC.Pixel.ZoomX;
  406.       for (j=0;j<m;j++) {
  407.          i = (j+skipcol) * xscale;
  408.          if (i<0)  i = n + i - 1;
  409.          zstencil[j] = stencil[i];
  410.       }
  411.    }
  412.  
  413.    /* write the span */
  414.    for (r=r0; r<r1; r++) {
  415.       gl_write_stencil_span( m, x+skipcol, r, zstencil );
  416.    }
  417. }
  418.  
  419.  
  420.  
  421.  
  422. void glPixelZoom( GLfloat xfactor, GLfloat yfactor )
  423. {
  424.    if (CC.CompileFlag) {
  425.       gl_save_pixelzoom( xfactor, yfactor );
  426.    }
  427.    if (CC.ExecuteFlag) {
  428.       if (INSIDE_BEGIN_END) {
  429.      gl_error( GL_INVALID_OPERATION, "glPixelZoom" );
  430.      return;
  431.       }
  432.       CC.Pixel.ZoomX = xfactor;
  433.       CC.Pixel.ZoomY = yfactor;
  434.       update_drawpixels_state();
  435.    }
  436. }
  437.  
  438.  
  439.  
  440. /**********************************************************************/
  441. /*****                    glPixelStore                            *****/
  442. /**********************************************************************/
  443.  
  444.  
  445. void glPixelStorei( GLenum pname, GLint param )
  446. {
  447.    /* NOTE: this call can't be compiled into the display list */
  448.  
  449.    if (INSIDE_BEGIN_END) {
  450.       gl_error( GL_INVALID_OPERATION, "glPixelStore" );
  451.       return;
  452.    }
  453.  
  454.    switch (pname) {
  455.       case GL_PACK_SWAP_BYTES:
  456.          CC.PackSwapBytes = param ? GL_TRUE : GL_FALSE;
  457.      break;
  458.       case GL_PACK_LSB_FIRST:
  459.          CC.PackLSBFirst = param ? GL_TRUE : GL_FALSE;
  460.      break;
  461.       case GL_PACK_ROW_LENGTH:
  462.      if (param<0) {
  463.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  464.      }
  465.      else {
  466.         CC.PackRowLength = param;
  467.      }
  468.      break;
  469.       case GL_PACK_SKIP_PIXELS:
  470.      if (param<0) {
  471.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  472.      }
  473.      else {
  474.         CC.PackSkipPixels = param;
  475.      }
  476.      break;
  477.       case GL_PACK_SKIP_ROWS:
  478.      if (param<0) {
  479.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  480.      }
  481.      else {
  482.         CC.PackSkipRows = param;
  483.      }
  484.      break;
  485.       case GL_PACK_ALIGNMENT:
  486.          if (param==1 || param==2 || param==4 || param==8) {
  487.         CC.PackAlignment = param;
  488.      }
  489.      else {
  490.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  491.      }
  492.      break;
  493.       case GL_UNPACK_SWAP_BYTES:
  494.      CC.UnpackSwapBytes = param ? GL_TRUE : GL_FALSE;
  495.          break;
  496.       case GL_UNPACK_LSB_FIRST:
  497.      CC.UnpackLSBFirst = param ? GL_TRUE : GL_FALSE;
  498.      break;
  499.       case GL_UNPACK_ROW_LENGTH:
  500.      if (param<0) {
  501.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  502.      }
  503.      else {
  504.         CC.UnpackRowLength = param;
  505.      }
  506.      break;
  507.       case GL_UNPACK_SKIP_PIXELS:
  508.      if (param<0) {
  509.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  510.      }
  511.      else {
  512.         CC.UnpackSkipPixels = param;
  513.      }
  514.      break;
  515.       case GL_UNPACK_SKIP_ROWS:
  516.      if (param<0) {
  517.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  518.      }
  519.      else {
  520.         CC.UnpackSkipRows = param;
  521.      }
  522.      break;
  523.       case GL_UNPACK_ALIGNMENT:
  524.          if (param==1 || param==2 || param==4 || param==8) {
  525.         CC.UnpackAlignment = param;
  526.      }
  527.      else {
  528.         gl_error( GL_INVALID_VALUE, "glPixelStore" );
  529.      }
  530.      break;
  531.       default:
  532.      gl_error( GL_INVALID_ENUM, "glPixelStore" );
  533.    }
  534.    update_drawpixels_state();
  535. }
  536.  
  537.  
  538.  
  539. void glPixelStoref( GLenum pname, GLfloat param )
  540. {
  541.    glPixelStorei( pname, (GLint) param );
  542. }
  543.  
  544.  
  545.  
  546. /**********************************************************************/
  547. /*****                         glPixelMap                         *****/
  548. /**********************************************************************/
  549.  
  550.  
  551.  
  552. void gl_pixel_map( GLenum map, GLint mapsize, const GLfloat *values )
  553. {
  554.    GLuint i;
  555.  
  556.    if (INSIDE_BEGIN_END) {
  557.       gl_error( GL_INVALID_OPERATION, "glPixelMapfv" );
  558.       return;
  559.    }
  560.  
  561.    if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
  562.       gl_error( GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  563.       return;
  564.    }
  565.  
  566.    if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
  567.       /* test that mapsize is a power of two */
  568.       GLuint p;
  569.       GLboolean ok = GL_FALSE;
  570.       for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
  571.      if ( (p&mapsize) == p ) {
  572.         ok = GL_TRUE;
  573.         break;
  574.      }
  575.       }
  576.       if (!ok) {
  577.      gl_error( GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  578.       }
  579.    }
  580.  
  581.    switch (map) {
  582.       case GL_PIXEL_MAP_S_TO_S:
  583.          CC.Pixel.MapStoSsize = mapsize;
  584.          for (i=0;i<mapsize;i++) {
  585.         CC.Pixel.MapStoS[i] = (GLint) values[i];
  586.      }
  587.      break;
  588.       case GL_PIXEL_MAP_I_TO_I:
  589.          CC.Pixel.MapItoIsize = mapsize;
  590.          for (i=0;i<mapsize;i++) {
  591.         CC.Pixel.MapItoI[i] = (GLint) values[i];
  592.      }
  593.      break;
  594.       case GL_PIXEL_MAP_I_TO_R:
  595.          CC.Pixel.MapItoRsize = mapsize;
  596.          for (i=0;i<mapsize;i++) {
  597.         CC.Pixel.MapItoR[i] = CLAMP( values[i], 0.0, 1.0 );
  598.      }
  599.      break;
  600.       case GL_PIXEL_MAP_I_TO_G:
  601.          CC.Pixel.MapItoGsize = mapsize;
  602.          for (i=0;i<mapsize;i++) {
  603.         CC.Pixel.MapItoG[i] = CLAMP( values[i], 0.0, 1.0 );
  604.      }
  605.      break;
  606.       case GL_PIXEL_MAP_I_TO_B:
  607.          CC.Pixel.MapItoBsize = mapsize;
  608.          for (i=0;i<mapsize;i++) {
  609.         CC.Pixel.MapItoB[i] = CLAMP( values[i], 0.0, 1.0 );
  610.      }
  611.      break;
  612.       case GL_PIXEL_MAP_I_TO_A:
  613.          CC.Pixel.MapItoAsize = mapsize;
  614.          for (i=0;i<mapsize;i++) {
  615.         CC.Pixel.MapItoA[i] = CLAMP( values[i], 0.0, 1.0 );
  616.      }
  617.      break;
  618.       case GL_PIXEL_MAP_R_TO_R:
  619.          CC.Pixel.MapRtoRsize = mapsize;
  620.          for (i=0;i<mapsize;i++) {
  621.         CC.Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
  622.      }
  623.      break;
  624.       case GL_PIXEL_MAP_G_TO_G:
  625.          CC.Pixel.MapGtoGsize = mapsize;
  626.          for (i=0;i<mapsize;i++) {
  627.         CC.Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
  628.      }
  629.      break;
  630.       case GL_PIXEL_MAP_B_TO_B:
  631.          CC.Pixel.MapBtoBsize = mapsize;
  632.          for (i=0;i<mapsize;i++) {
  633.         CC.Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
  634.      }
  635.      break;
  636.       case GL_PIXEL_MAP_A_TO_A:
  637.          CC.Pixel.MapAtoAsize = mapsize;
  638.          for (i=0;i<mapsize;i++) {
  639.         CC.Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
  640.      }
  641.      break;
  642.       default:
  643.          gl_error( GL_INVALID_ENUM, "glPixelMapfv(map)" );
  644.    }
  645. }
  646.  
  647.  
  648.  
  649. void glPixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
  650. {
  651.    if (CC.CompileFlag) {
  652.       gl_save_pixelmap( map, mapsize, values );
  653.    }
  654.    if (CC.ExecuteFlag) {
  655.       gl_pixel_map( map, mapsize, values );
  656.    }
  657. }
  658.  
  659.  
  660.  
  661.  
  662. void glPixelMapuiv( GLenum map, GLint mapsize, const GLuint *values )
  663. {
  664.    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
  665.    GLuint i;
  666.  
  667.    if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
  668.       for (i=0;i<mapsize;i++) {
  669.      fvalues[i] = (GLfloat) values[i];
  670.       }
  671.    }
  672.    else {
  673.       for (i=0;i<mapsize;i++) {
  674.      fvalues[i] = UINT_TO_FLOAT( values[i] );
  675.       }
  676.    }
  677.    glPixelMapfv( map, mapsize, fvalues );
  678. }
  679.  
  680.  
  681.  
  682. void glPixelMapusv( GLenum map, GLint mapsize, const GLushort *values )
  683. {
  684.    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
  685.    GLuint i;
  686.  
  687.    if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
  688.       for (i=0;i<mapsize;i++) {
  689.      fvalues[i] = (GLfloat) values[i];
  690.       }
  691.    }
  692.    else {
  693.       for (i=0;i<mapsize;i++) {
  694.      fvalues[i] = USHORT_TO_FLOAT( values[i] );
  695.       }
  696.    }
  697.    glPixelMapfv( map, mapsize, fvalues );
  698. }
  699.  
  700.  
  701.  
  702. void glGetPixelMapfv( GLenum map, GLfloat *values )
  703. {
  704.    GLuint i;
  705.  
  706.    if (INSIDE_BEGIN_END) {
  707.       gl_error( GL_INVALID_OPERATION, "glGetPixelMapfv" );
  708.       return;
  709.    }
  710.    switch (map) {
  711.       case GL_PIXEL_MAP_I_TO_I:
  712.          for (i=0;i<CC.Pixel.MapItoIsize;i++) {
  713.         values[i] = (GLfloat) CC.Pixel.MapItoI[i];
  714.      }
  715.      break;
  716.       case GL_PIXEL_MAP_S_TO_S:
  717.          for (i=0;i<CC.Pixel.MapStoSsize;i++) {
  718.         values[i] = (GLfloat) CC.Pixel.MapStoS[i];
  719.      }
  720.      break;
  721.       case GL_PIXEL_MAP_I_TO_R:
  722.          MEMCPY(values,CC.Pixel.MapItoR,CC.Pixel.MapItoRsize*sizeof(GLfloat));
  723.      break;
  724.       case GL_PIXEL_MAP_I_TO_G:
  725.          MEMCPY(values,CC.Pixel.MapItoG,CC.Pixel.MapItoGsize*sizeof(GLfloat));
  726.      break;
  727.       case GL_PIXEL_MAP_I_TO_B:
  728.          MEMCPY(values,CC.Pixel.MapItoB,CC.Pixel.MapItoBsize*sizeof(GLfloat));
  729.      break;
  730.       case GL_PIXEL_MAP_I_TO_A:
  731.          MEMCPY(values,CC.Pixel.MapItoA,CC.Pixel.MapItoAsize*sizeof(GLfloat));
  732.      break;
  733.       case GL_PIXEL_MAP_R_TO_R:
  734.          MEMCPY(values,CC.Pixel.MapRtoR,CC.Pixel.MapRtoRsize*sizeof(GLfloat));
  735.      break;
  736.       case GL_PIXEL_MAP_G_TO_G:
  737.          MEMCPY(values,CC.Pixel.MapGtoG,CC.Pixel.MapGtoGsize*sizeof(GLfloat));
  738.      break;
  739.       case GL_PIXEL_MAP_B_TO_B:
  740.          MEMCPY(values,CC.Pixel.MapBtoB,CC.Pixel.MapBtoBsize*sizeof(GLfloat));
  741.      break;
  742.       case GL_PIXEL_MAP_A_TO_A:
  743.          MEMCPY(values,CC.Pixel.MapAtoA,CC.Pixel.MapAtoAsize*sizeof(GLfloat));
  744.      break;
  745.       default:
  746.          gl_error( GL_INVALID_ENUM, "glGetPixelMapfv" );
  747.    }
  748. }
  749.  
  750.  
  751. void glGetPixelMapuiv( GLenum map, GLuint *values )
  752. {
  753.    GLuint i;
  754.  
  755.    if (INSIDE_BEGIN_END) {
  756.       gl_error( GL_INVALID_OPERATION, "glGetPixelMapfv" );
  757.       return;
  758.    }
  759.    switch (map) {
  760.       case GL_PIXEL_MAP_I_TO_I:
  761.          MEMCPY(values, CC.Pixel.MapItoI, CC.Pixel.MapItoIsize*sizeof(GLint));
  762.      break;
  763.       case GL_PIXEL_MAP_S_TO_S:
  764.          MEMCPY(values, CC.Pixel.MapStoS, CC.Pixel.MapStoSsize*sizeof(GLint));
  765.      break;
  766.       case GL_PIXEL_MAP_I_TO_R:
  767.      for (i=0;i<CC.Pixel.MapItoRsize;i++) {
  768.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoR[i] );
  769.      }
  770.      break;
  771.       case GL_PIXEL_MAP_I_TO_G:
  772.      for (i=0;i<CC.Pixel.MapItoGsize;i++) {
  773.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoG[i] );
  774.      }
  775.      break;
  776.       case GL_PIXEL_MAP_I_TO_B:
  777.      for (i=0;i<CC.Pixel.MapItoBsize;i++) {
  778.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoB[i] );
  779.      }
  780.      break;
  781.       case GL_PIXEL_MAP_I_TO_A:
  782.      for (i=0;i<CC.Pixel.MapItoAsize;i++) {
  783.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoA[i] );
  784.      }
  785.      break;
  786.       case GL_PIXEL_MAP_R_TO_R:
  787.      for (i=0;i<CC.Pixel.MapRtoRsize;i++) {
  788.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapRtoR[i] );
  789.      }
  790.      break;
  791.       case GL_PIXEL_MAP_G_TO_G:
  792.      for (i=0;i<CC.Pixel.MapGtoGsize;i++) {
  793.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapGtoG[i] );
  794.      }
  795.      break;
  796.       case GL_PIXEL_MAP_B_TO_B:
  797.      for (i=0;i<CC.Pixel.MapBtoBsize;i++) {
  798.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapBtoB[i] );
  799.      }
  800.      break;
  801.       case GL_PIXEL_MAP_A_TO_A:
  802.      for (i=0;i<CC.Pixel.MapAtoAsize;i++) {
  803.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapAtoA[i] );
  804.      }
  805.      break;
  806.       default:
  807.          gl_error( GL_INVALID_ENUM, "glGetPixelMapfv" );
  808.    }
  809. }
  810.  
  811.  
  812. void glGetPixelMapusv( GLenum map, GLushort *values )
  813. {
  814.    GLuint i;
  815.  
  816.    if (INSIDE_BEGIN_END) {
  817.       gl_error( GL_INVALID_OPERATION, "glGetPixelMapfv" );
  818.       return;
  819.    }
  820.    switch (map) {
  821.       case GL_PIXEL_MAP_I_TO_I:
  822.      for (i=0;i<CC.Pixel.MapItoIsize;i++) {
  823.         values[i] = (GLushort) CC.Pixel.MapItoI[i];
  824.      }
  825.      break;
  826.       case GL_PIXEL_MAP_S_TO_S:
  827.      for (i=0;i<CC.Pixel.MapStoSsize;i++) {
  828.         values[i] = (GLushort) CC.Pixel.MapStoS[i];
  829.      }
  830.      break;
  831.       case GL_PIXEL_MAP_I_TO_R:
  832.      for (i=0;i<CC.Pixel.MapItoRsize;i++) {
  833.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoR[i] );
  834.      }
  835.      break;
  836.       case GL_PIXEL_MAP_I_TO_G:
  837.      for (i=0;i<CC.Pixel.MapItoGsize;i++) {
  838.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoG[i] );
  839.      }
  840.      break;
  841.       case GL_PIXEL_MAP_I_TO_B:
  842.      for (i=0;i<CC.Pixel.MapItoBsize;i++) {
  843.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoB[i] );
  844.      }
  845.      break;
  846.       case GL_PIXEL_MAP_I_TO_A:
  847.      for (i=0;i<CC.Pixel.MapItoAsize;i++) {
  848.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoA[i] );
  849.      }
  850.      break;
  851.       case GL_PIXEL_MAP_R_TO_R:
  852.      for (i=0;i<CC.Pixel.MapRtoRsize;i++) {
  853.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapRtoR[i] );
  854.      }
  855.      break;
  856.       case GL_PIXEL_MAP_G_TO_G:
  857.      for (i=0;i<CC.Pixel.MapGtoGsize;i++) {
  858.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapGtoG[i] );
  859.      }
  860.      break;
  861.       case GL_PIXEL_MAP_B_TO_B:
  862.      for (i=0;i<CC.Pixel.MapBtoBsize;i++) {
  863.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapBtoB[i] );
  864.      }
  865.      break;
  866.       case GL_PIXEL_MAP_A_TO_A:
  867.      for (i=0;i<CC.Pixel.MapAtoAsize;i++) {
  868.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapAtoA[i] );
  869.      }
  870.      break;
  871.       default:
  872.          gl_error( GL_INVALID_ENUM, "glGetPixelMapfv" );
  873.    }
  874. }
  875.  
  876.  
  877.  
  878. /**********************************************************************/
  879. /*****                       glPixelTransfer                      *****/
  880. /**********************************************************************/
  881.  
  882.  
  883. /*
  884.  * Implements glPixelTransfer[fi] whether called immediately or from a
  885.  * display list.
  886.  */
  887. void gl_pixel_transfer( GLenum pname, GLfloat param )
  888. {
  889.    if (INSIDE_BEGIN_END) {
  890.       gl_error( GL_INVALID_OPERATION, "glPixelTransfer" );
  891.       return;
  892.    }
  893.  
  894.    switch (pname) {
  895.       case GL_MAP_COLOR:
  896.          CC.Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
  897.      break;
  898.       case GL_MAP_STENCIL:
  899.          CC.Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
  900.      break;
  901.       case GL_INDEX_SHIFT:
  902.          CC.Pixel.IndexShift = (GLint) param;
  903.      break;
  904.       case GL_INDEX_OFFSET:
  905.          CC.Pixel.IndexOffset = (GLint) param;
  906.      break;
  907.       case GL_RED_SCALE:
  908.          CC.Pixel.RedScale = param;
  909.      break;
  910.       case GL_RED_BIAS:
  911.          CC.Pixel.RedBias = param;
  912.      break;
  913.       case GL_GREEN_SCALE:
  914.          CC.Pixel.GreenScale = param;
  915.      break;
  916.       case GL_GREEN_BIAS:
  917.          CC.Pixel.GreenBias = param;
  918.      break;
  919.       case GL_BLUE_SCALE:
  920.          CC.Pixel.BlueScale = param;
  921.      break;
  922.       case GL_BLUE_BIAS:
  923.          CC.Pixel.BlueBias = param;
  924.      break;
  925.       case GL_ALPHA_SCALE:
  926.          CC.Pixel.AlphaScale = param;
  927.      break;
  928.       case GL_ALPHA_BIAS:
  929.          CC.Pixel.AlphaBias = param;
  930.      break;
  931.       case GL_DEPTH_SCALE:
  932.          CC.Pixel.DepthScale = param;
  933.      break;
  934.       case GL_DEPTH_BIAS:
  935.          CC.Pixel.DepthBias = param;
  936.      break;
  937.       default:
  938.          gl_error( GL_INVALID_ENUM, "glPixelTransfer(pname)" );
  939.          return;
  940.    }
  941.    update_drawpixels_state();
  942. }
  943.  
  944.  
  945.  
  946. void glPixelTransferf( GLenum pname, GLfloat param )
  947. {
  948.    if (CC.CompileFlag) {
  949.       gl_save_pixeltransfer( pname, param );
  950.    }
  951.    if (CC.ExecuteFlag) {
  952.       gl_pixel_transfer( pname, param );
  953.    }
  954. }
  955.  
  956.  
  957.  
  958. void glPixelTransferi( GLenum pname, GLint param )
  959. {
  960.    if (CC.CompileFlag) {
  961.       gl_save_pixeltransfer( pname, (GLfloat) param );
  962.    }
  963.    if (CC.ExecuteFlag) {
  964.       gl_pixel_transfer( pname, (GLfloat) param );
  965.    }
  966. }
  967.  
  968.  
  969.  
  970. /**********************************************************************/
  971. /*****                 Pixel packing/unpacking                    *****/
  972. /**********************************************************************/
  973.  
  974.  
  975.  
  976. /*
  977.  * Unpack pixel data according to parameters set by glPixelStore.
  978.     GLint PackAlignment;
  979.     GLint PackRowLength;
  980.     GLint PackSkipPixels;
  981.     GLint PackSkipRows;
  982.     GLboolean PackSwapBytes;
  983.     GLboolean PackLSBFirst;
  984.  
  985.     GLint UnpackAlignment;
  986.     GLint UnpackRowLength;
  987.     GLint UnpackSkipPixels;
  988.     GLint UnpackSkipRows;
  989.     GLboolean UnpackSwapBytes;
  990.     GLboolean UnpackLSBFirst;
  991.  */
  992.  
  993.  
  994.  
  995. /*
  996.  * Flip the 8 bits in each byte of the given array.
  997.  */
  998. void gl_flip_bytes( GLubyte *p, GLuint n )
  999. {
  1000.    register GLuint i, a, b;
  1001.  
  1002.    for (i=0;i<n;i++) {
  1003.       b = (GLuint) p[i];
  1004.       a = ((b & 0x01) << 7) |
  1005.       ((b & 0x02) << 5) |
  1006.       ((b & 0x04) << 3) |
  1007.       ((b & 0x08) << 1) |
  1008.       ((b & 0x10) >> 1) |
  1009.       ((b & 0x20) >> 3) |
  1010.       ((b & 0x40) >> 5) |
  1011.       ((b & 0x80) >> 7);
  1012.       p[i] = (GLubyte) a;
  1013.    }
  1014. }
  1015.  
  1016.  
  1017. /*
  1018.  * Flip the order of the 4 bytes in each word in the given array.
  1019.  */
  1020. static void swap4( GLuint *p, GLuint n )
  1021. {
  1022.    register GLuint i, a, b;
  1023.  
  1024.    for (i=0;i<n;i++) {
  1025.       b = p[i];
  1026.       a =  (b >> 24)
  1027.     | ((b >> 8) & 0xff00)
  1028.     | ((b << 8) & 0xff0000)
  1029.     | ((b << 24) & 0xff000000);
  1030.       p[i] = a;
  1031.    }
  1032. }
  1033.  
  1034.  
  1035. /*
  1036.  * Flip the order of the 2 bytes in each word in the given array.
  1037.  */
  1038. static void swap2( GLushort *p, GLuint n )
  1039. {
  1040.    register GLuint i;
  1041.  
  1042.    for (i=0;i<n;i++) {
  1043.       p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
  1044.    }
  1045. }
  1046.  
  1047.  
  1048. /*
  1049.  * Compute ceiling of integer quotient of A divided by B:
  1050.  */
  1051. #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
  1052.  
  1053.  
  1054.  
  1055.  
  1056. /*
  1057.  * Unpack the given 2-D pixel array data.  The unpacked format will be con-
  1058.  * tiguous (no "empty" bytes) with byte/bit swapping applied as needed.
  1059.  * Input:  same as glDrawPixels
  1060.  * Output:  pointer to block of pixel data in same format and type as input
  1061.  *          or NULL if error.
  1062.  */
  1063. GLvoid *gl_unpack( GLsizei width, GLsizei height, GLenum format, GLenum type,
  1064.                const GLvoid *pixels )
  1065. {
  1066.    GLuint i, s, a, n, l, k;
  1067.    GLuint bytes, width_in_bytes;
  1068.    GLubyte *dst, *src, *buffer;
  1069.  
  1070.    /* Compute bytes per component */
  1071.    switch (type) {
  1072.       case GL_UNSIGNED_BYTE:
  1073.          s = sizeof(GLubyte);
  1074.      break;
  1075.       case GL_BYTE:
  1076.      s = sizeof(GLbyte);
  1077.      break;
  1078.       case GL_BITMAP:
  1079.      s = 0;  /* special case */
  1080.      break;
  1081.       case GL_UNSIGNED_SHORT:
  1082.      s = sizeof(GLushort);
  1083.      break;
  1084.       case GL_SHORT:
  1085.      s = sizeof(GLshort);
  1086.      break;
  1087.       case GL_UNSIGNED_INT:
  1088.      s = sizeof(GLuint);
  1089.      break;
  1090.       case GL_INT:
  1091.      s = sizeof(GLint);
  1092.      break;
  1093.       case GL_FLOAT:
  1094.      s = sizeof(GLfloat);
  1095.      break;
  1096.       default:
  1097.      gl_error( GL_INVALID_ENUM, "internal error in gl_unpack(type)" );
  1098.      return NULL;
  1099.    }
  1100.  
  1101.    /* Check if unpacking really is needed */
  1102. #ifdef LEAVEOUT
  1103.    if (!CC.UnpackSwapBytes && !CC.UnpackLSBFirst
  1104.        && CC.UnpackRowLength==0 && CC.UnpackSkipPixels==0
  1105.        && CC.UnpackSkipRows==0 && s>=CC.UnpackAlignment) {
  1106.       /* No unpacking has to be done */
  1107.       return (GLvoid *) pixels;
  1108.    }
  1109. #endif
  1110.  
  1111.    /* Compute number of components per pixel */
  1112.    switch (format) {
  1113.       case GL_COLOR_INDEX:
  1114.       case GL_STENCIL_INDEX:
  1115.       case GL_DEPTH_COMPONENT:
  1116.       case GL_RED:
  1117.       case GL_GREEN:
  1118.       case GL_BLUE:
  1119.       case GL_ALPHA:
  1120.       case GL_LUMINANCE:
  1121.          n = 1;
  1122.      break;
  1123.       case GL_LUMINANCE_ALPHA:
  1124.      n = 2;
  1125.      break;
  1126.       case GL_RGB:
  1127.      n = 3;
  1128.      break;
  1129.       case GL_RGBA:
  1130.      n = 4;
  1131.      break;
  1132.       default:
  1133.      gl_error( GL_INVALID_ENUM, "internal error in gl_unpack(format)" );
  1134.      return NULL;
  1135.    }
  1136.  
  1137.    /* Compute alignment and row length */
  1138.    a = CC.UnpackAlignment;
  1139.    if (CC.UnpackRowLength>0) {
  1140.       l = CC.UnpackRowLength;
  1141.    }
  1142.    else {
  1143.       l = width;
  1144.    }
  1145.  
  1146.    /*
  1147.     * Unpack!
  1148.     */
  1149.    if (type==GL_BITMAP) {
  1150.       /* BITMAP data */
  1151.  
  1152.       k = 8 * a * CEILING( n*l, 8*a );
  1153.  
  1154.       /* allocate storage for unpacked pixel data */
  1155.       bytes = CEILING( width * height , 8 );
  1156.       buffer = (GLubyte *) malloc( bytes );
  1157.       if (!buffer) {
  1158.      return NULL;
  1159.       }
  1160.  
  1161.       /* Copy/unpack pixel data to buffer */
  1162.       width_in_bytes = CEILING( width, 8 );
  1163.       src = (GLubyte *) pixels
  1164.         + CC.UnpackSkipRows * k
  1165.             + CC.UnpackSkipPixels / 8;
  1166.       dst = buffer;
  1167.       for (i=0;i<height;i++) {
  1168.      MEMCPY( dst, src, width_in_bytes );
  1169.      dst += width_in_bytes;
  1170.      src += k * s;
  1171.       }
  1172.       if (CC.UnpackLSBFirst) {
  1173.      /* reverse order of 8 bits in each byte */
  1174.      gl_flip_bytes( buffer, bytes );
  1175.       }
  1176.    }
  1177.    else {
  1178.       /* Non-BITMAP data */
  1179.  
  1180.       if (s>=a) {
  1181.      k = n * l;
  1182.       }
  1183.       else {
  1184.      k = a/s * CEILING( s*n*l, a );
  1185.       }
  1186.  
  1187.       /* allocate storage for unpacked pixel data */
  1188.       bytes = width * height * n * s;
  1189.       buffer = (GLubyte *) malloc( bytes );
  1190.       if (!buffer) {
  1191.      return NULL;
  1192.       }
  1193.  
  1194.       /* Copy/unpack pixel data to buffer */
  1195.       width_in_bytes = width * n * s;
  1196.       src = (GLubyte *) pixels
  1197.         + CC.UnpackSkipRows * k * s
  1198.             + CC.UnpackSkipPixels * n * s;
  1199.       dst = buffer;
  1200.       for (i=0;i<height;i++) {
  1201.      MEMCPY( dst, src, width_in_bytes );
  1202.      dst += width_in_bytes;
  1203.      src += k * s;
  1204.       }
  1205.  
  1206.       if (CC.UnpackSwapBytes && s>1) {
  1207.      if (s==2) {
  1208.         swap2( (GLushort *) buffer, bytes/2 );
  1209.      }
  1210.      else if (s==4) {
  1211.         swap4( (GLuint *) buffer, bytes/4 );
  1212.      }
  1213.       }
  1214.    }
  1215.  
  1216.    return (GLvoid *) buffer;
  1217. }
  1218.  
  1219.  
  1220.  
  1221.  
  1222. /*
  1223.    if (s>=a) {
  1224.       k = n * l;
  1225.    }
  1226.    else {  *s<a*
  1227.       k = (a/s) * ceil( s*n*l / a );
  1228.    }
  1229.  
  1230.    s = size in bytes of a single component
  1231.    a = alignment
  1232.    n = number of components in a pixel
  1233.    l = number of pixels in a row
  1234.  
  1235.    k = number of components or indices between first pixel in each row in mem.
  1236. */
  1237.  
  1238.