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

  1. /* $Id: readpix.c,v 1.10 1997/07/24 01:25:18 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: readpix.c,v $
  26.  * Revision 1.10  1997/07/24 01:25:18  brianp
  27.  * changed precompiled header symbol from PCH to PC_HEADER
  28.  *
  29.  * Revision 1.9  1997/05/28 03:26:18  brianp
  30.  * added precompiled header (PCH) support
  31.  *
  32.  * Revision 1.8  1997/05/08 01:43:50  brianp
  33.  * added error check to gl_ReadPixels() for inside glBegin/glEnd
  34.  *
  35.  * Revision 1.7  1997/02/03 20:31:15  brianp
  36.  * added a few DEFARRAY macros for BeOS
  37.  *
  38.  * Revision 1.6  1997/01/16 19:24:05  brianp
  39.  * replaced a few abort()'s with gl_error() calls
  40.  *
  41.  * Revision 1.5  1996/12/20 20:28:04  brianp
  42.  * use DEF/UNDEFARRAY() macros in read_color_pixels() for Mac compilers
  43.  *
  44.  * Revision 1.4  1996/11/01 03:20:47  brianp
  45.  * reading GL_LUMINANCE pixels weren't clamped
  46.  *
  47.  * Revision 1.3  1996/09/27 01:29:47  brianp
  48.  * added missing default cases to switches
  49.  *
  50.  * Revision 1.2  1996/09/15 14:18:37  brianp
  51.  * now use GLframebuffer and GLvisual
  52.  *
  53.  * Revision 1.1  1996/09/13 01:38:16  brianp
  54.  * Initial revision
  55.  *
  56.  */
  57.  
  58.  
  59. #ifdef PC_HEADER
  60. #include "all.h"
  61. #else
  62. #include <math.h>
  63. #include <stdlib.h>
  64. #include <string.h>
  65. #include "alphabuf.h"
  66. #include "context.h"
  67. #include "depth.h"
  68. #include "feedback.h"
  69. #include "dlist.h"
  70. #include "macros.h"
  71. #include "image.h"
  72. #include "readpix.h"
  73. #include "span.h"
  74. #include "stencil.h"
  75. #include "types.h"
  76. #endif
  77.  
  78.  
  79.  
  80.  
  81. /*
  82.  * Read a block of color index pixels.
  83.  */
  84. static void read_index_pixels( GLcontext *ctx,
  85.                    GLint x, GLint y,
  86.                    GLsizei width, GLsizei height,
  87.                    GLenum type, GLvoid *pixels )
  88. {
  89.    GLint i, j;
  90.    GLuint a, s, k, l, start;
  91.  
  92.    /* error checking */
  93.    if (ctx->Visual->RGBAflag) {
  94.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  95.       return;
  96.    }
  97.  
  98.    /* Size of each component */
  99.    s = gl_sizeof_type( type );
  100.    if (s<=0) {
  101.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  102.       return;
  103.    }
  104.  
  105.    /* Compute packing parameters */
  106.    a = ctx->Pack.Alignment;
  107.    if (ctx->Pack.RowLength>0) {
  108.       l = ctx->Pack.RowLength;
  109.    }
  110.    else {
  111.       l = width;
  112.    }
  113.    /* k = offset between rows in components */
  114.    if (s>=a) {
  115.       k = l;
  116.    }
  117.    else {
  118.       k = a/s * CEILING( s*l, a );
  119.    }
  120.  
  121.    /* offset to first component returned */
  122.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
  123.  
  124.    /* process image row by row */
  125.    for (j=0;j<height;j++,y++) {
  126.       GLuint index[MAX_WIDTH];
  127.       (*ctx->Driver.ReadIndexSpan)( ctx, width, x, y, index );
  128.  
  129.       if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  130.      GLuint s;
  131.      if (ctx->Pixel.IndexShift<0) {
  132.         /* right shift */
  133.         s = -ctx->Pixel.IndexShift;
  134.         for (i=0;i<width;i++) {
  135.            index[i] = (index[i] >> s) + ctx->Pixel.IndexOffset;
  136.         }
  137.      }
  138.      else {
  139.         /* left shift */
  140.         s = ctx->Pixel.IndexShift;
  141.         for (i=0;i<width;i++) {
  142.            index[i] = (index[i] << s) + ctx->Pixel.IndexOffset;
  143.         }
  144.      }
  145.       }
  146.  
  147.       if (ctx->Pixel.MapColorFlag) {
  148.      for (i=0;i<width;i++) {
  149.         index[i] = ctx->Pixel.MapItoI[ index[i] ];
  150.      }
  151.       }
  152.  
  153.       switch (type) {
  154.      case GL_UNSIGNED_BYTE:
  155.         {
  156.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  157.            for (i=0;i<width;i++) {
  158.           *dst++ = (GLubyte) index[i];
  159.            }
  160.         }
  161.         break;
  162.      case GL_BYTE:
  163.         {
  164.            GLbyte *dst = (GLbyte *) pixels + start + j * k;
  165.            for (i=0;i<width;i++) {
  166.           *dst++ = (GLbyte) index[i];
  167.            }
  168.         }
  169.         break;
  170.      case GL_UNSIGNED_SHORT:
  171.         {
  172.            GLushort *dst = (GLushort *) pixels + start + j * k;
  173.            for (i=0;i<width;i++) {
  174.           *dst++ = (GLushort) index[i];
  175.            }
  176.            if (ctx->Pack.SwapBytes) {
  177.           gl_swap2( (GLushort *) pixels + start + j * k, width );
  178.            }
  179.         }
  180.         break;
  181.      case GL_SHORT:
  182.         {
  183.            GLshort *dst = (GLshort *) pixels + start + j * k;
  184.            for (i=0;i<width;i++) {
  185.           *dst++ = (GLshort) index[i];
  186.            }
  187.            if (ctx->Pack.SwapBytes) {
  188.           gl_swap2( (GLushort *) pixels + start + j * k, width );
  189.            }
  190.         }
  191.         break;
  192.      case GL_UNSIGNED_INT:
  193.         {
  194.            GLuint *dst = (GLuint *) pixels + start + j * k;
  195.            for (i=0;i<width;i++) {
  196.           *dst++ = (GLuint) index[i];
  197.            }
  198.            if (ctx->Pack.SwapBytes) {
  199.           gl_swap4( (GLuint *) pixels + start + j * k, width );
  200.            }
  201.         }
  202.         break;
  203.      case GL_INT:
  204.         {
  205.            GLint *dst = (GLint *) pixels + start + j * k;
  206.            for (i=0;i<width;i++) {
  207.           *dst++ = (GLint) index[i];
  208.            }
  209.            if (ctx->Pack.SwapBytes) {
  210.           gl_swap4( (GLuint *) pixels + start + j * k, width );
  211.            }
  212.         }
  213.         break;
  214.      case GL_FLOAT:
  215.         {
  216.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  217.            for (i=0;i<width;i++) {
  218.           *dst++ = (GLfloat) index[i];
  219.            }
  220.            if (ctx->Pack.SwapBytes) {
  221.           gl_swap4( (GLuint *) pixels + start + j * k, width );
  222.            }
  223.         }
  224.         break;
  225.      default:
  226.         gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  227.       }
  228.    }
  229. }
  230.  
  231.  
  232.  
  233. static void read_depth_pixels( GLcontext *ctx,
  234.                    GLint x, GLint y,
  235.                    GLsizei width, GLsizei height,
  236.                    GLenum type, GLvoid *pixels )
  237. {
  238.    GLint i, j;
  239.    GLuint a, s, k, l, start;
  240.    GLboolean bias_or_scale;
  241.  
  242.    /* Error checking */
  243.    if (ctx->Visual->DepthBits<=0) {
  244.       /* No depth buffer */
  245.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  246.       return;
  247.    }
  248.  
  249.    bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  250.  
  251.    /* Size of each component */
  252.    s = gl_sizeof_type( type );
  253.    if (s<=0) {
  254.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  255.       return;
  256.    }
  257.  
  258.    /* Compute packing parameters */
  259.    a = ctx->Pack.Alignment;
  260.    if (ctx->Pack.RowLength>0) {
  261.       l = ctx->Pack.RowLength;
  262.    }
  263.    else {
  264.       l = width;
  265.    }
  266.    /* k = offset between rows in components */
  267.    if (s>=a) {
  268.       k = l;
  269.    }
  270.    else {
  271.       k = a/s * CEILING( s*l, a );
  272.    }
  273.  
  274.    /* offset to first component returned */
  275.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
  276.  
  277.    if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  278.        && !bias_or_scale && !ctx->Pack.SwapBytes) {
  279.       /* Special case: directly read 16-bit unsigned depth values. */
  280.       for (j=0;j<height;j++,y++) {
  281.      GLushort *dst = (GLushort *) pixels + start + j * k;
  282.      (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
  283.       }
  284.    }
  285.    else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  286.         && !bias_or_scale && !ctx->Pack.SwapBytes) {
  287.       /* Special case: directly read 32-bit unsigned depth values. */
  288.       /* Compute shift value to scale depth values up to 32-bit uints. */
  289.       GLuint shift = 0;
  290.       GLuint max = MAX_DEPTH;
  291.       while ((max&0x80000000)==0) {
  292.      max = max << 1;
  293.      shift++;
  294.       }
  295.       for (j=0;j<height;j++,y++) {
  296.      GLuint *dst = (GLuint *) pixels + start + j * k;
  297.      (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
  298.      for (i=0;i<width;i++) {
  299.         dst[i] = dst[i] << shift;
  300.      }
  301.       }
  302.    }
  303.    else {
  304.       /* General case (slow) */
  305.       for (j=0;j<height;j++,y++) {
  306.      GLfloat depth[MAX_WIDTH];
  307.  
  308.      (*ctx->Driver.ReadDepthSpanFloat)( ctx, width, x, y, depth );
  309.  
  310.      if (bias_or_scale) {
  311.         for (i=0;i<width;i++) {
  312.            GLfloat d;
  313.            d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  314.            depth[i] = CLAMP( d, 0.0, 1.0 );
  315.         }
  316.      }
  317.  
  318.      switch (type) {
  319.         case GL_UNSIGNED_BYTE:
  320.            {
  321.           GLubyte *dst = (GLubyte *) pixels + start + j * k;
  322.           for (i=0;i<width;i++) {
  323.              *dst++ = FLOAT_TO_UBYTE( depth[i] );
  324.           }
  325.            }
  326.            break;
  327.         case GL_BYTE:
  328.            {
  329.           GLbyte *dst = (GLbyte *) pixels + start + j * k;
  330.           for (i=0;i<width;i++) {
  331.              *dst++ = FLOAT_TO_BYTE( depth[i] );
  332.           }
  333.            }
  334.            break;
  335.         case GL_UNSIGNED_SHORT:
  336.            {
  337.           GLushort *dst = (GLushort *) pixels + start + j * k;
  338.           for (i=0;i<width;i++) {
  339.              *dst++ = FLOAT_TO_USHORT( depth[i] );
  340.           }
  341.           if (ctx->Pack.SwapBytes) {
  342.              gl_swap2( (GLushort *) pixels + start + j * k, width );
  343.           }
  344.            }
  345.            break;
  346.         case GL_SHORT:
  347.            {
  348.           GLshort *dst = (GLshort *) pixels + start + j * k;
  349.           for (i=0;i<width;i++) {
  350.              *dst++ = FLOAT_TO_SHORT( depth[i] );
  351.           }
  352.           if (ctx->Pack.SwapBytes) {
  353.              gl_swap2( (GLushort *) pixels + start + j * k, width );
  354.           }
  355.            }
  356.            break;
  357.         case GL_UNSIGNED_INT:
  358.            {
  359.           GLuint *dst = (GLuint *) pixels + start + j * k;
  360.           for (i=0;i<width;i++) {
  361.              *dst++ = FLOAT_TO_UINT( depth[i] );
  362.           }
  363.           if (ctx->Pack.SwapBytes) {
  364.              gl_swap4( (GLuint *) pixels + start + j * k, width );
  365.           }
  366.            }
  367.            break;
  368.         case GL_INT:
  369.            {
  370.           GLint *dst = (GLint *) pixels + start + j * k;
  371.           for (i=0;i<width;i++) {
  372.              *dst++ = FLOAT_TO_INT( depth[i] );
  373.           }
  374.           if (ctx->Pack.SwapBytes) {
  375.              gl_swap4( (GLuint *) pixels + start + j * k, width );
  376.           }
  377.            }
  378.            break;
  379.         case GL_FLOAT:
  380.            {
  381.           GLfloat *dst = (GLfloat *) pixels + start + j * k;
  382.           for (i=0;i<width;i++) {
  383.              *dst++ = depth[i];
  384.           }
  385.           if (ctx->Pack.SwapBytes) {
  386.              gl_swap4( (GLuint *) pixels + start + j * k, width );
  387.           }
  388.            }
  389.            break;
  390.         default:
  391.            gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  392.      }
  393.       }
  394.    }
  395. }
  396.  
  397.  
  398.  
  399.  
  400. static void read_stencil_pixels( GLcontext *ctx,
  401.                  GLint x, GLint y,
  402.                  GLsizei width, GLsizei height,
  403.                  GLenum type, GLvoid *pixels )
  404. {
  405.    GLint i, j;
  406.    GLuint a, s, k, l, start;
  407.    GLboolean shift_or_offset;
  408.  
  409.    if (ctx->Visual->StencilBits<=0) {
  410.       /* No stencil buffer */
  411.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  412.       return;
  413.    }
  414.  
  415.    shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
  416.  
  417.    /* Size of each component */
  418.    s = gl_sizeof_type( type );
  419.    if (s<=0) {
  420.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  421.       return;
  422.    }
  423.  
  424.    /* Compute packing parameters */
  425.    a = ctx->Pack.Alignment;
  426.    if (ctx->Pack.RowLength>0) {
  427.       l = ctx->Pack.RowLength;
  428.    }
  429.    else {
  430.       l = width;
  431.    }
  432.    /* k = offset between rows in components */
  433.    if (s>=a) {
  434.       k = l;
  435.    }
  436.    else {
  437.       k = a/s * CEILING( s*l, a );
  438.    }
  439.  
  440.    /* offset to first component returned */
  441.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
  442.  
  443.    /* process image row by row */
  444.    for (j=0;j<height;j++,y++) {
  445.       GLubyte stencil[MAX_WIDTH];
  446.  
  447.       gl_read_stencil_span( ctx, width, x, y, stencil );
  448.  
  449.       if (shift_or_offset) {
  450.      GLuint s;
  451.      if (ctx->Pixel.IndexShift<0) {
  452.         /* right shift */
  453.         s = -ctx->Pixel.IndexShift;
  454.         for (i=0;i<width;i++) {
  455.            stencil[i] = (stencil[i] >> s) + ctx->Pixel.IndexOffset;
  456.         }
  457.      }
  458.      else {
  459.         /* left shift */
  460.         s = ctx->Pixel.IndexShift;
  461.         for (i=0;i<width;i++) {
  462.            stencil[i] = (stencil[i] << s) + ctx->Pixel.IndexOffset;
  463.         }
  464.      }
  465.       }
  466.  
  467.       if (ctx->Pixel.MapStencilFlag) {
  468.      for (i=0;i<width;i++) {
  469.         stencil[i] = ctx->Pixel.MapStoS[ stencil[i] ];
  470.      }
  471.       }
  472.  
  473.       switch (type) {
  474.      case GL_UNSIGNED_BYTE:
  475.         {
  476.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  477.            MEMCPY( dst, stencil, width );
  478.         }
  479.         break;
  480.      case GL_BYTE:
  481.         {
  482.            GLbyte *dst = (GLbyte  *) pixels + start + j * k;
  483.            MEMCPY( dst, stencil, width );
  484.         }
  485.         break;
  486.      case GL_UNSIGNED_SHORT:
  487.         {
  488.            GLushort *dst = (GLushort *) pixels + start + j * k;
  489.            for (i=0;i<width;i++) {
  490.           *dst++ = (GLushort) stencil[i];
  491.            }
  492.            if (ctx->Pack.SwapBytes) {
  493.           gl_swap2( (GLushort *) pixels + start +j * k, width );
  494.            }
  495.         }
  496.         break;
  497.      case GL_SHORT:
  498.         {
  499.            GLshort *dst = (GLshort *) pixels + start + j * k;
  500.            for (i=0;i<width;i++) {
  501.           *dst++ = (GLshort) stencil[i];
  502.            }
  503.            if (ctx->Pack.SwapBytes) {
  504.           gl_swap2( (GLushort *) pixels + start +j * k, width );
  505.            }
  506.         }
  507.         break;
  508.      case GL_UNSIGNED_INT:
  509.         {
  510.            GLuint *dst = (GLuint *) pixels + start + j * k;
  511.            for (i=0;i<width;i++) {
  512.           *dst++ = (GLuint) stencil[i];
  513.            }
  514.            if (ctx->Pack.SwapBytes) {
  515.           gl_swap4( (GLuint *) pixels + start +j * k, width );
  516.            }
  517.         }
  518.         break;
  519.      case GL_INT:
  520.         {
  521.            GLint *dst = (GLint *) pixels + start + j * k;
  522.            for (i=0;i<width;i++) {
  523.           *dst++ = (GLint) stencil[i];
  524.            }
  525.            if (ctx->Pack.SwapBytes) {
  526.           gl_swap4( (GLuint *) pixels + start +j * k, width );
  527.            }
  528.         }
  529.         break;
  530.      case GL_FLOAT:
  531.         {
  532.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  533.            for (i=0;i<width;i++) {
  534.           *dst++ = (GLfloat) stencil[i];
  535.            }
  536.            if (ctx->Pack.SwapBytes) {
  537.           gl_swap4( (GLuint *) pixels + start +j * k, width );
  538.            }
  539.         }
  540.         break;
  541.      default:
  542.         gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  543.       }
  544.    }
  545. }
  546.  
  547.  
  548.  
  549. /*
  550.  * Test if scaling or biasing of colors is needed.
  551.  */
  552. static GLboolean scale_or_bias_rgba( GLcontext *ctx )
  553. {
  554.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  555.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  556.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  557.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  558.       return GL_TRUE;
  559.    }
  560.    else {
  561.       return GL_FALSE;
  562.    }
  563. }
  564.  
  565.  
  566.  
  567. /*
  568.  * Apply scale and bias factors to an array of RGBA pixels.
  569.  */
  570. static void scale_and_bias_rgba( GLcontext *ctx,
  571.                  GLint n,
  572.                  GLfloat red[], GLfloat green[],
  573.                  GLfloat blue[], GLfloat alpha[] )
  574. {
  575.    register GLint i;
  576.    register GLfloat r, g, b, a;
  577.  
  578.    for (i=0;i<n;i++) {
  579.       r = red[i]   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  580.       g = green[i] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  581.       b = blue[i]  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  582.       a = alpha[i] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  583.       red[i]   = CLAMP( r, 0.0F, 1.0F );
  584.       green[i] = CLAMP( g, 0.0F, 1.0F );
  585.       blue[i]  = CLAMP( b, 0.0F, 1.0F );
  586.       alpha[i] = CLAMP( a, 0.0F, 1.0F );
  587.    }
  588. }
  589.  
  590.  
  591.  
  592. /*
  593.  * Apply pixel mapping to an array of RGBA pixels.
  594.  */
  595. static void map_rgba( GLcontext *ctx,
  596.               GLint n,
  597.               GLfloat red[], GLfloat green[],
  598.               GLfloat blue[], GLfloat alpha[] )
  599. {
  600.    GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
  601.    GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
  602.    GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
  603.    GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
  604.    GLint i;
  605.  
  606.    for (i=0;i<n;i++) {
  607.       red[i]   = ctx->Pixel.MapRtoR[ (GLint) (red[i]   * rscale) ];
  608.       green[i] = ctx->Pixel.MapGtoG[ (GLint) (green[i] * gscale) ];
  609.       blue[i]  = ctx->Pixel.MapBtoB[ (GLint) (blue[i]  * bscale) ];
  610.       alpha[i] = ctx->Pixel.MapAtoA[ (GLint) (alpha[i] * ascale) ];
  611.    }
  612. }
  613.  
  614.  
  615. /* temporary bugfix for StormCPPC */
  616.  
  617. #if defined(__STORM__) && defined(__PPC__)
  618.    DEFARRAY(GLfloat, g_red, MAX_WIDTH);
  619.    DEFARRAY(GLfloat, g_green, MAX_WIDTH);
  620.    DEFARRAY(GLfloat, g_blue, MAX_WIDTH);
  621.    DEFARRAY(GLfloat, g_alpha, MAX_WIDTH);
  622.    DEFARRAY(GLfloat, g_luminance, MAX_WIDTH);
  623.    GLuint g_index[MAX_WIDTH];
  624. #endif
  625.  
  626. #if defined(__STORM__) && defined(__PPC__)
  627.  
  628. /*
  629.  * Read R, G, B, A, RGB, L, or LA pixels.
  630.  */
  631. static void read_color_pixels( GLcontext *ctx,
  632.                    GLint x, GLint y,
  633.                    GLsizei width, GLsizei height,
  634.                    GLenum format, GLenum type, GLvoid *pixels )
  635. {
  636.    GLint i, j, n, a, s, l, k;
  637.    GLboolean scale_or_bias;
  638.    GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  639.    GLuint start;
  640.  
  641.    scale_or_bias = scale_or_bias_rgba( ctx );
  642.  
  643.    /* Determine how many / which components to return */
  644.    r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  645.    switch (format) {
  646.       case GL_RED:                              r_flag = GL_TRUE;  n = 1;  break;
  647.       case GL_GREEN:                            g_flag = GL_TRUE;  n = 1;  break;
  648.       case GL_BLUE:                             b_flag = GL_TRUE;  n = 1;  break;
  649.       case GL_ALPHA:                            a_flag = GL_TRUE;  n = 1;  break;
  650.       case GL_LUMINANCE:                        l_flag = GL_TRUE;  n = 1;  break;
  651.       case GL_LUMINANCE_ALPHA:         l_flag = a_flag = GL_TRUE;  n = 2;  break;
  652.       case GL_RGB:            r_flag = g_flag = b_flag = GL_TRUE;  n = 3;  break;
  653.       case GL_RGBA:  r_flag = g_flag = b_flag = a_flag = GL_TRUE;  n = 4;  break;
  654.       default:
  655.      gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
  656.      return;
  657.    }
  658.  
  659.    /* Size of each component */
  660.    s = gl_sizeof_type( type );
  661.    if (s<=0) {
  662.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  663.       return;
  664.    }
  665.  
  666.    /* Compute packing parameters */
  667.    a = ctx->Pack.Alignment;
  668.    if (ctx->Pack.RowLength>0) {
  669.       l = ctx->Pack.RowLength;
  670.    }
  671.    else {
  672.       l = width;
  673.    }
  674.    /* k = offset between rows in components */
  675.    if (s>=a) {
  676.       k = n * l;
  677.    }
  678.    else {
  679.       k = a/s * CEILING( s*n*l, a );
  680.    }
  681.  
  682.    /* offset to first component returned */
  683.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels * n;
  684.  
  685.    /* process image row by row */
  686.    for (j=0;j<height;j++,y++) {
  687.  
  688.       /*
  689.        * Read the pixels from frame buffer
  690.        */
  691.       if (ctx->Visual->RGBAflag) {
  692.      DEFARRAY(GLubyte, r, MAX_WIDTH);
  693.      DEFARRAY(GLubyte, g, MAX_WIDTH);
  694.      DEFARRAY(GLubyte, b, MAX_WIDTH);
  695.      DEFARRAY(GLubyte, a, MAX_WIDTH);
  696.      GLfloat rscale = 1.0F * ctx->Visual->InvRedScale;
  697.      GLfloat gscale = 1.0F * ctx->Visual->InvGreenScale;
  698.      GLfloat bscale = 1.0F * ctx->Visual->InvBlueScale;
  699.      GLfloat ascale = 1.0F * ctx->Visual->InvAlphaScale;
  700.  
  701.      /* read colors and convert to floats */
  702.      (*ctx->Driver.ReadColorSpan)( ctx, width, x, y, r, g, b, a );
  703.      if (ctx->RasterMask & ALPHABUF_BIT) {
  704.         gl_read_alpha_span( ctx, width, x, y, a );
  705.      }
  706.      for (i=0;i<width;i++) {
  707.         g_red[i]   = r[i] * rscale;
  708.         g_green[i] = g[i] * gscale;
  709.         g_blue[i]  = b[i] * bscale;
  710.         g_alpha[i] = a[i] * ascale;
  711.      }
  712.  
  713.      if (scale_or_bias) {
  714.         scale_and_bias_rgba( ctx, width, g_red, g_green, g_blue, g_alpha );
  715.      }
  716.      if (ctx->Pixel.MapColorFlag) {
  717.         map_rgba( ctx, width, g_red, g_green, g_blue, g_alpha );
  718.      }
  719.      UNDEFARRAY(r);
  720.      UNDEFARRAY(g);
  721.      UNDEFARRAY(b);
  722.      UNDEFARRAY(a);
  723.       }
  724.       else {
  725.      /* convert CI values to RGBA */
  726.      (*ctx->Driver.ReadIndexSpan)( ctx, width, x, y, g_index );
  727.  
  728.      if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  729.         GLuint s;
  730.         if (ctx->Pixel.IndexShift<0) {
  731.            /* right shift */
  732.            s = -ctx->Pixel.IndexShift;
  733.            for (i=0;i<width;i++) {
  734.           g_index[i] = (g_index[i] >> s) + ctx->Pixel.IndexOffset;
  735.            }
  736.         }
  737.         else {
  738.            /* left shift */
  739.            s = ctx->Pixel.IndexShift;
  740.            for (i=0;i<width;i++) {
  741.           g_index[i] = (g_index[i] << s) + ctx->Pixel.IndexOffset;
  742.            }
  743.         }
  744.      }
  745.  
  746.      for (i=0;i<width;i++) {
  747.         g_red[i]   = ctx->Pixel.MapItoR[ g_index[i] ];
  748.         g_green[i] = ctx->Pixel.MapItoG[ g_index[i] ];
  749.         g_blue[i]  = ctx->Pixel.MapItoB[ g_index[i] ];
  750.         g_alpha[i] = ctx->Pixel.MapItoA[ g_index[i] ];
  751.      }
  752.       }
  753.  
  754.       if (l_flag) {
  755.      for (i=0;i<width;i++) {
  756.         GLfloat sum = g_red[i] + g_green[i] + g_blue[i];
  757.         g_luminance[i] = CLAMP( sum, 0.0F, 1.0F );
  758.      }
  759.       }
  760.  
  761.       /*
  762.        * Pack/transfer/store the pixels
  763.        */
  764.  
  765.       switch (type) {
  766.      case GL_UNSIGNED_BYTE:
  767.         {
  768.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  769.            for (i=0;i<width;i++) {
  770.           if (r_flag)  *dst++ = FLOAT_TO_UBYTE( g_red[i] );
  771.           if (g_flag)  *dst++ = FLOAT_TO_UBYTE( g_green[i] );
  772.           if (b_flag)  *dst++ = FLOAT_TO_UBYTE( g_blue[i] );
  773.           if (l_flag)  *dst++ = FLOAT_TO_UBYTE( g_luminance[i] );
  774.           if (a_flag)  *dst++ = FLOAT_TO_UBYTE( g_alpha[i] );
  775.            }
  776.         }
  777.         break;
  778.      case GL_BYTE:
  779.         {
  780.            GLbyte *dst = (GLbyte *) pixels + start + j * k;
  781.            for (i=0;i<width;i++) {
  782.           if (r_flag)  *dst++ = FLOAT_TO_BYTE( g_red[i] );
  783.           if (g_flag)  *dst++ = FLOAT_TO_BYTE( g_green[i] );
  784.           if (b_flag)  *dst++ = FLOAT_TO_BYTE( g_blue[i] );
  785.           if (l_flag)  *dst++ = FLOAT_TO_BYTE( g_luminance[i] );
  786.           if (a_flag)  *dst++ = FLOAT_TO_BYTE( g_alpha[i] );
  787.            }
  788.         }
  789.         break;
  790.      case GL_UNSIGNED_SHORT:
  791.         {
  792.            GLushort *dst = (GLushort *) pixels + start + j * k;
  793.            for (i=0;i<width;i++) {
  794.           if (r_flag)  *dst++ = FLOAT_TO_USHORT( g_red[i] );
  795.           if (g_flag)  *dst++ = FLOAT_TO_USHORT( g_green[i] );
  796.           if (b_flag)  *dst++ = FLOAT_TO_USHORT( g_blue[i] );
  797.           if (l_flag)  *dst++ = FLOAT_TO_USHORT( g_luminance[i] );
  798.           if (a_flag)  *dst++ = FLOAT_TO_USHORT( g_alpha[i] );
  799.            }
  800.         }
  801.         if (ctx->Pack.SwapBytes) {
  802.            gl_swap2( (GLushort *) pixels + start + j * k, width*n );
  803.         }
  804.         break;
  805.      case GL_SHORT:
  806.         {
  807.            GLshort *dst = (GLshort *) pixels + start + j * k;
  808.            for (i=0;i<width;i++) {
  809.           if (r_flag)  *dst++ = FLOAT_TO_SHORT( g_red[i] );
  810.           if (g_flag)  *dst++ = FLOAT_TO_SHORT( g_green[i] );
  811.           if (b_flag)  *dst++ = FLOAT_TO_SHORT( g_blue[i] );
  812.           if (l_flag)  *dst++ = FLOAT_TO_SHORT( g_luminance[i] );
  813.           if (a_flag)  *dst++ = FLOAT_TO_SHORT( g_alpha[i] );
  814.            }
  815.            if (ctx->Pack.SwapBytes) {
  816.           gl_swap2( (GLushort *) pixels + start + j * k, width*n );
  817.            }
  818.         }
  819.         break;
  820.      case GL_UNSIGNED_INT:
  821.         {
  822.            GLuint *dst = (GLuint *) pixels + start + j * k;
  823.            for (i=0;i<width;i++) {
  824.           if (r_flag)  *dst++ = FLOAT_TO_UINT( g_red[i] );
  825.           if (g_flag)  *dst++ = FLOAT_TO_UINT( g_green[i] );
  826.           if (b_flag)  *dst++ = FLOAT_TO_UINT( g_blue[i] );
  827.           if (l_flag)  *dst++ = FLOAT_TO_UINT( g_luminance[i] );
  828.           if (a_flag)  *dst++ = FLOAT_TO_UINT( g_alpha[i] );
  829.            }
  830.            if (ctx->Pack.SwapBytes) {
  831.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  832.            }
  833.         }
  834.         break;
  835.      case GL_INT:
  836.         {
  837.            GLint *dst = (GLint *) pixels + start + j * k;
  838.            for (i=0;i<width;i++) {
  839.           if (r_flag)  *dst++ = FLOAT_TO_INT( g_red[i] );
  840.           if (g_flag)  *dst++ = FLOAT_TO_INT( g_green[i] );
  841.           if (b_flag)  *dst++ = FLOAT_TO_INT( g_blue[i] );
  842.           if (l_flag)  *dst++ = FLOAT_TO_INT( g_luminance[i] );
  843.           if (a_flag)  *dst++ = FLOAT_TO_INT( g_alpha[i] );
  844.            }
  845.            if (ctx->Pack.SwapBytes) {
  846.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  847.            }
  848.         }
  849.         break;
  850.      case GL_FLOAT:
  851.         {
  852.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  853.            for (i=0;i<width;i++) {
  854.           if (r_flag)  *dst++ = g_red[i];
  855.           if (g_flag)  *dst++ = g_green[i];
  856.           if (b_flag)  *dst++ = g_blue[i];
  857.           if (l_flag)  *dst++ = g_luminance[i];
  858.           if (a_flag)  *dst++ = g_alpha[i];
  859.            }
  860.            if (ctx->Pack.SwapBytes) {
  861.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  862.            }
  863.         }
  864.         break;
  865.      default:
  866.         gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  867.       }
  868.    }
  869. }
  870.  
  871. #else
  872.  
  873. /*
  874.  * Read R, G, B, A, RGB, L, or LA pixels.
  875.  */
  876. static void read_color_pixels( GLcontext *ctx,
  877.                    GLint x, GLint y,
  878.                    GLsizei width, GLsizei height,
  879.                    GLenum format, GLenum type, GLvoid *pixels )
  880. {
  881.    GLint i, j, n, a, s, l, k;
  882.    GLboolean scale_or_bias;
  883.    DEFARRAY(GLfloat, red, MAX_WIDTH);
  884.    DEFARRAY(GLfloat, green, MAX_WIDTH);
  885.    DEFARRAY(GLfloat, blue, MAX_WIDTH);
  886.    DEFARRAY(GLfloat, alpha, MAX_WIDTH);
  887.    DEFARRAY(GLfloat, luminance, MAX_WIDTH);
  888.    GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  889.    GLuint start;
  890.  
  891.    scale_or_bias = scale_or_bias_rgba( ctx );
  892.  
  893.    /* Determine how many / which components to return */
  894.    r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  895.    switch (format) {
  896.       case GL_RED:                              r_flag = GL_TRUE;  n = 1;  break;
  897.       case GL_GREEN:                            g_flag = GL_TRUE;  n = 1;  break;
  898.       case GL_BLUE:                             b_flag = GL_TRUE;  n = 1;  break;
  899.       case GL_ALPHA:                            a_flag = GL_TRUE;  n = 1;  break;
  900.       case GL_LUMINANCE:                        l_flag = GL_TRUE;  n = 1;  break;
  901.       case GL_LUMINANCE_ALPHA:         l_flag = a_flag = GL_TRUE;  n = 2;  break;
  902.       case GL_RGB:            r_flag = g_flag = b_flag = GL_TRUE;  n = 3;  break;
  903.       case GL_RGBA:  r_flag = g_flag = b_flag = a_flag = GL_TRUE;  n = 4;  break;
  904.       default:
  905.      gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
  906.      UNDEFARRAY( red );
  907.      UNDEFARRAY( green );
  908.      UNDEFARRAY( blue );
  909.      UNDEFARRAY( alpha );
  910.      UNDEFARRAY( luminance );
  911.      return;
  912.    }
  913.  
  914.    /* Size of each component */
  915.    s = gl_sizeof_type( type );
  916.    if (s<=0) {
  917.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  918.       UNDEFARRAY( red );
  919.       UNDEFARRAY( green );
  920.       UNDEFARRAY( blue );
  921.       UNDEFARRAY( alpha );
  922.       UNDEFARRAY( luminance );
  923.       return;
  924.    }
  925.  
  926.    /* Compute packing parameters */
  927.    a = ctx->Pack.Alignment;
  928.    if (ctx->Pack.RowLength>0) {
  929.       l = ctx->Pack.RowLength;
  930.    }
  931.    else {
  932.       l = width;
  933.    }
  934.    /* k = offset between rows in components */
  935.    if (s>=a) {
  936.       k = n * l;
  937.    }
  938.    else {
  939.       k = a/s * CEILING( s*n*l, a );
  940.    }
  941.  
  942.    /* offset to first component returned */
  943.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels * n;
  944.  
  945.    /* process image row by row */
  946.    for (j=0;j<height;j++,y++) {
  947.  
  948.       /*
  949.        * Read the pixels from frame buffer
  950.        */
  951.       if (ctx->Visual->RGBAflag) {
  952.      DEFARRAY(GLubyte, r, MAX_WIDTH);
  953.      DEFARRAY(GLubyte, g, MAX_WIDTH);
  954.      DEFARRAY(GLubyte, b, MAX_WIDTH);
  955.      DEFARRAY(GLubyte, a, MAX_WIDTH);
  956.      GLfloat rscale = 1.0F * ctx->Visual->InvRedScale;
  957.      GLfloat gscale = 1.0F * ctx->Visual->InvGreenScale;
  958.      GLfloat bscale = 1.0F * ctx->Visual->InvBlueScale;
  959.      GLfloat ascale = 1.0F * ctx->Visual->InvAlphaScale;
  960.  
  961.      /* read colors and convert to floats */
  962.      (*ctx->Driver.ReadColorSpan)( ctx, width, x, y, r, g, b, a );
  963.      if (ctx->RasterMask & ALPHABUF_BIT) {
  964.         gl_read_alpha_span( ctx, width, x, y, a );
  965.      }
  966.      for (i=0;i<width;i++) {
  967.         red[i]   = r[i] * rscale;
  968.         green[i] = g[i] * gscale;
  969.         blue[i]  = b[i] * bscale;
  970.         alpha[i] = a[i] * ascale;
  971.      }
  972.  
  973.      if (scale_or_bias) {
  974.         scale_and_bias_rgba( ctx, width, red, green, blue, alpha );
  975.      }
  976.      if (ctx->Pixel.MapColorFlag) {
  977.         map_rgba( ctx, width, red, green, blue, alpha );
  978.      }
  979.      UNDEFARRAY(r);
  980.      UNDEFARRAY(g);
  981.      UNDEFARRAY(b);
  982.      UNDEFARRAY(a);
  983.       }
  984.       else {
  985.      /* convert CI values to RGBA */
  986.      GLuint index[MAX_WIDTH];
  987.      (*ctx->Driver.ReadIndexSpan)( ctx, width, x, y, index );
  988.  
  989.      if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  990.         GLuint s;
  991.         if (ctx->Pixel.IndexShift<0) {
  992.            /* right shift */
  993.            s = -ctx->Pixel.IndexShift;
  994.            for (i=0;i<width;i++) {
  995.           index[i] = (index[i] >> s) + ctx->Pixel.IndexOffset;
  996.            }
  997.         }
  998.         else {
  999.            /* left shift */
  1000.            s = ctx->Pixel.IndexShift;
  1001.            for (i=0;i<width;i++) {
  1002.           index[i] = (index[i] << s) + ctx->Pixel.IndexOffset;
  1003.            }
  1004.         }
  1005.      }
  1006.  
  1007.      for (i=0;i<width;i++) {
  1008.         red[i]   = ctx->Pixel.MapItoR[ index[i] ];
  1009.         green[i] = ctx->Pixel.MapItoG[ index[i] ];
  1010.         blue[i]  = ctx->Pixel.MapItoB[ index[i] ];
  1011.         alpha[i] = ctx->Pixel.MapItoA[ index[i] ];
  1012.      }
  1013.       }
  1014.  
  1015.       if (l_flag) {
  1016.      for (i=0;i<width;i++) {
  1017.         GLfloat sum = red[i] + green[i] + blue[i];
  1018.         luminance[i] = CLAMP( sum, 0.0F, 1.0F );
  1019.      }
  1020.       }
  1021.  
  1022.       /*
  1023.        * Pack/transfer/store the pixels
  1024.        */
  1025.  
  1026.       switch (type) {
  1027.      case GL_UNSIGNED_BYTE:
  1028.         {
  1029.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  1030.            for (i=0;i<width;i++) {
  1031.           if (r_flag)  *dst++ = FLOAT_TO_UBYTE( red[i] );
  1032.           if (g_flag)  *dst++ = FLOAT_TO_UBYTE( green[i] );
  1033.           if (b_flag)  *dst++ = FLOAT_TO_UBYTE( blue[i] );
  1034.           if (l_flag)  *dst++ = FLOAT_TO_UBYTE( luminance[i] );
  1035.           if (a_flag)  *dst++ = FLOAT_TO_UBYTE( alpha[i] );
  1036.            }
  1037.         }
  1038.         break;
  1039.      case GL_BYTE:
  1040.         {
  1041.            GLbyte *dst = (GLbyte *) pixels + start + j * k;
  1042.            for (i=0;i<width;i++) {
  1043.           if (r_flag)  *dst++ = FLOAT_TO_BYTE( red[i] );
  1044.           if (g_flag)  *dst++ = FLOAT_TO_BYTE( green[i] );
  1045.           if (b_flag)  *dst++ = FLOAT_TO_BYTE( blue[i] );
  1046.           if (l_flag)  *dst++ = FLOAT_TO_BYTE( luminance[i] );
  1047.           if (a_flag)  *dst++ = FLOAT_TO_BYTE( alpha[i] );
  1048.            }
  1049.         }
  1050.         break;
  1051.      case GL_UNSIGNED_SHORT:
  1052.         {
  1053.            GLushort *dst = (GLushort *) pixels + start + j * k;
  1054.            for (i=0;i<width;i++) {
  1055.           if (r_flag)  *dst++ = FLOAT_TO_USHORT( red[i] );
  1056.           if (g_flag)  *dst++ = FLOAT_TO_USHORT( green[i] );
  1057.           if (b_flag)  *dst++ = FLOAT_TO_USHORT( blue[i] );
  1058.           if (l_flag)  *dst++ = FLOAT_TO_USHORT( luminance[i] );
  1059.           if (a_flag)  *dst++ = FLOAT_TO_USHORT( alpha[i] );
  1060.            }
  1061.         }
  1062.         if (ctx->Pack.SwapBytes) {
  1063.            gl_swap2( (GLushort *) pixels + start + j * k, width*n );
  1064.         }
  1065.         break;
  1066.      case GL_SHORT:
  1067.         {
  1068.            GLshort *dst = (GLshort *) pixels + start + j * k;
  1069.            for (i=0;i<width;i++) {
  1070.           if (r_flag)  *dst++ = FLOAT_TO_SHORT( red[i] );
  1071.           if (g_flag)  *dst++ = FLOAT_TO_SHORT( green[i] );
  1072.           if (b_flag)  *dst++ = FLOAT_TO_SHORT( blue[i] );
  1073.           if (l_flag)  *dst++ = FLOAT_TO_SHORT( luminance[i] );
  1074.           if (a_flag)  *dst++ = FLOAT_TO_SHORT( alpha[i] );
  1075.            }
  1076.            if (ctx->Pack.SwapBytes) {
  1077.           gl_swap2( (GLushort *) pixels + start + j * k, width*n );
  1078.            }
  1079.         }
  1080.         break;
  1081.      case GL_UNSIGNED_INT:
  1082.         {
  1083.            GLuint *dst = (GLuint *) pixels + start + j * k;
  1084.            for (i=0;i<width;i++) {
  1085.           if (r_flag)  *dst++ = FLOAT_TO_UINT( red[i] );
  1086.           if (g_flag)  *dst++ = FLOAT_TO_UINT( green[i] );
  1087.           if (b_flag)  *dst++ = FLOAT_TO_UINT( blue[i] );
  1088.           if (l_flag)  *dst++ = FLOAT_TO_UINT( luminance[i] );
  1089.           if (a_flag)  *dst++ = FLOAT_TO_UINT( alpha[i] );
  1090.            }
  1091.            if (ctx->Pack.SwapBytes) {
  1092.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  1093.            }
  1094.         }
  1095.         break;
  1096.      case GL_INT:
  1097.         {
  1098.            GLint *dst = (GLint *) pixels + start + j * k;
  1099.            for (i=0;i<width;i++) {
  1100.           if (r_flag)  *dst++ = FLOAT_TO_INT( red[i] );
  1101.           if (g_flag)  *dst++ = FLOAT_TO_INT( green[i] );
  1102.           if (b_flag)  *dst++ = FLOAT_TO_INT( blue[i] );
  1103.           if (l_flag)  *dst++ = FLOAT_TO_INT( luminance[i] );
  1104.           if (a_flag)  *dst++ = FLOAT_TO_INT( alpha[i] );
  1105.            }
  1106.            if (ctx->Pack.SwapBytes) {
  1107.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  1108.            }
  1109.         }
  1110.         break;
  1111.      case GL_FLOAT:
  1112.         {
  1113.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  1114.            for (i=0;i<width;i++) {
  1115.           if (r_flag)  *dst++ = red[i];
  1116.           if (g_flag)  *dst++ = green[i];
  1117.           if (b_flag)  *dst++ = blue[i];
  1118.           if (l_flag)  *dst++ = luminance[i];
  1119.           if (a_flag)  *dst++ = alpha[i];
  1120.            }
  1121.            if (ctx->Pack.SwapBytes) {
  1122.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  1123.            }
  1124.         }
  1125.         break;
  1126.      default:
  1127.         gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  1128.       }
  1129.    }
  1130.    UNDEFARRAY( red );
  1131.    UNDEFARRAY( green );
  1132.    UNDEFARRAY( blue );
  1133.    UNDEFARRAY( alpha );
  1134.    UNDEFARRAY( luminance );
  1135. }
  1136.  
  1137. #endif
  1138.  
  1139. void gl_ReadPixels( GLcontext *ctx,
  1140.             GLint x, GLint y, GLsizei width, GLsizei height,
  1141.             GLenum format, GLenum type, GLvoid *pixels )
  1142. {
  1143.    if (INSIDE_BEGIN_END(ctx)) {
  1144.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  1145.       return;
  1146.    }
  1147.  
  1148.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  1149.  
  1150.    switch (format) {
  1151.       case GL_COLOR_INDEX:
  1152.      read_index_pixels( ctx, x, y, width, height, type, pixels );
  1153.      break;
  1154.       case GL_STENCIL_INDEX:
  1155.      read_stencil_pixels( ctx, x, y, width, height, type, pixels );
  1156.      break;
  1157.       case GL_DEPTH_COMPONENT:
  1158.      read_depth_pixels( ctx, x, y, width, height, type, pixels );
  1159.      break;
  1160.       case GL_RED:
  1161.       case GL_GREEN:
  1162.       case GL_BLUE:
  1163.       case GL_ALPHA:
  1164.       case GL_RGB:
  1165.       case GL_LUMINANCE:
  1166.       case GL_LUMINANCE_ALPHA:
  1167.       case GL_RGBA:
  1168.      read_color_pixels( ctx, x, y, width, height, format, type, pixels );
  1169.      break;
  1170.       default:
  1171.      gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
  1172.    }
  1173.  
  1174.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  1175. }
  1176.