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

  1. /* $Id: teximage.c,v 1.11 1999/11/08 07:36:44 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. #ifdef PC_HEADER
  29. #include "all.h"
  30. #else
  31. #ifndef XFree86Server
  32. #include <assert.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #else
  37. #include "GL/xf86glx.h"
  38. #endif
  39. #include "context.h"
  40. #include "image.h"
  41. #include "macros.h"
  42. #include "mmath.h"
  43. #include "span.h"
  44. #include "teximage.h"
  45. #include "texstate.h"
  46. #include "types.h"
  47. #endif
  48.  
  49.  
  50. /*
  51.  * NOTES:
  52.  *
  53.  * Mesa's native texture datatype is GLubyte.  Native formats are
  54.  * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
  55.  * and GL_COLOR_INDEX.
  56.  * Device drivers are free to implement any internal format they want.
  57.  */
  58.  
  59.  
  60.  
  61. static struct gl_pixelstore_attrib defaultPacking = {
  62.    1,            /* Alignment */
  63.    0,            /* RowLength */
  64.    0,            /* SkipPixels */
  65.    0,            /* SkipRows */
  66.    0,            /* ImageHeight */
  67.    0,            /* SkipImages */
  68.    GL_FALSE,     /* SwapBytes */
  69.    GL_FALSE      /* LsbFirst */
  70. };
  71.  
  72.  
  73.  
  74. /*
  75.  * Compute log base 2 of n.
  76.  * If n isn't an exact power of two return -1.
  77.  * If n<0 return -1.
  78.  */
  79. static int logbase2( int n )
  80. {
  81.    GLint i = 1;
  82.    GLint log2 = 0;
  83.  
  84.    if (n<0) {
  85.       return -1;
  86.    }
  87.  
  88.    while ( n > i ) {
  89.       i *= 2;
  90.       log2++;
  91.    }
  92.    if (i != n) {
  93.       return -1;
  94.    }
  95.    else {
  96.       return log2;
  97.    }
  98. }
  99.  
  100.  
  101.  
  102. /*
  103.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  104.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  105.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
  106.  * Return -1 if invalid enum.
  107.  */
  108. static GLint decode_internal_format( GLint format )
  109. {
  110.    switch (format) {
  111.       case GL_ALPHA:
  112.       case GL_ALPHA4:
  113.       case GL_ALPHA8:
  114.       case GL_ALPHA12:
  115.       case GL_ALPHA16:
  116.          return GL_ALPHA;
  117.       case 1:
  118.       case GL_LUMINANCE:
  119.       case GL_LUMINANCE4:
  120.       case GL_LUMINANCE8:
  121.       case GL_LUMINANCE12:
  122.       case GL_LUMINANCE16:
  123.          return GL_LUMINANCE;
  124.       case 2:
  125.       case GL_LUMINANCE_ALPHA:
  126.       case GL_LUMINANCE4_ALPHA4:
  127.       case GL_LUMINANCE6_ALPHA2:
  128.       case GL_LUMINANCE8_ALPHA8:
  129.       case GL_LUMINANCE12_ALPHA4:
  130.       case GL_LUMINANCE12_ALPHA12:
  131.       case GL_LUMINANCE16_ALPHA16:
  132.          return GL_LUMINANCE_ALPHA;
  133.       case GL_INTENSITY:
  134.       case GL_INTENSITY4:
  135.       case GL_INTENSITY8:
  136.       case GL_INTENSITY12:
  137.       case GL_INTENSITY16:
  138.          return GL_INTENSITY;
  139.       case 3:
  140.       case GL_RGB:
  141.       case GL_R3_G3_B2:
  142.       case GL_RGB4:
  143.       case GL_RGB5:
  144.       case GL_RGB8:
  145.       case GL_RGB10:
  146.       case GL_RGB12:
  147.       case GL_RGB16:
  148.          return GL_RGB;
  149.       case 4:
  150.       case GL_RGBA:
  151.       case GL_RGBA2:
  152.       case GL_RGBA4:
  153.       case GL_RGB5_A1:
  154.       case GL_RGBA8:
  155.       case GL_RGB10_A2:
  156.       case GL_RGBA12:
  157.       case GL_RGBA16:
  158.          return GL_RGBA;
  159.       case GL_COLOR_INDEX:
  160.       case GL_COLOR_INDEX1_EXT:
  161.       case GL_COLOR_INDEX2_EXT:
  162.       case GL_COLOR_INDEX4_EXT:
  163.       case GL_COLOR_INDEX8_EXT:
  164.       case GL_COLOR_INDEX12_EXT:
  165.       case GL_COLOR_INDEX16_EXT:
  166.          return GL_COLOR_INDEX;
  167.       default:
  168.          return -1;  /* error */
  169.    }
  170. }
  171.  
  172.  
  173.  
  174. /*
  175.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  176.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  177.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
  178.  * number of components for the format.  Return -1 if invalid enum.
  179.  */
  180. static GLint components_in_intformat( GLint format )
  181. {
  182.    switch (format) {
  183.       case GL_ALPHA:
  184.       case GL_ALPHA4:
  185.       case GL_ALPHA8:
  186.       case GL_ALPHA12:
  187.       case GL_ALPHA16:
  188.          return 1;
  189.       case 1:
  190.       case GL_LUMINANCE:
  191.       case GL_LUMINANCE4:
  192.       case GL_LUMINANCE8:
  193.       case GL_LUMINANCE12:
  194.       case GL_LUMINANCE16:
  195.          return 1;
  196.       case 2:
  197.       case GL_LUMINANCE_ALPHA:
  198.       case GL_LUMINANCE4_ALPHA4:
  199.       case GL_LUMINANCE6_ALPHA2:
  200.       case GL_LUMINANCE8_ALPHA8:
  201.       case GL_LUMINANCE12_ALPHA4:
  202.       case GL_LUMINANCE12_ALPHA12:
  203.       case GL_LUMINANCE16_ALPHA16:
  204.          return 2;
  205.       case GL_INTENSITY:
  206.       case GL_INTENSITY4:
  207.       case GL_INTENSITY8:
  208.       case GL_INTENSITY12:
  209.       case GL_INTENSITY16:
  210.          return 1;
  211.       case 3:
  212.       case GL_RGB:
  213.       case GL_R3_G3_B2:
  214.       case GL_RGB4:
  215.       case GL_RGB5:
  216.       case GL_RGB8:
  217.       case GL_RGB10:
  218.       case GL_RGB12:
  219.       case GL_RGB16:
  220.          return 3;
  221.       case 4:
  222.       case GL_RGBA:
  223.       case GL_RGBA2:
  224.       case GL_RGBA4:
  225.       case GL_RGB5_A1:
  226.       case GL_RGBA8:
  227.       case GL_RGB10_A2:
  228.       case GL_RGBA12:
  229.       case GL_RGBA16:
  230.          return 4;
  231.       case GL_COLOR_INDEX:
  232.       case GL_COLOR_INDEX1_EXT:
  233.       case GL_COLOR_INDEX2_EXT:
  234.       case GL_COLOR_INDEX4_EXT:
  235.       case GL_COLOR_INDEX8_EXT:
  236.       case GL_COLOR_INDEX12_EXT:
  237.       case GL_COLOR_INDEX16_EXT:
  238.          return 1;
  239.       default:
  240.          return -1;  /* error */
  241.    }
  242. }
  243.  
  244.  
  245.  
  246. struct gl_texture_image *gl_alloc_texture_image( void )
  247. {
  248.    return CALLOC_STRUCT(gl_texture_image);
  249. }
  250.  
  251.  
  252.  
  253. void gl_free_texture_image( struct gl_texture_image *teximage )
  254. {
  255.    if (teximage->Data) {
  256.       FREE( teximage->Data );
  257.       teximage->Data = NULL;
  258.    }
  259.    FREE( teximage );
  260. }
  261.  
  262.  
  263.  
  264. /*
  265.  * Examine the texImage->Format field and set the Red, Green, Blue, etc
  266.  * texel component sizes to default values.
  267.  * These fields are set only here by core Mesa but device drivers may
  268.  * overwritting these fields to indicate true texel resolution.
  269.  */
  270. static void set_teximage_component_sizes( struct gl_texture_image *texImage )
  271. {
  272.    switch (texImage->Format) {
  273.       case GL_ALPHA:
  274.          texImage->RedBits = 0;
  275.          texImage->GreenBits = 0;
  276.          texImage->BlueBits = 0;
  277.          texImage->AlphaBits = 8;
  278.          texImage->IntensityBits = 0;
  279.          texImage->LuminanceBits = 0;
  280.          texImage->IndexBits = 0;
  281.          break;
  282.       case GL_LUMINANCE:
  283.          texImage->RedBits = 0;
  284.          texImage->GreenBits = 0;
  285.          texImage->BlueBits = 0;
  286.          texImage->AlphaBits = 0;
  287.          texImage->IntensityBits = 0;
  288.          texImage->LuminanceBits = 8;
  289.          texImage->IndexBits = 0;
  290.          break;
  291.       case GL_LUMINANCE_ALPHA:
  292.          texImage->RedBits = 0;
  293.          texImage->GreenBits = 0;
  294.          texImage->BlueBits = 0;
  295.          texImage->AlphaBits = 8;
  296.          texImage->IntensityBits = 0;
  297.          texImage->LuminanceBits = 8;
  298.          texImage->IndexBits = 0;
  299.          break;
  300.       case GL_INTENSITY:
  301.          texImage->RedBits = 0;
  302.          texImage->GreenBits = 0;
  303.          texImage->BlueBits = 0;
  304.          texImage->AlphaBits = 0;
  305.          texImage->IntensityBits = 8;
  306.          texImage->LuminanceBits = 0;
  307.          texImage->IndexBits = 0;
  308.          break;
  309.       case GL_RED:
  310.          texImage->RedBits = 8;
  311.          texImage->GreenBits = 0;
  312.          texImage->BlueBits = 0;
  313.          texImage->AlphaBits = 0;
  314.          texImage->IntensityBits = 0;
  315.          texImage->LuminanceBits = 0;
  316.          texImage->IndexBits = 0;
  317.          break;
  318.       case GL_GREEN:
  319.          texImage->RedBits = 0;
  320.          texImage->GreenBits = 8;
  321.          texImage->BlueBits = 0;
  322.          texImage->AlphaBits = 0;
  323.          texImage->IntensityBits = 0;
  324.          texImage->LuminanceBits = 0;
  325.          texImage->IndexBits = 0;
  326.          break;
  327.       case GL_BLUE:
  328.          texImage->RedBits = 0;
  329.          texImage->GreenBits = 0;
  330.          texImage->BlueBits = 8;
  331.          texImage->AlphaBits = 0;
  332.          texImage->IntensityBits = 0;
  333.          texImage->LuminanceBits = 0;
  334.          texImage->IndexBits = 0;
  335.          break;
  336.       case GL_RGB:
  337.       case GL_BGR:
  338.          texImage->RedBits = 8;
  339.          texImage->GreenBits = 8;
  340.          texImage->BlueBits = 8;
  341.          texImage->AlphaBits = 0;
  342.          texImage->IntensityBits = 0;
  343.          texImage->LuminanceBits = 0;
  344.          texImage->IndexBits = 0;
  345.          break;
  346.       case GL_RGBA:
  347.       case GL_BGRA:
  348.       case GL_ABGR_EXT:
  349.          texImage->RedBits = 8;
  350.          texImage->GreenBits = 8;
  351.          texImage->BlueBits = 8;
  352.          texImage->AlphaBits = 8;
  353.          texImage->IntensityBits = 0;
  354.          texImage->LuminanceBits = 0;
  355.          texImage->IndexBits = 0;
  356.          break;
  357.       case GL_COLOR_INDEX:
  358.          texImage->RedBits = 0;
  359.          texImage->GreenBits = 0;
  360.          texImage->BlueBits = 0;
  361.          texImage->AlphaBits = 0;
  362.          texImage->IntensityBits = 0;
  363.          texImage->LuminanceBits = 0;
  364.          texImage->IndexBits = 8;
  365.          break;
  366.       default:
  367.          gl_problem(NULL, "unexpected format in set_teximage_component_sizes");
  368.    }
  369. }
  370.  
  371.  
  372. /* Need this to prevent an out-of-bounds memory access when using
  373.  * X86 optimized code.
  374.  */
  375. #ifdef USE_X86_ASM
  376. #  define EXTRA_BYTE 1
  377. #else
  378. #  define EXTRA_BYTE 0
  379. #endif
  380.  
  381.  
  382.  
  383. /*
  384.  * This is called by glTexImage[123]D in order to build a gl_texture_image
  385.  * object given the client's parameters and image data.
  386.  * 
  387.  * NOTES: Width, height and depth should include the border.
  388.  *        All texture image parameters should have already been error checked.
  389.  */
  390. static struct gl_texture_image *
  391. make_texture_image( GLcontext *ctx, GLint internalFormat,
  392.                     GLint width, GLint height, GLint depth, GLint border,
  393.                     GLenum srcFormat, GLenum srcType, const GLvoid *pixels,
  394.                     const struct gl_pixelstore_attrib *unpacking)
  395. {
  396.    GLint components, numPixels;
  397.    struct gl_texture_image *texImage;
  398.  
  399.    assert(width > 0);
  400.    assert(height > 0);
  401.    assert(depth > 0);
  402.    assert(border == 0 || border == 1);
  403.    assert(pixels);
  404.    assert(unpacking);
  405.  
  406.  
  407.    /*
  408.     * Allocate and initialize the texture_image struct
  409.     */
  410.    texImage = gl_alloc_texture_image();
  411.    if (!texImage)
  412.       return NULL;
  413.  
  414.    texImage->Format = (GLenum) decode_internal_format(internalFormat);
  415.    set_teximage_component_sizes( texImage );
  416.    texImage->IntFormat = (GLenum) internalFormat;
  417.    texImage->Border = border;
  418.    texImage->Width = width;
  419.    texImage->Height = height;
  420.    texImage->Depth = depth;
  421.    texImage->WidthLog2 = logbase2(width - 2 * border);
  422.    if (height == 1)  /* 1-D texture */
  423.       texImage->HeightLog2 = 0;
  424.    else
  425.       texImage->HeightLog2 = logbase2(height - 2 * border);
  426.    if (depth == 1)   /* 2-D texture */
  427.       texImage->DepthLog2 = 0;
  428.    else
  429.       texImage->DepthLog2 = logbase2(depth - 2 * border);
  430.    texImage->Width2 = 1 << texImage->WidthLog2;
  431.    texImage->Height2 = 1 << texImage->HeightLog2;
  432.    texImage->Depth2 = 1 << texImage->DepthLog2;
  433.    texImage->MaxLog2 = MAX2(texImage->WidthLog2, texImage->HeightLog2);
  434.  
  435.    components = components_in_intformat(internalFormat);
  436.    numPixels = texImage->Width * texImage->Height * texImage->Depth;
  437.  
  438.    texImage->Data = (GLubyte *) MALLOC(numPixels * components + EXTRA_BYTE);
  439.  
  440.    if (!texImage->Data) {
  441.       /* out of memory */
  442.       gl_free_texture_image(texImage);
  443.       return NULL;
  444.    }
  445.  
  446.  
  447.    /*
  448.     * OK, the texture image struct has been initialized and the texture
  449.     * image memory has been allocated.
  450.     * Now fill in the texture image from the source data.
  451.     * This includes applying the pixel transfer operations.
  452.     */
  453.  
  454.    /* try common 2D texture cases first */
  455.    if (!ctx->Pixel.ScaleOrBiasRGBA && !ctx->Pixel.MapColorFlag
  456.        && !ctx->Pixel.IndexOffset && !ctx->Pixel.IndexShift
  457.        && srcType == GL_UNSIGNED_BYTE && depth == 1) {
  458.  
  459.       if (srcFormat == internalFormat) {
  460.          /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
  461.           * GL_LUMINANCE_ALPHA, etc. texture formats.
  462.           */
  463.          const GLubyte *src = gl_pixel_addr_in_image(unpacking,
  464.                 pixels, width, height, srcFormat, srcType, 0, 0, 0);
  465.          const GLubyte *src1 = gl_pixel_addr_in_image(unpacking,
  466.                 pixels, width, height, srcFormat, srcType, 0, 1, 0);
  467.          const GLint srcStride = src1 - src;
  468.          GLubyte *dst = texImage->Data;
  469.          GLint dstBytesPerRow = width * components * sizeof(GLubyte);
  470.          if (srcStride == dstBytesPerRow) {
  471.             MEMCPY(dst, src, height * dstBytesPerRow);
  472.          }
  473.          else {
  474.             GLint i;
  475.             for (i = 0; i < height; i++) {
  476.                MEMCPY(dst, src, dstBytesPerRow);
  477.                src += srcStride;
  478.                dst += dstBytesPerRow;
  479.             }
  480.          }
  481.          return texImage;  /* all done */
  482.       }
  483.       else if (srcFormat == GL_RGBA && internalFormat == GL_RGB) {
  484.          /* commonly used by Quake */
  485.          const GLubyte *src = gl_pixel_addr_in_image(unpacking,
  486.                 pixels, width, height, srcFormat, srcType, 0, 0, 0);
  487.          const GLubyte *src1 = gl_pixel_addr_in_image(unpacking,
  488.                 pixels, width, height, srcFormat, srcType, 0, 1, 0);
  489.          const GLint srcStride = src1 - src;
  490.          GLubyte *dst = texImage->Data;
  491.          GLint i, j;
  492.          for (i = 0; i < height; i++) {
  493.             const GLubyte *s = src;
  494.             for (j = 0; j < width; j++) {
  495.                *dst++ = *s++;  /*red*/
  496.                *dst++ = *s++;  /*green*/
  497.                *dst++ = *s++;  /*blue*/
  498.                s++;            /*alpha*/
  499.             }
  500.             src += srcStride;
  501.          }
  502.          return texImage;  /* all done */
  503.       }
  504.    }      
  505.  
  506.  
  507.    /*
  508.     * General case solutions
  509.     */
  510.    if (texImage->Format == GL_COLOR_INDEX) {
  511.       /* color index texture */
  512.       const GLint destBytesPerRow = width * components * sizeof(GLubyte);
  513.       const GLenum dstType = GL_UNSIGNED_BYTE;
  514.       GLubyte *dest = texImage->Data;
  515.       GLint img, row;
  516.       for (img = 0; img < depth; img++) {
  517.          for (row = 0; row < height; row++) {
  518.             const GLvoid *source = gl_pixel_addr_in_image(unpacking,
  519.                 pixels, width, height, srcFormat, srcType, img, row, 0);
  520.             _mesa_unpack_index_span(ctx, width, dstType, dest,
  521.                                     srcType, source, unpacking, GL_TRUE);
  522.             dest += destBytesPerRow;
  523.          }
  524.       }
  525.    }
  526.    else {
  527.       /* regular, color texture */
  528.       const GLint destBytesPerRow = width * components * sizeof(GLubyte);
  529.       const GLenum dstFormat = texImage->Format;
  530.       GLubyte *dest = texImage->Data;
  531.       GLint img, row;
  532.       for (img = 0; img < depth; img++) {
  533.          for (row = 0; row < height; row++) {
  534.             const GLvoid *source = gl_pixel_addr_in_image(unpacking,
  535.                    pixels, width, height, srcFormat, srcType, img, row, 0);
  536.             _mesa_unpack_ubyte_color_span(ctx, width, dstFormat, dest,
  537.                    srcFormat, srcType, source, unpacking, GL_TRUE);
  538.             dest += destBytesPerRow;
  539.          }
  540.       }
  541.    }
  542.  
  543.    return texImage;   /* All done! */
  544. }
  545.  
  546.  
  547.  
  548. /*
  549.  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  550.  * create a texture image with unspecified image contents per the OpenGL
  551.  * spec.
  552.  */
  553. static struct gl_texture_image *
  554. make_null_texture( GLcontext *ctx, GLenum internalFormat,
  555.                    GLsizei width, GLsizei height, GLsizei depth, GLint border )
  556. {
  557.    GLint components;
  558.    struct gl_texture_image *texImage;
  559.    GLint numPixels;
  560.    (void) ctx;
  561.  
  562.    /*internalFormat = decode_internal_format(internalFormat);*/
  563.    components = components_in_intformat(internalFormat);
  564.    numPixels = width * height * depth;
  565.  
  566.    texImage = gl_alloc_texture_image();
  567.    if (!texImage)
  568.       return NULL;
  569.  
  570.    texImage->Format = (GLenum) decode_internal_format(internalFormat);
  571.    set_teximage_component_sizes( texImage );
  572.    texImage->IntFormat = internalFormat;
  573.    texImage->Border = border;
  574.    texImage->Width = width;
  575.    texImage->Height = height;
  576.    texImage->Depth = depth;
  577.    texImage->WidthLog2 = logbase2(width - 2*border);
  578.    if (height==1)  /* 1-D texture */
  579.       texImage->HeightLog2 = 0;
  580.    else
  581.       texImage->HeightLog2 = logbase2(height - 2*border);
  582.    if (depth==1)   /* 2-D texture */
  583.       texImage->DepthLog2 = 0;
  584.    else
  585.       texImage->DepthLog2 = logbase2(depth - 2*border);
  586.    texImage->Width2 = 1 << texImage->WidthLog2;
  587.    texImage->Height2 = 1 << texImage->HeightLog2;
  588.    texImage->Depth2 = 1 << texImage->DepthLog2;
  589.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  590.  
  591.    /* XXX should we really allocate memory for the image or let it be NULL? */
  592.    /*texImage->Data = NULL;*/
  593.  
  594.    texImage->Data = (GLubyte *) MALLOC( numPixels * components + EXTRA_BYTE );
  595.  
  596.    /*
  597.     * Let's see if anyone finds this.  If glTexImage2D() is called with
  598.     * a NULL image pointer then load the texture image with something
  599.     * interesting instead of leaving it indeterminate.
  600.     */
  601.    if (texImage->Data) {
  602.       char message[8][32] = {
  603.          "   X   X  XXXXX   XXX     X    ",
  604.          "   XX XX  X      X   X   X X   ",
  605.          "   X X X  X      X      X   X  ",
  606.          "   X   X  XXXX    XXX   XXXXX  ",
  607.          "   X   X  X          X  X   X  ",
  608.          "   X   X  X      X   X  X   X  ",
  609.          "   X   X  XXXXX   XXX   X   X  ",
  610.          "                               "
  611.       };
  612.  
  613.       GLubyte *imgPtr = texImage->Data;
  614.       GLint i, j, k;
  615.       for (i=0;i<height;i++) {
  616.          GLint srcRow = 7 - i % 8;
  617.          for (j=0;j<width;j++) {
  618.             GLint srcCol = j % 32;
  619.             GLint texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
  620.             for (k=0;k<components;k++) {
  621.                *imgPtr++ = (GLubyte) texel;
  622.             }
  623.          }
  624.       }
  625.    }
  626.  
  627.    return texImage;
  628. }
  629.  
  630.  
  631.  
  632. /*
  633.  * Test glTexImage[123]D() parameters for errors.
  634.  * Input:
  635.  *         dimensions - must be 1 or 2 or 3
  636.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  637.  */
  638. static GLboolean
  639. texture_error_check( GLcontext *ctx, GLenum target,
  640.                      GLint level, GLint internalFormat,
  641.                      GLenum format, GLenum type,
  642.                      GLuint dimensions,
  643.                      GLint width, GLint height,
  644.                      GLint depth, GLint border )
  645. {
  646.    GLboolean isProxy;
  647.    GLint iformat;
  648.  
  649.    if (dimensions == 1) {
  650.       isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_1D);
  651.       if (target != GL_TEXTURE_1D && !isProxy) {
  652.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  653.          return GL_TRUE;
  654.       }
  655.    }
  656.    else if (dimensions == 2) {
  657.       isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D);
  658.       if (target != GL_TEXTURE_2D && !isProxy) {
  659.           gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  660.           return GL_TRUE;
  661.       }
  662.    }
  663.    else if (dimensions == 3) {
  664.       isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_3D);
  665.       if (target != GL_TEXTURE_3D && !isProxy) {
  666.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
  667.          return GL_TRUE;
  668.       }
  669.    }
  670.    else {
  671.       gl_problem( ctx, "bad dims in texture_error_check" );
  672.       return GL_TRUE;
  673.    }
  674.  
  675.    /* Border */
  676.    if (border!=0 && border!=1) {
  677.       if (!isProxy) {
  678.          char message[100];
  679.          sprintf(message, "glTexImage%dD(border)", dimensions);
  680.          gl_error(ctx, GL_INVALID_VALUE, message);
  681.       }
  682.       return GL_TRUE;
  683.    }
  684.  
  685.    /* Width */
  686.    if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize
  687.        || logbase2( width - 2 * border ) < 0) {
  688.       if (!isProxy) {
  689.          char message[100];
  690.          sprintf(message, "glTexImage%dD(width)", dimensions);
  691.          gl_error(ctx, GL_INVALID_VALUE, message);
  692.       }
  693.       return GL_TRUE;
  694.    }
  695.  
  696.    /* Height */
  697.    if (dimensions >= 2) {
  698.       if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize
  699.           || logbase2( height - 2 * border ) < 0) {
  700.          if (!isProxy) {
  701.             char message[100];
  702.             sprintf(message, "glTexImage%dD(height)", dimensions);
  703.             gl_error(ctx, GL_INVALID_VALUE, message);
  704.          }
  705.          return GL_TRUE;
  706.       }
  707.    }
  708.  
  709.    /* Depth */
  710.    if (dimensions >= 3) {
  711.       if (depth < 2 * border || depth > 2 + ctx->Const.MaxTextureSize
  712.           || logbase2( depth - 2 * border ) < 0) {
  713.          if (!isProxy) {
  714.             gl_error( ctx, GL_INVALID_VALUE, "glTexImage3D(depth)" );
  715.          }
  716.          return GL_TRUE;
  717.       }
  718.    }
  719.  
  720.    /* Level */
  721.    if (level<0 || level>=ctx->Const.MaxTextureLevels) {
  722.       if (!isProxy) {
  723.          char message[100];
  724.          sprintf(message, "glTexImage%dD(level)", dimensions);
  725.          gl_error(ctx, GL_INVALID_VALUE, message);
  726.       }
  727.       return GL_TRUE;
  728.    }
  729.  
  730.    iformat = decode_internal_format( internalFormat );
  731.    if (iformat < 0) {
  732.       if (!isProxy) {
  733.          char message[100];
  734.          sprintf(message, "glTexImage%dD(internalFormat)", dimensions);
  735.          gl_error(ctx, GL_INVALID_VALUE, message);
  736.       }
  737.       return GL_TRUE;
  738.    }
  739.  
  740.    if (!gl_is_legal_format_and_type( format, type )) {
  741.       /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there
  742.        * is a type/format mismatch.  See 1.2 spec page 94, sec 3.6.4.
  743.        */
  744.       if (!isProxy) {
  745.          char message[100];
  746.          sprintf(message, "glTexImage%dD(format or type)", dimensions);
  747.          gl_error(ctx, GL_INVALID_OPERATION, message);
  748.       }
  749.       return GL_TRUE;
  750.    }
  751.  
  752.    /* if we get here, the parameters are OK */
  753.    return GL_FALSE;
  754. }
  755.  
  756.  
  757.  
  758. /*
  759.  * Test glTexSubImage[123]D() parameters for errors.
  760.  * Input:
  761.  *         dimensions - must be 1 or 2 or 3
  762.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  763.  */
  764. static GLboolean
  765. subtexture_error_check( GLcontext *ctx, GLint dimensions,
  766.                         GLenum target, GLint level,
  767.                         GLint xoffset, GLint yoffset, GLint zoffset,
  768.                         GLint width, GLint height, GLint depth,
  769.                         GLenum format, GLenum type )
  770. {
  771.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  772.    struct gl_texture_image *destTex;
  773.  
  774.    if (dimensions == 1) {
  775.       if (target != GL_TEXTURE_1D) {
  776.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
  777.          return GL_TRUE;
  778.       }
  779.    }
  780.    else if (dimensions == 2) {
  781.       if (target != GL_TEXTURE_2D) {
  782.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
  783.          return GL_TRUE;
  784.       }
  785.    }
  786.    else if (dimensions == 3) {
  787.       if (target != GL_TEXTURE_3D) {
  788.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" );
  789.          return GL_TRUE;
  790.       }
  791.    }
  792.    else {
  793.       gl_problem( ctx, "bad dims in texture_error_check" );
  794.       return GL_TRUE;
  795.    }
  796.  
  797.    if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
  798.       gl_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level)");
  799.       return GL_TRUE;
  800.    }
  801.  
  802.    if (width < 0) {
  803.       char message[100];
  804.       sprintf(message, "glTexSubImage%dD(width)", dimensions);
  805.       gl_error(ctx, GL_INVALID_VALUE, message);
  806.       return GL_TRUE;
  807.    }
  808.    if (height < 0 && dimensions > 1) {
  809.       char message[100];
  810.       sprintf(message, "glTexSubImage%dD(height)", dimensions);
  811.       gl_error(ctx, GL_INVALID_VALUE, message);
  812.       return GL_TRUE;
  813.    }
  814.    if (depth < 0 && dimensions > 2) {
  815.       char message[100];
  816.       sprintf(message, "glTexSubImage%dD(depth)", dimensions);
  817.       gl_error(ctx, GL_INVALID_VALUE, message);
  818.       return GL_TRUE;
  819.    }
  820.  
  821.    destTex = texUnit->CurrentD[2]->Image[level];
  822.    if (!destTex) {
  823.       gl_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D");
  824.       return GL_TRUE;
  825.    }
  826.  
  827.    if (xoffset < -((GLint)destTex->Border)) {
  828.       gl_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)");
  829.       return GL_TRUE;
  830.    }
  831.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  832.       gl_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)");
  833.       return GL_TRUE;
  834.    }
  835.    if (dimensions > 1) {
  836.       if (yoffset < -((GLint)destTex->Border)) {
  837.          gl_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)");
  838.          return GL_TRUE;
  839.       }
  840.       if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
  841.          gl_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)");
  842.          return GL_TRUE;
  843.       }
  844.    }
  845.    if (dimensions > 2) {
  846.       if (zoffset < -((GLint)destTex->Border)) {
  847.          gl_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
  848.          return GL_TRUE;
  849.       }
  850.       if (zoffset + depth  > (GLint) (destTex->Depth+destTex->Border)) {
  851.          gl_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
  852.          return GL_TRUE;
  853.       }
  854.    }
  855.  
  856.    if (!gl_is_legal_format_and_type(format, type)) {
  857.       char message[100];
  858.       sprintf(message, "glTexSubImage%dD(format or type)", dimensions);
  859.       gl_error(ctx, GL_INVALID_ENUM, message);
  860.       return GL_TRUE;
  861.    }
  862.  
  863.    return GL_FALSE;
  864. }
  865.  
  866.  
  867. /*
  868.  * Test glCopyTexImage[12]D() parameters for errors.
  869.  * Input:  dimensions - must be 1 or 2 or 3
  870.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  871.  */
  872. static GLboolean
  873. copytexture_error_check( GLcontext *ctx, GLint dimensions,
  874.                          GLenum target, GLint level, GLint internalFormat,
  875.                          GLint width, GLint height, GLint border )
  876. {
  877.    GLint iformat;
  878.  
  879.    if (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) {
  880.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1/2D(target)" );
  881.       return GL_TRUE;
  882.    }
  883.  
  884.    if (dimensions == 1 && target != GL_TEXTURE_1D) {
  885.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
  886.       return GL_TRUE;
  887.    }
  888.    else if (dimensions == 2 && target != GL_TEXTURE_2D) {
  889.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  890.       return GL_TRUE;
  891.    }
  892.  
  893.    /* Border */
  894.    if (border!=0 && border!=1) {
  895.       char message[100];
  896.       sprintf(message, "glCopyTexImage%dD(border)", dimensions);
  897.       gl_error(ctx, GL_INVALID_VALUE, message);
  898.       return GL_TRUE;
  899.    }
  900.  
  901.    /* Width */
  902.    if (width < 2 * border || width > 2 + ctx->Const.MaxTextureSize
  903.        || logbase2( width - 2 * border ) < 0) {
  904.       char message[100];
  905.       sprintf(message, "glCopyTexImage%dD(width)", dimensions);
  906.       gl_error(ctx, GL_INVALID_VALUE, message);
  907.       return GL_TRUE;
  908.    }
  909.  
  910.    /* Height */
  911.    if (dimensions >= 2) {
  912.       if (height < 2 * border || height > 2 + ctx->Const.MaxTextureSize
  913.           || logbase2( height - 2 * border ) < 0) {
  914.          char message[100];
  915.          sprintf(message, "glCopyTexImage%dD(height)", dimensions);
  916.          gl_error(ctx, GL_INVALID_VALUE, message);
  917.          return GL_TRUE;
  918.       }
  919.    }
  920.  
  921.    /* Level */
  922.    if (level<0 || level>=ctx->Const.MaxTextureLevels) {
  923.       char message[100];
  924.       sprintf(message, "glCopyTexImage%dD(level)", dimensions);
  925.       gl_error(ctx, GL_INVALID_VALUE, message);
  926.       return GL_TRUE;
  927.    }
  928.  
  929.    iformat = decode_internal_format( internalFormat );
  930.    if (iformat < 0) {
  931.       char message[100];
  932.       sprintf(message, "glCopyTexImage%dD(internalFormat)", dimensions);
  933.       gl_error(ctx, GL_INVALID_VALUE, message);
  934.       return GL_TRUE;
  935.    }
  936.  
  937.    /* if we get here, the parameters are OK */
  938.    return GL_FALSE;
  939. }
  940.  
  941.  
  942. static GLboolean
  943. copytexsubimage_error_check( GLcontext *ctx, GLint dimensions,
  944.                              GLenum target, GLint level,
  945.                              GLint xoffset, GLint yoffset, GLint zoffset,
  946.                              GLsizei width, GLsizei height )
  947. {
  948.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  949.    struct gl_texture_image *teximage;
  950.  
  951.    if (dimensions == 1 && target != GL_TEXTURE_1D) {
  952.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
  953.       return GL_TRUE;
  954.    }
  955.    else if (dimensions == 2 && target != GL_TEXTURE_2D) {
  956.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  957.       return GL_TRUE;
  958.    }
  959.    else if (dimensions == 3 && target != GL_TEXTURE_3D) {
  960.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" );
  961.       return GL_TRUE;
  962.    }
  963.  
  964.    if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
  965.       char message[100];
  966.       sprintf(message, "glCopyTexSubImage%dD(level)", dimensions);
  967.       gl_error(ctx, GL_INVALID_VALUE, message);
  968.       return GL_TRUE;
  969.    }
  970.  
  971.    if (width < 0) {
  972.       char message[100];
  973.       sprintf(message, "glCopyTexSubImage%dD(width)", dimensions );
  974.       gl_error(ctx, GL_INVALID_VALUE, message);
  975.       return GL_TRUE;
  976.    }
  977.    if (dimensions > 1 && height < 0) {
  978.       char message[100];
  979.       sprintf(message, "glCopyTexSubImage%dD(height)", dimensions );
  980.       gl_error(ctx, GL_INVALID_VALUE, message);
  981.       return GL_TRUE;
  982.    }
  983.  
  984.    teximage = texUnit->CurrentD[dimensions]->Image[level];
  985.    if (!teximage) {
  986.       char message[100];
  987.       sprintf(message, "glCopyTexSubImage%dD(undefined texture)", dimensions);
  988.       gl_error(ctx, GL_INVALID_OPERATION, message);
  989.       return GL_TRUE;
  990.    }
  991.  
  992.    if (xoffset < -((GLint)teximage->Border)) {
  993.       char message[100];
  994.       sprintf(message, "glCopyTexSubImage%dD(xoffset)", dimensions);
  995.       gl_error(ctx, GL_INVALID_VALUE, message);
  996.       return GL_TRUE;
  997.    }
  998.    if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  999.       char message[100];
  1000.       sprintf(message, "glCopyTexSubImage%dD(xoffset+width)", dimensions);
  1001.       gl_error(ctx, GL_INVALID_VALUE, message);
  1002.       return GL_TRUE;
  1003.    }
  1004.    if (dimensions > 1) {
  1005.       if (yoffset < -((GLint)teximage->Border)) {
  1006.          char message[100];
  1007.          sprintf(message, "glCopyTexSubImage%dD(yoffset)", dimensions);
  1008.          gl_error(ctx, GL_INVALID_VALUE, message);
  1009.          return GL_TRUE;
  1010.       }
  1011.       /* NOTE: we're adding the border here, not subtracting! */
  1012.       if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
  1013.          char message[100];
  1014.          sprintf(message, "glCopyTexSubImage%dD(yoffset+height)", dimensions);
  1015.          gl_error(ctx, GL_INVALID_VALUE, message);
  1016.          return GL_TRUE;
  1017.       }
  1018.    }
  1019.  
  1020.    if (dimensions > 2) {
  1021.       if (zoffset < -((GLint)teximage->Border)) {
  1022.          char message[100];
  1023.          sprintf(message, "glCopyTexSubImage%dD(zoffset)", dimensions);
  1024.          gl_error(ctx, GL_INVALID_VALUE, message);
  1025.          return GL_TRUE;
  1026.       }
  1027.       if (zoffset > (GLint) (teximage->Depth+teximage->Border)) {
  1028.          char message[100];
  1029.          sprintf(message, "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
  1030.          gl_error(ctx, GL_INVALID_VALUE, message);
  1031.          return GL_TRUE;
  1032.       }
  1033.    }
  1034.  
  1035.    /* if we get here, the parameters are OK */
  1036.    return GL_FALSE;
  1037. }
  1038.  
  1039.  
  1040.  
  1041.  
  1042. /*
  1043.  * Called from the API.  Note that width includes the border.
  1044.  */
  1045. void gl_TexImage1D( GLcontext *ctx, GLenum target, GLint level,
  1046.                     GLint internalformat,
  1047.                     GLsizei width, GLint border, GLenum format,
  1048.                     GLenum type, const GLvoid *pixels )
  1049. {
  1050.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1051.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage1D");
  1052.  
  1053.    if (target==GL_TEXTURE_1D) {
  1054.       struct gl_texture_image *teximage;
  1055.       if (texture_error_check( ctx, target, level, internalformat,
  1056.                                format, type, 1, width, 1, 1, border )) {
  1057.          /* error in texture image was detected */
  1058.          return;
  1059.       }
  1060.  
  1061.       /* free current texture image, if any */
  1062.       if (texUnit->CurrentD[1]->Image[level]) {
  1063.          gl_free_texture_image( texUnit->CurrentD[1]->Image[level] );
  1064.       }
  1065.  
  1066.       /* make new texture from source image */
  1067.       if (pixels) {
  1068.          teximage = make_texture_image(ctx, internalformat, width, 1, 1,
  1069.                               border, format, type, pixels, &ctx->Unpack);
  1070.       }
  1071.       else {
  1072.          teximage = make_null_texture(ctx, (GLenum) internalformat,
  1073.                                       width, 1, 1, border);
  1074.       }
  1075.  
  1076.       /* install new texture image */
  1077.       texUnit->CurrentD[1]->Image[level] = teximage;
  1078.       gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
  1079.       ctx->NewState |= NEW_TEXTURING;
  1080.  
  1081.       /* tell driver about change */
  1082.       if (ctx->Driver.TexImage) {
  1083.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  1084.                                   texUnit->CurrentD[1],
  1085.                                   level, internalformat, teximage );
  1086.       }
  1087.    }
  1088.    else if (target==GL_PROXY_TEXTURE_1D) {
  1089.       /* Proxy texture: check for errors and update proxy state */
  1090.       if (texture_error_check( ctx, target, level, internalformat,
  1091.                                format, type, 1, width, 1, 1, border )) {
  1092.          if (level>=0 && level<ctx->Const.MaxTextureLevels) {
  1093.             MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
  1094.                     sizeof(struct gl_texture_image) );
  1095.          }
  1096.       }
  1097.       else {
  1098.          ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) format;
  1099.          set_teximage_component_sizes( ctx->Texture.Proxy1D->Image[level] );
  1100.          ctx->Texture.Proxy1D->Image[level]->IntFormat = (GLenum) internalformat;
  1101.          ctx->Texture.Proxy1D->Image[level]->Border = border;
  1102.          ctx->Texture.Proxy1D->Image[level]->Width = width;
  1103.          ctx->Texture.Proxy1D->Image[level]->Height = 1;
  1104.          ctx->Texture.Proxy1D->Image[level]->Depth = 1;
  1105.       }
  1106.    }
  1107.    else {
  1108.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  1109.       return;
  1110.    }
  1111. }
  1112.  
  1113.  
  1114. void gl_TexImage2D( GLcontext *ctx, GLenum target, GLint level,
  1115.                     GLint internalformat,
  1116.                     GLsizei width, GLsizei height, GLint border,
  1117.                     GLenum format, GLenum type,
  1118.                     const GLvoid *pixels )
  1119. {
  1120.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1121.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage2D");
  1122.  
  1123.    if (target==GL_TEXTURE_2D) {
  1124.       struct gl_texture_image *teximage;
  1125.       if (texture_error_check( ctx, target, level, internalformat,
  1126.                                format, type, 2, width, height, 1, border )) {
  1127.          /* error in texture image was detected */
  1128.          return;
  1129.       }
  1130.  
  1131.       /* free current texture image, if any */
  1132.       if (texUnit->CurrentD[2]->Image[level]) {
  1133.          gl_free_texture_image( texUnit->CurrentD[2]->Image[level] );
  1134.       }
  1135.  
  1136.       /* make new texture from source image */
  1137.       if (pixels) {
  1138.          teximage = make_texture_image(ctx, internalformat, width, height, 1,
  1139.                                   border, format, type, pixels, &ctx->Unpack);
  1140.       }
  1141.       else {
  1142.          teximage = make_null_texture(ctx, (GLenum) internalformat,
  1143.                                       width, height, 1, border);
  1144.       }
  1145.  
  1146.       /* install new texture image */
  1147.       texUnit->CurrentD[2]->Image[level] = teximage;
  1148.       gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[2] );
  1149.       ctx->NewState |= NEW_TEXTURING;
  1150.  
  1151.       /* tell driver about change */
  1152.       if (ctx->Driver.TexImage) {
  1153.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
  1154.                                   texUnit->CurrentD[2],
  1155.                                   level, internalformat, teximage );
  1156.       }
  1157.    }
  1158.    else if (target==GL_PROXY_TEXTURE_2D) {
  1159.       /* Proxy texture: check for errors and update proxy state */
  1160.       if (texture_error_check( ctx, target, level, internalformat,
  1161.                                format, type, 2, width, height, 1, border )) {
  1162.          if (level>=0 && level<ctx->Const.MaxTextureLevels) {
  1163.             MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
  1164.                     sizeof(struct gl_texture_image) );
  1165.          }
  1166.       }
  1167.       else {
  1168.          ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) format;
  1169.          set_teximage_component_sizes( ctx->Texture.Proxy2D->Image[level] );
  1170.          ctx->Texture.Proxy2D->Image[level]->IntFormat = (GLenum) internalformat;
  1171.          ctx->Texture.Proxy2D->Image[level]->Border = border;
  1172.          ctx->Texture.Proxy2D->Image[level]->Width = width;
  1173.          ctx->Texture.Proxy2D->Image[level]->Height = height;
  1174.          ctx->Texture.Proxy2D->Image[level]->Depth = 1;
  1175.       }
  1176.    }
  1177.    else {
  1178.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  1179.       return;
  1180.    }
  1181. }
  1182.  
  1183.  
  1184.  
  1185. /*
  1186.  * Called by the API or display list executor.
  1187.  * Note that width and height include the border.
  1188.  */
  1189. void gl_TexImage3D( GLcontext *ctx, GLenum target, GLint level,
  1190.                     GLint internalformat,
  1191.                     GLsizei width, GLsizei height, GLsizei depth,
  1192.                     GLint border, GLenum format, GLenum type,
  1193.                     const GLvoid *pixels )
  1194. {
  1195.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1196.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexImage3D");
  1197.  
  1198.    if (target==GL_TEXTURE_3D) {
  1199.       struct gl_texture_image *teximage;
  1200.       if (texture_error_check( ctx, target, level, internalformat,
  1201.                                format, type, 3, width, height, depth,
  1202.                                border )) {
  1203.          /* error in texture image was detected */
  1204.          return;
  1205.       }
  1206.  
  1207.       /* free current texture image, if any */
  1208.       if (texUnit->CurrentD[3]->Image[level]) {
  1209.          gl_free_texture_image( texUnit->CurrentD[3]->Image[level] );
  1210.       }
  1211.  
  1212.       /* make new texture from source image */
  1213.       if (pixels) {
  1214.          teximage = make_texture_image(ctx, internalformat, width, height,
  1215.                        depth, border, format, type, pixels, &ctx->Unpack);
  1216.       }
  1217.       else {
  1218.          teximage = make_null_texture(ctx, (GLenum) internalformat,
  1219.                                       width, height, depth, border);
  1220.       }
  1221.  
  1222.       /* install new texture image */
  1223.       texUnit->CurrentD[3]->Image[level] = teximage;
  1224.       gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[3] );
  1225.       ctx->NewState |= NEW_TEXTURING;
  1226.  
  1227.       /* tell driver about change */
  1228.       if (ctx->Driver.TexImage) {
  1229.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
  1230.                                   texUnit->CurrentD[3],
  1231.                                   level, internalformat, teximage );
  1232.       }
  1233.    }
  1234.    else if (target==GL_PROXY_TEXTURE_3D_EXT) {
  1235.       /* Proxy texture: check for errors and update proxy state */
  1236.       if (texture_error_check( ctx, target, level, internalformat,
  1237.                                format, type, 3, width, height, depth,
  1238.                                border )) {
  1239.          if (level>=0 && level<ctx->Const.MaxTextureLevels) {
  1240.             MEMSET( ctx->Texture.Proxy3D->Image[level], 0,
  1241.                     sizeof(struct gl_texture_image) );
  1242.          }
  1243.       }
  1244.       else {
  1245.          ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) format;
  1246.          set_teximage_component_sizes( ctx->Texture.Proxy3D->Image[level] );
  1247.          ctx->Texture.Proxy3D->Image[level]->IntFormat = (GLenum) internalformat;
  1248.          ctx->Texture.Proxy3D->Image[level]->Border = border;
  1249.          ctx->Texture.Proxy3D->Image[level]->Width = width;
  1250.          ctx->Texture.Proxy3D->Image[level]->Height = height;
  1251.          ctx->Texture.Proxy3D->Image[level]->Depth  = depth;
  1252.       }
  1253.    }
  1254.    else {
  1255.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" );
  1256.       return;
  1257.    }
  1258. }
  1259.  
  1260.  
  1261.  
  1262. void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
  1263.                      GLenum type, GLvoid *pixels )
  1264. {
  1265.    const struct gl_texture_object *texObj;
  1266.  
  1267.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetTexImage");
  1268.  
  1269.    if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
  1270.       gl_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
  1271.       return;
  1272.    }
  1273.  
  1274.    if (gl_sizeof_type(type) <= 0) {
  1275.       gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
  1276.       return;
  1277.    }
  1278.  
  1279.    if (gl_components_in_format(format) <= 0) {
  1280.       gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
  1281.       return;
  1282.    }
  1283.  
  1284.    if (!pixels)
  1285.       return;  /* XXX generate an error??? */
  1286.  
  1287.    switch (target) {
  1288.       case GL_TEXTURE_1D:
  1289.          texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[1];
  1290.          break;
  1291.       case GL_TEXTURE_2D:
  1292.          texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[2];
  1293.          break;
  1294.       case GL_TEXTURE_3D:
  1295.          texObj = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentD[3];
  1296.          break;
  1297.       default:
  1298.          gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(target)" );
  1299.          return;
  1300.    }
  1301.  
  1302.    if (texObj->Image[level] && texObj->Image[level]->Data) {
  1303.       const struct gl_texture_image *texImage = texObj->Image[level];
  1304.       GLint width = texImage->Width;
  1305.       GLint height = texImage->Height;
  1306.       GLint row;
  1307.  
  1308.       for (row = 0; row < height; row++) {
  1309.          /* compute destination address in client memory */
  1310.          GLvoid *dest = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
  1311.                                                 width, height,
  1312.                                                 format, type, 0, row, 0);
  1313.  
  1314.          assert(dest);
  1315.          if (texImage->Format == GL_RGBA) {
  1316.             const GLubyte *src = texImage->Data + row * width * 4 * sizeof(GLubyte);
  1317.             gl_pack_rgba_span( ctx, width, (void *) src, format, type, dest,
  1318.                                &ctx->Pack, GL_TRUE );
  1319.          }
  1320.          else {
  1321.             /* fetch RGBA row from texture image then pack it in client mem */
  1322.             GLubyte rgba[MAX_WIDTH][4];
  1323.             GLint i;
  1324.             const GLubyte *src;
  1325.             switch (texImage->Format) {
  1326.                case GL_ALPHA:
  1327.                   src = texImage->Data + row * width * sizeof(GLubyte);
  1328.                   for (i = 0; i < width; i++) {
  1329.                      rgba[i][RCOMP] = 255;
  1330.                      rgba[i][GCOMP] = 255;
  1331.                      rgba[i][BCOMP] = 255;
  1332.                      rgba[i][ACOMP] = src[i];
  1333.                   }
  1334.                   break;
  1335.                case GL_LUMINANCE:
  1336.                   src = texImage->Data + row * width * sizeof(GLubyte);
  1337.                   for (i = 0; i < width; i++) {
  1338.                      rgba[i][RCOMP] = src[i];
  1339.                      rgba[i][GCOMP] = src[i];
  1340.                      rgba[i][BCOMP] = src[i];
  1341.                      rgba[i][ACOMP] = 255;
  1342.                    }
  1343.                   break;
  1344.                case GL_LUMINANCE_ALPHA:
  1345.                   src = texImage->Data + row * 2 * width * sizeof(GLubyte);
  1346.                   for (i = 0; i < width; i++) {
  1347.                      rgba[i][RCOMP] = src[i*2+0];
  1348.                      rgba[i][GCOMP] = src[i*2+0];
  1349.                      rgba[i][BCOMP] = src[i*2+0];
  1350.                      rgba[i][ACOMP] = src[i*2+1];
  1351.                   }
  1352.                   break;
  1353.                case GL_INTENSITY:
  1354.                   src = texImage->Data + row * width * sizeof(GLubyte);
  1355.                   for (i = 0; i < width; i++) {
  1356.                      rgba[i][RCOMP] = src[i];
  1357.                      rgba[i][GCOMP] = src[i];
  1358.                      rgba[i][BCOMP] = src[i];
  1359.                      rgba[i][ACOMP] = 255;
  1360.                   }
  1361.                   break;
  1362.                case GL_RGB:
  1363.                   src = texImage->Data + row * 3 * width * sizeof(GLubyte);
  1364.                   for (i = 0; i < width; i++) {
  1365.                      rgba[i][RCOMP] = src[i*3+0];
  1366.                      rgba[i][GCOMP] = src[i*3+1];
  1367.                      rgba[i][BCOMP] = src[i*3+2];
  1368.                      rgba[i][ACOMP] = 255;
  1369.                   }
  1370.                   break;
  1371.                case GL_RGBA:
  1372.                   /* this special case should have been handled above! */
  1373.                   gl_problem( ctx, "error 1 in gl_GetTexImage" );
  1374.                   break;
  1375.                case GL_COLOR_INDEX:
  1376.                   gl_problem( ctx, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
  1377.                   break;
  1378.                default:
  1379.                   gl_problem( ctx, "bad format in gl_GetTexImage" );
  1380.             }
  1381.             gl_pack_rgba_span( ctx, width, (const GLubyte (*)[4])rgba,
  1382.                                format, type, dest, &ctx->Pack, GL_TRUE );
  1383.          }
  1384.       }
  1385.    }
  1386. }
  1387.  
  1388.  
  1389.  
  1390. void gl_TexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
  1391.                        GLint xoffset, GLsizei width,
  1392.                        GLenum format, GLenum type,
  1393.                        const GLvoid *pixels )
  1394. {
  1395.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1396.    struct gl_texture_image *destTex;
  1397.  
  1398.    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
  1399.                               width, 1, 1, format, type)) {
  1400.       /* error was detected */
  1401.       return;
  1402.    }
  1403.  
  1404.    destTex = texUnit->CurrentD[1]->Image[level];
  1405.    assert(destTex);
  1406.  
  1407.    if (width == 0 || !pixels)
  1408.       return;  /* no-op, not an error */
  1409.  
  1410.  
  1411.    /*
  1412.     * Replace the texture subimage
  1413.     */
  1414.    {
  1415.       const GLint texComponents = components_in_intformat(destTex->Format);
  1416.       const GLenum texFormat = destTex->Format;
  1417.       const GLint xoffsetb = xoffset + destTex->Border;
  1418.       GLubyte *dst = destTex->Data + xoffsetb * texComponents;
  1419.       if (texFormat == GL_COLOR_INDEX) {
  1420.          /* color index texture */
  1421.          const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
  1422.                                   width, 1, format, type, 0, 0, 0);
  1423.          _mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst,
  1424.                                     type, src, &ctx->Unpack, GL_TRUE);
  1425.       }
  1426.       else {
  1427.          /* color texture */
  1428.          const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
  1429.                                   width, 1, format, type, 0, 0, 0);
  1430.          _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst,
  1431.                               format, type, src, &ctx->Unpack, GL_TRUE);
  1432.       }
  1433.    }
  1434.  
  1435.    gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
  1436.  
  1437.    /*
  1438.     * Inform device driver of texture image change.
  1439.     */
  1440.    if (ctx->Driver.TexSubImage) {
  1441.       (*ctx->Driver.TexSubImage)(ctx, GL_TEXTURE_1D, texUnit->CurrentD[1],
  1442.                                  level, xoffset, 0, width, 1,
  1443.                                  texUnit->CurrentD[1]->Image[level]->IntFormat,
  1444.                                  destTex );
  1445.    }
  1446.    else {
  1447.       if (ctx->Driver.TexImage) {
  1448.          (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, texUnit->CurrentD[1],
  1449.                                  level,
  1450.                                  texUnit->CurrentD[1]->Image[level]->IntFormat,
  1451.                                  destTex );
  1452.       }
  1453.    }
  1454. }
  1455.  
  1456.  
  1457. void gl_TexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
  1458.                        GLint xoffset, GLint yoffset,
  1459.                        GLsizei width, GLsizei height,
  1460.                        GLenum format, GLenum type,
  1461.                        const GLvoid *pixels )
  1462. {
  1463.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1464.    struct gl_texture_image *destTex;
  1465.  
  1466.    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
  1467.                               width, height, 1, format, type)) {
  1468.       /* error was detected */
  1469.       return;
  1470.    }
  1471.  
  1472.    destTex = texUnit->CurrentD[2]->Image[level];
  1473.    assert(destTex);
  1474.  
  1475.    if (width == 0 || height == 0 || !pixels)
  1476.       return;  /* no-op, not an error */
  1477.  
  1478.  
  1479.    /*
  1480.     * Replace the texture subimage
  1481.     */
  1482.    {
  1483.       const GLint texComponents = components_in_intformat(destTex->Format);
  1484.       const GLenum texFormat = destTex->Format;
  1485.       const GLint xoffsetb = xoffset + destTex->Border;
  1486.       const GLint yoffsetb = yoffset + destTex->Border;
  1487.       GLubyte *dst = destTex->Data
  1488.                    + (yoffsetb * destTex->Width + xoffsetb) * texComponents;
  1489.       if (texFormat == GL_COLOR_INDEX) {
  1490.          /* color index texture */
  1491.          const GLint stride = destTex->Width * sizeof(GLubyte);
  1492.          GLint row;
  1493.          for (row = 0; row < height; row++) {
  1494.             const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
  1495.                                      width, height, format, type, 0, row, 0);
  1496.             _mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst,
  1497.                                     type, src, &ctx->Unpack, GL_TRUE);
  1498.             dst += stride;
  1499.          }
  1500.       }
  1501.       else {
  1502.          /* color texture */
  1503.          const GLint stride = destTex->Width * texComponents * sizeof(GLubyte);
  1504.          GLint row;
  1505.          for (row = 0; row < height; row++) {
  1506.             const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
  1507.                                      width, height, format, type, 0, row, 0);
  1508.             _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst,
  1509.                                  format, type, src, &ctx->Unpack, GL_TRUE);
  1510.             dst += stride;
  1511.          }
  1512.       }
  1513.    }
  1514.  
  1515.    gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[2] );
  1516.  
  1517.    /*
  1518.     * Inform device driver of texture image change.
  1519.     */
  1520.    if (ctx->Driver.TexSubImage) {
  1521.       (*ctx->Driver.TexSubImage)(ctx, GL_TEXTURE_2D, texUnit->CurrentD[2],
  1522.                                  level, xoffset, yoffset, width, height,
  1523.                                  texUnit->CurrentD[2]->Image[level]->IntFormat,
  1524.                                  destTex );
  1525.    }
  1526.    else {
  1527.       if (ctx->Driver.TexImage) {
  1528.          (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, texUnit->CurrentD[2],
  1529.                                  level,
  1530.                                  texUnit->CurrentD[2]->Image[level]->IntFormat,
  1531.                                  destTex );
  1532.       }
  1533.    }
  1534. }
  1535.  
  1536.  
  1537.  
  1538. void gl_TexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
  1539.                        GLint xoffset, GLint yoffset, GLint zoffset,
  1540.                        GLsizei width, GLsizei height, GLsizei depth,
  1541.                        GLenum format, GLenum type,
  1542.                        const GLvoid *pixels )
  1543. {
  1544.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1545.    struct gl_texture_image *destTex;
  1546.  
  1547.    if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
  1548.                               width, height, depth, format, type)) {
  1549.       /* error was detected */
  1550.       return;
  1551.    }
  1552.  
  1553.    destTex = texUnit->CurrentD[3]->Image[level];
  1554.    assert(destTex);
  1555.  
  1556.    if (width == 0 || height == 0 || height == 0 || !pixels)
  1557.       return;  /* no-op, not an error */
  1558.  
  1559.    /*
  1560.     * Replace the texture subimage
  1561.     */
  1562.    {
  1563.       const GLint texComponents = components_in_intformat(destTex->Format);
  1564.       const GLenum texFormat = destTex->Format;
  1565.       const GLint xoffsetb = xoffset + destTex->Border;
  1566.       const GLint yoffsetb = yoffset + destTex->Border;
  1567.       const GLint zoffsetb = zoffset + destTex->Border;
  1568.       GLint dstRectArea = destTex->Width * destTex->Height;
  1569.       GLubyte *dst = destTex->Data 
  1570.             + (zoffsetb * dstRectArea +  yoffsetb * destTex->Width + xoffsetb)
  1571.             * texComponents;
  1572.  
  1573.       if (texFormat == GL_COLOR_INDEX) {
  1574.          /* color index texture */
  1575.          const GLint stride = destTex->Width * sizeof(GLubyte);
  1576.          GLint img, row;
  1577.          for (img = 0; img < depth; img++) {
  1578.             for (row = 0; row < height; row++) {
  1579.                const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
  1580.                                     width, height, format, type, img, row, 0);
  1581.                _mesa_unpack_index_span(ctx, width, GL_UNSIGNED_BYTE, dst,
  1582.                                        type, src, &ctx->Unpack, GL_TRUE);
  1583.                dst += stride;
  1584.             }
  1585.          }
  1586.       }
  1587.       else {
  1588.          /* color texture */
  1589.          const GLint stride = destTex->Width * texComponents * sizeof(GLubyte);
  1590.          GLint img, row;
  1591.          for (img = 0; img < depth; img++) {
  1592.             for (row = 0; row < height; row++) {
  1593.                const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, pixels,
  1594.                                      width, height, format, type, img, row, 0);
  1595.                _mesa_unpack_ubyte_color_span(ctx, width, texFormat, dst,
  1596.                                     format, type, src, &ctx->Unpack, GL_TRUE);
  1597.                dst += stride;
  1598.             }
  1599.          }
  1600.       }
  1601.    }
  1602.  
  1603.    gl_put_texobj_on_dirty_list( ctx, texUnit->CurrentD[1] );
  1604.  
  1605.    /*
  1606.     * Inform device driver of texture image change.
  1607.     */
  1608.    /* XXX todo */
  1609. }
  1610.  
  1611.  
  1612.  
  1613. /*
  1614.  * Read an RGBA image from the frame buffer.
  1615.  * This is used by glCopyTexSubImage[12]D().
  1616.  * Input:  ctx - the context
  1617.  *         x, y - lower left corner
  1618.  *         width, height - size of region to read
  1619.  * Return: pointer to block of GL_RGBA, GLubyte data.
  1620.  */
  1621. static GLubyte *
  1622. read_color_image( GLcontext *ctx, GLint x, GLint y,
  1623.                   GLsizei width, GLsizei height )
  1624. {
  1625.    GLint stride, i;
  1626.    GLubyte *image, *dst;
  1627.  
  1628.    image = MALLOC(width * height * 4 * sizeof(GLubyte));
  1629.    if (!image)
  1630.       return NULL;
  1631.  
  1632.    /* Select buffer to read from */
  1633.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
  1634.  
  1635.    dst = image;
  1636.    stride = width * 4 * sizeof(GLubyte);
  1637.    for (i = 0; i < height; i++) {
  1638.       gl_read_rgba_span( ctx, width, x, y + i, (GLubyte (*)[4]) dst );
  1639.       dst += stride;
  1640.    }
  1641.  
  1642.    /* Restore drawing buffer */
  1643.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
  1644.  
  1645.    return image;
  1646. }
  1647.  
  1648.  
  1649.  
  1650. void gl_CopyTexImage1D( GLcontext *ctx, GLenum target, GLint level,
  1651.                         GLenum internalFormat,
  1652.                         GLint x, GLint y,
  1653.                         GLsizei width, GLint border )
  1654. {
  1655.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexImage1D");
  1656.  
  1657.    if (!copytexture_error_check(ctx, 1, target, level, internalFormat,
  1658.                                width, 1, border)) {
  1659.       GLubyte *image  = read_color_image( ctx, x, y, width, 1 );
  1660.       if (!image) {
  1661.          gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
  1662.          return;
  1663.       }
  1664.       (*ctx->Exec.TexImage1D)( ctx, target, level, internalFormat, width,
  1665.                                border, GL_RGBA, GL_UNSIGNED_BYTE, image );
  1666.       FREE(image);
  1667.    }
  1668. }
  1669.  
  1670.  
  1671.  
  1672. void gl_CopyTexImage2D( GLcontext *ctx, GLenum target, GLint level,
  1673.                         GLenum internalFormat,
  1674.                         GLint x, GLint y, GLsizei width, GLsizei height,
  1675.                         GLint border )
  1676. {
  1677.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexImage2D");
  1678.  
  1679.    if (!copytexture_error_check(ctx, 2, target, level, internalFormat,
  1680.                                width, height, border)) {
  1681.       GLubyte *image  = read_color_image( ctx, x, y, width, height );
  1682.       if (!image) {
  1683.          gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
  1684.          return;
  1685.       }
  1686.       {
  1687.          struct gl_pixelstore_attrib save = ctx->Unpack;
  1688.          ctx->Unpack = defaultPacking;
  1689.          (ctx->Exec.TexImage2D)( ctx, target, level, internalFormat, width,
  1690.                          height, border, GL_RGBA, GL_UNSIGNED_BYTE, image );
  1691.          ctx->Unpack = save;  /* restore */
  1692.       }
  1693.       FREE(image);
  1694.    }
  1695. }
  1696.  
  1697.  
  1698.  
  1699. /*
  1700.  * Do the work of glCopyTexSubImage[123]D.
  1701.  */
  1702. static void
  1703. copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
  1704.                     GLint width, GLint height,
  1705.                     GLint srcx, GLint srcy,
  1706.                     GLint dstx, GLint dsty, GLint dstz )
  1707. {
  1708.    static struct gl_pixelstore_attrib packing = {
  1709.       1,            /* Alignment */
  1710.       0,            /* RowLength */
  1711.       0,            /* SkipPixels */
  1712.       0,            /* SkipRows */
  1713.       0,            /* ImageHeight */
  1714.       0,            /* SkipImages */
  1715.       GL_FALSE,     /* SwapBytes */
  1716.       GL_FALSE      /* LsbFirst */
  1717.    };
  1718.  
  1719.    GLint i;
  1720.    GLint format, components, rectarea;
  1721.    GLint texwidth, texheight, zoffset;
  1722.  
  1723.    /* dst[xyz] may be negative if we have a texture border! */
  1724.    dstx += dest->Border;
  1725.    dsty += dest->Border;
  1726.    dstz += dest->Border;
  1727.    texwidth = dest->Width;
  1728.    texheight = dest->Height;
  1729.    rectarea = texwidth * texheight;
  1730.    zoffset = dstz * rectarea; 
  1731.    format = dest->Format;
  1732.    components = components_in_intformat( format );
  1733.  
  1734.    /* Select buffer to read from */
  1735.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
  1736.  
  1737.    for (i = 0;i < height; i++) {
  1738.       GLubyte rgba[MAX_WIDTH][4];
  1739.       GLubyte *dst;
  1740.       gl_read_rgba_span( ctx, width, srcx, srcy + i, rgba );
  1741.       dst = dest->Data + ( zoffset + (dsty+i) * texwidth + dstx) * components;
  1742.       _mesa_unpack_ubyte_color_span(ctx, width, format, dst,
  1743.                                     GL_RGBA, GL_UNSIGNED_BYTE, rgba,
  1744.                                     &packing, GL_TRUE);
  1745.    }
  1746.  
  1747.    /* Restore drawing buffer */
  1748.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
  1749. }
  1750.  
  1751.  
  1752.  
  1753.  
  1754. void gl_CopyTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
  1755.                            GLint xoffset, GLint x, GLint y, GLsizei width )
  1756. {
  1757.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage1D");
  1758.  
  1759.    if (!copytexsubimage_error_check(ctx, 1, target, level,
  1760.                     xoffset, 0, 0, width, 1)) {
  1761.       struct gl_texture_unit *texUnit;
  1762.       struct gl_texture_image *teximage;
  1763.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1764.       teximage = texUnit->CurrentD[1]->Image[level];
  1765.       assert(teximage);
  1766.       if (teximage->Data) {
  1767.          copy_tex_sub_image(ctx, teximage, width, 1, x, y, xoffset, 0, 0);
  1768.      /* tell driver about the change */
  1769.      if (ctx->Driver.TexImage) {
  1770.        (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  1771.                                     texUnit->CurrentD[1],
  1772.                     level, teximage->IntFormat, teximage );
  1773.      }
  1774.       }
  1775.    }
  1776. }
  1777.  
  1778.  
  1779.  
  1780. void gl_CopyTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
  1781.                            GLint xoffset, GLint yoffset,
  1782.                            GLint x, GLint y, GLsizei width, GLsizei height )
  1783. {
  1784.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage2D");
  1785.  
  1786.    if (!copytexsubimage_error_check(ctx, 2, target, level,
  1787.                     xoffset, yoffset, 0, width, height)) {
  1788.       struct gl_texture_unit *texUnit;
  1789.       struct gl_texture_image *teximage;
  1790.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1791.       teximage = texUnit->CurrentD[2]->Image[level];
  1792.       assert(teximage);
  1793.       if (teximage->Data) {
  1794.          copy_tex_sub_image(ctx, teximage, width, height,
  1795.                             x, y, xoffset, yoffset, 0);
  1796.      /* tell driver about the change */
  1797.      if (ctx->Driver.TexImage) {
  1798.        (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
  1799.                                     texUnit->CurrentD[2],
  1800.                     level, teximage->IntFormat, teximage );
  1801.      }
  1802.       }
  1803.    }
  1804. }
  1805.  
  1806.  
  1807.  
  1808. void gl_CopyTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
  1809.                            GLint xoffset, GLint yoffset, GLint zoffset,
  1810.                            GLint x, GLint y, GLsizei width, GLsizei height )
  1811. {
  1812.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glCopyTexSubImage3D");
  1813.  
  1814.    if (!copytexsubimage_error_check(ctx, 3, target, level,
  1815.                     xoffset, yoffset, zoffset, width, height)) {
  1816.       struct gl_texture_unit *texUnit;
  1817.       struct gl_texture_image *teximage;
  1818.       texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
  1819.       teximage = texUnit->CurrentD[3]->Image[level];
  1820.       assert(teximage);
  1821.       if (teximage->Data) {
  1822.          copy_tex_sub_image(ctx, teximage, width, height, 
  1823.                             x, y, xoffset, yoffset, zoffset);
  1824.      /* tell driver about the change */
  1825.      if (ctx->Driver.TexImage) {
  1826.        (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D,
  1827.                                     texUnit->CurrentD[3],
  1828.                     level, teximage->IntFormat, teximage );
  1829.      }
  1830.       }
  1831.    }
  1832. }
  1833.  
  1834.