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

  1. /* $Id: readpix.c,v 1.5.2.1 1999/11/19 18:28:47 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 <math.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #else
  39. #include "GL/xf86glx.h"
  40. #endif
  41. #include "alphabuf.h"
  42. #include "context.h"
  43. #include "depth.h"
  44. #include "feedback.h"
  45. #include "image.h"
  46. #include "macros.h"
  47. #include "pixel.h"
  48. #include "readpix.h"
  49. #include "span.h"
  50. #include "stencil.h"
  51. #include "types.h"
  52. #endif
  53.  
  54.  
  55.  
  56.  
  57. /*
  58.  * Read a block of color index pixels.
  59.  */
  60. static void read_index_pixels( GLcontext *ctx,
  61.                                GLint x, GLint y,
  62.                    GLsizei width, GLsizei height,
  63.                    GLenum type, GLvoid *pixels,
  64.                                const struct gl_pixelstore_attrib *packing )
  65. {
  66.    GLint i, j, readWidth;
  67.  
  68.    /* error checking */
  69.    if (ctx->Visual->RGBAflag) {
  70.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  71.       return;
  72.    }
  73.  
  74.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
  75.  
  76.    readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
  77.  
  78.    /* process image row by row */
  79.    for (j=0;j<height;j++,y++) {
  80.       GLuint index[MAX_WIDTH];
  81.       GLvoid *dest;
  82.  
  83.       (*ctx->Driver.ReadCI32Span)( ctx, readWidth, x, y, index );
  84.  
  85.       if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  86.          gl_shift_and_offset_ci( ctx, readWidth, index);
  87.       }
  88.  
  89.       if (ctx->Pixel.MapColorFlag) {
  90.          gl_map_ci(ctx, readWidth, index);
  91.       }
  92.  
  93.       dest = gl_pixel_addr_in_image(packing, pixels,
  94.                          width, height, GL_COLOR_INDEX, type, 0, j, 0);
  95.  
  96.       switch (type) {
  97.      case GL_UNSIGNED_BYTE:
  98.         {
  99.                GLubyte *dst = (GLubyte *) dest;
  100.            for (i=0;i<readWidth;i++) {
  101.           *dst++ = (GLubyte) index[i];
  102.            }
  103.         }
  104.         break;
  105.      case GL_BYTE:
  106.         {
  107.                GLbyte *dst = (GLbyte *) dest;
  108.            for (i=0;i<readWidth;i++) {
  109.           dst[i] = (GLbyte) index[i];
  110.            }
  111.         }
  112.         break;
  113.      case GL_UNSIGNED_SHORT:
  114.         {
  115.                GLushort *dst = (GLushort *) dest;
  116.            for (i=0;i<readWidth;i++) {
  117.           dst[i] = (GLushort) index[i];
  118.            }
  119.            if (packing->SwapBytes) {
  120.           gl_swap2( (GLushort *) dst, readWidth );
  121.            }
  122.         }
  123.         break;
  124.      case GL_SHORT:
  125.         {
  126.                GLshort *dst = (GLshort *) dest;
  127.            for (i=0;i<readWidth;i++) {
  128.           dst[i] = (GLshort) index[i];
  129.            }
  130.            if (packing->SwapBytes) {
  131.           gl_swap2( (GLushort *) dst, readWidth );
  132.            }
  133.         }
  134.         break;
  135.      case GL_UNSIGNED_INT:
  136.         {
  137.                GLuint *dst = (GLuint *) dest;
  138.            for (i=0;i<readWidth;i++) {
  139.           dst[i] = (GLuint) index[i];
  140.            }
  141.            if (packing->SwapBytes) {
  142.           gl_swap4( (GLuint *) dst, readWidth );
  143.            }
  144.         }
  145.         break;
  146.      case GL_INT:
  147.         {
  148.                GLint *dst = (GLint *) dest;
  149.            for (i=0;i<readWidth;i++) {
  150.           dst[i] = (GLint) index[i];
  151.            }
  152.            if (packing->SwapBytes) {
  153.           gl_swap4( (GLuint *) dst, readWidth );
  154.            }
  155.         }
  156.         break;
  157.      case GL_FLOAT:
  158.         {
  159.                GLfloat *dst = (GLfloat *) dest;
  160.            for (i=0;i<readWidth;i++) {
  161.           dst[i] = (GLfloat) index[i];
  162.            }
  163.            if (packing->SwapBytes) {
  164.           gl_swap4( (GLuint *) dst, readWidth );
  165.            }
  166.         }
  167.         break;
  168.          default:
  169.             gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  170.             j = height + 1; /* exit loop */
  171.       }
  172.    }
  173.  
  174.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
  175. }
  176.  
  177.  
  178.  
  179. static void read_depth_pixels( GLcontext *ctx,
  180.                                GLint x, GLint y,
  181.                    GLsizei width, GLsizei height,
  182.                    GLenum type, GLvoid *pixels,
  183.                                const struct gl_pixelstore_attrib *packing )
  184. {
  185.    GLint i, j, readWidth;
  186.    GLboolean bias_or_scale;
  187.  
  188.    /* Error checking */
  189.    if (ctx->Visual->DepthBits <= 0) {
  190.       /* No depth buffer */
  191.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  192.       return;
  193.    }
  194.  
  195.    readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
  196.  
  197.    if (type != GL_BYTE &&
  198.        type != GL_UNSIGNED_BYTE &&
  199.        type != GL_SHORT &&
  200.        type != GL_UNSIGNED_SHORT &&
  201.        type != GL_INT &&
  202.        type != GL_UNSIGNED_INT &&
  203.        type != GL_FLOAT) {
  204.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels(depth type)");
  205.       return;
  206.    }
  207.  
  208.    bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  209.  
  210.    if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  211.        && !bias_or_scale && !packing->SwapBytes) {
  212.       /* Special case: directly read 16-bit unsigned depth values. */
  213.       for (j=0;j<height;j++,y++) {
  214.          GLushort *dst = (GLushort*) gl_pixel_addr_in_image( packing, pixels,
  215.                          width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 );
  216.          (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
  217.       }
  218.    }
  219.    else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  220.             && !bias_or_scale && !packing->SwapBytes) {
  221.       /* Special case: directly read 32-bit unsigned depth values. */
  222.       /* Compute shift value to scale depth values up to 32-bit uints. */
  223.       GLuint shift = 0;
  224.       GLuint max = MAX_DEPTH;
  225.       while ((max&0x80000000)==0) {
  226.          max = max << 1;
  227.          shift++;
  228.       }
  229.       for (j=0;j<height;j++,y++) {
  230.          GLuint *dst = (GLuint *) gl_pixel_addr_in_image( packing, pixels,
  231.                          width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 );
  232.          (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
  233.          for (i=0;i<width;i++) {
  234.             dst[i] = dst[i] << shift;
  235.          }
  236.       }
  237.    }
  238.    else {
  239.       /* General case (slow) */
  240.       for (j=0;j<height;j++,y++) {
  241.          GLfloat depth[MAX_WIDTH];
  242.          GLvoid *dest;
  243.  
  244.          (*ctx->Driver.ReadDepthSpanFloat)( ctx, readWidth, x, y, depth );
  245.  
  246.          if (bias_or_scale) {
  247.             for (i=0;i<readWidth;i++) {
  248.                GLfloat d;
  249.                d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  250.                depth[i] = CLAMP( d, 0.0F, 1.0F );
  251.             }
  252.          }
  253.  
  254.          dest = gl_pixel_addr_in_image(packing, pixels,
  255.                          width, height, GL_DEPTH_COMPONENT, type, 0, j, 0);
  256.  
  257.          switch (type) {
  258.             case GL_UNSIGNED_BYTE:
  259.                {
  260.                   GLubyte *dst = (GLubyte *) dest;
  261.                   for (i=0;i<readWidth;i++) {
  262.                      dst[i] = FLOAT_TO_UBYTE( depth[i] );
  263.                   }
  264.                }
  265.                break;
  266.             case GL_BYTE:
  267.                {
  268.                   GLbyte *dst = (GLbyte *) dest;
  269.                   for (i=0;i<readWidth;i++) {
  270.                      dst[i] = FLOAT_TO_BYTE( depth[i] );
  271.                   }
  272.                }
  273.                break;
  274.             case GL_UNSIGNED_SHORT:
  275.                {
  276.                   GLushort *dst = (GLushort *) dest;
  277.                   for (i=0;i<readWidth;i++) {
  278.                      dst[i] = FLOAT_TO_USHORT( depth[i] );
  279.                   }
  280.                   if (packing->SwapBytes) {
  281.                      gl_swap2( (GLushort *) dst, readWidth );
  282.                   }
  283.                }
  284.                break;
  285.             case GL_SHORT:
  286.                {
  287.                   GLshort *dst = (GLshort *) dest;
  288.                   for (i=0;i<readWidth;i++) {
  289.                      dst[i] = FLOAT_TO_SHORT( depth[i] );
  290.                   }
  291.                   if (packing->SwapBytes) {
  292.                      gl_swap2( (GLushort *) dst, readWidth );
  293.                   }
  294.                }
  295.                break;
  296.             case GL_UNSIGNED_INT:
  297.                {
  298.                   GLuint *dst = (GLuint *) dest;
  299.                   for (i=0;i<readWidth;i++) {
  300.                      dst[i] = FLOAT_TO_UINT( depth[i] );
  301.                   }
  302.                   if (packing->SwapBytes) {
  303.                      gl_swap4( (GLuint *) dst, readWidth );
  304.                   }
  305.                }
  306.                break;
  307.             case GL_INT:
  308.                {
  309.                   GLint *dst = (GLint *) dest;
  310.                   for (i=0;i<readWidth;i++) {
  311.                      dst[i] = FLOAT_TO_INT( depth[i] );
  312.                   }
  313.                   if (packing->SwapBytes) {
  314.                      gl_swap4( (GLuint *) dst, readWidth );
  315.                   }
  316.                }
  317.                break;
  318.             case GL_FLOAT:
  319.                {
  320.                   GLfloat *dst = (GLfloat *) dest;
  321.                   for (i=0;i<readWidth;i++) {
  322.                      dst[i] = depth[i];
  323.                   }
  324.                   if (packing->SwapBytes) {
  325.                      gl_swap4( (GLuint *) dst, readWidth );
  326.                   }
  327.                }
  328.                break;
  329.             default:
  330.                gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  331.          }
  332.       }
  333.    }
  334. }
  335.  
  336.  
  337.  
  338.  
  339. static void read_stencil_pixels( GLcontext *ctx,
  340.                                  GLint x, GLint y,
  341.                  GLsizei width, GLsizei height,
  342.                  GLenum type, GLvoid *pixels,
  343.                                  const struct gl_pixelstore_attrib *packing )
  344. {
  345.    GLboolean shift_or_offset;
  346.    GLint i, j, readWidth;
  347.  
  348.    if (type != GL_BYTE &&
  349.        type != GL_UNSIGNED_BYTE &&
  350.        type != GL_SHORT &&
  351.        type != GL_UNSIGNED_SHORT &&
  352.        type != GL_INT &&
  353.        type != GL_UNSIGNED_INT &&
  354.        type != GL_FLOAT &&
  355.        type != GL_BITMAP) {
  356.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels(stencil type)");
  357.       return;
  358.    }
  359.  
  360.    readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
  361.  
  362.    if (ctx->Visual->StencilBits<=0) {
  363.       /* No stencil buffer */
  364.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  365.       return;
  366.    }
  367.  
  368.    shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
  369.  
  370.    /* process image row by row */
  371.    for (j=0;j<height;j++,y++) {
  372.       GLvoid *dest;
  373.       GLstencil stencil[MAX_WIDTH];
  374.  
  375.       gl_read_stencil_span( ctx, readWidth, x, y, stencil );
  376.  
  377.       if (shift_or_offset) {
  378.          gl_shift_and_offset_stencil( ctx, readWidth, stencil );
  379.       }
  380.  
  381.       if (ctx->Pixel.MapStencilFlag) {
  382.          gl_map_stencil( ctx, readWidth, stencil );
  383.       }
  384.  
  385.       dest = gl_pixel_addr_in_image( packing, pixels,
  386.                           width, height, GL_STENCIL_INDEX, type, 0, j, 0 );
  387.  
  388.       switch (type) {
  389.      case GL_UNSIGNED_BYTE:
  390.             if (sizeof(GLstencil) == 8) {
  391.                MEMCPY( dest, stencil, readWidth );
  392.             }
  393.             else {
  394.                GLubyte *dst = (GLubyte *) dest;
  395.            for (i=0;i<readWidth;i++) {
  396.           dst[i] = (GLubyte) stencil[i];
  397.            }
  398.             }
  399.         break;
  400.      case GL_BYTE:
  401.             if (sizeof(GLstencil) == 8) {
  402.                MEMCPY( dest, stencil, readWidth );
  403.             }
  404.             else {
  405.                GLbyte *dst = (GLbyte *) dest;
  406.            for (i=0;i<readWidth;i++) {
  407.           dst[i] = (GLbyte) stencil[i];
  408.            }
  409.             }
  410.         break;
  411.      case GL_UNSIGNED_SHORT:
  412.         {
  413.                GLushort *dst = (GLushort *) dest;
  414.            for (i=0;i<readWidth;i++) {
  415.           dst[i] = (GLushort) stencil[i];
  416.            }
  417.            if (packing->SwapBytes) {
  418.           gl_swap2( (GLushort *) dst, readWidth );
  419.            }
  420.         }
  421.         break;
  422.      case GL_SHORT:
  423.         {
  424.                GLshort *dst = (GLshort *) dest;
  425.            for (i=0;i<readWidth;i++) {
  426.           dst[i] = (GLshort) stencil[i];
  427.            }
  428.            if (packing->SwapBytes) {
  429.           gl_swap2( (GLushort *) dst, readWidth );
  430.            }
  431.         }
  432.         break;
  433.      case GL_UNSIGNED_INT:
  434.         {
  435.                GLuint *dst = (GLuint *) dest;
  436.            for (i=0;i<readWidth;i++) {
  437.           dst[i] = (GLuint) stencil[i];
  438.            }
  439.            if (packing->SwapBytes) {
  440.           gl_swap4( (GLuint *) dst, readWidth );
  441.            }
  442.         }
  443.         break;
  444.      case GL_INT:
  445.         {
  446.                GLint *dst = (GLint *) dest;
  447.            for (i=0;i<readWidth;i++) {
  448.           *dst++ = (GLint) stencil[i];
  449.            }
  450.            if (packing->SwapBytes) {
  451.           gl_swap4( (GLuint *) dst, readWidth );
  452.            }
  453.         }
  454.         break;
  455.      case GL_FLOAT:
  456.         {
  457.                GLfloat *dst = (GLfloat *) dest;
  458.            for (i=0;i<readWidth;i++) {
  459.           dst[i] = (GLfloat) stencil[i];
  460.            }
  461.            if (packing->SwapBytes) {
  462.           gl_swap4( (GLuint *) dst, readWidth );
  463.            }
  464.         }
  465.         break;
  466.          case GL_BITMAP:
  467.             if (packing->LsbFirst) {
  468.                GLubyte *dst = (GLubyte*) dest;
  469.                GLint shift = 0;
  470.                for (i = 0; i < readWidth; i++) {
  471.                   if (shift == 0)
  472.                      *dst = 0;
  473.                   *dst |= ((stencil != 0) << shift);
  474.                   shift++;
  475.                   if (shift == 8) {
  476.                      shift = 0;
  477.                      dst++;
  478.                   }
  479.                }
  480.             }
  481.             else {
  482.                GLubyte *dst = (GLubyte*) dest;
  483.                GLint shift = 7;
  484.                for (i = 0; i < readWidth; i++) {
  485.                   if (shift == 7)
  486.                      *dst = 0;
  487.                   *dst |= ((stencil != 0) << shift);
  488.                   shift--;
  489.                   if (shift < 0) {
  490.                      shift = 7;
  491.                      dst++;
  492.                   }
  493.                }
  494.             }
  495.             break;
  496.          default:
  497.             gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  498.       }
  499.    }
  500. }
  501.  
  502.  
  503.  
  504. /*
  505.  * Optimized glReadPixels for particular pixel formats:
  506.  *   GL_UNSIGNED_BYTE, GL_RGBA
  507.  * when pixel scaling, biasing and mapping are disabled.
  508.  */
  509. static GLboolean
  510. read_fast_rgba_pixels( GLcontext *ctx,
  511.                        GLint x, GLint y,
  512.                        GLsizei width, GLsizei height,
  513.                        GLenum format, GLenum type,
  514.                        GLvoid *pixels,
  515.                        const struct gl_pixelstore_attrib *packing )
  516. {
  517.    /* can't do scale, bias or mapping */
  518.    if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag)
  519.        return GL_FALSE;
  520.  
  521.    /* can't do fancy pixel packing */
  522.    if (packing->Alignment != 1 || packing->SwapBytes || packing->LsbFirst)
  523.       return GL_FALSE;
  524.  
  525.    {
  526.       GLint srcX = x;
  527.       GLint srcY = y;
  528.       GLint readWidth = width;           /* actual width read */
  529.       GLint readHeight = height;         /* actual height read */
  530.       GLint skipPixels = packing->SkipPixels;
  531.       GLint skipRows = packing->SkipRows;
  532.       GLint rowLength;
  533.  
  534.       if (packing->RowLength > 0)
  535.          rowLength = packing->RowLength;
  536.       else
  537.          rowLength = width;
  538.  
  539.       /* horizontal clipping */
  540.       if (srcX < ctx->Buffer->Xmin) {
  541.          skipPixels += (ctx->Buffer->Xmin - srcX);
  542.          readWidth  -= (ctx->Buffer->Xmin - srcX);
  543.          srcX = ctx->Buffer->Xmin;
  544.       }
  545.       if (srcX + readWidth > ctx->Buffer->Xmax)
  546.          readWidth -= (srcX + readWidth - ctx->Buffer->Xmax - 1);
  547.       if (readWidth <= 0)
  548.          return GL_TRUE;
  549.  
  550.       /* vertical clipping */
  551.       if (srcY < ctx->Buffer->Ymin) {
  552.          skipRows   += (ctx->Buffer->Ymin - srcY);
  553.          readHeight -= (ctx->Buffer->Ymin - srcY);
  554.          srcY = ctx->Buffer->Ymin;
  555.       }
  556.       if (srcY + readHeight > ctx->Buffer->Ymax)
  557.          readHeight -= (srcY + readHeight - ctx->Buffer->Ymax - 1);
  558.       if (readHeight <= 0)
  559.          return GL_TRUE;
  560.  
  561.       /*
  562.        * Ready to read!
  563.        * The window region at (destX, destY) of size (readWidth, readHeight)
  564.        * will be read back.
  565.        * We'll write pixel data to buffer pointed to by "pixels" but we'll
  566.        * skip "skipRows" rows and skip "skipPixels" pixels/row.
  567.        */
  568.       if (format==GL_RGBA && type==GL_UNSIGNED_BYTE) {
  569.          GLubyte *dest = (GLubyte *) pixels
  570.                          + (skipRows * rowLength + skipPixels) * 4;
  571.          GLint row;
  572.          for (row=0; row<readHeight; row++) {
  573.             (*ctx->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY,
  574.                                         (GLubyte (*)[4]) dest);
  575.             if (ctx->Visual->SoftwareAlpha) {
  576.                gl_read_alpha_span(ctx, readWidth, srcX, srcY,
  577.                                   (GLubyte (*)[4]) dest);
  578.             }
  579.             dest += rowLength * 4;
  580.             srcY++;
  581.          }
  582.          return GL_TRUE;
  583.       }
  584.       else {
  585.          /* can't do this format/type combination */
  586.          return GL_FALSE;
  587.       }
  588.    }
  589. }
  590.  
  591.  
  592.  
  593. /*
  594.  * Read R, G, B, A, RGB, L, or LA pixels.
  595.  */
  596. static void read_rgba_pixels( GLcontext *ctx,
  597.                               GLint x, GLint y,
  598.                               GLsizei width, GLsizei height,
  599.                               GLenum format, GLenum type, GLvoid *pixels,
  600.                               const struct gl_pixelstore_attrib *packing )
  601. {
  602.    GLint readWidth;
  603.  
  604.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
  605.  
  606.    /* Try optimized path first */
  607.    if (read_fast_rgba_pixels( ctx, x, y, width, height,
  608.                               format, type, pixels, packing )) {
  609.  
  610.       (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
  611.       return; /* done! */
  612.    }
  613.  
  614.    readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
  615.  
  616.    /* do error checking on pixel type, format was already checked by caller */
  617.    switch (type) {
  618.       case GL_UNSIGNED_BYTE:
  619.       case GL_BYTE:
  620.       case GL_UNSIGNED_SHORT:
  621.       case GL_SHORT:
  622.       case GL_UNSIGNED_INT:
  623.       case GL_INT:
  624.       case GL_FLOAT:
  625.       case GL_UNSIGNED_BYTE_3_3_2:
  626.       case GL_UNSIGNED_BYTE_2_3_3_REV:
  627.       case GL_UNSIGNED_SHORT_5_6_5:
  628.       case GL_UNSIGNED_SHORT_5_6_5_REV:
  629.       case GL_UNSIGNED_SHORT_4_4_4_4:
  630.       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  631.       case GL_UNSIGNED_SHORT_5_5_5_1:
  632.       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  633.       case GL_UNSIGNED_INT_8_8_8_8:
  634.       case GL_UNSIGNED_INT_8_8_8_8_REV:
  635.       case GL_UNSIGNED_INT_10_10_10_2:
  636.       case GL_UNSIGNED_INT_2_10_10_10_REV:
  637.          /* valid pixel type */
  638.          break;
  639.       default:
  640.          gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  641.          return;
  642.    }
  643.  
  644.    if (!gl_is_legal_format_and_type(format, type)) {
  645.       gl_error(ctx, GL_INVALID_OPERATION, "glReadPixels(format or type)");
  646.       return;
  647.    }
  648.  
  649.    if (ctx->Visual->RGBAflag) {
  650.       GLint j;
  651.       for (j=0;j<height;j++,y++) {
  652.          GLubyte rgba[MAX_WIDTH][4];
  653.          GLvoid *dest;
  654.  
  655.          gl_read_rgba_span( ctx, readWidth, x, y, rgba );
  656.  
  657.          dest = gl_pixel_addr_in_image( packing, pixels, width, height,
  658.                                         format, type, 0, j, 0);
  659.  
  660.          gl_pack_rgba_span( ctx, readWidth, (const GLubyte (*)[4]) rgba,
  661.                             format, type, dest, packing, GL_TRUE );
  662.       }
  663.    }
  664.    else {
  665.       GLint j;
  666.       for (j=0;j<height;j++,y++) {
  667.          GLubyte rgba[MAX_WIDTH][4];
  668.      GLuint index[MAX_WIDTH];
  669.          GLvoid *dest;
  670.  
  671.      (*ctx->Driver.ReadCI32Span)( ctx, readWidth, x, y, index );
  672.  
  673.      if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  674.             gl_map_ci( ctx, readWidth, index );
  675.      }
  676.  
  677.          gl_map_ci_to_rgba(ctx, readWidth, index, rgba );
  678.  
  679.          dest = gl_pixel_addr_in_image( packing, pixels, width, height,
  680.                                         format, type, 0, j, 0);
  681.  
  682.          gl_pack_rgba_span( ctx, readWidth, (const GLubyte (*)[4]) rgba,
  683.                             format, type, dest, packing, GL_TRUE );
  684.       }
  685.    }
  686.  
  687.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
  688. }
  689.  
  690.  
  691.  
  692. void gl_ReadPixels( GLcontext *ctx,
  693.                     GLint x, GLint y, GLsizei width, GLsizei height,
  694.             GLenum format, GLenum type, GLvoid *pixels )
  695. {
  696.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glReadPixels");
  697.  
  698.    if (!pixels) {
  699.       gl_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" );
  700.       return;
  701.    }
  702.  
  703.    switch (format) {
  704.       case GL_COLOR_INDEX:
  705.          read_index_pixels( ctx, x, y, width, height, type, pixels, &ctx->Pack );
  706.      break;
  707.       case GL_STENCIL_INDEX:
  708.      read_stencil_pixels( ctx, x, y, width, height, type, pixels, &ctx->Pack );
  709.          break;
  710.       case GL_DEPTH_COMPONENT:
  711.      read_depth_pixels( ctx, x, y, width, height, type, pixels, &ctx->Pack );
  712.      break;
  713.       case GL_RED:
  714.       case GL_GREEN:
  715.       case GL_BLUE:
  716.       case GL_ALPHA:
  717.       case GL_RGB:
  718.       case GL_LUMINANCE:
  719.       case GL_LUMINANCE_ALPHA:
  720.       case GL_RGBA:
  721.       case GL_BGR:
  722.       case GL_BGRA:
  723.       case GL_ABGR_EXT:
  724.          read_rgba_pixels( ctx, x, y, width, height, format, type, pixels, &ctx->Pack );
  725.      break;
  726.       default:
  727.      gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
  728.    }
  729. }
  730.