home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / drawpix.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  30KB  |  957 lines

  1. /* $Id: drawpix.c,v 1.5.2.1 1999/11/26 16:28:03 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28.  
  29.  
  30.  
  31. #ifdef PC_HEADER
  32. #include "all.h"
  33. #else
  34. #ifndef XFree86Server
  35. #include <assert.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #else
  39. #include "GL/xf86glx.h"
  40. #endif
  41. #include "context.h"
  42. #include "drawpix.h"
  43. #include "feedback.h"
  44. #include "image.h"
  45. #include "macros.h"
  46. #include "mmath.h"
  47. #include "pixel.h"
  48. #include "span.h"
  49. #include "stencil.h"
  50. #include "types.h"
  51. #include "zoom.h"
  52. #endif
  53.  
  54.  
  55.  
  56. /* TODO:  apply texture mapping to fragments */
  57.  
  58.  
  59. /*
  60.  * Try to do a fast glDrawPixels.  Conditions include:
  61.  *   not using a display list
  62.  *   simple pixel unpacking
  63.  *   no raster ops
  64.  *   etc....
  65.  * Return:  GL_TRUE if success, GL_FALSE if slow path must be used instead
  66.  */
  67. GLboolean gl_direct_DrawPixels( GLcontext *ctx,
  68.                                 const struct gl_pixelstore_attrib *unpack,
  69.                                 GLsizei width, GLsizei height,
  70.                                 GLenum format, GLenum type,
  71.                                 const GLvoid *pixels )
  72. {
  73.    GLubyte rgb[MAX_WIDTH][3];
  74.    GLubyte rgba[MAX_WIDTH][4];
  75.  
  76.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels", 
  77.                           GL_FALSE);
  78.  
  79.  
  80.    if (!ctx->Current.RasterPosValid) {
  81.       /* no-op */
  82.       return GL_TRUE;
  83.    }
  84.  
  85.    if (ctx->NewState) {
  86.       gl_update_state(ctx);
  87.    }
  88.  
  89.    /* see if device driver can do the drawpix */
  90.    if (ctx->Driver.DrawPixels) {
  91.       GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  92.       GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  93.       if ((*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
  94.                                     unpack, pixels))
  95.          return GL_TRUE;
  96.    }
  97.  
  98.    if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
  99.        && ctx->Pixel.RedBias==0.0 && ctx->Pixel.RedScale==1.0
  100.        && ctx->Pixel.GreenBias==0.0 && ctx->Pixel.GreenScale==1.0
  101.        && ctx->Pixel.BlueBias==0.0 && ctx->Pixel.BlueScale==1.0
  102.        && ctx->Pixel.AlphaBias==0.0 && ctx->Pixel.AlphaScale==1.0
  103.        && ctx->Pixel.IndexShift==0 && ctx->Pixel.IndexOffset==0
  104.        && ctx->Pixel.MapColorFlag==0
  105.        && unpack->Alignment==1
  106.        && !unpack->SwapBytes
  107.        && !unpack->LsbFirst) {
  108.  
  109.       GLint destX = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  110.       GLint destY = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  111.       GLint drawWidth = width;           /* actual width drawn */
  112.       GLint drawHeight = height;         /* actual height drawn */
  113.       GLint skipPixels = unpack->SkipPixels;
  114.       GLint skipRows = unpack->SkipRows;
  115.       GLint rowLength;
  116.       GLdepth zSpan[MAX_WIDTH];  /* only used when zooming */
  117.       GLint zoomY0;
  118.  
  119.       if (unpack->RowLength > 0)
  120.          rowLength = unpack->RowLength;
  121.       else
  122.          rowLength = width;
  123.  
  124.       /* If we're not using pixel zoom then do all clipping calculations
  125.        * now.  Otherwise, we'll let the gl_write_zoomed_*_span() functions
  126.        * handle the clipping.
  127.        */
  128.       if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  129.          /* horizontal clipping */
  130.          if (destX < ctx->Buffer->Xmin) {
  131.             skipPixels += (ctx->Buffer->Xmin - destX);
  132.             drawWidth  -= (ctx->Buffer->Xmin - destX);
  133.             destX = ctx->Buffer->Xmin;
  134.          }
  135.          if (destX + drawWidth > ctx->Buffer->Xmax)
  136.             drawWidth -= (destX + drawWidth - ctx->Buffer->Xmax - 1);
  137.          if (drawWidth <= 0)
  138.             return GL_TRUE;
  139.  
  140.          /* vertical clipping */
  141.          if (destY < ctx->Buffer->Ymin) {
  142.             skipRows   += (ctx->Buffer->Ymin - destY);
  143.             drawHeight -= (ctx->Buffer->Ymin - destY);
  144.             destY = ctx->Buffer->Ymin;
  145.          }
  146.          if (destY + drawHeight > ctx->Buffer->Ymax)
  147.             drawHeight -= (destY + drawHeight - ctx->Buffer->Ymax - 1);
  148.          if (drawHeight <= 0)
  149.             return GL_TRUE;
  150.       }
  151.       else {
  152.          /* setup array of fragment Z value to pass to zoom function */
  153.          GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  154.          GLint i;
  155.          assert(drawWidth < MAX_WIDTH);
  156.          for (i=0; i<drawWidth; i++)
  157.             zSpan[i] = z;
  158.  
  159.          /* save Y value of first row */
  160.          zoomY0 = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  161.       }
  162.  
  163.  
  164.       /*
  165.        * Ready to draw!
  166.        * The window region at (destX, destY) of size (drawWidth, drawHeight)
  167.        * will be written to.
  168.        * We'll take pixel data from buffer pointed to by "pixels" but we'll
  169.        * skip "skipRows" rows and skip "skipPixels" pixels/row.
  170.        */
  171.  
  172.       if (format==GL_RGBA && type==GL_UNSIGNED_BYTE) {
  173.          if (ctx->Visual->RGBAflag) {
  174.             GLubyte *src = (GLubyte *) pixels
  175.                + (skipRows * rowLength + skipPixels) * 4;
  176.             if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  177.                /* no zooming */
  178.                GLint row;
  179.                for (row=0; row<drawHeight; row++) {
  180.                   (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  181.                                                (void *) src, NULL);
  182.                   src += rowLength * 4;
  183.                   destY++;
  184.                }
  185.             }
  186.             else {
  187.                /* with zooming */
  188.                GLint row;
  189.                for (row=0; row<drawHeight; row++) {
  190.                   gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
  191.                                             zSpan, (void *) src, zoomY0);
  192.                   src += rowLength * 4;
  193.                   destY++;
  194.                }
  195.             }
  196.          }
  197.          return GL_TRUE;
  198.       }
  199.       else if (format==GL_RGB && type==GL_UNSIGNED_BYTE) {
  200.          if (ctx->Visual->RGBAflag) {
  201.             GLubyte *src = (GLubyte *) pixels
  202.                + (skipRows * rowLength + skipPixels) * 3;
  203.             if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  204.                GLint row;
  205.                for (row=0; row<drawHeight; row++) {
  206.                   (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
  207.                                               (void *) src, NULL);
  208.                   src += rowLength * 3;
  209.                   destY++;
  210.                }
  211.             }
  212.             else {
  213.                /* with zooming */
  214.                GLint row;
  215.                for (row=0; row<drawHeight; row++) {
  216.                   gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
  217.                                            zSpan, (void *) src, zoomY0);
  218.                   src += rowLength * 3;
  219.                   destY++;
  220.                }
  221.             }
  222.          }
  223.          return GL_TRUE;
  224.       }
  225.       else if (format==GL_LUMINANCE && type==GL_UNSIGNED_BYTE) {
  226.          if (ctx->Visual->RGBAflag) {
  227.             GLubyte *src = (GLubyte *) pixels
  228.                + (skipRows * rowLength + skipPixels);
  229.             if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  230.                /* no zooming */
  231.                GLint row;
  232.                assert(drawWidth < MAX_WIDTH);
  233.                for (row=0; row<drawHeight; row++) {
  234.                   GLint i;
  235.           for (i=0;i<drawWidth;i++) {
  236.                      rgb[i][0] = src[i];
  237.                      rgb[i][1] = src[i];
  238.                      rgb[i][2] = src[i];
  239.           }
  240.                   (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
  241.                                               (void *) rgb, NULL);
  242.                   src += rowLength;
  243.                   destY++;
  244.                }
  245.             }
  246.             else {
  247.                /* with zooming */
  248.                GLint row;
  249.                assert(drawWidth < MAX_WIDTH);
  250.                for (row=0; row<drawHeight; row++) {
  251.                   GLint i;
  252.           for (i=0;i<drawWidth;i++) {
  253.                      rgb[i][0] = src[i];
  254.                      rgb[i][1] = src[i];
  255.                      rgb[i][2] = src[i];
  256.           }
  257.                   gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
  258.                                            zSpan, (void *) rgb, zoomY0);
  259.                   src += rowLength;
  260.                   destY++;
  261.                }
  262.             }
  263.          }
  264.          return GL_TRUE;
  265.       }
  266.       else if (format==GL_LUMINANCE_ALPHA && type==GL_UNSIGNED_BYTE) {
  267.          if (ctx->Visual->RGBAflag) {
  268.             GLubyte *src = (GLubyte *) pixels
  269.                + (skipRows * rowLength + skipPixels)*2;
  270.             if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  271.                /* no zooming */
  272.                GLint row;
  273.                assert(drawWidth < MAX_WIDTH);
  274.                for (row=0; row<drawHeight; row++) {
  275.                   GLint i;
  276.                   GLubyte *ptr = src;
  277.           for (i=0;i<drawWidth;i++) {
  278.                      rgba[i][0] = *ptr;
  279.                      rgba[i][1] = *ptr;
  280.                      rgba[i][2] = *ptr++;
  281.                      rgba[i][3] = *ptr++;
  282.           }
  283.                   (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  284.                                                (void *) rgba, NULL);
  285.                   src += rowLength*2;
  286.                   destY++;
  287.                }
  288.             }
  289.             else {
  290.                /* with zooming */
  291.                GLint row;
  292.                assert(drawWidth < MAX_WIDTH);
  293.                for (row=0; row<drawHeight; row++) {
  294.                   GLubyte *ptr = src;
  295.                   GLint i;
  296.           for (i=0;i<drawWidth;i++) {
  297.                      rgba[i][0] = *ptr;
  298.                      rgba[i][1] = *ptr;
  299.                      rgba[i][2] = *ptr++;
  300.                      rgba[i][3] = *ptr++;
  301.           }
  302.                   gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
  303.                                             zSpan, (void *) rgba, zoomY0);
  304.                   src += rowLength*2;
  305.                   destY++;
  306.                }
  307.             }
  308.          }
  309.          return GL_TRUE;
  310.       }
  311.       else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) {
  312.          GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels;
  313.          if (ctx->Visual->RGBAflag) {
  314.             /* convert CI data to RGBA */
  315.             if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  316.                /* no zooming */
  317.                GLint row;
  318.                for (row=0; row<drawHeight; row++) {
  319.                   assert(drawWidth < MAX_WIDTH);
  320.                   gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
  321.                   (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  322.                                                (const GLubyte (*)[4])rgba, 
  323.                            NULL);
  324.                   src += rowLength;
  325.                   destY++;
  326.                }
  327.                return GL_TRUE;
  328.             }
  329.             else {
  330.                /* with zooming */
  331.                GLint row;
  332.                for (row=0; row<drawHeight; row++) {
  333.                   assert(drawWidth < MAX_WIDTH);
  334.                   gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
  335.                   gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
  336.                                             zSpan, (void *) rgba, zoomY0);
  337.                   src += rowLength;
  338.                   destY++;
  339.                }
  340.                return GL_TRUE;
  341.             }
  342.          }
  343.          else {
  344.             /* write CI data to CI frame buffer */
  345.             GLint row;
  346.             if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  347.                /* no zooming */
  348.                for (row=0; row<drawHeight; row++) {
  349.                   (*ctx->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY,
  350.                                               src, NULL);
  351.                   src += rowLength;
  352.                   destY++;
  353.                }
  354.                return GL_TRUE;
  355.             }
  356.             else {
  357.                /* with zooming */
  358.                return GL_FALSE;
  359.             }
  360.          }
  361.       }
  362.       else {
  363.          /* can't handle this pixel format and/or data type here */
  364.          return GL_FALSE;
  365.       }
  366.    }
  367.    else {
  368.       /* can't do direct render, have to use slow path */
  369.       return GL_FALSE;
  370.    }
  371. }
  372.  
  373.  
  374.  
  375. /*
  376.  * Do glDrawPixels of index pixels.
  377.  */
  378. static void draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
  379.                                const struct gl_image *image )
  380. {
  381.    GLint width, height, widthInBytes;
  382.    const GLint desty = y;
  383.    GLint i, j;
  384.    GLdepth zspan[MAX_WIDTH];
  385.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  386.  
  387.    assert(image);
  388.    assert(image->Format == GL_COLOR_INDEX);
  389.  
  390.    width = image->Width;
  391.    height = image->Height;
  392.    if (image->Type == GL_BITMAP)
  393.       widthInBytes = (width + 7) / 8;
  394.    else
  395.       widthInBytes = width;
  396.  
  397.    /* Fragment depth values */
  398.    if (ctx->Depth.Test || ctx->Fog.Enabled) {
  399.       GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  400.       for (i=0;i<width;i++) {
  401.      zspan[i] = zval;
  402.       }
  403.    }
  404.  
  405.    /* process the image row by row */
  406.    for (i=0;i<height;i++,y++) {
  407.       GLuint ispan[MAX_WIDTH];
  408.  
  409.       /* convert to uints */
  410.       switch (image->Type) {
  411.      case GL_UNSIGNED_BYTE:
  412.         {
  413.            GLubyte *src = (GLubyte *) image->Data + i * width;
  414.            for (j=0;j<width;j++) {
  415.           ispan[j] = (GLuint) *src++;
  416.            }
  417.         }
  418.         break;
  419.      case GL_FLOAT:
  420.         {
  421.            GLfloat *src = (GLfloat *) image->Data + i * width;
  422.            for (j=0;j<width;j++) {
  423.           ispan[j] = (GLuint) (GLint) *src++;
  424.            }
  425.         }
  426.         break;
  427.          case GL_BITMAP:
  428.             {
  429.            GLubyte *src = (GLubyte *) image->Data + i * widthInBytes;
  430.            for (j=0;j<width;j++) {
  431.           ispan[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
  432.            }
  433.             }
  434.             break;
  435.      default:
  436.         gl_problem( ctx, "draw_index_pixels type" );
  437.             return;
  438.       }
  439.  
  440.       /* apply shift and offset */
  441.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  442.          gl_shift_and_offset_ci( ctx, width, ispan );
  443.       }
  444.  
  445.       if (ctx->Visual->RGBAflag) {
  446.      /* Convert index to RGBA and write to frame buffer */
  447.      GLubyte rgba[MAX_WIDTH][4];
  448.          gl_map_ci_to_rgba( ctx, width, ispan, rgba );
  449.          if (zoom) {
  450.             gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 
  451.                        (const GLubyte (*)[4])rgba, desty );
  452.          }
  453.          else {
  454.             gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
  455.          }
  456.       }
  457.       else {
  458.      /* optionally apply index map then write to frame buffer */
  459.      if (ctx->Pixel.MapColorFlag) {
  460.             gl_map_ci(ctx, width, ispan);
  461.      }
  462.          if (zoom) {
  463.             gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty );
  464.          }
  465.          else {
  466.             gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  467.          }
  468.       }
  469.    }
  470.  
  471. }
  472.  
  473.  
  474.  
  475. /*
  476.  * Do glDrawPixels of stencil image.  The image datatype may either
  477.  * be GLubyte or GLbitmap.
  478.  */
  479. static void draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
  480.                                  const struct gl_image *image )
  481. {
  482.    GLint widthInBytes, width, height;
  483.    const GLint desty = y;
  484.    GLint i;
  485.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  486.  
  487.    if (image->Type != GL_BYTE &&
  488.        image->Type != GL_UNSIGNED_BYTE &&
  489.        image->Type != GL_SHORT &&
  490.        image->Type != GL_UNSIGNED_SHORT &&
  491.        image->Type != GL_INT &&
  492.        image->Type != GL_UNSIGNED_INT &&
  493.        image->Type != GL_FLOAT &&
  494.        image->Type != GL_BITMAP) {
  495.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels(stencil type)");
  496.       return;
  497.    }
  498.  
  499.    assert(image);
  500.    assert(image->Format == GL_STENCIL_INDEX);
  501.    assert(image->Type == GL_UNSIGNED_BYTE || image->Type == GL_BITMAP);
  502.  
  503.    if (image->Type == GL_UNSIGNED_BYTE)
  504.       widthInBytes = image->Width;
  505.    else
  506.       widthInBytes = (image->Width + 7) / 8;
  507.    width = image->Width;
  508.    height = image->Height;
  509.  
  510.    /* process the image row by row */
  511.    for (i=0;i<height;i++,y++) {
  512.       GLstencil *src = (GLstencil*)image->Data + i * widthInBytes;
  513.       GLstencil *stencilValues;
  514.       GLstencil stencilCopy[MAX_WIDTH];
  515.  
  516.       if (image->Type == GL_BITMAP) {
  517.          /* convert bitmap data to GLubyte (0 or 1) data */
  518.          GLint j;
  519.          for (j = 0; j < width; j++) {
  520.             stencilCopy[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
  521.          }
  522.          src = stencilCopy;
  523.       }
  524.  
  525.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift
  526.           || ctx->Pixel.MapStencilFlag) {
  527.  
  528.          /* make copy of stencil values */
  529.          if (src != stencilCopy)
  530.             MEMCPY( stencilCopy, src, width * sizeof(GLstencil));
  531.  
  532.          /* apply shift and offset */
  533.          if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  534.             gl_shift_and_offset_stencil( ctx, width, stencilCopy );
  535.          }
  536.  
  537.          /* mapping */
  538.          if (ctx->Pixel.MapStencilFlag) {
  539.             gl_map_stencil( ctx, width, stencilCopy );
  540.          }
  541.  
  542.          stencilValues = stencilCopy;
  543.       }
  544.       else {
  545.          /* use stencil values in-place */
  546.          stencilValues = src;
  547.       }
  548.  
  549.       /* write stencil values to stencil buffer */
  550.       if (zoom) {
  551.          gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y,
  552.                                        stencilValues, desty );
  553.       }
  554.       else {
  555.          gl_write_stencil_span( ctx, (GLuint) width, x, y, stencilValues );
  556.       }
  557.    }
  558. }
  559.  
  560.  
  561.  
  562. /*
  563.  * Do a glDrawPixels of depth values.
  564.  */
  565. static void draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
  566.                                const struct gl_image *image )
  567. {
  568.    GLint width, height;
  569.    const GLint desty = y;
  570.    GLubyte rgba[MAX_WIDTH][4];
  571.    GLuint ispan[MAX_WIDTH];
  572.    const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  573.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  574.  
  575.    assert(image);
  576.    assert(image->Format == GL_DEPTH_COMPONENT);
  577.  
  578.    width = image->Width;
  579.    height = image->Height;
  580.  
  581.    /* Color or index */
  582.    if (ctx->Visual->RGBAflag) {
  583.       GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
  584.       GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0F);
  585.       GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0F);
  586.       GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
  587.       GLint i;
  588.       for (i=0; i<width; i++) {
  589.          rgba[i][RCOMP] = r;
  590.          rgba[i][GCOMP] = g;
  591.          rgba[i][BCOMP] = b;
  592.          rgba[i][ACOMP] = a;
  593.       }
  594.    }
  595.    else {
  596.       GLint i;
  597.       for (i=0;i<width;i++) {
  598.      ispan[i] = ctx->Current.RasterIndex;
  599.       }
  600.    }
  601.  
  602.    if (image->Type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  603.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  604.       /* Special case: directly write 16-bit depth values */
  605.       GLint j;
  606.       for (j=0;j<height;j++,y++) {
  607.          GLdepth *zptr = (GLdepth *) image->Data + j * width;
  608.          gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP );
  609.       }
  610.    }
  611.    else if (image->Type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  612.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  613.       /* Special case: directly write 32-bit depth values */
  614.       GLint i, j;
  615.       /* Compute shift value to scale 32-bit uints down to depth values. */
  616.       GLuint shift = 0;
  617.       GLuint max = MAX_DEPTH;
  618.       while ((max&0x80000000)==0) {
  619.          max = max << 1;
  620.          shift++;
  621.       }
  622.       for (j=0;j<height;j++,y++) {
  623.          GLdepth zspan[MAX_WIDTH];
  624.          GLuint *zptr = (GLuint *) image->Data + j * width;
  625.          for (i=0;i<width;i++) {
  626.             zspan[i] = zptr[i] >> shift;
  627.          }
  628.          gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
  629.       }
  630.    }
  631.    else {
  632.       /* General case (slower) */
  633.       GLint i, j;
  634.  
  635.       /* process image row by row */
  636.       for (i=0;i<height;i++,y++) {
  637.          GLfloat depth[MAX_WIDTH];
  638.          GLdepth zspan[MAX_WIDTH];
  639.  
  640.          switch (image->Type) {
  641.             case GL_UNSIGNED_SHORT:
  642.                {
  643.                   GLushort *src = (GLushort *) image->Data + i * width;
  644.                   for (j=0;j<width;j++) {
  645.                      depth[j] = USHORT_TO_FLOAT( *src++ );
  646.                   }
  647.                }
  648.                break;
  649.             case GL_UNSIGNED_INT:
  650.                {
  651.                   GLuint *src = (GLuint *) image->Data + i * width;
  652.                   for (j=0;j<width;j++) {
  653.                      depth[j] = UINT_TO_FLOAT( *src++ );
  654.                   }
  655.                }
  656.                break;
  657.             case GL_FLOAT:
  658.                {
  659.                   GLfloat *src = (GLfloat *) image->Data + i * width;
  660.                   for (j=0;j<width;j++) {
  661.                      depth[j] = *src++;
  662.                   }
  663.                }
  664.                break;
  665.             default:
  666.                gl_problem(ctx, "Bad type in draw_depth_pixels");
  667.                return;
  668.          }
  669.  
  670.          /* apply depth scale and bias */
  671.          if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) {
  672.             for (j=0;j<width;j++) {
  673.                depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  674.             }
  675.          }
  676.  
  677.          /* clamp depth values to [0,1] and convert from floats to integers */
  678.          for (j=0;j<width;j++) {
  679.             zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
  680.          }
  681.  
  682.          if (ctx->Visual->RGBAflag) {
  683.             if (zoom) {
  684.                gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
  685.                                           (const GLubyte (*)[4])rgba, desty );
  686.             }
  687.             else {
  688.                gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
  689.             }
  690.          }
  691.          else {
  692.             if (zoom) {
  693.                gl_write_zoomed_index_span( ctx, width, x, y, zspan,
  694.                                            ispan, GL_BITMAP );
  695.             }
  696.             else {
  697.                gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  698.             }
  699.          }
  700.  
  701.       }
  702.    }
  703. }
  704.  
  705.  
  706.  
  707. /* Simple unpacking parameters: */
  708. static struct gl_pixelstore_attrib NoUnpack = {
  709.    1,            /* Alignment */
  710.    0,            /* RowLength */
  711.    0,            /* SkipPixels */
  712.    0,            /* SkipRows */
  713.    0,            /* ImageHeight */
  714.    0,            /* SkipImages */
  715.    GL_FALSE,     /* SwapBytes */
  716.    GL_FALSE      /* LsbFirst */
  717. };
  718.  
  719.  
  720. /*
  721.  * Do glDrawPixels of RGBA pixels.
  722.  */
  723. static void draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
  724.                               const struct gl_image *image )
  725. {
  726.    GLint width, height;
  727.    GLint i, j;
  728.    const GLint desty = y;
  729.    GLdepth zspan[MAX_WIDTH];
  730.    GLboolean quickDraw;
  731.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  732.  
  733.    assert(image);
  734.  
  735.    /* Try an optimized glDrawPixels first */
  736.    if (gl_direct_DrawPixels(ctx, &NoUnpack, image->Width, image->Height,
  737.                             image->Format, image->Type, image->Data ))
  738.       return;
  739.  
  740.    width = image->Width;
  741.    height = image->Height;
  742.  
  743.    /* Fragment depth values */
  744.    if (ctx->Depth.Test || ctx->Fog.Enabled) {
  745.       /* fill in array of z values */
  746.       GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  747.       for (i=0;i<width;i++) {
  748.      zspan[i] = z;
  749.       }
  750.    }
  751.  
  752.    if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
  753.        && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
  754.       quickDraw = GL_TRUE;
  755.    }
  756.    else {
  757.       quickDraw = GL_FALSE;
  758.    }
  759.  
  760.    {
  761.       /* General solution */
  762.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  763.       GLuint components;
  764.       GLubyte rgba[MAX_WIDTH][4];
  765.       GLfloat  rf[MAX_WIDTH];
  766.       GLfloat  gf[MAX_WIDTH];
  767.       GLfloat  bf[MAX_WIDTH];
  768.       DEFARRAY(GLfloat,af,MAX_WIDTH);
  769.       CHECKARRAY(af,return);
  770.  
  771.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  772.       switch (image->Format) {
  773.      case GL_RED:
  774.         r_flag = GL_TRUE;
  775.         components = 1;
  776.         break;
  777.      case GL_GREEN:
  778.         g_flag = GL_TRUE;
  779.         components = 1;
  780.         break;
  781.      case GL_BLUE:
  782.         b_flag = GL_TRUE;
  783.         components = 1;
  784.         break;
  785.      case GL_ALPHA:
  786.         a_flag = GL_TRUE;
  787.         components = 1;
  788.         break;
  789.      case GL_RGB:
  790.         r_flag = g_flag = b_flag = GL_TRUE;
  791.         components = 3;
  792.         break;
  793.      case GL_LUMINANCE:
  794.         l_flag = GL_TRUE;
  795.         components = 1;
  796.         break;
  797.      case GL_LUMINANCE_ALPHA:
  798.         l_flag = a_flag = GL_TRUE;
  799.         components = 2;
  800.         break;
  801.      case GL_RGBA:
  802.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  803.         components = 4;
  804.         break;
  805.          default:
  806.             gl_problem(ctx, "Bad type in draw_rgba_pixels");
  807.             goto cleanup;
  808.       }
  809.  
  810.       /* process the image row by row */
  811.       for (i=0;i<height;i++,y++) {
  812.      /* convert to floats */
  813.      switch (image->Type) {
  814.         case GL_UNSIGNED_BYTE:
  815.            {
  816.           GLubyte *src = (GLubyte *) image->Data + i * width * components;
  817.           for (j=0;j<width;j++) {
  818.              if (l_flag) {
  819.             rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
  820.              }
  821.              else {
  822.             rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  823.             gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  824.             bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  825.              }
  826.              af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  827.           }
  828.            }
  829.            break;
  830.         case GL_FLOAT:
  831.            {
  832.           GLfloat *src = (GLfloat *) image->Data + i * width * components;
  833.           for (j=0;j<width;j++) {
  834.              if (l_flag) {
  835.             rf[j] = gf[j] = bf[j] = *src++;
  836.              }
  837.              else {
  838.             rf[j] = r_flag ? *src++ : 0.0;
  839.             gf[j] = g_flag ? *src++ : 0.0;
  840.             bf[j] = b_flag ? *src++ : 0.0;
  841.              }
  842.              af[j] = a_flag ? *src++ : 1.0;
  843.           }
  844.            }
  845.            break;
  846.         default:
  847.            gl_problem( ctx, "draw_rgba_pixels type" );
  848.                goto cleanup;
  849.      }
  850.  
  851.      /* apply scale and bias */
  852.      if (ctx->Pixel.ScaleOrBiasRGBA) {
  853.             gl_scale_and_bias_color(ctx, width, rf, gf, bf, af);
  854.      }
  855.  
  856.      /* apply pixel mappings */
  857.      if (ctx->Pixel.MapColorFlag) {
  858.             gl_map_color(ctx, width, rf, gf, bf, af);
  859.      }
  860.  
  861.      /* convert to integers */
  862.      for (j=0;j<width;j++) {
  863.         rgba[j][RCOMP] = (GLint) (rf[j] * 255.0F);
  864.         rgba[j][GCOMP] = (GLint) (gf[j] * 255.0F);
  865.         rgba[j][BCOMP] = (GLint) (bf[j] * 255.0F);
  866.         rgba[j][ACOMP] = (GLint) (af[j] * 255.0F);
  867.      }
  868.  
  869.      /* write to frame buffer */
  870.          if (quickDraw) {
  871.             (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, 
  872.                       (const GLubyte (*)[4])rgba, NULL);
  873.          }
  874.          else if (zoom) {
  875.             gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 
  876.                        (const GLubyte (*)[4])rgba, desty );
  877.          }
  878.          else {
  879.             gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, rgba, GL_BITMAP);
  880.          }
  881.       }
  882. cleanup:
  883.       UNDEFARRAY(af);
  884.    }
  885. }
  886.  
  887.  
  888.  
  889. /*
  890.  * Execute glDrawPixels
  891.  */
  892. void gl_DrawPixels( GLcontext* ctx, struct gl_image *image )
  893. {
  894.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels");
  895.  
  896.  
  897.    if (gl_image_error_test( ctx, image, "glDrawPixels" ))
  898.       return;
  899.  
  900.    if (ctx->RenderMode==GL_RENDER) {
  901.       GLint x, y;
  902.       if (!ctx->Current.RasterPosValid) {
  903.      return;
  904.       }
  905.  
  906.       x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  907.       y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  908.  
  909.       switch (image->Format) {
  910.      case GL_COLOR_INDEX:
  911.             draw_index_pixels( ctx, x, y, image );
  912.         break;
  913.      case GL_STENCIL_INDEX:
  914.         draw_stencil_pixels( ctx, x, y, image );
  915.         break;
  916.      case GL_DEPTH_COMPONENT:
  917.         draw_depth_pixels( ctx, x, y, image );
  918.         break;
  919.      case GL_RED:
  920.      case GL_GREEN:
  921.      case GL_BLUE:
  922.      case GL_ALPHA:
  923.      case GL_RGB:
  924.      case GL_LUMINANCE:
  925.      case GL_LUMINANCE_ALPHA:
  926.      case GL_RGBA:
  927.             draw_rgba_pixels( ctx, x, y, image );
  928.         break;
  929.      default:
  930.         gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  931.             return;
  932.       }
  933.    }
  934.    else if (ctx->RenderMode==GL_FEEDBACK) {
  935.       if (ctx->Current.RasterPosValid) {
  936.          GLfloat color[4];
  937.      GLfloat texcoord[4], invq;
  938.      UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor);
  939.          invq = 1.0F / ctx->Current.Texcoord[0][3];
  940.          texcoord[0] = ctx->Current.Texcoord[0][0] * invq;
  941.          texcoord[1] = ctx->Current.Texcoord[0][1] * invq;
  942.          texcoord[2] = ctx->Current.Texcoord[0][2] * invq;
  943.          texcoord[3] = ctx->Current.Texcoord[0][3];
  944.          FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
  945.          gl_feedback_vertex( ctx,
  946.                              ctx->Current.RasterPos,
  947.                              color, ctx->Current.Index, texcoord );
  948.       }
  949.    }
  950.    else if (ctx->RenderMode==GL_SELECT) {
  951.       if (ctx->Current.RasterPosValid) {
  952.          gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
  953.       }
  954.    }
  955. }
  956.  
  957.