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

  1. /* $Id: teximage.c,v 1.31 1997/11/07 03:38:07 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.5
  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: teximage.c,v $
  26.  * Revision 1.31  1997/11/07 03:38:07  brianp
  27.  * added stdio.h include for SunOS 4.x
  28.  *
  29.  * Revision 1.30  1997/11/02 20:20:30  brianp
  30.  * rewrote gl_TexSubImage[123]D()
  31.  *
  32.  * Revision 1.29  1997/10/16 01:14:04  brianp
  33.  * removed teximage Dirty flag
  34.  *
  35.  * Revision 1.28  1997/10/14 00:40:20  brianp
  36.  * added DavidB's v19 fxmesa changes
  37.  *
  38.  * Revision 1.27  1997/09/29 23:28:14  brianp
  39.  * updated for new device driver texture functions
  40.  *
  41.  * Revision 1.26  1997/09/28 15:29:03  brianp
  42.  * initialize image->Depth = 1 in read_color_image() (Hiroki Honda)
  43.  *
  44.  * Revision 1.25  1997/09/27 00:14:39  brianp
  45.  * added GL_EXT_paletted_texture extension
  46.  *
  47.  * Revision 1.24  1997/09/03 13:17:17  brianp
  48.  * added a few pointer casts
  49.  *
  50.  * Revision 1.23  1997/08/23 18:40:46  brianp
  51.  * glTexImage[123]D() with NULL image pointer is correctly handled now
  52.  *
  53.  * Revision 1.22  1997/08/11 01:23:29  brianp
  54.  * added a few pointer casts
  55.  *
  56.  * Revision 1.21  1997/07/24 01:25:34  brianp
  57.  * changed precompiled header symbol from PCH to PC_HEADER
  58.  *
  59.  * Revision 1.20  1997/07/05 16:21:17  brianp
  60.  * fixed unitialized variable bug in gl_TexSubImage1D()
  61.  *
  62.  * Revision 1.19  1997/06/24 01:13:53  brianp
  63.  * call gl_free_image() in gl_TexSubImage[123]D() if ref count==0
  64.  *
  65.  * Revision 1.18  1997/06/04 00:33:14  brianp
  66.  * fixed reference count bug in gl_CopyTexImage1/2D() (Randy Frank)
  67.  *
  68.  * Revision 1.17  1997/05/28 03:26:49  brianp
  69.  * added precompiled header (PCH) support
  70.  *
  71.  * Revision 1.16  1997/05/03 00:52:19  brianp
  72.  * set texture object Dirty flag when changing texture image
  73.  *
  74.  * Revision 1.15  1997/04/20 20:29:11  brianp
  75.  * replaced abort() with gl_problem()
  76.  *
  77.  * Revision 1.14  1997/03/04 19:18:29  brianp
  78.  * added texture image Width2, Height2, and Depth2 fields
  79.  *
  80.  * Revision 1.13  1997/02/27 19:58:08  brianp
  81.  * call gl_problem() instead of gl_warning()
  82.  *
  83.  * Revision 1.12  1997/02/09 18:53:05  brianp
  84.  * added GL_EXT_texture3D support
  85.  *
  86.  * Revision 1.11  1997/01/16 03:35:10  brianp
  87.  * added calls to device driver TexImage() function
  88.  *
  89.  * Revision 1.10  1997/01/09 21:26:46  brianp
  90.  * gl_TexImage[12]D() didn't free the incoming image- a memory leak
  91.  *
  92.  * Revision 1.9  1997/01/09 19:55:52  brianp
  93.  * fixed a few error messages
  94.  *
  95.  * Revision 1.8  1997/01/09 19:49:18  brianp
  96.  * better error checking
  97.  *
  98.  * Revision 1.7  1996/12/02 18:59:54  brianp
  99.  * added code to handle GL_COLOR_INDEX textures, per Randy Frank
  100.  *
  101.  * Revision 1.6  1996/11/07 04:13:24  brianp
  102.  * all new texture image handling, now pixel scale, bias, mapping work
  103.  *
  104.  * Revision 1.5  1996/09/27 01:29:57  brianp
  105.  * removed unused variables, fixed cut&paste bug in color scaling
  106.  *
  107.  * Revision 1.4  1996/09/26 22:35:10  brianp
  108.  * fixed a few compiler warnings from IRIX 6 -n32 and -64 compiler
  109.  *
  110.  * Revision 1.3  1996/09/15 14:18:55  brianp
  111.  * now use GLframebuffer and GLvisual
  112.  *
  113.  * Revision 1.2  1996/09/15 01:48:58  brianp
  114.  * removed #define NULL 0
  115.  *
  116.  * Revision 1.1  1996/09/13 01:38:16  brianp
  117.  * Initial revision
  118.  *
  119.  */
  120.  
  121.  
  122. #ifdef PC_HEADER
  123. #include "all.h"
  124. #else
  125. #include <assert.h>
  126. #include <stdio.h>
  127. #include <stdlib.h>
  128. #include <string.h>
  129. #include "context.h"
  130. #include "image.h"
  131. #include "macros.h"
  132. #include "pixel.h"
  133. #include "span.h"
  134. #include "teximage.h"
  135. #include "types.h"
  136. #endif
  137.  
  138.  
  139. /*
  140.  * NOTES:
  141.  *
  142.  * The internal texture storage convension is an array of N GLubytes
  143.  * where N = width * height * components.  There is no padding.
  144.  */
  145.  
  146.  
  147.  
  148.  
  149. /*
  150.  * Compute log base 2 of n.
  151.  * If n isn't an exact power of two return -1.
  152.  * If n<0 return -1.
  153.  */
  154. static int logbase2( int n )
  155. {
  156.    GLint i = 1;
  157.    GLint log2 = 0;
  158.  
  159.    if (n<0) {
  160.       return -1;
  161.    }
  162.  
  163.    while ( n > i ) {
  164.       i *= 2;
  165.       log2++;
  166.    }
  167.    if (i != n) {
  168.       return -1;
  169.    }
  170.    else {
  171.       return log2;
  172.    }
  173. }
  174.  
  175.  
  176.  
  177. /*
  178.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  179.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  180.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return -1 if
  181.  * invalid enum.
  182.  */
  183. static GLint decode_internal_format( GLint format )
  184. {
  185.    switch (format) {
  186.       case GL_ALPHA:
  187.       case GL_ALPHA4:
  188.       case GL_ALPHA8:
  189.       case GL_ALPHA12:
  190.       case GL_ALPHA16:
  191.          return GL_ALPHA;
  192.       case 1:
  193.       case GL_LUMINANCE:
  194.       case GL_LUMINANCE4:
  195.       case GL_LUMINANCE8:
  196.       case GL_LUMINANCE12:
  197.       case GL_LUMINANCE16:
  198.          return GL_LUMINANCE;
  199.       case 2:
  200.       case GL_LUMINANCE_ALPHA:
  201.       case GL_LUMINANCE4_ALPHA4:
  202.       case GL_LUMINANCE6_ALPHA2:
  203.       case GL_LUMINANCE8_ALPHA8:
  204.       case GL_LUMINANCE12_ALPHA4:
  205.       case GL_LUMINANCE12_ALPHA12:
  206.       case GL_LUMINANCE16_ALPHA16:
  207.          return GL_LUMINANCE_ALPHA;
  208.       case GL_INTENSITY:
  209.       case GL_INTENSITY4:
  210.       case GL_INTENSITY8:
  211.       case GL_INTENSITY12:
  212.       case GL_INTENSITY16:
  213.          return GL_INTENSITY;
  214.       case 3:
  215.       case GL_RGB:
  216.       case GL_R3_G3_B2:
  217.       case GL_RGB4:
  218.       case GL_RGB5:
  219.       case GL_RGB8:
  220.       case GL_RGB10:
  221.       case GL_RGB12:
  222.       case GL_RGB16:
  223.          return GL_RGB;
  224.       case 4:
  225.       case GL_RGBA:
  226.       case GL_RGBA2:
  227.       case GL_RGBA4:
  228.       case GL_RGB5_A1:
  229.       case GL_RGBA8:
  230.       case GL_RGB10_A2:
  231.       case GL_RGBA12:
  232.       case GL_RGBA16:
  233.          return GL_RGBA;
  234.       case GL_COLOR_INDEX1_EXT:
  235.       case GL_COLOR_INDEX2_EXT:
  236.       case GL_COLOR_INDEX4_EXT:
  237.       case GL_COLOR_INDEX8_EXT:
  238.       case GL_COLOR_INDEX12_EXT:
  239.       case GL_COLOR_INDEX16_EXT:
  240.          return GL_COLOR_INDEX;
  241.       default:
  242.          return -1;  /* error */
  243.    }
  244. }
  245.  
  246.  
  247.  
  248. /*
  249.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  250.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  251.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
  252.  * number of components for the format.  Return -1 if invalid enum.
  253.  */
  254. static GLint components_in_intformat( GLint format )
  255. {
  256.    switch (format) {
  257.       case GL_ALPHA:
  258.       case GL_ALPHA4:
  259.       case GL_ALPHA8:
  260.       case GL_ALPHA12:
  261.       case GL_ALPHA16:
  262.          return 1;
  263.       case 1:
  264.       case GL_LUMINANCE:
  265.       case GL_LUMINANCE4:
  266.       case GL_LUMINANCE8:
  267.       case GL_LUMINANCE12:
  268.       case GL_LUMINANCE16:
  269.          return 1;
  270.       case 2:
  271.       case GL_LUMINANCE_ALPHA:
  272.       case GL_LUMINANCE4_ALPHA4:
  273.       case GL_LUMINANCE6_ALPHA2:
  274.       case GL_LUMINANCE8_ALPHA8:
  275.       case GL_LUMINANCE12_ALPHA4:
  276.       case GL_LUMINANCE12_ALPHA12:
  277.       case GL_LUMINANCE16_ALPHA16:
  278.          return 2;
  279.       case GL_INTENSITY:
  280.       case GL_INTENSITY4:
  281.       case GL_INTENSITY8:
  282.       case GL_INTENSITY12:
  283.       case GL_INTENSITY16:
  284.          return 1;
  285.       case 3:
  286.       case GL_RGB:
  287.       case GL_R3_G3_B2:
  288.       case GL_RGB4:
  289.       case GL_RGB5:
  290.       case GL_RGB8:
  291.       case GL_RGB10:
  292.       case GL_RGB12:
  293.       case GL_RGB16:
  294.          return 3;
  295.       case 4:
  296.       case GL_RGBA:
  297.       case GL_RGBA2:
  298.       case GL_RGBA4:
  299.       case GL_RGB5_A1:
  300.       case GL_RGBA8:
  301.       case GL_RGB10_A2:
  302.       case GL_RGBA12:
  303.       case GL_RGBA16:
  304.          return 4;
  305.       case GL_COLOR_INDEX1_EXT:
  306.       case GL_COLOR_INDEX2_EXT:
  307.       case GL_COLOR_INDEX4_EXT:
  308.       case GL_COLOR_INDEX8_EXT:
  309.       case GL_COLOR_INDEX12_EXT:
  310.       case GL_COLOR_INDEX16_EXT:
  311.          return 1;
  312.       default:
  313.          return -1;  /* error */
  314.    }
  315. }
  316.  
  317.  
  318.  
  319. struct gl_texture_image *gl_alloc_texture_image( void )
  320. {
  321.    return (struct gl_texture_image *) calloc( 1, sizeof(struct gl_texture_image) );
  322. }
  323.  
  324.  
  325.  
  326. void gl_free_texture_image( struct gl_texture_image *teximage )
  327. {
  328.    if (teximage->Data) {
  329.       free( teximage->Data );
  330.    }
  331.    free( teximage );
  332. }
  333.  
  334.  
  335.  
  336. /*
  337.  * Given a gl_image, apply the pixel transfer scale, bias, and mapping
  338.  * to produce a gl_texture_image.  Convert image data to GLubytes.
  339.  * Input:  image - the incoming gl_image
  340.  *         internalFormat - desired format of resultant texture
  341.  *         border - texture border width (0 or 1)
  342.  * Return:  pointer to a gl_texture_image or NULL if an error occurs.
  343.  */
  344. static struct gl_texture_image *
  345. image_to_texture( GLcontext *ctx, const struct gl_image *image,
  346.                   GLenum internalFormat, GLint border )
  347. {
  348.    GLint components;
  349.    struct gl_texture_image *texImage;
  350.    GLint numPixels, pixel;
  351.    GLboolean scaleOrBias;
  352.  
  353.    assert(image);
  354.    assert(image->Width>0);
  355.    assert(image->Height>0);
  356.    assert(image->Depth>0);
  357.  
  358.    /*   internalFormat = decode_internal_format(internalFormat);*/
  359.    components = components_in_intformat(internalFormat);
  360.    numPixels = image->Width * image->Height * image->Depth;
  361.  
  362.    texImage = gl_alloc_texture_image();
  363.    if (!texImage)
  364.       return NULL;
  365.  
  366.    texImage->Format = decode_internal_format(internalFormat);
  367.    texImage->IntFormat = internalFormat;
  368.    texImage->Border = border;
  369.    texImage->Width = image->Width;
  370.    texImage->Height = image->Height;
  371.    texImage->Depth = image->Depth;
  372.    texImage->WidthLog2 = logbase2(image->Width - 2*border);
  373.    if (image->Height==1)  /* 1-D texture */
  374.       texImage->HeightLog2 = 0;
  375.    else
  376.       texImage->HeightLog2 = logbase2(image->Height - 2*border);
  377.    if (image->Depth==1)   /* 2-D texture */
  378.       texImage->DepthLog2 = 0;
  379.    else
  380.       texImage->DepthLog2 = logbase2(image->Depth - 2*border);
  381.    texImage->Width2 = 1 << texImage->WidthLog2;
  382.    texImage->Height2 = 1 << texImage->HeightLog2;
  383.    texImage->Depth2 = 1 << texImage->DepthLog2;
  384.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  385.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  386.  
  387.    assert(texImage->WidthLog2>=0);
  388.    assert(texImage->HeightLog2>=0);
  389.    assert(texImage->DepthLog2>=0);
  390.  
  391.    if (!texImage->Data) {
  392.       /* out of memory */
  393.       gl_free_texture_image( texImage );
  394.       return NULL;
  395.    }
  396.  
  397.    /* Determine if scaling and/or biasing is needed */
  398.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  399.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  400.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  401.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  402.       scaleOrBias = GL_TRUE;
  403.    }
  404.    else {
  405.       scaleOrBias = GL_FALSE;
  406.    }
  407.  
  408.    switch (image->Type) {
  409.       case GL_BITMAP:
  410.          {
  411.             GLint shift = ctx->Pixel.IndexShift;
  412.             GLint offset = ctx->Pixel.IndexOffset;
  413.             /* MapIto[RGBA]Size must be powers of two */
  414.             GLint rMask = ctx->Pixel.MapItoRsize-1;
  415.             GLint gMask = ctx->Pixel.MapItoGsize-1;
  416.             GLint bMask = ctx->Pixel.MapItoBsize-1;
  417.             GLint aMask = ctx->Pixel.MapItoAsize-1;
  418.             GLint i, j;
  419.             GLubyte *srcPtr = (GLubyte *) image->Data;
  420.  
  421.             assert( image->Format==GL_COLOR_INDEX );
  422.  
  423.             for (j=0; j<image->Height; j++) {
  424.                GLubyte bitMask = 128;
  425.                for (i=0; i<image->Width; i++) {
  426.                   GLint index;
  427.                   GLubyte red, green, blue, alpha;
  428.  
  429.                   /* Fetch image color index */
  430.                   index = (*srcPtr & bitMask) ? 1 : 0;
  431.                   bitMask = bitMask >> 1;
  432.                   if (bitMask==0) {
  433.                      bitMask = 128;
  434.                      srcPtr++;
  435.                   }
  436.                   /* apply index shift and offset */
  437.                   if (shift>=0) {
  438.                      index = (index << shift) + offset;
  439.                   }
  440.                   else {
  441.                      index = (index >> -shift) + offset;
  442.                   }
  443.                   /* convert index to RGBA */
  444.                   red   = (GLint) (ctx->Pixel.MapItoR[index & rMask] * 255.0F);
  445.                   green = (GLint) (ctx->Pixel.MapItoG[index & gMask] * 255.0F);
  446.                   blue  = (GLint) (ctx->Pixel.MapItoB[index & bMask] * 255.0F);
  447.                   alpha = (GLint) (ctx->Pixel.MapItoA[index & aMask] * 255.0F);
  448.  
  449.                   /* store texel (components are GLubytes in [0,255]) */
  450.                   pixel = j * image->Width + i;
  451.                   switch (texImage->Format) {
  452.                      case GL_ALPHA:
  453.                         texImage->Data[pixel] = alpha;
  454.                         break;
  455.                      case GL_LUMINANCE:
  456.                         texImage->Data[pixel] = red;
  457.                         break;
  458.                      case GL_LUMINANCE_ALPHA:
  459.                         texImage->Data[pixel*2+0] = red;
  460.                         texImage->Data[pixel*2+1] = alpha;
  461.                         break;
  462.                      case GL_INTENSITY:
  463.                         texImage->Data[pixel] = red;
  464.                         break;
  465.                      case GL_RGB:
  466.                         texImage->Data[pixel*3+0] = red;
  467.                         texImage->Data[pixel*3+1] = green;
  468.                         texImage->Data[pixel*3+2] = blue;
  469.                         break;
  470.                      case GL_RGBA:
  471.                         texImage->Data[pixel*4+0] = red;
  472.                         texImage->Data[pixel*4+1] = green;
  473.                         texImage->Data[pixel*4+2] = blue;
  474.                         texImage->Data[pixel*4+3] = alpha;
  475.                         break;
  476.                      default:
  477.                         gl_problem(ctx,"Bad format in image_to_texture");
  478.                         return NULL;
  479.                   }
  480.                }
  481.                if (bitMask!=128) {
  482.                   srcPtr++;
  483.                }
  484.             }
  485.          }
  486.          break;
  487.  
  488.       case GL_UNSIGNED_BYTE:
  489.          for (pixel=0; pixel<numPixels; pixel++) {
  490.             GLubyte red, green, blue, alpha;
  491.             switch (image->Format) {
  492.                case GL_COLOR_INDEX:
  493.                   if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
  494.                      /* a paletted texture */
  495.                      GLint index = ((GLubyte*)image->Data)[pixel];
  496.                      red = index;
  497.                   }
  498.                   else {
  499.                      /* convert color index to RGBA */
  500.                      GLint index = ((GLubyte*)image->Data)[pixel];
  501.                      red   = 255.0F * ctx->Pixel.MapItoR[index];
  502.                      green = 255.0F * ctx->Pixel.MapItoG[index];
  503.                      blue  = 255.0F * ctx->Pixel.MapItoB[index];
  504.                      alpha = 255.0F * ctx->Pixel.MapItoA[index];
  505.                   }
  506.                   break;
  507.                case GL_RGB:
  508.                   /* Fetch image RGBA values */
  509.                   red   = ((GLubyte*) image->Data)[pixel*3+0];
  510.                   green = ((GLubyte*) image->Data)[pixel*3+1];
  511.                   blue  = ((GLubyte*) image->Data)[pixel*3+2];
  512.                   alpha = 255;
  513.                   break;
  514.                case GL_RGBA:
  515.                   red   = ((GLubyte*) image->Data)[pixel*4+0];
  516.                   green = ((GLubyte*) image->Data)[pixel*4+1];
  517.                   blue  = ((GLubyte*) image->Data)[pixel*4+2];
  518.                   alpha = ((GLubyte*) image->Data)[pixel*4+3];
  519.                   break;
  520.                case GL_RED:
  521.                   red   = ((GLubyte*) image->Data)[pixel];
  522.                   green = 0;
  523.                   blue  = 0;
  524.                   alpha = 255;
  525.                   break;
  526.                case GL_GREEN:
  527.                   red   = 0;
  528.                   green = ((GLubyte*) image->Data)[pixel];
  529.                   blue  = 0;
  530.                   alpha = 255;
  531.                   break;
  532.                case GL_BLUE:
  533.                   red   = 0;
  534.                   green = 0;
  535.                   blue  = ((GLubyte*) image->Data)[pixel];
  536.                   alpha = 255;
  537.                   break;
  538.                case GL_ALPHA:
  539.                   red   = 0;
  540.                   green = 0;
  541.                   blue  = 0;
  542.                   alpha = ((GLubyte*) image->Data)[pixel];
  543.                   break;
  544.                case GL_LUMINANCE: 
  545.                   red   = ((GLubyte*) image->Data)[pixel];
  546.                   green = red;
  547.                   blue  = red;
  548.                   alpha = 255;
  549.                   break;
  550.               case GL_LUMINANCE_ALPHA:
  551.                   red   = ((GLubyte*) image->Data)[pixel*2+0];
  552.                   green = red;
  553.                   blue  = red;
  554.                   alpha = ((GLubyte*) image->Data)[pixel*2+1];
  555.                   break;
  556.               default:
  557.                  gl_problem(ctx,"Bad format (2) in image_to_texture");
  558.                  return NULL;
  559.             }
  560.             
  561.             if (scaleOrBias || ctx->Pixel.MapColorFlag) {
  562.                /* Apply RGBA scale and bias */
  563.                GLfloat r = red   * (1.0F/255.0F);
  564.                GLfloat g = green * (1.0F/255.0F);
  565.                GLfloat b = blue  * (1.0F/255.0F);
  566.                GLfloat a = alpha * (1.0F/255.0F);
  567.                if (scaleOrBias) {
  568.                   /* r,g,b,a now in [0,1] */
  569.                   r = r * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  570.                   g = g * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  571.                   b = b * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  572.                   a = a * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  573.                   r = CLAMP( r, 0.0F, 1.0F );
  574.                   g = CLAMP( g, 0.0F, 1.0F );
  575.                   b = CLAMP( b, 0.0F, 1.0F );
  576.                   a = CLAMP( a, 0.0F, 1.0F );
  577.                }
  578.                /* Apply pixel maps */
  579.                if (ctx->Pixel.MapColorFlag) {
  580.                   GLint ir = (GLint) (r*ctx->Pixel.MapRtoRsize);
  581.                   GLint ig = (GLint) (g*ctx->Pixel.MapGtoGsize);
  582.                   GLint ib = (GLint) (b*ctx->Pixel.MapBtoBsize);
  583.                   GLint ia = (GLint) (a*ctx->Pixel.MapAtoAsize);
  584.                   r = ctx->Pixel.MapRtoR[ir];
  585.                   g = ctx->Pixel.MapGtoG[ig];
  586.                   b = ctx->Pixel.MapBtoB[ib];
  587.                   a = ctx->Pixel.MapAtoA[ia];
  588.                }
  589.                red   = (GLint) (r * 255.0F);
  590.                green = (GLint) (g * 255.0F);
  591.                blue  = (GLint) (b * 255.0F);
  592.                alpha = (GLint) (a * 255.0F);
  593.             }
  594.  
  595.             /* store texel (components are GLubytes in [0,255]) */
  596.             switch (texImage->Format) {
  597.                case GL_COLOR_INDEX:
  598.                   texImage->Data[pixel] = red; /* really an index */
  599.                   break;
  600.                case GL_ALPHA:
  601.                   texImage->Data[pixel] = alpha;
  602.                   break;
  603.                case GL_LUMINANCE:
  604.                   texImage->Data[pixel] = red;
  605.                   break;
  606.                case GL_LUMINANCE_ALPHA:
  607.                   texImage->Data[pixel*2+0] = red;
  608.                   texImage->Data[pixel*2+1] = alpha;
  609.                   break;
  610.                case GL_INTENSITY:
  611.                   texImage->Data[pixel] = red;
  612.                   break;
  613.                case GL_RGB:
  614.                   texImage->Data[pixel*3+0] = red;
  615.                   texImage->Data[pixel*3+1] = green;
  616.                   texImage->Data[pixel*3+2] = blue;
  617.                   break;
  618.                case GL_RGBA:
  619.                   texImage->Data[pixel*4+0] = red;
  620.                   texImage->Data[pixel*4+1] = green;
  621.                   texImage->Data[pixel*4+2] = blue;
  622.                   texImage->Data[pixel*4+3] = alpha;
  623.                   break;
  624.                default:
  625.                   gl_problem(ctx,"Bad format (3) in image_to_texture");
  626.                   return NULL;
  627.             }
  628.          }
  629.          break;
  630.  
  631.       case GL_FLOAT:
  632.          for (pixel=0; pixel<numPixels; pixel++) {
  633.             GLfloat red, green, blue, alpha;
  634.             switch (texImage->Format) {
  635.                case GL_COLOR_INDEX:
  636.                   if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
  637.                      /* a paletted texture */
  638.                      GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  639.                      red = index;
  640.                   }
  641.                   else {
  642.                      GLint shift = ctx->Pixel.IndexShift;
  643.                      GLint offset = ctx->Pixel.IndexOffset;
  644.                      /* MapIto[RGBA]Size must be powers of two */
  645.                      GLint rMask = ctx->Pixel.MapItoRsize-1;
  646.                      GLint gMask = ctx->Pixel.MapItoGsize-1;
  647.                      GLint bMask = ctx->Pixel.MapItoBsize-1;
  648.                      GLint aMask = ctx->Pixel.MapItoAsize-1;
  649.                      /* Fetch image color index */
  650.                      GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  651.                      /* apply index shift and offset */
  652.                      if (shift>=0) {
  653.                         index = (index << shift) + offset;
  654.                      }
  655.                      else {
  656.                         index = (index >> -shift) + offset;
  657.                      }
  658.                      /* convert index to RGBA */
  659.                      red   = ctx->Pixel.MapItoR[index & rMask];
  660.                      green = ctx->Pixel.MapItoG[index & gMask];
  661.                      blue  = ctx->Pixel.MapItoB[index & bMask];
  662.                      alpha = ctx->Pixel.MapItoA[index & aMask];
  663.                   }
  664.                   break;
  665.                case GL_RGB:
  666.                   /* Fetch image RGBA values */
  667.                   red   = ((GLfloat*) image->Data)[pixel*3+0];
  668.                   green = ((GLfloat*) image->Data)[pixel*3+1];
  669.                   blue  = ((GLfloat*) image->Data)[pixel*3+2];
  670.                   alpha = 1.0;
  671.                   break;
  672.                case GL_RGBA:
  673.                   red   = ((GLfloat*) image->Data)[pixel*4+0];
  674.                   green = ((GLfloat*) image->Data)[pixel*4+1];
  675.                   blue  = ((GLfloat*) image->Data)[pixel*4+2];
  676.                   alpha = ((GLfloat*) image->Data)[pixel*4+3];
  677.                   break;
  678.                case GL_RED:
  679.                   red   = ((GLfloat*) image->Data)[pixel];
  680.                   green = 0.0;
  681.                   blue  = 0.0;
  682.                   alpha = 1.0;
  683.                   break;
  684.                case GL_GREEN:
  685.                   red   = 0.0;
  686.                   green = ((GLfloat*) image->Data)[pixel];
  687.                   blue  = 0.0;
  688.                   alpha = 1.0;
  689.                   break;
  690.                case GL_BLUE:
  691.                   red   = 0.0;
  692.                   green = 0.0;
  693.                   blue  = ((GLfloat*) image->Data)[pixel];
  694.                   alpha = 1.0;
  695.                   break;
  696.                case GL_ALPHA:
  697.                   red   = 0.0;
  698.                   green = 0.0;
  699.                   blue  = 0.0;
  700.                   alpha = ((GLfloat*) image->Data)[pixel];
  701.                   break;
  702.                case GL_LUMINANCE: 
  703.                   red   = ((GLfloat*) image->Data)[pixel];
  704.                   green = red;
  705.                   blue  = red;
  706.                   alpha = 1.0;
  707.                   break;
  708.               case GL_LUMINANCE_ALPHA:
  709.                   red   = ((GLfloat*) image->Data)[pixel*2+0];
  710.                   green = red;
  711.                   blue  = red;
  712.                   alpha = ((GLfloat*) image->Data)[pixel*2+1];
  713.                   break;
  714.                default:
  715.                   gl_problem(ctx,"Bad format (4) in image_to_texture");
  716.                   return NULL;
  717.             }
  718.             
  719.             if (image->Format!=GL_COLOR_INDEX) {
  720.                /* Apply RGBA scale and bias */
  721.                if (scaleOrBias) {
  722.                   red   = red   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  723.                   green = green * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  724.                   blue  = blue  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  725.                   alpha = alpha * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  726.                   red   = CLAMP( red,    0.0F, 1.0F );
  727.                   green = CLAMP( green,  0.0F, 1.0F );
  728.                   blue  = CLAMP( blue,   0.0F, 1.0F );
  729.                   alpha = CLAMP( alpha,  0.0F, 1.0F );
  730.                }
  731.                /* Apply pixel maps */
  732.                if (ctx->Pixel.MapColorFlag) {
  733.                   GLint ir = (GLint) (red  *ctx->Pixel.MapRtoRsize);
  734.                   GLint ig = (GLint) (green*ctx->Pixel.MapGtoGsize);
  735.                   GLint ib = (GLint) (blue *ctx->Pixel.MapBtoBsize);
  736.                   GLint ia = (GLint) (alpha*ctx->Pixel.MapAtoAsize);
  737.                   red   = ctx->Pixel.MapRtoR[ir];
  738.                   green = ctx->Pixel.MapGtoG[ig];
  739.                   blue  = ctx->Pixel.MapBtoB[ib];
  740.                   alpha = ctx->Pixel.MapAtoA[ia];
  741.                }
  742.             }
  743.  
  744.             /* store texel (components are GLubytes in [0,255]) */
  745.             switch (texImage->Format) {
  746.                case GL_COLOR_INDEX:
  747.                   /* a paletted texture */
  748.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  749.                   break;
  750.                case GL_ALPHA:
  751.                   texImage->Data[pixel] = (GLint) (alpha * 255.0F);
  752.                   break;
  753.                case GL_LUMINANCE:
  754.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  755.                   break;
  756.                case GL_LUMINANCE_ALPHA:
  757.                   texImage->Data[pixel*2+0] = (GLint) (red * 255.0F);
  758.                   texImage->Data[pixel*2+1] = (GLint) (alpha * 255.0F);
  759.                   break;
  760.                case GL_INTENSITY:
  761.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  762.                   break;
  763.                case GL_RGB:
  764.                   texImage->Data[pixel*3+0] = (GLint) (red   * 255.0F);
  765.                   texImage->Data[pixel*3+1] = (GLint) (green * 255.0F);
  766.                   texImage->Data[pixel*3+2] = (GLint) (blue  * 255.0F);
  767.                   break;
  768.                case GL_RGBA:
  769.                   texImage->Data[pixel*4+0] = (GLint) (red   * 255.0F);
  770.                   texImage->Data[pixel*4+1] = (GLint) (green * 255.0F);
  771.                   texImage->Data[pixel*4+2] = (GLint) (blue  * 255.0F);
  772.                   texImage->Data[pixel*4+3] = (GLint) (alpha * 255.0F);
  773.                   break;
  774.                default:
  775.                   gl_problem(ctx,"Bad format (5) in image_to_texture");
  776.                   return NULL;
  777.             }
  778.          }
  779.          break;
  780.  
  781.       default:
  782.          gl_problem(ctx, "Bad image type in image_to_texture");
  783.          return NULL;
  784.    }
  785.  
  786.    return texImage;
  787. }
  788.  
  789.  
  790.  
  791. /*
  792.  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  793.  * create a texture image with unspecified image contents per the OpenGL
  794.  * spec.
  795.  */
  796. static struct gl_texture_image *
  797. make_null_texture( GLcontext *ctx, GLenum internalFormat,
  798.                    GLsizei width, GLsizei height, GLsizei depth, GLint border )
  799. {
  800.    GLint components;
  801.    struct gl_texture_image *texImage;
  802.    GLint numPixels;
  803.  
  804.    /*internalFormat = decode_internal_format(internalFormat);*/
  805.    components = components_in_intformat(internalFormat);
  806.    numPixels = width * height * depth;
  807.  
  808.    texImage = gl_alloc_texture_image();
  809.    if (!texImage)
  810.       return NULL;
  811.  
  812.    texImage->Format = decode_internal_format(internalFormat);
  813.    texImage->IntFormat = internalFormat;
  814.    texImage->Border = border;
  815.    texImage->Width = width;
  816.    texImage->Height = height;
  817.    texImage->Depth = depth;
  818.    texImage->WidthLog2 = logbase2(width - 2*border);
  819.    if (height==1)  /* 1-D texture */
  820.       texImage->HeightLog2 = 0;
  821.    else
  822.       texImage->HeightLog2 = logbase2(height - 2*border);
  823.    if (depth==1)   /* 2-D texture */
  824.       texImage->DepthLog2 = 0;
  825.    else
  826.       texImage->DepthLog2 = logbase2(depth - 2*border);
  827.    texImage->Width2 = 1 << texImage->WidthLog2;
  828.    texImage->Height2 = 1 << texImage->HeightLog2;
  829.    texImage->Depth2 = 1 << texImage->DepthLog2;
  830.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  831.  
  832.    /* XXX should we really allocate memory for the image or let it be NULL? */
  833.    /*texImage->Data = NULL;*/
  834.  
  835.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  836.  
  837.    /*
  838.     * Let's see if anyone finds this.  If glTexImage2D() is called with
  839.     * a NULL image pointer then load the texture image with something
  840.     * interesting instead of leaving it indeterminate.
  841.     */
  842.    if (texImage->Data) {
  843.       char message[8][32] = {
  844.          "   X   X  XXXXX   XXX     X    ",
  845.          "   XX XX  X      X   X   X X   ",
  846.          "   X X X  X      X      X   X  ",
  847.          "   X   X  XXXX    XXX   XXXXX  ",
  848.          "   X   X  X          X  X   X  ",
  849.          "   X   X  X      X   X  X   X  ",
  850.          "   X   X  XXXXX   XXX   X   X  ",
  851.          "                               "
  852.       };
  853.  
  854.       GLubyte *imgPtr = texImage->Data;
  855.       GLint i, j, k;
  856.       for (i=0;i<height;i++) {
  857.          GLint srcRow = 7 - i % 8;
  858.          for (j=0;j<width;j++) {
  859.             GLint srcCol = j % 32;
  860.             GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
  861.             for (k=0;k<components;k++) {
  862.                *imgPtr++ = texel;
  863.             }
  864.          }
  865.       }
  866.    }
  867.  
  868.    return texImage;
  869. }
  870.  
  871.  
  872.  
  873.  
  874. /*
  875.  * Test glTexImagee1D() parameters for errors.
  876.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  877.  */
  878. static GLboolean texture_1d_error_check( GLcontext *ctx, GLenum target,
  879.                                          GLint level, GLenum internalFormat,
  880.                                          GLenum format, GLenum type,
  881.                                          GLint width, GLint border )
  882. {
  883.    GLint iformat;
  884.    if (target!=GL_TEXTURE_1D && target!=GL_PROXY_TEXTURE_1D) {
  885.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D" );
  886.       return GL_TRUE;
  887.    }
  888.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  889.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(level)" );
  890.       return GL_TRUE;
  891.    }
  892.    iformat = decode_internal_format( internalFormat );
  893.    if (iformat<0) {
  894.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(internalFormat)" );
  895.       return GL_TRUE;
  896.    }
  897.    if (border!=0 && border!=1) {
  898.       if (target!=GL_PROXY_TEXTURE_1D) {
  899.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(border)" );
  900.       }
  901.       return GL_TRUE;
  902.    }
  903.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  904.       if (target!=GL_PROXY_TEXTURE_1D) {
  905.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(width)" );
  906.       }
  907.       return GL_TRUE;
  908.    }
  909.    if (logbase2( width-2*border )<0) {
  910.       gl_error( ctx, GL_INVALID_VALUE,
  911.                "glTexImage1D(width != 2^k + 2*border)");
  912.       return GL_TRUE;
  913.    }
  914.    switch (format) {
  915.       case GL_COLOR_INDEX:
  916.       case GL_RED:
  917.       case GL_GREEN:
  918.       case GL_BLUE:
  919.       case GL_ALPHA:
  920.       case GL_RGB:
  921.       case GL_RGBA:
  922.       case GL_LUMINANCE:
  923.       case GL_LUMINANCE_ALPHA:
  924.          /* OK */
  925.          break;
  926.       default:
  927.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(format)" );
  928.          return GL_TRUE;
  929.    }
  930.    switch (type) {
  931.       case GL_UNSIGNED_BYTE:
  932.       case GL_BYTE:
  933.       case GL_UNSIGNED_SHORT:
  934.       case GL_SHORT:
  935.       case GL_FLOAT:
  936.          /* OK */
  937.          break;
  938.       default:
  939.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(type)" );
  940.          return GL_TRUE;
  941.    }
  942.    return GL_FALSE;
  943. }
  944.  
  945.  
  946. /*
  947.  * Test glTexImagee2D() parameters for errors.
  948.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  949.  */
  950. static GLboolean texture_2d_error_check( GLcontext *ctx, GLenum target,
  951.                                          GLint level, GLenum internalFormat,
  952.                                          GLenum format, GLenum type,
  953.                                          GLint width, GLint height,
  954.                                          GLint border )
  955. {
  956.    GLint iformat;
  957.    if (target!=GL_TEXTURE_2D && target!=GL_PROXY_TEXTURE_2D) {
  958.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  959.       return GL_TRUE;
  960.    }
  961.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  962.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(level)" );
  963.       return GL_TRUE;
  964.    }
  965.    iformat = decode_internal_format( internalFormat );
  966.    if (iformat<0) {
  967.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(internalFormat)" );
  968.       return GL_TRUE;
  969.    }
  970.    if (border!=0 && border!=1) {
  971.       if (target!=GL_PROXY_TEXTURE_2D) {
  972.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(border)" );
  973.       }
  974.       return GL_TRUE;
  975.    }
  976.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  977.       if (target!=GL_PROXY_TEXTURE_2D) {
  978.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(width)" );
  979.       }
  980.       return GL_TRUE;
  981.    }
  982.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  983.       if (target!=GL_PROXY_TEXTURE_2D) {
  984.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(height)" );
  985.       }
  986.       return GL_TRUE;
  987.    }
  988.    if (logbase2( width-2*border )<0) {
  989.       gl_error( ctx,GL_INVALID_VALUE,
  990.                "glTexImage2D(width != 2^k + 2*border)");
  991.       return GL_TRUE;
  992.    }
  993.    if (logbase2( height-2*border )<0) {
  994.       gl_error( ctx,GL_INVALID_VALUE,
  995.                "glTexImage2D(height != 2^k + 2*border)");
  996.       return GL_TRUE;
  997.    }
  998.    switch (format) {
  999.       case GL_COLOR_INDEX:
  1000.       case GL_RED:
  1001.       case GL_GREEN:
  1002.       case GL_BLUE:
  1003.       case GL_ALPHA:
  1004.       case GL_RGB:
  1005.       case GL_RGBA:
  1006.       case GL_LUMINANCE:
  1007.       case GL_LUMINANCE_ALPHA:
  1008.          /* OK */
  1009.          break;
  1010.       default:
  1011.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(format)" );
  1012.          return GL_TRUE;
  1013.    }
  1014.    switch (type) {
  1015.       case GL_UNSIGNED_BYTE:
  1016.       case GL_BYTE:
  1017.       case GL_UNSIGNED_SHORT:
  1018.       case GL_SHORT:
  1019.       case GL_UNSIGNED_INT:
  1020.       case GL_INT:
  1021.       case GL_FLOAT:
  1022.          /* OK */
  1023.          break;
  1024.       default:
  1025.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(type)" );
  1026.          return GL_TRUE;
  1027.    }
  1028.    return GL_FALSE;
  1029. }
  1030.  
  1031.  
  1032. /*
  1033.  * Test glTexImage3DEXT() parameters for errors.
  1034.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  1035.  */
  1036. static GLboolean texture_3d_error_check( GLcontext *ctx, GLenum target,
  1037.                                          GLint level, GLenum internalFormat,
  1038.                                          GLenum format, GLenum type,
  1039.                                          GLint width, GLint height,
  1040.                                          GLint depth, GLint border )
  1041. {
  1042.    GLint iformat;
  1043.    if (target!=GL_TEXTURE_3D_EXT && target!=GL_PROXY_TEXTURE_3D_EXT) {
  1044.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  1045.       return GL_TRUE;
  1046.    }
  1047.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1048.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(level)" );
  1049.       return GL_TRUE;
  1050.    }
  1051.    iformat = decode_internal_format( internalFormat );
  1052.    if (iformat<0) {
  1053.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(internalFormat)" );
  1054.       return GL_TRUE;
  1055.    }
  1056.    if (border!=0 && border!=1) {
  1057.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1058.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(border)" );
  1059.       }
  1060.       return GL_TRUE;
  1061.    }
  1062.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  1063.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1064.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(width)" );
  1065.       }
  1066.       return GL_TRUE;
  1067.    }
  1068.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  1069.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1070.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(height)" );
  1071.       }
  1072.       return GL_TRUE;
  1073.    }
  1074.    if (depth<2*border || depth>2+MAX_TEXTURE_SIZE) {
  1075.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1076.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(depth)" );
  1077.       }
  1078.       return GL_TRUE;
  1079.    }
  1080.    if (logbase2( width-2*border )<0) {
  1081.       gl_error( ctx,GL_INVALID_VALUE,
  1082.                "glTexImage3DEXT(width != 2^k + 2*border))");
  1083.       return GL_TRUE;
  1084.    }
  1085.    if (logbase2( height-2*border )<0) {
  1086.       gl_error( ctx,GL_INVALID_VALUE,
  1087.                "glTexImage3DEXT(height != 2^k + 2*border))");
  1088.       return GL_TRUE;
  1089.    }
  1090.    if (logbase2( depth-2*border )<0) {
  1091.       gl_error( ctx,GL_INVALID_VALUE,
  1092.                "glTexImage3DEXT(depth  != 2^k + 2*border))");
  1093.       return GL_TRUE;
  1094.    }
  1095.    switch (format) {
  1096.       case GL_COLOR_INDEX:
  1097.       case GL_RED:
  1098.       case GL_GREEN:
  1099.       case GL_BLUE:
  1100.       case GL_ALPHA:
  1101.       case GL_RGB:
  1102.       case GL_RGBA:
  1103.       case GL_LUMINANCE:
  1104.       case GL_LUMINANCE_ALPHA:
  1105.          /* OK */
  1106.          break;
  1107.       default:
  1108.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(format)" );
  1109.          return GL_TRUE;
  1110.    }
  1111.    switch (type) {
  1112.       case GL_UNSIGNED_BYTE:
  1113.       case GL_BYTE:
  1114.       case GL_UNSIGNED_SHORT:
  1115.       case GL_SHORT:
  1116.       case GL_UNSIGNED_INT:
  1117.       case GL_INT:
  1118.       case GL_FLOAT:
  1119.          /* OK */
  1120.          break;
  1121.       default:
  1122.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(type)" );
  1123.          return GL_TRUE;
  1124.    }
  1125.    return GL_FALSE;
  1126. }
  1127.  
  1128.  
  1129.  
  1130. /*
  1131.  * Called from the API.  Note that width includes the border.
  1132.  */
  1133. void gl_TexImage1D( GLcontext *ctx,
  1134.                     GLenum target, GLint level, GLint internalformat,
  1135.             GLsizei width, GLint border, GLenum format,
  1136.             GLenum type, struct gl_image *image )
  1137. {
  1138.    if (INSIDE_BEGIN_END(ctx)) {
  1139.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage1D" );
  1140.       return;
  1141.    }
  1142.  
  1143.    if (target==GL_TEXTURE_1D) {
  1144.       struct gl_texture_image *teximage;
  1145.       if (texture_1d_error_check( ctx, target, level, internalformat,
  1146.                                   format, type, width, border )) {
  1147.          /* error in texture image was detected */
  1148.          return;
  1149.       }
  1150.  
  1151.       /* free current texture image, if any */
  1152.       if (ctx->Texture.Current1D->Image[level]) {
  1153.          gl_free_texture_image( ctx->Texture.Current1D->Image[level] );
  1154.       }
  1155.  
  1156.       /* make new texture from source image */
  1157.       if (image) {
  1158.          teximage = image_to_texture(ctx, image, internalformat, border);
  1159.       }
  1160.       else {
  1161.          teximage = make_null_texture(ctx, internalformat,
  1162.                                       width, 1, 1, border);
  1163.       }
  1164.  
  1165.       /* install new texture image */
  1166.       ctx->Texture.Current1D->Image[level] = teximage;
  1167.       ctx->Texture.Current1D->Dirty = GL_TRUE;
  1168.       ctx->NewState |= NEW_TEXTURING;
  1169.  
  1170.       /* free the source image */
  1171.       if (image && image->RefCount==0) {
  1172.          /* if RefCount>0 then image must be in a display list */
  1173.          gl_free_image(image);
  1174.       }
  1175.  
  1176.       /* tell driver about change */
  1177.       if (ctx->Driver.TexImage) {
  1178.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  1179.                                   ctx->Texture.Current1D,
  1180.                                   level, internalformat, teximage );
  1181.       }
  1182.    }
  1183.    else if (target==GL_PROXY_TEXTURE_1D) {
  1184.       /* Proxy texture: check for errors and update proxy state */
  1185.       if (texture_1d_error_check( ctx, target, level, internalformat,
  1186.                                   format, type, width, border )) {
  1187.          if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1188.             MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
  1189.                     sizeof(struct gl_texture_image) );
  1190.          }
  1191.       }
  1192.       else {
  1193.          ctx->Texture.Proxy1D->Image[level]->Format = internalformat;
  1194.          ctx->Texture.Proxy1D->Image[level]->Border = border;
  1195.          ctx->Texture.Proxy1D->Image[level]->Width = width;
  1196.          ctx->Texture.Proxy1D->Image[level]->Height = 1;
  1197.       }
  1198.       if (image->RefCount==0) {
  1199.          /* if RefCount>0 then image must be in a display list */
  1200.          gl_free_image(image);
  1201.       }
  1202.    }
  1203.    else {
  1204.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  1205.       return;
  1206.    }
  1207. }
  1208.  
  1209.  
  1210.  
  1211.  
  1212. /*
  1213.  * Called by the API or display list executor.
  1214.  * Note that width and height include the border.
  1215.  */
  1216. void gl_TexImage2D( GLcontext *ctx,
  1217.                     GLenum target, GLint level, GLint internalformat,
  1218.                     GLsizei width, GLsizei height, GLint border,
  1219.                     GLenum format, GLenum type,
  1220.                     struct gl_image *image )
  1221. {
  1222.    if (INSIDE_BEGIN_END(ctx)) {
  1223.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage2D" );
  1224.       return;
  1225.    }
  1226.  
  1227.    if (target==GL_TEXTURE_2D) {
  1228.       struct gl_texture_image *teximage;
  1229.       if (texture_2d_error_check( ctx, target, level, internalformat,
  1230.                                   format, type, width, height, border )) {
  1231.          /* error in texture image was detected */
  1232.          return;
  1233.       }
  1234.  
  1235.       /* free current texture image, if any */
  1236.       if (ctx->Texture.Current2D->Image[level]) {
  1237.          gl_free_texture_image( ctx->Texture.Current2D->Image[level] );
  1238.       }
  1239.  
  1240.       /* make new texture from source image */
  1241.       if (image) {
  1242.          teximage = image_to_texture(ctx, image, internalformat, border);
  1243.       }
  1244.       else {
  1245.          teximage = make_null_texture(ctx, internalformat,
  1246.                                       width, height, 1, border);
  1247.       }
  1248.  
  1249.       /* install new texture image */
  1250.       ctx->Texture.Current2D->Image[level] = teximage;
  1251.       ctx->Texture.Current2D->Dirty = GL_TRUE;
  1252.       ctx->NewState |= NEW_TEXTURING;
  1253.  
  1254.       /* free the source image */
  1255.       if (image && image->RefCount==0) {
  1256.          /* if RefCount>0 then image must be in a display list */
  1257.          gl_free_image(image);
  1258.       }
  1259.  
  1260.       /* tell driver about change */
  1261.       if (ctx->Driver.TexImage) {
  1262.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
  1263.                                   ctx->Texture.Current2D,
  1264.                                   level, internalformat, teximage );
  1265.       }
  1266.    }
  1267.    else if (target==GL_PROXY_TEXTURE_2D) {
  1268.       /* Proxy texture: check for errors and update proxy state */
  1269.       if (texture_2d_error_check( ctx, target, level, internalformat,
  1270.                                   format, type, width, height, border )) {
  1271.          if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1272.             MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
  1273.                     sizeof(struct gl_texture_image) );
  1274.          }
  1275.       }
  1276.       else {
  1277.          ctx->Texture.Proxy2D->Image[level]->Format = internalformat;
  1278.          ctx->Texture.Proxy2D->Image[level]->Border = border;
  1279.          ctx->Texture.Proxy2D->Image[level]->Width = width;
  1280.          ctx->Texture.Proxy2D->Image[level]->Height = height;
  1281.       }
  1282.       if (image->RefCount==0) {
  1283.          /* if RefCount>0 then image must be in a display list */
  1284.          gl_free_image(image);
  1285.       }
  1286.    }
  1287.    else {
  1288.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  1289.       return;
  1290.    }
  1291. }
  1292.  
  1293.  
  1294.  
  1295. /*
  1296.  * Called by the API or display list executor.
  1297.  * Note that width and height include the border.
  1298.  */
  1299. void gl_TexImage3DEXT( GLcontext *ctx,
  1300.                        GLenum target, GLint level, GLint internalformat,
  1301.                        GLsizei width, GLsizei height, GLsizei depth,
  1302.                        GLint border, GLenum format, GLenum type,
  1303.                        struct gl_image *image )
  1304. {
  1305.    if (INSIDE_BEGIN_END(ctx)) {
  1306.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage3DEXT" );
  1307.       return;
  1308.    }
  1309.  
  1310.    if (target==GL_TEXTURE_3D_EXT) {
  1311.       struct gl_texture_image *teximage;
  1312.       if (texture_3d_error_check( ctx, target, level, internalformat,
  1313.                                   format, type, width, height, depth,
  1314.                                   border )) {
  1315.          /* error in texture image was detected */
  1316.          return;
  1317.       }
  1318.  
  1319.       /* free current texture image, if any */
  1320.       if (ctx->Texture.Current3D->Image[level]) {
  1321.          gl_free_texture_image( ctx->Texture.Current3D->Image[level] );
  1322.       }
  1323.  
  1324.       /* make new texture from source image */
  1325.       if (image) {
  1326.          teximage = image_to_texture(ctx, image, internalformat, border);
  1327.       }
  1328.       else {
  1329.          teximage = make_null_texture(ctx, internalformat,
  1330.                                       width, height, depth, border);
  1331.       }
  1332.  
  1333.       /* install new texture image */
  1334.       ctx->Texture.Current3D->Image[level] = teximage;
  1335.       ctx->Texture.Current3D->Dirty = GL_TRUE;
  1336.       ctx->NewState |= NEW_TEXTURING;
  1337.  
  1338.       /* free the source image */
  1339.       if (image && image->RefCount==0) {
  1340.          /* if RefCount>0 then image must be in a display list */
  1341.          gl_free_image(image);
  1342.       }
  1343.  
  1344.       /* tell driver about change */
  1345.       if (ctx->Driver.TexImage) {
  1346.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
  1347.                                   ctx->Texture.Current3D,
  1348.                                   level, internalformat, teximage );
  1349.       }
  1350.    }
  1351.    else if (target==GL_PROXY_TEXTURE_3D_EXT) {
  1352.       /* Proxy texture: check for errors and update proxy state */
  1353.       if (texture_3d_error_check( ctx, target, level, internalformat,
  1354.                                   format, type, width, height, depth,
  1355.                                   border )) {
  1356.          if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1357.             MEMSET( ctx->Texture.Proxy3D->Image[level], 0,
  1358.                     sizeof(struct gl_texture_image) );
  1359.          }
  1360.       }
  1361.       else {
  1362.          ctx->Texture.Proxy3D->Image[level]->Format = internalformat;
  1363.          ctx->Texture.Proxy3D->Image[level]->Border = border;
  1364.          ctx->Texture.Proxy3D->Image[level]->Width = width;
  1365.          ctx->Texture.Proxy3D->Image[level]->Height = height;
  1366.          ctx->Texture.Proxy3D->Image[level]->Depth  = depth;
  1367.       }
  1368.       if (image->RefCount==0) {
  1369.          /* if RefCount>0 then image must be in a display list */
  1370.          gl_free_image(image);
  1371.       }
  1372.    }
  1373.    else {
  1374.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  1375.       return;
  1376.    }
  1377. }
  1378.  
  1379.  
  1380.  
  1381. void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
  1382.                      GLenum type, GLvoid *pixels )
  1383. {
  1384.    gl_problem(ctx, "glGetTexImage not implemented");
  1385.    /* TODO */
  1386. }
  1387.  
  1388.  
  1389.  
  1390.  
  1391. /*
  1392.  * Unpack the image data given to glTexSubImage[123]D.
  1393.  * This function is just a wrapper for gl_unpack_image() but it does
  1394.  * some extra error checking.
  1395.  */
  1396. struct gl_image *
  1397. gl_unpack_texsubimage( GLcontext *ctx, GLint width, GLint height, GLint depth,
  1398.                        GLenum format, GLenum type, const GLvoid *pixels )
  1399. {
  1400.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1401.       return NULL;
  1402.    }
  1403.  
  1404.    if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
  1405.       return NULL;
  1406.    }
  1407.  
  1408.    if (gl_sizeof_type(type)<=0) {
  1409.       return NULL;
  1410.    }
  1411.  
  1412.    return gl_unpack_image3D( ctx, width, height, depth, format, type, pixels );
  1413. }
  1414.  
  1415.  
  1416.  
  1417. void gl_TexSubImage1D( GLcontext *ctx,
  1418.                        GLenum target, GLint level, GLint xoffset,
  1419.                        GLsizei width, GLenum format, GLenum type,
  1420.                        struct gl_image *image )
  1421. {
  1422.    struct gl_texture_image *destTex;
  1423.  
  1424.    if (target!=GL_TEXTURE_1D) {
  1425.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
  1426.       return;
  1427.    }
  1428.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1429.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(level)" );
  1430.       return;
  1431.    }
  1432.  
  1433.    destTex = ctx->Texture.Current1D->Image[level];
  1434.    if (!destTex) {
  1435.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage1D" );
  1436.       return;
  1437.    }
  1438.  
  1439.    if (xoffset < -destTex->Border) {
  1440.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset)" );
  1441.       return;
  1442.    }
  1443.    if (xoffset + width > destTex->Width + destTex->Border) {
  1444.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset+width)" );
  1445.       return;
  1446.    }
  1447.  
  1448.    if (image) {
  1449.       /* unpacking must have been error-free */
  1450.       GLint texcomponents = components_in_intformat(destTex->Format);
  1451.  
  1452.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1453.          /* Simple case, just byte copy image data into texture image */
  1454.          /* row by row. */
  1455.          GLubyte *dst = destTex->Data + texcomponents * xoffset;
  1456.          GLubyte *src = (GLubyte *) image->Data;
  1457.          MEMCPY( dst, src, width * texcomponents );
  1458.       }
  1459.       else {
  1460.          /* General case, convert image pixels into texels, scale, bias, etc */
  1461.          struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1462.                                         destTex->IntFormat, destTex->Border);
  1463.          GLubyte *dst = destTex->Data + texcomponents * xoffset;
  1464.          GLubyte *src = subTexImg->Data;
  1465.          MEMCPY( dst, src, width * texcomponents );
  1466.          gl_free_texture_image(subTexImg);
  1467.       }
  1468.  
  1469.       /* if the image's reference count is zero, delete it now */
  1470.       if (image->RefCount==0) {
  1471.          gl_free_image(image);
  1472.       }
  1473.  
  1474.       ctx->Texture.Current1D->Dirty = GL_TRUE;
  1475.  
  1476.       /* tell driver about change */
  1477.       if (ctx->Driver.TexImage) {
  1478.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  1479.                                   ctx->Texture.Current1D,
  1480.                                   level, ctx->Texture.Current1D->Image[level]->IntFormat,
  1481.                   destTex );
  1482.       }
  1483.    }
  1484.    else {
  1485.       /* if no image, an error must have occured, do more testing now */
  1486.       GLint components, size;
  1487.  
  1488.       if (width<0) {
  1489.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(width)" );
  1490.          return;
  1491.       }
  1492.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1493.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1494.          return;
  1495.       }
  1496.       components = components_in_intformat( format );
  1497.       if (components<0 || format==GL_STENCIL_INDEX
  1498.           || format==GL_DEPTH_COMPONENT){
  1499.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1500.          return;
  1501.       }
  1502.       size = gl_sizeof_type( type );
  1503.       if (size<=0) {
  1504.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(type)" );
  1505.          return;
  1506.       }
  1507.       /* if we get here, probably ran out of memory during unpacking */
  1508.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D" );
  1509.    }
  1510. }
  1511.  
  1512.  
  1513.  
  1514. void gl_TexSubImage2D( GLcontext *ctx,
  1515.                        GLenum target, GLint level,
  1516.                        GLint xoffset, GLint yoffset,
  1517.                        GLsizei width, GLsizei height,
  1518.                        GLenum format, GLenum type,
  1519.                        struct gl_image *image )
  1520. {
  1521.    struct gl_texture_image *destTex;
  1522.  
  1523.    if (target!=GL_TEXTURE_2D) {
  1524.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
  1525.       return;
  1526.    }
  1527.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1528.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(level)" );
  1529.       return;
  1530.    }
  1531.  
  1532.    destTex = ctx->Texture.Current2D->Image[level];
  1533.    if (!destTex) {
  1534.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage2D" );
  1535.       return;
  1536.    }
  1537.  
  1538.    if (xoffset < -destTex->Border) {
  1539.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset)" );
  1540.       return;
  1541.    }
  1542.    if (yoffset < -destTex->Border) {
  1543.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset)" );
  1544.       return;
  1545.    }
  1546.    if (xoffset + width > destTex->Width + destTex->Border) {
  1547.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset+width)" );
  1548.       return;
  1549.    }
  1550.    if (yoffset + height > destTex->Height + destTex->Border) {
  1551.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset+height)" );
  1552.       return;
  1553.    }
  1554.  
  1555.    if (image) {
  1556.       /* unpacking must have been error-free */
  1557.       GLint texcomponents = components_in_intformat(destTex->Format);
  1558.  
  1559.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1560.          /* Simple case, just byte copy image data into texture image */
  1561.          /* row by row. */
  1562.          GLubyte *dst = destTex->Data 
  1563.                       + (yoffset * destTex->Width + xoffset) * texcomponents;
  1564.          GLubyte *src = (GLubyte *) image->Data;
  1565.          GLint  j;
  1566.          for (j=0;j<height;j++) {
  1567.             MEMCPY( dst, src, width * texcomponents );
  1568.             dst += destTex->Width * texcomponents * sizeof(GLubyte);
  1569.             src += width * texcomponents * sizeof(GLubyte);
  1570.          }
  1571.       }
  1572.       else {
  1573.          /* General case, convert image pixels into texels, scale, bias, etc */
  1574.          struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1575.                                         destTex->IntFormat, destTex->Border);
  1576.          GLubyte *dst = destTex->Data
  1577.                   + (yoffset * destTex->Width + xoffset) * texcomponents;
  1578.          GLubyte *src = subTexImg->Data;
  1579.          GLint j;
  1580.          for (j=0;j<height;j++) {
  1581.             MEMCPY( dst, src, width * texcomponents );
  1582.             dst += destTex->Width * texcomponents * sizeof(GLubyte);
  1583.             src += width * texcomponents * sizeof(GLubyte);
  1584.          }
  1585.          gl_free_texture_image(subTexImg);
  1586.       }
  1587.  
  1588.       /* if the image's reference count is zero, delete it now */
  1589.       if (image->RefCount==0) {
  1590.          gl_free_image(image);
  1591.       }
  1592.  
  1593.       ctx->Texture.Current2D->Dirty = GL_TRUE;
  1594.  
  1595.       /* tell driver about change */
  1596.       if (ctx->Driver.TexImage) {
  1597.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, ctx->Texture.Current2D,
  1598.                                   level, ctx->Texture.Current2D->Image[level]->IntFormat,
  1599.                   destTex );
  1600.       }
  1601.    }
  1602.    else {
  1603.       /* if no image, an error must have occured, do more testing now */
  1604.       GLint components, size;
  1605.  
  1606.       if (width<0) {
  1607.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(width)" );
  1608.          return;
  1609.       }
  1610.       if (height<0) {
  1611.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(height)" );
  1612.          return;
  1613.       }
  1614.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1615.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1616.          return;
  1617.       }
  1618.       components = gl_components_in_format( format );
  1619.       if (components<0 || format==GL_STENCIL_INDEX
  1620.           || format==GL_DEPTH_COMPONENT){
  1621.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(format)" );
  1622.          return;
  1623.       }
  1624.       size = gl_sizeof_type( type );
  1625.       if (size<=0) {
  1626.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(type)" );
  1627.          return;
  1628.       }
  1629.       /* if we get here, probably ran out of memory during unpacking */
  1630.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D" );
  1631.    }
  1632. }
  1633.  
  1634.  
  1635.  
  1636. void gl_TexSubImage3DEXT( GLcontext *ctx,
  1637.                           GLenum target, GLint level,
  1638.                           GLint xoffset, GLint yoffset, GLint zoffset,
  1639.                           GLsizei width, GLsizei height, GLsizei depth,
  1640.                           GLenum format, GLenum type,
  1641.                           struct gl_image *image )
  1642. {
  1643.    struct gl_texture_image *destTex;
  1644.  
  1645.    if (target!=GL_TEXTURE_3D_EXT) {
  1646.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(target)" );
  1647.       return;
  1648.    }
  1649.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1650.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(level)" );
  1651.       return;
  1652.    }
  1653.  
  1654.    destTex = ctx->Texture.Current3D->Image[level];
  1655.    if (!destTex) {
  1656.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage3DEXT" );
  1657.       return;
  1658.    }
  1659.  
  1660.    if (xoffset < -destTex->Border) {
  1661.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset)" );
  1662.       return;
  1663.    }
  1664.    if (yoffset < -destTex->Border) {
  1665.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset)" );
  1666.       return;
  1667.    }
  1668.    if (zoffset < -destTex->Border) {
  1669.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset)" );
  1670.       return;
  1671.    }
  1672.    if (xoffset + width > destTex->Width+destTex->Border) {
  1673.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset+width)" );
  1674.       return;
  1675.    }
  1676.    if (yoffset + height > destTex->Height+destTex->Border) {
  1677.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset+height)" );
  1678.       return;
  1679.    }
  1680.    if (zoffset + depth  > destTex->Depth+destTex->Border) {
  1681.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset+depth)" );
  1682.       return;
  1683.    }
  1684.  
  1685.    if (image) {
  1686.       /* unpacking must have been error-free */
  1687.       GLint texcomponents = components_in_intformat(destTex->Format);
  1688.       GLint dstRectArea = destTex->Width * destTex->Height;
  1689.       GLint srcRectArea = width * height;
  1690.  
  1691.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1692.          /* Simple case, just byte copy image data into texture image */
  1693.          /* row by row. */
  1694.          GLubyte *dst = destTex->Data 
  1695.                + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
  1696.                * texcomponents;
  1697.          GLubyte *src = (GLubyte *) image->Data;
  1698.          GLint j, k;
  1699.          for(k=0;k<depth; k++) {
  1700.            for (j=0;j<height;j++) {
  1701.               MEMCPY( dst, src, width * texcomponents );
  1702.               dst += destTex->Width * texcomponents;
  1703.               src += width * texcomponents;
  1704.            }
  1705.            dst += dstRectArea * texcomponents * sizeof(GLubyte);
  1706.            src += srcRectArea * texcomponents * sizeof(GLubyte);
  1707.          }
  1708.       }
  1709.       else {
  1710.          /* General case, convert image pixels into texels, scale, bias, etc */
  1711.          struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1712.                                         destTex->IntFormat, destTex->Border);
  1713.          GLubyte *dst = destTex->Data 
  1714.                + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
  1715.                * texcomponents;
  1716.          GLubyte *src = subTexImg->Data;
  1717.          GLint j, k;
  1718.          for(k=0;k<depth; k++) {
  1719.            for (j=0;j<height;j++) {
  1720.               MEMCPY( dst, src, width * texcomponents );
  1721.               dst += destTex->Width * texcomponents;
  1722.               src += width * texcomponents;
  1723.            }
  1724.            dst += dstRectArea * texcomponents * sizeof(GLubyte);
  1725.            src += srcRectArea * texcomponents * sizeof(GLubyte);
  1726.          }
  1727.          gl_free_texture_image(subTexImg);
  1728.       }
  1729.       /* if the image's reference count is zero, delete it now */
  1730.       if (image->RefCount==0) {
  1731.          gl_free_image(image);
  1732.       }
  1733.  
  1734.       ctx->Texture.Current3D->Dirty = GL_TRUE;
  1735.  
  1736.       /* tell driver about change */
  1737.       if (ctx->Driver.TexImage) {
  1738.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
  1739.                                   ctx->Texture.Current3D,
  1740.                                   level, ctx->Texture.Current3D->Image[level]->IntFormat,
  1741.                   destTex );
  1742.       }
  1743.    }
  1744.    else {
  1745.       /* if no image, an error must have occured, do more testing now */
  1746.       GLint components, size;
  1747.  
  1748.       if (width<0) {
  1749.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(width)" );
  1750.          return;
  1751.       }
  1752.       if (height<0) {
  1753.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(height)" );
  1754.          return;
  1755.       }
  1756.       if (depth<0) {
  1757.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(depth)" );
  1758.          return;
  1759.       }
  1760.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1761.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1762.          return;
  1763.       }
  1764.       components = components_in_intformat( format );
  1765.       if (components<0 || format==GL_STENCIL_INDEX
  1766.           || format==GL_DEPTH_COMPONENT){
  1767.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1768.          return;
  1769.       }
  1770.       size = gl_sizeof_type( type );
  1771.       if (size<=0) {
  1772.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(type)" );
  1773.          return;
  1774.       }
  1775.       /* if we get here, probably ran out of memory during unpacking */
  1776.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage3DEXT" );
  1777.    }
  1778. }
  1779.  
  1780.  
  1781.  
  1782. /*
  1783.  * Read an RGBA image from the frame buffer.
  1784.  * Input:  ctx - the context
  1785.  *         x, y - lower left corner
  1786.  *         width, height - size of region to read
  1787.  *         format - one of GL_RED, GL_RGB, GL_LUMINANCE, etc.
  1788.  * Return: gl_image pointer or NULL if out of memory
  1789.  */
  1790. static struct gl_image *read_color_image( GLcontext *ctx, GLint x, GLint y,
  1791.                                           GLsizei width, GLsizei height,
  1792.                                           GLint format )
  1793. {
  1794.    struct gl_image *image;
  1795.    GLubyte *imgptr;
  1796.    GLint components;
  1797.    GLint i, j;
  1798.  
  1799.    components = components_in_intformat( format );
  1800.  
  1801.    /*
  1802.     * Allocate image struct and image data buffer
  1803.     */
  1804.    image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  1805.    if (image) {
  1806.       image->Width = width;
  1807.       image->Height = height;
  1808.       image->Depth = 1;
  1809.       image->Components = components;
  1810.       image->Format = format;
  1811.       image->Type = GL_UNSIGNED_BYTE;
  1812.       image->RefCount = 0;
  1813.       image->Data = (GLubyte *) malloc( width * height * components );
  1814.       if (!image->Data) {
  1815.          free(image);
  1816.          return NULL;
  1817.       }
  1818.    }
  1819.    else {
  1820.       return NULL;
  1821.    }
  1822.  
  1823.    imgptr = (GLubyte *) image->Data;
  1824.  
  1825.    /* Select buffer to read from */
  1826.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  1827.  
  1828.    for (j=0;j<height;j++) {
  1829.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  1830.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  1831.       gl_read_color_span( ctx, width, x, y+j, red, green, blue, alpha );
  1832.  
  1833.       if (!ctx->Visual->EightBitColor) {
  1834.          /* scale red, green, blue, alpha values to range [0,255] */
  1835.          GLfloat rscale = 255.0f * ctx->Visual->InvRedScale;
  1836.          GLfloat gscale = 255.0f * ctx->Visual->InvGreenScale;
  1837.          GLfloat bscale = 255.0f * ctx->Visual->InvBlueScale;
  1838.          GLfloat ascale = 255.0f * ctx->Visual->InvAlphaScale;
  1839.          for (i=0;i<width;i++) {
  1840.             red[i]   = (GLubyte) (GLint) (red[i]   * rscale);
  1841.             green[i] = (GLubyte) (GLint) (green[i] * gscale);
  1842.             blue[i]  = (GLubyte) (GLint) (blue[i]  * bscale);
  1843.             alpha[i] = (GLubyte) (GLint) (alpha[i] * ascale);
  1844.          }
  1845.       }
  1846.  
  1847.       switch (format) {
  1848.          case GL_ALPHA:
  1849.             for (i=0;i<width;i++) {
  1850.                *imgptr++ = alpha[i];
  1851.             }
  1852.             break;
  1853.          case GL_LUMINANCE:
  1854.             for (i=0;i<width;i++) {
  1855.                *imgptr++ = red[i];
  1856.             }
  1857.             break;
  1858.          case GL_LUMINANCE_ALPHA:
  1859.             for (i=0;i<width;i++) {
  1860.                *imgptr++ = red[i];
  1861.                *imgptr++ = alpha[i];
  1862.             }
  1863.             break;
  1864.          case GL_INTENSITY:
  1865.             for (i=0;i<width;i++) {
  1866.                *imgptr++ = red[i];
  1867.             }
  1868.             break;
  1869.          case GL_RGB:
  1870.             for (i=0;i<width;i++) {
  1871.                *imgptr++ = red[i];
  1872.                *imgptr++ = green[i];
  1873.                *imgptr++ = blue[i];
  1874.             }
  1875.             break;
  1876.          case GL_RGBA:
  1877.             for (i=0;i<width;i++) {
  1878.                *imgptr++ = red[i];
  1879.                *imgptr++ = green[i];
  1880.                *imgptr++ = blue[i];
  1881.                *imgptr++ = alpha[i];
  1882.             }
  1883.             break;
  1884.       } /*switch*/
  1885.  
  1886.    } /*for*/         
  1887.  
  1888.    /* Restore drawing buffer */
  1889.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  1890.  
  1891.    return image;
  1892. }
  1893.  
  1894.  
  1895.  
  1896.  
  1897. void gl_CopyTexImage1D( GLcontext *ctx,
  1898.                         GLenum target, GLint level,
  1899.                         GLenum internalformat,
  1900.                         GLint x, GLint y,
  1901.                         GLsizei width, GLint border )
  1902. {
  1903.    GLint format;
  1904.    struct gl_image *teximage;
  1905.  
  1906.    if (INSIDE_BEGIN_END(ctx)) {
  1907.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage1D" );
  1908.       return;
  1909.    }
  1910.    if (target!=GL_TEXTURE_1D) {
  1911.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
  1912.       return;
  1913.    }
  1914.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1915.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(level)" );
  1916.       return;
  1917.    }
  1918.    if (border!=0 && border!=1) {
  1919.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(border)" );
  1920.       return;
  1921.    }
  1922.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  1923.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(width)" );
  1924.       return;
  1925.    }
  1926.    format = decode_internal_format( internalformat );
  1927.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  1928.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(format)" );
  1929.       return;
  1930.    }
  1931.  
  1932.    teximage = read_color_image( ctx, x, y, width, 1, format );
  1933.    if (!teximage) {
  1934.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
  1935.       return;
  1936.    }
  1937.  
  1938.    gl_TexImage1D( ctx, target, level, internalformat, width,
  1939.                   border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  1940.  
  1941.    /* teximage was freed in gl_TexImage1D */
  1942. }
  1943.  
  1944.  
  1945.  
  1946. void gl_CopyTexImage2D( GLcontext *ctx,
  1947.                         GLenum target, GLint level, GLenum internalformat,
  1948.                         GLint x, GLint y, GLsizei width, GLsizei height,
  1949.                         GLint border )
  1950. {
  1951.    GLint format;
  1952.    struct gl_image *teximage;
  1953.  
  1954.    if (INSIDE_BEGIN_END(ctx)) {
  1955.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage2D" );
  1956.       return;
  1957.    }
  1958.    if (target!=GL_TEXTURE_2D) {
  1959.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  1960.       return;
  1961.    }
  1962.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1963.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(level)" );
  1964.       return;
  1965.    }
  1966.    if (border!=0 && border!=1) {
  1967.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(border)" );
  1968.       return;
  1969.    }
  1970.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  1971.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width)" );
  1972.       return;
  1973.    }
  1974.    if (height<2*border || height>2+MAX_TEXTURE_SIZE || height<0) {
  1975.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(height)" );
  1976.       return;
  1977.    }
  1978.    format = decode_internal_format( internalformat );
  1979.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  1980.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(format)" );
  1981.       return;
  1982.    }
  1983.  
  1984.    teximage = read_color_image( ctx, x, y, width, height, format );
  1985.    if (!teximage) {
  1986.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
  1987.       return;
  1988.    }
  1989.  
  1990.    gl_TexImage2D( ctx, target, level, internalformat, width, height,
  1991.                   border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  1992.  
  1993.    /* teximage was freed in gl_TexImage2D */
  1994. }
  1995.  
  1996.  
  1997.  
  1998.  
  1999. /*
  2000.  * Do the work of glCopyTexSubImage[12]D.
  2001.  * TODO: apply pixel bias scale and mapping.
  2002.  */
  2003. static void copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
  2004.                                 GLint width, GLint height,
  2005.                                 GLint srcx, GLint srcy,
  2006.                                 GLint dstx, GLint dsty, GLint zoffset )
  2007. {
  2008.    GLint i, j;
  2009.    GLint format, components, rectarea;
  2010.  
  2011.    rectarea = width*height;
  2012.    zoffset *= rectarea; 
  2013.    format = dest->Format;
  2014.    components = components_in_intformat( format );
  2015.  
  2016.    for (j=0;j<height;j++) {
  2017.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  2018.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  2019.       GLubyte *texptr;
  2020.  
  2021.       gl_read_color_span( ctx, width, srcx, srcy+j, red, green, blue, alpha );
  2022.  
  2023.       if (!ctx->Visual->EightBitColor) {
  2024.          /* scale red, green, blue, alpha values to range [0,255] */
  2025.          GLfloat rscale = 255.0f * ctx->Visual->InvRedScale;
  2026.          GLfloat gscale = 255.0f * ctx->Visual->InvGreenScale;
  2027.          GLfloat bscale = 255.0f * ctx->Visual->InvBlueScale;
  2028.          GLfloat ascale = 255.0f * ctx->Visual->InvAlphaScale;
  2029.          for (i=0;i<width;i++) {
  2030.             red[i]   = (GLubyte) (GLint) (red[i]   * rscale);
  2031.             green[i] = (GLubyte) (GLint) (green[i] * gscale);
  2032.             blue[i]  = (GLubyte) (GLint) (blue[i]  * bscale);
  2033.             alpha[i] = (GLubyte) (GLint) (alpha[i] * ascale);
  2034.          }
  2035.       }
  2036.  
  2037.       texptr = dest->Data + ( zoffset + (dsty+j) * width + dstx) * components;
  2038.  
  2039.       switch (format) {
  2040.          case GL_ALPHA:
  2041.             for (i=0;i<width;i++) {
  2042.                *texptr++ = alpha[i];
  2043.             }
  2044.             break;
  2045.          case GL_LUMINANCE:
  2046.             for (i=0;i<width;i++) {
  2047.                *texptr++ = red[i];
  2048.             }
  2049.             break;
  2050.          case GL_LUMINANCE_ALPHA:
  2051.             for (i=0;i<width;i++) {
  2052.                *texptr++ = red[i];
  2053.                *texptr++ = alpha[i];
  2054.             }
  2055.             break;
  2056.          case GL_INTENSITY:
  2057.             for (i=0;i<width;i++) {
  2058.                *texptr++ = red[i];
  2059.             }
  2060.             break;
  2061.          case GL_RGB:
  2062.             for (i=0;i<width;i++) {
  2063.                *texptr++ = red[i];
  2064.                *texptr++ = green[i];
  2065.                *texptr++ = blue[i];
  2066.             }
  2067.             break;
  2068.          case GL_RGBA:
  2069.             for (i=0;i<width;i++) {
  2070.                *texptr++ = red[i];
  2071.                *texptr++ = green[i];
  2072.                *texptr++ = blue[i];
  2073.                *texptr++ = alpha[i];
  2074.             }
  2075.             break;
  2076.       } /*switch*/
  2077.    } /*for*/         
  2078. }
  2079.  
  2080.  
  2081.  
  2082.  
  2083. void gl_CopyTexSubImage1D( GLcontext *ctx,
  2084.                               GLenum target, GLint level,
  2085.                               GLint xoffset, GLint x, GLint y, GLsizei width )
  2086. {
  2087.    struct gl_texture_image *teximage;
  2088.  
  2089.    if (INSIDE_BEGIN_END(ctx)) {
  2090.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  2091.       return;
  2092.    }
  2093.    if (target!=GL_TEXTURE_1D) {
  2094.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
  2095.       return;
  2096.    }
  2097.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2098.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(level)" );
  2099.       return;
  2100.    }
  2101.    if (width<0) {
  2102.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(width)" );
  2103.       return;
  2104.    }
  2105.  
  2106.    teximage = ctx->Texture.Current1D->Image[level];
  2107.  
  2108.    if (teximage) {
  2109.       if (xoffset < -teximage->Border) {
  2110.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(xoffset)" );
  2111.          return;
  2112.       }
  2113.       /* NOTE: we're adding the border here, not subtracting! */
  2114.       if (xoffset+width > teximage->Width+teximage->Border) {
  2115.          gl_error( ctx, GL_INVALID_VALUE,
  2116.                    "glCopyTexSubImage1D(xoffset+width)" );
  2117.          return;
  2118.       }
  2119.       if (teximage->Data) {
  2120.          copy_tex_sub_image( ctx, teximage, width, 1, x, y, xoffset, 0, 0 );
  2121.       }
  2122.    }
  2123.    else {
  2124.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  2125.    }
  2126. }
  2127.  
  2128.  
  2129.  
  2130. void gl_CopyTexSubImage2D( GLcontext *ctx,
  2131.                               GLenum target, GLint level,
  2132.                               GLint xoffset, GLint yoffset,
  2133.                               GLint x, GLint y, GLsizei width, GLsizei height )
  2134. {
  2135.    struct gl_texture_image *teximage;
  2136.  
  2137.    if (INSIDE_BEGIN_END(ctx)) {
  2138.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2139.       return;
  2140.    }
  2141.    if (target!=GL_TEXTURE_2D) {
  2142.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  2143.       return;
  2144.    }
  2145.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2146.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(level)" );
  2147.       return;
  2148.    }
  2149.    if (width<0) {
  2150.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(width)" );
  2151.       return;
  2152.    }
  2153.    if (height<0) {
  2154.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(height)" );
  2155.       return;
  2156.    }
  2157.  
  2158.    teximage = ctx->Texture.Current2D->Image[level];
  2159.  
  2160.    if (teximage) {
  2161.       if (xoffset < -teximage->Border) {
  2162.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(xoffset)" );
  2163.          return;
  2164.       }
  2165.       if (yoffset < -teximage->Border) {
  2166.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(yoffset)" );
  2167.          return;
  2168.       }
  2169.       /* NOTE: we're adding the border here, not subtracting! */
  2170.       if (xoffset+width > teximage->Width+teximage->Border) {
  2171.          gl_error( ctx, GL_INVALID_VALUE,
  2172.                    "glCopyTexSubImage2D(xoffset+width)" );
  2173.          return;
  2174.       }
  2175.       if (yoffset+height > teximage->Height+teximage->Border) {
  2176.          gl_error( ctx, GL_INVALID_VALUE,
  2177.                    "glCopyTexSubImage2D(yoffset+height)" );
  2178.          return;
  2179.       }
  2180.  
  2181.       if (teximage->Data) {
  2182.          copy_tex_sub_image( ctx, teximage, width, height,
  2183.                              x, y, xoffset, yoffset, 0 );
  2184.       }
  2185.    }
  2186.    else {
  2187.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2188.    }
  2189. }
  2190.  
  2191.  
  2192.  
  2193. void gl_CopyTexSubImage3DEXT( GLcontext *ctx,
  2194.                               GLenum target, GLint level,
  2195.                               GLint xoffset, GLint yoffset, GLint zoffset,
  2196.                               GLint x, GLint y, GLsizei width, GLsizei height )
  2197. {
  2198.    struct gl_texture_image *teximage;
  2199.  
  2200.    if (INSIDE_BEGIN_END(ctx)) {
  2201.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2202.       return;
  2203.    }
  2204.    if (target!=GL_TEXTURE_2D) {
  2205.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3DEXT(target)" );
  2206.       return;
  2207.    }
  2208.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2209.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(level)" );
  2210.       return;
  2211.    }
  2212.    if (width<0) {
  2213.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(width)" );
  2214.       return;
  2215.    }
  2216.    if (height<0) {
  2217.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(height)" );
  2218.       return;
  2219.    }
  2220.  
  2221.    teximage = ctx->Texture.Current3D->Image[level];
  2222.    if (teximage) {
  2223.       if (xoffset < -teximage->Border) {
  2224.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(xoffset)" );
  2225.          return;
  2226.       }
  2227.       if (yoffset < -teximage->Border) {
  2228.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(yoffset)" );
  2229.          return;
  2230.       }
  2231.       if (zoffset < -teximage->Border) {
  2232.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(zoffset)" );
  2233.          return;
  2234.       }
  2235.       /* NOTE: we're adding the border here, not subtracting! */
  2236.       if (xoffset+width > teximage->Width+teximage->Border) {
  2237.          gl_error( ctx, GL_INVALID_VALUE,
  2238.                    "glCopyTexSubImage3DEXT(xoffset+width)" );
  2239.          return;
  2240.       }
  2241.       if (yoffset+height > teximage->Height+teximage->Border) {
  2242.          gl_error( ctx, GL_INVALID_VALUE,
  2243.                    "glCopyTexSubImage3DEXT(yoffset+height)" );
  2244.          return;
  2245.       }
  2246.       if (zoffset > teximage->Depth+teximage->Border) {
  2247.          gl_error( ctx, GL_INVALID_VALUE,
  2248.                    "glCopyTexSubImage3DEXT(zoffset+depth)" );
  2249.          return;
  2250.       }
  2251.  
  2252.       if (teximage->Data) {
  2253.          copy_tex_sub_image( ctx, teximage, width, height, 
  2254.                              x, y, xoffset, yoffset, zoffset);
  2255.       }
  2256.    }
  2257.    else {
  2258.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2259.    }
  2260. }
  2261.  
  2262.