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

  1. /* $Id: drawpix.c,v 1.15 1997/08/26 02:10:11 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: drawpix.c,v $
  26.  * Revision 1.15  1997/08/26 02:10:11  brianp
  27.  * another bug fix related to glPixelStore()
  28.  *
  29.  * Revision 1.14  1997/08/24 02:31:23  brianp
  30.  * bug fix: glPixelStore() params weren't ignored during display list execute
  31.  *
  32.  * Revision 1.13  1997/07/24 01:25:01  brianp
  33.  * changed precompiled header symbol from PCH to PC_HEADER
  34.  *
  35.  * Revision 1.12  1997/06/20 02:18:23  brianp
  36.  * replaced Current.IntColor with Current.ByteColor
  37.  *
  38.  * Revision 1.11  1997/05/28 03:24:22  brianp
  39.  * added precompiled header (PCH) support
  40.  *
  41.  * Revision 1.10  1997/04/24 00:18:56  brianp
  42.  * added some missing UNDEFARRAY()s.  Reported by Randy Frank.
  43.  *
  44.  * Revision 1.9  1997/04/20 20:28:49  brianp
  45.  * replaced abort() with gl_problem()
  46.  *
  47.  * Revision 1.8  1997/04/11 23:24:25  brianp
  48.  * move call to gl_update_state() into gl_DrawPixels() from drawpixels()
  49.  *
  50.  * Revision 1.7  1997/03/18 01:55:47  brianp
  51.  * only generate feedback/selection if raster position is valid
  52.  *
  53.  * Revision 1.6  1997/02/10 20:26:57  brianp
  54.  * fixed memory leak in quickdraw_rgb()
  55.  *
  56.  * Revision 1.5  1997/02/03 20:30:31  brianp
  57.  * added a few DEFARRAY macros for BeOS
  58.  *
  59.  * Revision 1.4  1996/10/16 00:58:53  brianp
  60.  * renamed gl_drawpixels() to drawpixels()
  61.  *
  62.  * Revision 1.3  1996/09/27 01:26:25  brianp
  63.  * added missing default cases to switches
  64.  *
  65.  * Revision 1.2  1996/09/15 14:17:30  brianp
  66.  * now use GLframebuffer and GLvisual
  67.  *
  68.  * Revision 1.1  1996/09/13 01:38:16  brianp
  69.  * Initial revision
  70.  *
  71.  */
  72.  
  73.  
  74. #ifdef PC_HEADER
  75. #include "all.h"
  76. #else
  77. #include <stdlib.h>
  78. #include <string.h>
  79. #include "context.h"
  80. #include "drawpix.h"
  81. #include "feedback.h"
  82. #include "dlist.h"
  83. #include "macros.h"
  84. #include "pixel.h"
  85. #include "span.h"
  86. #include "stencil.h"
  87. #include "types.h"
  88. #endif
  89.  
  90. #define BOOL_TO_FLOAT(X)        ( (GLfloat)(GLint) (X) )
  91. #define BOOL_TO_DOUBLE(X)        ( (GLdouble)(GLint) (X) )
  92.  
  93.  
  94. /* TODO:  apply texture mapping to fragments */
  95.  
  96.  
  97.  
  98. static void draw_index_pixels( GLcontext* ctx, GLsizei width, GLsizei height,
  99.                    GLenum type, const GLvoid *pixels )
  100. {
  101.    GLint x, y, desty;
  102.    GLuint i, j;
  103.    GLdepth zspan[MAX_WIDTH];
  104.    GLboolean zoom;
  105.  
  106.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  107.  
  108.    /* Position, depth of pixels */
  109.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  110.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  111.    desty = y;
  112.    if (ctx->Depth.Test) {
  113.       GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  114.       for (i=0;i<width;i++) {
  115.      zspan[i] = zval;
  116.       }
  117.    }
  118.  
  119.    /* process the image row by row */
  120.    for (i=0;i<height;i++,y++) {
  121.       GLuint ispan[MAX_WIDTH];
  122.  
  123.       /* convert to uints */
  124.       switch (type) {
  125.      case GL_UNSIGNED_BYTE:
  126.         {
  127.            GLubyte *src = (GLubyte *) pixels + i * width;
  128.            for (j=0;j<width;j++) {
  129.           ispan[j] = (GLuint) *src++;
  130.            }
  131.         }
  132.         break;
  133.      case GL_BYTE:
  134.         {
  135.            GLbyte *src = (GLbyte *) pixels + i * width;
  136.            for (j=0;j<width;j++) {
  137.           ispan[j] = (GLuint) *src++;
  138.            }
  139.         }
  140.         break;
  141.      case GL_UNSIGNED_SHORT:
  142.         {
  143.            GLushort *src = (GLushort *) pixels + i * width;
  144.            for (j=0;j<width;j++) {
  145.           ispan[j] = (GLuint) *src++;
  146.            }
  147.         }
  148.         break;
  149.      case GL_SHORT:
  150.         {
  151.            GLshort *src = (GLshort *) pixels + i * width;
  152.            for (j=0;j<width;j++) {
  153.           ispan[j] = (GLuint) *src++;
  154.            }
  155.         }
  156.         break;
  157.      case GL_UNSIGNED_INT:
  158.         {
  159.            GLuint *src = (GLuint *) pixels + i * width;
  160.            for (j=0;j<width;j++) {
  161.           ispan[j] = *src++;
  162.            }
  163.         }
  164.         break;
  165.      case GL_INT:
  166.         {
  167.            GLint *src = (GLint *) pixels + i * width;
  168.            for (j=0;j<width;j++) {
  169.           ispan[j] = (GLuint) *src++;
  170.            }
  171.         }
  172.         break;
  173.      case GL_BITMAP:
  174.         /* TODO */
  175.         break;
  176.      case GL_FLOAT:
  177.         {
  178.            GLfloat *src = (GLfloat *) pixels + i * width;
  179.            for (j=0;j<width;j++) {
  180.           ispan[j] = (GLuint) (GLint) *src++;
  181.            }
  182.         }
  183.         break;
  184.      default:
  185.         gl_error( ctx, GL_INVALID_ENUM, "Internal: draw_index_pixels" );
  186.       }
  187.  
  188.       /* apply shift and offset */
  189.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  190.      if (ctx->Pixel.IndexShift>=0) {
  191.         for (j=0;j<width;j++) {
  192.            ispan[j] = (ispan[j] << ctx->Pixel.IndexShift)
  193.               + ctx->Pixel.IndexOffset;
  194.         }
  195.      }
  196.      else {
  197.         for (j=0;j<width;j++) {
  198.            ispan[j] = (ispan[j] >> -ctx->Pixel.IndexShift)
  199.               + ctx->Pixel.IndexOffset;
  200.         }
  201.      }
  202.       }
  203.  
  204.       if (ctx->Visual->RGBAflag) {
  205.      /* Convert index to RGBA and write to frame buffer */
  206.      GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  207.      GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  208.      for (j=0;j<width;j++) {
  209.         red[j]   = (GLint) (ctx->Pixel.MapItoR[ispan[j]] * ctx->Visual->RedScale);
  210.         green[j] = (GLint) (ctx->Pixel.MapItoG[ispan[j]] * ctx->Visual->GreenScale);
  211.         blue[j]  = (GLint) (ctx->Pixel.MapItoB[ispan[j]] * ctx->Visual->BlueScale);
  212.         alpha[j] = (GLint) (ctx->Pixel.MapItoA[ispan[j]] * ctx->Visual->AlphaScale);
  213.      }
  214.      if (zoom) {
  215.         gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  216.                     red, green, blue, alpha, desty );
  217.      }
  218.      else {
  219.         gl_write_color_span( ctx, width, x, y, zspan,
  220.                  red, green, blue, alpha, GL_BITMAP );
  221.      }
  222.       }
  223.       else {
  224.      /* optionally apply index map then write to frame buffer */
  225.      if (ctx->Pixel.MapColorFlag) {
  226.         for (j=0;j<width;j++) {
  227.            ispan[j] = ctx->Pixel.MapItoI[ispan[j]];
  228.         }
  229.      }
  230.      if (zoom) {
  231.         gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty );
  232.      }
  233.      else {
  234.         gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  235.      }
  236.       }
  237.    }
  238.  
  239. }
  240.  
  241.  
  242.  
  243. static void draw_stencil_pixels( GLcontext* ctx, GLsizei width, GLsizei height,
  244.                  GLenum type, const GLvoid *pixels )
  245. {
  246.    GLint x, y, desty;
  247.    GLuint i, j;
  248.    GLboolean zoom;
  249.  
  250.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  251.  
  252.    /* Position, depth of pixels */
  253.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  254.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  255.    desty = y;
  256.  
  257.    /* process the image row by row */
  258.    for (i=0;i<height;i++,y++) {
  259.       GLubyte stencil[MAX_WIDTH];
  260.  
  261.       /* convert to ubytes */
  262.       switch (type) {
  263.      case GL_UNSIGNED_BYTE:
  264.         {
  265.            GLubyte *src = (GLubyte *) pixels + i * width;
  266.            MEMCPY( stencil, src, width );
  267.         }
  268.         break;
  269.      case GL_BYTE:
  270.         {
  271.            GLbyte *src = (GLbyte *) pixels + i * width;
  272.            MEMCPY( stencil, src, width );
  273.         }
  274.         break;
  275.      case GL_UNSIGNED_SHORT:
  276.         {
  277.            GLushort *src = (GLushort *) pixels + i * width;
  278.            for (j=0;j<width;j++) {
  279.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  280.            }
  281.         }
  282.         break;
  283.      case GL_SHORT:
  284.         {
  285.            GLshort *src = (GLshort *) pixels + i * width;
  286.            for (j=0;j<width;j++) {
  287.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  288.            }
  289.         }
  290.         break;
  291.      case GL_UNSIGNED_INT:
  292.         {
  293.            GLuint *src = (GLuint *) pixels + i * width;
  294.            for (j=0;j<width;j++) {
  295.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  296.            }
  297.         }
  298.         break;
  299.      case GL_INT:
  300.         {
  301.            GLint *src = (GLint *) pixels + i * width;
  302.            for (j=0;j<width;j++) {
  303.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  304.            }
  305.         }
  306.         break;
  307.      case GL_BITMAP:
  308.         /* TODO */
  309.         break;
  310.      case GL_FLOAT:
  311.         {
  312.            GLfloat *src = (GLfloat *) pixels + i * width;
  313.            for (j=0;j<width;j++) {
  314.           stencil[j] = (GLubyte) (((GLint) *src++) & 0xff);
  315.            }
  316.         }
  317.         break;
  318.      default:
  319.         gl_error( ctx, GL_INVALID_ENUM, "Internal: draw_stencil_pixels" );
  320.       }
  321.  
  322.       /* apply shift and offset */
  323.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  324.      if (ctx->Pixel.IndexShift>=0) {
  325.         for (j=0;j<width;j++) {
  326.            stencil[j] = (stencil[j] << ctx->Pixel.IndexShift)
  327.               + ctx->Pixel.IndexOffset;
  328.         }
  329.      }
  330.      else {
  331.         for (j=0;j<width;j++) {
  332.            stencil[j] = (stencil[j] >> -ctx->Pixel.IndexShift)
  333.               + ctx->Pixel.IndexOffset;
  334.         }
  335.      }
  336.       }
  337.  
  338.       /* mapping */
  339.       if (ctx->Pixel.MapStencilFlag) {
  340.      for (j=0;j<width;j++) {
  341.         stencil[j] = ctx->Pixel.MapStoS[ stencil[j] ];
  342.      }
  343.       }
  344.  
  345.       /* write stencil values to stencil buffer */
  346.       if (zoom) {
  347.      gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y, stencil, desty );
  348.       }
  349.       else {
  350.      gl_write_stencil_span( ctx, (GLuint) width, x, y, stencil );
  351.       }
  352.    }
  353. }
  354.  
  355.  
  356.  
  357. static void draw_depth_pixels( GLcontext* ctx, GLsizei width, GLsizei height,
  358.                    GLenum type, const GLvoid *pixels )
  359. {
  360.    GLint x, y, desty;
  361.    GLubyte red[MAX_WIDTH], green[MAX_WIDTH], blue[MAX_WIDTH], alpha[MAX_WIDTH];
  362.    GLuint ispan[MAX_WIDTH];
  363.    GLboolean bias_or_scale;
  364.    GLboolean zoom;
  365.  
  366.    bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  367.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  368.  
  369.    /* Position, depth of pixels */
  370.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  371.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  372.    desty = y;
  373.  
  374.    /* Color or index */
  375.    if (ctx->Visual->RGBAflag) {
  376.       GLint r, g, b, a;
  377.       r = (GLint) (ctx->Current.RasterColor[0] * ctx->Visual->RedScale);
  378.       g = (GLint) (ctx->Current.RasterColor[1] * ctx->Visual->GreenScale);
  379.       b = (GLint) (ctx->Current.RasterColor[2] * ctx->Visual->BlueScale);
  380.       a = (GLint) (ctx->Current.RasterColor[3] * ctx->Visual->AlphaScale);
  381.       MEMSET( red,   r, width );
  382.       MEMSET( green, g, width );
  383.       MEMSET( blue,  b, width );
  384.       MEMSET( alpha, a, width );
  385.    }
  386.    else {
  387.       GLuint i;
  388.       for (i=0;i<width;i++) {
  389.      ispan[i] = ctx->Current.RasterIndex;
  390.       }
  391.    }
  392.  
  393.    if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  394.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  395.       /* Special case: directly write 16-bit depth values */
  396.       GLuint j;
  397.       for (j=0;j<height;j++,y++) {
  398.      GLdepth *zptr = (GLdepth *) pixels + j * width;
  399.      gl_write_color_span( ctx, width, x, y, zptr,
  400.                   red, green, blue, alpha, GL_BITMAP );
  401.       }
  402.    }
  403.    else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  404.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  405.       /* Special case: directly write 32-bit depth values */
  406.       GLuint i, j;
  407.       /* Compute shift value to scale 32-bit uints down to depth values. */
  408.       GLuint shift = 0;
  409.       GLuint max = MAX_DEPTH;
  410.       while ((max&0x80000000)==0) {
  411.      max = max << 1;
  412.      shift++;
  413.       }
  414.       for (j=0;j<height;j++,y++) {
  415.      GLdepth zspan[MAX_WIDTH];
  416.      GLuint *zptr = (GLuint *) pixels + j * width;
  417.      for (i=0;i<width;i++) {
  418.         zspan[i] = zptr[i] >> shift;
  419.      }
  420.      gl_write_color_span( ctx, width, x, y, zspan,
  421.                   red, green, blue, alpha, GL_BITMAP );
  422.       }
  423.    }
  424.    else {
  425.       /* General case (slower) */
  426.       GLuint i, j;
  427.  
  428.       /* process image row by row */
  429.       for (i=0;i<height;i++,y++) {
  430.      GLfloat depth[MAX_WIDTH];
  431.      GLdepth zspan[MAX_WIDTH];
  432.  
  433.      switch (type) {
  434.         case GL_UNSIGNED_BYTE:
  435.            {
  436.           GLubyte *src = (GLubyte *) pixels + i * width;
  437.           for (j=0;j<width;j++) {
  438.              depth[j] = UBYTE_TO_FLOAT( *src++ );
  439.           }
  440.            }
  441.            break;
  442.         case GL_BYTE:
  443.            {
  444.           GLbyte *src = (GLbyte *) pixels + i * width;
  445.           for (j=0;j<width;j++) {
  446.              depth[j] = BYTE_TO_FLOAT( *src++ );
  447.           }
  448.            }
  449.            break;
  450.         case GL_UNSIGNED_SHORT:
  451.            {
  452.           GLushort *src = (GLushort *) pixels + i * width;
  453.           for (j=0;j<width;j++) {
  454.              depth[j] = USHORT_TO_FLOAT( *src++ );
  455.           }
  456.            }
  457.            break;
  458.         case GL_SHORT:
  459.            {
  460.           GLshort *src = (GLshort *) pixels + i * width;
  461.           for (j=0;j<width;j++) {
  462.              depth[j] = SHORT_TO_FLOAT( *src++ );
  463.           }
  464.            }
  465.            break;
  466.         case GL_UNSIGNED_INT:
  467.            {
  468.           GLuint *src = (GLuint *) pixels + i * width;
  469.           for (j=0;j<width;j++) {
  470.              depth[j] = UINT_TO_FLOAT( *src++ );
  471.           }
  472.            }
  473.            break;
  474.         case GL_INT:
  475.            {
  476.           GLint *src = (GLint *) pixels + i * width;
  477.           for (j=0;j<width;j++) {
  478.              depth[j] = INT_TO_FLOAT( *src++ );
  479.           }
  480.            }
  481.            break;
  482.         case GL_FLOAT:
  483.            {
  484.           GLfloat *src = (GLfloat *) pixels + i * width;
  485.           for (j=0;j<width;j++) {
  486.              depth[j] = *src++;
  487.           }
  488.            }
  489.            break;
  490.         default:
  491.            gl_problem(ctx, "Bad type in draw_depth_pixels");
  492.            return;
  493.      }
  494.  
  495.      /* apply depth scale and bias */
  496.      if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) {
  497.         for (j=0;j<width;j++) {
  498.            depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  499.         }
  500.      }
  501.  
  502.      /* clamp depth values to [0,1] and convert from floats to integers */
  503.      for (j=0;j<width;j++) {
  504.         zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
  505.      }
  506.  
  507.      if (ctx->Visual->RGBAflag) {
  508.         if (zoom) {
  509.            gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  510.                        red, green, blue, alpha, desty );
  511.         }
  512.         else {
  513.            gl_write_color_span( ctx, width, x, y, zspan,
  514.                     red, green, blue, alpha, GL_BITMAP );
  515.         }
  516.      }
  517.      else {
  518.         if (zoom) {
  519.            gl_write_zoomed_index_span( ctx, width, x, y, zspan,
  520.                        ispan, GL_BITMAP );
  521.         }
  522.         else {
  523.            gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  524.         }
  525.      }
  526.  
  527.       }
  528.    }
  529. }
  530.  
  531.  
  532. /* temporary bugfix for StormCPPC */
  533.  
  534. #if defined(__STORM__) && defined(__PPC__)
  535.      DEFARRAY(GLfloat, g_rf, MAX_WIDTH);
  536.      DEFARRAY(GLfloat, g_gf, MAX_WIDTH);
  537.      DEFARRAY(GLfloat, g_bf, MAX_WIDTH);
  538.      DEFARRAY(GLfloat, g_af, MAX_WIDTH);
  539.      DEFARRAY(GLubyte, g_red, MAX_WIDTH);
  540.      DEFARRAY(GLubyte, g_green, MAX_WIDTH);
  541.      DEFARRAY(GLubyte, g_blue, MAX_WIDTH);
  542.      DEFARRAY(GLubyte, g_alpha, MAX_WIDTH);
  543. #endif
  544.  
  545. #if defined(__STORM__) && defined(__PPC__)
  546.  
  547.  
  548. static void draw_color_pixels( GLcontext* ctx,
  549.                    GLsizei width, GLsizei height, GLenum format,
  550.                    GLenum type, const GLvoid *pixels )
  551. {
  552.    GLuint i, j;
  553.    GLint x, y, desty;
  554.    GLdepth zspan[MAX_WIDTH];
  555.    GLboolean scale_or_bias, quick_draw;
  556.    GLboolean zoom;
  557.  
  558.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  559.  
  560.    /* Position, depth of pixels */
  561.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  562.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  563.    desty = y;
  564.    if (ctx->Depth.Test) {
  565.       /* fill in array of z values */
  566.       GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  567.       for (i=0;i<width;i++) {
  568.      zspan[i] = z;
  569.       }
  570.    }
  571.  
  572.    /* Determine if scaling and/or biasing is needed */
  573.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  574.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  575.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  576.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  577.       scale_or_bias = GL_TRUE;
  578.    }
  579.    else {
  580.       scale_or_bias = GL_FALSE;
  581.    }
  582.  
  583.    /* Determine if we can directly call the device driver function */
  584.    if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
  585.        && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
  586.       quick_draw = GL_TRUE;
  587.    }
  588.    else {
  589.       quick_draw = GL_FALSE;
  590.    }
  591.  
  592.    /* First check for common cases */
  593.    if (type==GL_UNSIGNED_BYTE && (format==GL_RGB || format == GL_LUMINANCE)
  594.        && !ctx->Pixel.MapColorFlag && !scale_or_bias
  595.        && ctx->Visual->EightBitColor) {
  596.       DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  597.       GLubyte *src = (GLubyte *) pixels;
  598.       /* constant alpha */
  599.       MEMSET( alpha, (GLint) ctx->Visual->AlphaScale, width );
  600.       if (format == GL_RGB) {
  601.      /* 8-bit RGB pixels */
  602.      DEFARRAY( GLubyte, red, MAX_WIDTH );
  603.      DEFARRAY( GLubyte, green, MAX_WIDTH );
  604.      DEFARRAY( GLubyte, blue, MAX_WIDTH );
  605.      for (i=0;i<height;i++,y++) {
  606.         for (j=0;j<width;j++) {
  607.            red[j]   = *src++;
  608.            green[j] = *src++;
  609.            blue[j]  = *src++;
  610.         }
  611.         if (quick_draw) {
  612.            (*ctx->Driver.WriteColorSpan)( ctx, width, x, y,
  613.                           red, green, blue, alpha, NULL);
  614.         }
  615.         else if (zoom) {
  616.            gl_write_zoomed_color_span( ctx, (GLuint) width, x, y, zspan,
  617.                        red, green, blue, alpha, desty );
  618.         }
  619.         else {
  620.            gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  621.                     red, green, blue, alpha, GL_BITMAP );
  622.         }
  623.      }
  624.      UNDEFARRAY( red );
  625.      UNDEFARRAY( green );
  626.      UNDEFARRAY( blue );
  627.       }
  628.       else {
  629.      /* 8-bit Luminance pixels */
  630.      GLubyte *lum = (GLubyte *) pixels;
  631.      for (i=0;i<height;i++,y++,lum+=width) {
  632.         if (quick_draw) {
  633.            (*ctx->Driver.WriteColorSpan)( ctx, width, x,y,
  634.                           lum, lum, lum, alpha, NULL);
  635.         }
  636.         else if (zoom) {
  637.            gl_write_zoomed_color_span( ctx, (GLuint) width, x, y, zspan,
  638.                        lum, lum, lum, alpha, desty );
  639.         }
  640.         else {
  641.            gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  642.                     lum, lum, lum, alpha, GL_BITMAP );
  643.         }
  644.      }
  645.       }
  646.       UNDEFARRAY( alpha );
  647.    }
  648.    else {
  649.       /* General solution */
  650.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  651.       GLuint components;
  652.  
  653.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  654.       switch (format) {
  655.      case GL_RED:
  656.         r_flag = GL_TRUE;
  657.         components = 1;
  658.         break;
  659.      case GL_GREEN:
  660.         g_flag = GL_TRUE;
  661.         components = 1;
  662.         break;
  663.      case GL_BLUE:
  664.         b_flag = GL_TRUE;
  665.         components = 1;
  666.         break;
  667.      case GL_ALPHA:
  668.         a_flag = GL_TRUE;
  669.         components = 1;
  670.         break;
  671.      case GL_RGB:
  672.         r_flag = g_flag = b_flag = GL_TRUE;
  673.         components = 3;
  674.         break;
  675.      case GL_LUMINANCE:
  676.         l_flag = GL_TRUE;
  677.         components = 1;
  678.         break;
  679.      case GL_LUMINANCE_ALPHA:
  680.         l_flag = a_flag = GL_TRUE;
  681.         components = 2;
  682.         break;
  683.      case GL_RGBA:
  684.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  685.         components = 4;
  686.         break;
  687.      default:
  688.         gl_problem(ctx, "Bad type in draw_color_pixels");
  689.         return;
  690.       }
  691.  
  692.       /* process the image row by row */
  693.       for (i=0;i<height;i++,y++) {
  694.  
  695.      /* convert to floats */
  696.      switch (type) {
  697.         case GL_UNSIGNED_BYTE:
  698.            {
  699.           GLubyte *src = (GLubyte *) pixels + i * width * components;
  700.           for (j=0;j<width;j++) {
  701.              if (l_flag) {
  702.             g_rf[j] = g_gf[j] = g_bf[j] = UBYTE_TO_FLOAT(*src++);
  703.              }
  704.              else {
  705.             g_rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  706.             g_gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  707.             g_bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  708.              }
  709.              g_af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  710.           }
  711.            }
  712.            break;
  713.         case GL_BYTE:
  714.            {
  715.           GLbyte *src = (GLbyte *) pixels + i * width * components;
  716.           for (j=0;j<width;j++) {
  717.              if (l_flag) {
  718.             g_rf[j] = g_gf[j] = g_bf[j] = BYTE_TO_FLOAT(*src++);
  719.              }
  720.              else {
  721.             g_rf[j] = r_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  722.             g_gf[j] = g_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  723.             g_bf[j] = b_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  724.              }
  725.              g_af[j] = a_flag ? BYTE_TO_FLOAT(*src++) : 1.0;
  726.           }
  727.            }
  728.            break;
  729.         case GL_BITMAP:
  730.            /* special case */
  731.            break;
  732.         case GL_UNSIGNED_SHORT:
  733.            {
  734.           GLushort *src = (GLushort *) pixels + i * width * components;
  735.           for (j=0;j<width;j++) {
  736.              if (l_flag) {
  737.             g_rf[j] = g_gf[j] = g_bf[j] = USHORT_TO_FLOAT(*src++);
  738.              }
  739.              else {
  740.             g_rf[j] = r_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  741.             g_gf[j] = g_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  742.             g_bf[j] = b_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  743.              }
  744.              g_af[j] = a_flag ? USHORT_TO_FLOAT(*src++) : 1.0;
  745.           }
  746.            }
  747.            break;
  748.         case GL_SHORT:
  749.            {
  750.           GLshort *src = (GLshort *) pixels + i * width * components;
  751.           for (j=0;j<width;j++) {
  752.              if (l_flag) {
  753.             g_rf[j] = g_gf[j] = g_bf[j] = SHORT_TO_FLOAT(*src++);
  754.              }
  755.              else {
  756.             g_rf[j] = r_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  757.             g_gf[j] = g_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  758.             g_bf[j] = b_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  759.              }
  760.              g_af[j] = a_flag ? SHORT_TO_FLOAT(*src++) : 1.0;
  761.           }
  762.            }
  763.            break;
  764.         case GL_UNSIGNED_INT:
  765.            {
  766.           GLuint *src = (GLuint *) pixels + i * width * components;
  767.           for (j=0;j<width;j++) {
  768.              if (l_flag) {
  769.             g_rf[j] = g_gf[j] = g_bf[j] = UINT_TO_FLOAT(*src++);
  770.              }
  771.              else {
  772.             g_rf[j] = r_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  773.             g_gf[j] = g_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  774.             g_bf[j] = b_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  775.              }
  776.              g_af[j] = a_flag ? g_af[j] = UINT_TO_FLOAT(*src++) : 1.0;
  777.           }
  778.            }
  779.            break;
  780.         case GL_INT:
  781.            {
  782.           GLint *src = (GLint *) pixels + i * width * components;
  783.           for (j=0;j<width;j++) {
  784.              if (l_flag) {
  785.             g_rf[j] = g_gf[j] = g_bf[j] = INT_TO_FLOAT(*src++);
  786.              }
  787.              else {
  788.             g_rf[j] = r_flag ? INT_TO_FLOAT(*src++) : 0.0;
  789.             g_gf[j] = g_flag ? INT_TO_FLOAT(*src++) : 0.0;
  790.             g_bf[j] = b_flag ? INT_TO_FLOAT(*src++) : 0.0;
  791.              }
  792.              g_af[j] = a_flag ? INT_TO_FLOAT(*src++) : 1.0;
  793.           }
  794.            }
  795.            break;
  796.         case GL_FLOAT:
  797.            {
  798.           GLfloat *src = (GLfloat *) pixels + i * width * components;
  799.           for (j=0;j<width;j++) {
  800.              if (l_flag) {
  801.             g_rf[j] = g_gf[j] = g_bf[j] = *src++;
  802.              }
  803.              else {
  804.             g_rf[j] = r_flag ? *src++ : 0.0;
  805.             g_gf[j] = g_flag ? *src++ : 0.0;
  806.             g_bf[j] = b_flag ? *src++ : 0.0;
  807.              }
  808.              g_af[j] = a_flag ? *src++ : 1.0;
  809.           }
  810.            }
  811.            break;
  812.         default:
  813.            gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  814.            return;
  815.      }
  816.  
  817.      /* apply scale and bias */
  818.      if (scale_or_bias) {
  819.         for (j=0;j<width;j++) {
  820.            GLfloat r, g, b, a;
  821.            r = g_rf[j] * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  822.            g = g_gf[j] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  823.            b = g_bf[j] * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  824.            a = g_af[j] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  825.            g_rf[j] = CLAMP( r, 0.0, 1.0 );
  826.            g_gf[j] = CLAMP( g, 0.0, 1.0 );
  827.            g_bf[j] = CLAMP( b, 0.0, 1.0 );
  828.            g_af[j] = CLAMP( a, 0.0, 1.0 );
  829.         }
  830.      }
  831.  
  832.      /* apply pixel mappings */
  833.      if (ctx->Pixel.MapColorFlag) {
  834.         GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
  835.         GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
  836.         GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
  837.         GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
  838.         for (j=0;j<width;j++) {
  839.            g_rf[j] = ctx->Pixel.MapRtoR[ (GLint) (g_rf[j] * rscale) ];
  840.            g_gf[j] = ctx->Pixel.MapGtoG[ (GLint) (g_gf[j] * gscale) ];
  841.            g_bf[j] = ctx->Pixel.MapBtoB[ (GLint) (g_bf[j] * bscale) ];
  842.            g_af[j] = ctx->Pixel.MapAtoA[ (GLint) (g_af[j] * ascale) ];
  843.         }
  844.      }
  845.  
  846.      /* convert to integers */
  847.      for (j=0;j<width;j++) {
  848.         g_red[j]   = (GLint) (g_rf[j] * ctx->Visual->RedScale);
  849.         g_green[j] = (GLint) (g_gf[j] * ctx->Visual->GreenScale);
  850.         g_blue[j]  = (GLint) (g_bf[j] * ctx->Visual->BlueScale);
  851.         g_alpha[j] = (GLint) (g_af[j] * ctx->Visual->AlphaScale);
  852.      }
  853.  
  854.      /* write to frame buffer */
  855.      if (quick_draw) {
  856.         (*ctx->Driver.WriteColorSpan)( ctx, width, x, y,
  857.                        g_red, g_green, g_blue, g_alpha, NULL);
  858.      }
  859.      else if (zoom) {
  860.         gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  861.                     g_red, g_green, g_blue, g_alpha, desty );
  862.      }
  863.      else {
  864.         gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  865.                  g_red, g_green, g_blue, g_alpha, GL_BITMAP );
  866.      }
  867.       }
  868.    }
  869.  
  870. }
  871.  
  872. #else
  873.  
  874. static void draw_color_pixels( GLcontext* ctx,
  875.                    GLsizei width, GLsizei height, GLenum format,
  876.                    GLenum type, const GLvoid *pixels )
  877. {
  878.    GLuint i, j;
  879.    GLint x, y, desty;
  880.    GLdepth zspan[MAX_WIDTH];
  881.    GLboolean scale_or_bias, quick_draw;
  882.    GLboolean zoom;
  883.  
  884.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  885.  
  886.    /* Position, depth of pixels */
  887.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  888.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  889.    desty = y;
  890.    if (ctx->Depth.Test) {
  891.       /* fill in array of z values */
  892.       GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  893.       for (i=0;i<width;i++) {
  894.      zspan[i] = z;
  895.       }
  896.    }
  897.  
  898.    /* Determine if scaling and/or biasing is needed */
  899.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  900.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  901.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  902.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  903.       scale_or_bias = GL_TRUE;
  904.    }
  905.    else {
  906.       scale_or_bias = GL_FALSE;
  907.    }
  908.  
  909.    /* Determine if we can directly call the device driver function */
  910.    if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
  911.        && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
  912.       quick_draw = GL_TRUE;
  913.    }
  914.    else {
  915.       quick_draw = GL_FALSE;
  916.    }
  917.  
  918.    /* First check for common cases */
  919.    if (type==GL_UNSIGNED_BYTE && (format==GL_RGB || format == GL_LUMINANCE)
  920.        && !ctx->Pixel.MapColorFlag && !scale_or_bias
  921.        && ctx->Visual->EightBitColor) {
  922.       DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  923.       GLubyte *src = (GLubyte *) pixels;
  924.       /* constant alpha */
  925.       MEMSET( alpha, (GLint) ctx->Visual->AlphaScale, width );
  926.       if (format == GL_RGB) {
  927.      /* 8-bit RGB pixels */
  928.      DEFARRAY( GLubyte, red, MAX_WIDTH );
  929.      DEFARRAY( GLubyte, green, MAX_WIDTH );
  930.      DEFARRAY( GLubyte, blue, MAX_WIDTH );
  931.      for (i=0;i<height;i++,y++) {
  932.         for (j=0;j<width;j++) {
  933.            red[j]   = *src++;
  934.            green[j] = *src++;
  935.            blue[j]  = *src++;
  936.         }
  937.         if (quick_draw) {
  938.            (*ctx->Driver.WriteColorSpan)( ctx, width, x, y,
  939.                           red, green, blue, alpha, NULL);
  940.         }
  941.         else if (zoom) {
  942.            gl_write_zoomed_color_span( ctx, (GLuint) width, x, y, zspan,
  943.                        red, green, blue, alpha, desty );
  944.         }
  945.         else {
  946.            gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  947.                     red, green, blue, alpha, GL_BITMAP );
  948.         }
  949.      }
  950.      UNDEFARRAY( red );
  951.      UNDEFARRAY( green );
  952.      UNDEFARRAY( blue );
  953.       }
  954.       else {
  955.      /* 8-bit Luminance pixels */
  956.      GLubyte *lum = (GLubyte *) pixels;
  957.      for (i=0;i<height;i++,y++,lum+=width) {
  958.         if (quick_draw) {
  959.            (*ctx->Driver.WriteColorSpan)( ctx, width, x,y,
  960.                           lum, lum, lum, alpha, NULL);
  961.         }
  962.         else if (zoom) {
  963.            gl_write_zoomed_color_span( ctx, (GLuint) width, x, y, zspan,
  964.                        lum, lum, lum, alpha, desty );
  965.         }
  966.         else {
  967.            gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  968.                     lum, lum, lum, alpha, GL_BITMAP );
  969.         }
  970.      }
  971.       }
  972.       UNDEFARRAY( alpha );
  973.    }
  974.    else {
  975.       /* General solution */
  976.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  977.       GLuint components;
  978.  
  979.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  980.       switch (format) {
  981.      case GL_RED:
  982.         r_flag = GL_TRUE;
  983.         components = 1;
  984.         break;
  985.      case GL_GREEN:
  986.         g_flag = GL_TRUE;
  987.         components = 1;
  988.         break;
  989.      case GL_BLUE:
  990.         b_flag = GL_TRUE;
  991.         components = 1;
  992.         break;
  993.      case GL_ALPHA:
  994.         a_flag = GL_TRUE;
  995.         components = 1;
  996.         break;
  997.      case GL_RGB:
  998.         r_flag = g_flag = b_flag = GL_TRUE;
  999.         components = 3;
  1000.         break;
  1001.      case GL_LUMINANCE:
  1002.         l_flag = GL_TRUE;
  1003.         components = 1;
  1004.         break;
  1005.      case GL_LUMINANCE_ALPHA:
  1006.         l_flag = a_flag = GL_TRUE;
  1007.         components = 2;
  1008.         break;
  1009.      case GL_RGBA:
  1010.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  1011.         components = 4;
  1012.         break;
  1013.      default:
  1014.         gl_problem(ctx, "Bad type in draw_color_pixels");
  1015.         return;
  1016.       }
  1017.  
  1018.       /* process the image row by row */
  1019.       for (i=0;i<height;i++,y++) {
  1020.      DEFARRAY(GLfloat, rf, MAX_WIDTH);
  1021.      DEFARRAY(GLfloat, gf, MAX_WIDTH);
  1022.      DEFARRAY(GLfloat, bf, MAX_WIDTH);
  1023.      DEFARRAY(GLfloat, af, MAX_WIDTH);
  1024.      DEFARRAY(GLubyte, red, MAX_WIDTH);
  1025.      DEFARRAY(GLubyte, green, MAX_WIDTH);
  1026.      DEFARRAY(GLubyte, blue, MAX_WIDTH);
  1027.      DEFARRAY(GLubyte, alpha, MAX_WIDTH);
  1028.  
  1029.      /* convert to floats */
  1030.      switch (type) {
  1031.         case GL_UNSIGNED_BYTE:
  1032.            {
  1033.           GLubyte *src = (GLubyte *) pixels + i * width * components;
  1034.           for (j=0;j<width;j++) {
  1035.              if (l_flag) {
  1036.             rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
  1037.              }
  1038.              else {
  1039.             rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  1040.             gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  1041.             bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  1042.              }
  1043.              af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  1044.           }
  1045.            }
  1046.            break;
  1047.         case GL_BYTE:
  1048.            {
  1049.           GLbyte *src = (GLbyte *) pixels + i * width * components;
  1050.           for (j=0;j<width;j++) {
  1051.              if (l_flag) {
  1052.             rf[j] = gf[j] = bf[j] = BYTE_TO_FLOAT(*src++);
  1053.              }
  1054.              else {
  1055.             rf[j] = r_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  1056.             gf[j] = g_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  1057.             bf[j] = b_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  1058.              }
  1059.              af[j] = a_flag ? BYTE_TO_FLOAT(*src++) : 1.0;
  1060.           }
  1061.            }
  1062.            break;
  1063.         case GL_BITMAP:
  1064.            /* special case */
  1065.            break;
  1066.         case GL_UNSIGNED_SHORT:
  1067.            {
  1068.           GLushort *src = (GLushort *) pixels + i * width * components;
  1069.           for (j=0;j<width;j++) {
  1070.              if (l_flag) {
  1071.             rf[j] = gf[j] = bf[j] = USHORT_TO_FLOAT(*src++);
  1072.              }
  1073.              else {
  1074.             rf[j] = r_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  1075.             gf[j] = g_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  1076.             bf[j] = b_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  1077.              }
  1078.              af[j] = a_flag ? USHORT_TO_FLOAT(*src++) : 1.0;
  1079.           }
  1080.            }
  1081.            break;
  1082.         case GL_SHORT:
  1083.            {
  1084.           GLshort *src = (GLshort *) pixels + i * width * components;
  1085.           for (j=0;j<width;j++) {
  1086.              if (l_flag) {
  1087.             rf[j] = gf[j] = bf[j] = SHORT_TO_FLOAT(*src++);
  1088.              }
  1089.              else {
  1090.             rf[j] = r_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  1091.             gf[j] = g_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  1092.             bf[j] = b_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  1093.              }
  1094.              af[j] = a_flag ? SHORT_TO_FLOAT(*src++) : 1.0;
  1095.           }
  1096.            }
  1097.            break;
  1098.         case GL_UNSIGNED_INT:
  1099.            {
  1100.           GLuint *src = (GLuint *) pixels + i * width * components;
  1101.           for (j=0;j<width;j++) {
  1102.              if (l_flag) {
  1103.             rf[j] = gf[j] = bf[j] = UINT_TO_FLOAT(*src++);
  1104.              }
  1105.              else {
  1106.             rf[j] = r_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  1107.             gf[j] = g_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  1108.             bf[j] = b_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  1109.              }
  1110.              af[j] = a_flag ? af[j] = UINT_TO_FLOAT(*src++) : 1.0;
  1111.           }
  1112.            }
  1113.            break;
  1114.         case GL_INT:
  1115.            {
  1116.           GLint *src = (GLint *) pixels + i * width * components;
  1117.           for (j=0;j<width;j++) {
  1118.              if (l_flag) {
  1119.             rf[j] = gf[j] = bf[j] = INT_TO_FLOAT(*src++);
  1120.              }
  1121.              else {
  1122.             rf[j] = r_flag ? INT_TO_FLOAT(*src++) : 0.0;
  1123.             gf[j] = g_flag ? INT_TO_FLOAT(*src++) : 0.0;
  1124.             bf[j] = b_flag ? INT_TO_FLOAT(*src++) : 0.0;
  1125.              }
  1126.              af[j] = a_flag ? INT_TO_FLOAT(*src++) : 1.0;
  1127.           }
  1128.            }
  1129.            break;
  1130.         case GL_FLOAT:
  1131.            {
  1132.           GLfloat *src = (GLfloat *) pixels + i * width * components;
  1133.           for (j=0;j<width;j++) {
  1134.              if (l_flag) {
  1135.             rf[j] = gf[j] = bf[j] = *src++;
  1136.              }
  1137.              else {
  1138.             rf[j] = r_flag ? *src++ : 0.0;
  1139.             gf[j] = g_flag ? *src++ : 0.0;
  1140.             bf[j] = b_flag ? *src++ : 0.0;
  1141.              }
  1142.              af[j] = a_flag ? *src++ : 1.0;
  1143.           }
  1144.            }
  1145.            break;
  1146.         default:
  1147.            gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  1148.            return;
  1149.      }
  1150.  
  1151.      /* apply scale and bias */
  1152.      if (scale_or_bias) {
  1153.         for (j=0;j<width;j++) {
  1154.            GLfloat r, g, b, a;
  1155.            r = rf[j] * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  1156.            g = gf[j] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  1157.            b = bf[j] * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  1158.            a = af[j] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  1159.            rf[j] = CLAMP( r, 0.0, 1.0 );
  1160.            gf[j] = CLAMP( g, 0.0, 1.0 );
  1161.            bf[j] = CLAMP( b, 0.0, 1.0 );
  1162.            af[j] = CLAMP( a, 0.0, 1.0 );
  1163.         }
  1164.      }
  1165.  
  1166.      /* apply pixel mappings */
  1167.      if (ctx->Pixel.MapColorFlag) {
  1168.         GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
  1169.         GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
  1170.         GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
  1171.         GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
  1172.         for (j=0;j<width;j++) {
  1173.            rf[j] = ctx->Pixel.MapRtoR[ (GLint) (rf[j] * rscale) ];
  1174.            gf[j] = ctx->Pixel.MapGtoG[ (GLint) (gf[j] * gscale) ];
  1175.            bf[j] = ctx->Pixel.MapBtoB[ (GLint) (bf[j] * bscale) ];
  1176.            af[j] = ctx->Pixel.MapAtoA[ (GLint) (af[j] * ascale) ];
  1177.         }
  1178.      }
  1179.  
  1180.      /* convert to integers */
  1181.      for (j=0;j<width;j++) {
  1182.         red[j]   = (GLint) (rf[j] * ctx->Visual->RedScale);
  1183.         green[j] = (GLint) (gf[j] * ctx->Visual->GreenScale);
  1184.         blue[j]  = (GLint) (bf[j] * ctx->Visual->BlueScale);
  1185.         alpha[j] = (GLint) (af[j] * ctx->Visual->AlphaScale);
  1186.      }
  1187.  
  1188.      /* write to frame buffer */
  1189.      if (quick_draw) {
  1190.         (*ctx->Driver.WriteColorSpan)( ctx, width, x, y,
  1191.                        red, green, blue, alpha, NULL);
  1192.      }
  1193.      else if (zoom) {
  1194.         gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  1195.                     red, green, blue, alpha, desty );
  1196.      }
  1197.      else {
  1198.         gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  1199.                  red, green, blue, alpha, GL_BITMAP );
  1200.      }
  1201.  
  1202.      UNDEFARRAY(rf);
  1203.      UNDEFARRAY(gf);
  1204.      UNDEFARRAY(bf);
  1205.      UNDEFARRAY(af);
  1206.      UNDEFARRAY(red);
  1207.      UNDEFARRAY(green);
  1208.      UNDEFARRAY(blue);
  1209.      UNDEFARRAY(alpha);
  1210.       }
  1211.    }
  1212.  
  1213. }
  1214.  
  1215. #endif
  1216.  
  1217. /*
  1218.  * Do a glDrawPixels( w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels ) optimized
  1219.  * for the case of no pixel mapping, no scale, no bias, no zoom, default
  1220.  * storage mode, no raster ops, and no pixel clipping.
  1221.  * Return:  GL_TRUE if success
  1222.  *          GL_FALSE if conditions weren't met for optimized drawing
  1223.  */
  1224. static GLboolean quickdraw_rgb( GLcontext* ctx, GLsizei width, GLsizei height,
  1225.                 const void *pixels )
  1226. {
  1227.    DEFARRAY( GLubyte, red, MAX_WIDTH );
  1228.    DEFARRAY( GLubyte, green, MAX_WIDTH );
  1229.    DEFARRAY( GLubyte, blue, MAX_WIDTH );
  1230.    DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  1231.    GLint i, j;
  1232.    GLint x, y;
  1233.    GLint bytes_per_row;
  1234.    GLboolean result;
  1235.  
  1236.    bytes_per_row = width * 3 + (width % ctx->Unpack.Alignment);
  1237.  
  1238.    if (!ctx->Current.RasterPosValid) {
  1239.       /* This is success, actually. */
  1240.       result = GL_TRUE;
  1241.    }
  1242.    else {
  1243.       x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  1244.       y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  1245.  
  1246.       if (x<0 || y<0
  1247.       || x+width>ctx->Buffer->Width || y+height>ctx->Buffer->Height) {
  1248.      result = GL_FALSE;  /* can't handle this situation */
  1249.       }
  1250.       else {
  1251.      /* constant alpha */
  1252.      for (j=0;j<width;j++) {
  1253.         alpha[j] = (GLint) ctx->Visual->AlphaScale;
  1254.      }
  1255.  
  1256.      /* write directly to device driver */
  1257.      for (i=0;i<height;i++) {
  1258.         /* each row of pixel data starts at 4-byte boundary */
  1259.         GLubyte *src = (GLubyte *) pixels + i * bytes_per_row;
  1260.         for (j=0;j<width;j++) {
  1261.            red[j]   = *src++;
  1262.            green[j] = *src++;
  1263.            blue[j]  = *src++;
  1264.         }
  1265.         (*ctx->Driver.WriteColorSpan)( ctx, width, x, y+i,
  1266.                        red, green, blue, alpha, NULL);
  1267.      }
  1268.      result = GL_TRUE;
  1269.       }
  1270.    }
  1271.  
  1272.    UNDEFARRAY( red );
  1273.    UNDEFARRAY( green );
  1274.    UNDEFARRAY( blue );
  1275.    UNDEFARRAY( alpha );
  1276.  
  1277.    return result;
  1278. }
  1279.  
  1280.  
  1281.  
  1282. /*
  1283.  * Implements general glDrawPixels operation.
  1284.  */
  1285. static void drawpixels( GLcontext* ctx, GLsizei width, GLsizei height,
  1286.             GLenum format, GLenum type, const GLvoid *pixels )
  1287. {
  1288.    if (INSIDE_BEGIN_END(ctx)) {
  1289.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels" );
  1290.       return;
  1291.    }
  1292.  
  1293.    if (ctx->RenderMode==GL_RENDER) {
  1294.       if (!ctx->Current.RasterPosValid) {
  1295.      return;
  1296.       }
  1297.       switch (format) {
  1298.      case GL_COLOR_INDEX:
  1299.         draw_index_pixels( ctx, width, height, type, pixels );
  1300.         break;
  1301.      case GL_STENCIL_INDEX:
  1302.         draw_stencil_pixels( ctx, width, height, type, pixels );
  1303.         break;
  1304.      case GL_DEPTH_COMPONENT:
  1305.         draw_depth_pixels( ctx, width, height, type, pixels );
  1306.         break;
  1307.      case GL_RED:
  1308.      case GL_GREEN:
  1309.      case GL_BLUE:
  1310.      case GL_ALPHA:
  1311.      case GL_RGB:
  1312.      case GL_LUMINANCE:
  1313.      case GL_LUMINANCE_ALPHA:
  1314.      case GL_RGBA:
  1315.         draw_color_pixels( ctx, width, height, format, type, pixels );
  1316.         break;
  1317.      default:
  1318.         gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  1319.       }
  1320.    }
  1321.    else if (ctx->RenderMode==GL_FEEDBACK) {
  1322.       if (ctx->Current.RasterPosValid) {
  1323.      GLfloat color[4], texcoord[4], invq;
  1324.      color[0] = ctx->Current.ByteColor[0] * ctx->Visual->InvRedScale;
  1325.      color[1] = ctx->Current.ByteColor[1] * ctx->Visual->InvGreenScale;
  1326.      color[2] = ctx->Current.ByteColor[2] * ctx->Visual->InvBlueScale;
  1327.      color[3] = ctx->Current.ByteColor[3] * ctx->Visual->InvAlphaScale;
  1328.      invq = 1.0F / ctx->Current.TexCoord[3];
  1329.      texcoord[0] = ctx->Current.TexCoord[0] * invq;
  1330.      texcoord[1] = ctx->Current.TexCoord[1] * invq;
  1331.      texcoord[2] = ctx->Current.TexCoord[2] * invq;
  1332.      texcoord[3] = ctx->Current.TexCoord[3];
  1333.      FEEDBACK_TOKEN( ctx, BOOL_TO_FLOAT(GL_DRAW_PIXEL_TOKEN) );
  1334.      gl_feedback_vertex( ctx, ctx->Current.RasterPos[0],
  1335.                  ctx->Current.RasterPos[1],
  1336.                  ctx->Current.RasterPos[2],
  1337.                  ctx->Current.RasterPos[3],
  1338.                  color, ctx->Current.Index, texcoord );
  1339.       }
  1340.    }
  1341.    else if (ctx->RenderMode==GL_SELECT) {
  1342.       if (ctx->Current.RasterPosValid) {
  1343.      gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
  1344.       }
  1345.    }
  1346. }
  1347.  
  1348.  
  1349.  
  1350. /*
  1351.  * Compile OR Execute a glDrawPixels!
  1352.  */
  1353. void gl_DrawPixels( GLcontext* ctx, GLsizei width, GLsizei height,
  1354.             GLenum format, GLenum type, const GLvoid *pixels )
  1355. {
  1356.    GLvoid *image;
  1357.  
  1358.    if (width<0 || height<0) {
  1359.       gl_error( ctx, GL_INVALID_VALUE, "glDrawPixels" );
  1360.       return;
  1361.    }
  1362.  
  1363.    if (ctx->NewState) {
  1364.       gl_update_state(ctx);
  1365.    }
  1366.  
  1367.    /* Let the device driver take a crack at glDrawPixels */
  1368.    if (!ctx->CompileFlag && ctx->Driver.DrawPixels) {
  1369.       GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  1370.       GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  1371.       if ((*ctx->Driver.DrawPixels)( ctx, x, y, width, height,
  1372.                       format, type, GL_FALSE, pixels )) {
  1373.      /* Device driver did the job */
  1374.      return;
  1375.       }
  1376.    }
  1377.  
  1378.    if (format==GL_RGB && type==GL_UNSIGNED_BYTE && ctx->FastDrawPixels
  1379.        && !ctx->CompileFlag && ctx->RenderMode==GL_RENDER
  1380.        && ctx->RasterMask==0 && ctx->CallDepth==0) {
  1381.       /* optimized path */
  1382.       if (quickdraw_rgb( ctx, width, height, pixels )) {
  1383.      /* success */
  1384.      return;
  1385.       }
  1386.    }
  1387.  
  1388.    /* take the general path */
  1389.  
  1390.    /* THIS IS A REAL HACK - FIX IN MESA 2.5
  1391.     * If we're inside glCallList then we don't have to unpack the pixels again.
  1392.     */
  1393.    if (ctx->CallDepth == 0) {
  1394.       image = gl_unpack_pixels( ctx, width, height, format, type, pixels );
  1395.       if (!image) {
  1396.      gl_error( ctx, GL_OUT_OF_MEMORY, "glDrawPixels" );
  1397.      return;
  1398.       }
  1399.    }
  1400.    else {
  1401.       image = (GLvoid *) pixels;
  1402.    }
  1403.  
  1404.    if (ctx->CompileFlag) {
  1405.       gl_save_DrawPixels( ctx, width, height, format, type, image );
  1406.    }
  1407.    if (ctx->ExecuteFlag) {
  1408.       drawpixels( ctx, width, height, format, type, image );
  1409.       if (!ctx->CompileFlag) {
  1410.      /* may discard unpacked image now */
  1411.      if (image!=pixels)
  1412.         free( image );
  1413.       }
  1414.    }
  1415. }
  1416.