ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

texstore.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.3
00004  *
00005  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 /*
00026  * Authors:
00027  *   Brian Paul
00028  */
00029 
00054 #include "glheader.h"
00055 #include "bufferobj.h"
00056 #include "colormac.h"
00057 #include "context.h"
00058 #if FEATURE_convolve
00059 #include "convolve.h"
00060 #endif
00061 #include "image.h"
00062 #include "macros.h"
00063 #include "mipmap.h"
00064 #include "imports.h"
00065 #include "texcompress.h"
00066 #include "texformat.h"
00067 #include "teximage.h"
00068 #include "texstore.h"
00069 #include "enums.h"
00070 
00071 
00072 enum {
00073    ZERO = 4, 
00074    ONE = 5
00075 };
00076 
00077 
00082 static GLboolean
00083 can_swizzle(GLenum logicalBaseFormat)
00084 {
00085    switch (logicalBaseFormat) {
00086    case GL_RGBA:
00087    case GL_RGB:
00088    case GL_LUMINANCE_ALPHA:
00089    case GL_INTENSITY:
00090    case GL_ALPHA:
00091    case GL_LUMINANCE:
00092    case GL_RED:
00093    case GL_GREEN:
00094    case GL_BLUE:
00095    case GL_BGR:
00096    case GL_BGRA:
00097    case GL_ABGR_EXT:
00098       return GL_TRUE;
00099    default:
00100       return GL_FALSE;
00101    }
00102 }
00103 
00104 
00105 
00106 enum {
00107    IDX_LUMINANCE = 0,
00108    IDX_ALPHA,
00109    IDX_INTENSITY,
00110    IDX_LUMINANCE_ALPHA,
00111    IDX_RGB,
00112    IDX_RGBA,
00113    IDX_RED,
00114    IDX_GREEN,
00115    IDX_BLUE,
00116    IDX_BGR,
00117    IDX_BGRA,
00118    IDX_ABGR,
00119    MAX_IDX
00120 };
00121 
00122 #define MAP1(x)       MAP4(x, ZERO, ZERO, ZERO)
00123 #define MAP2(x,y)     MAP4(x, y, ZERO, ZERO)
00124 #define MAP3(x,y,z)   MAP4(x, y, z, ZERO)
00125 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
00126 
00127 
00128 static const struct {
00129    GLubyte format_idx;
00130    GLubyte to_rgba[6];
00131    GLubyte from_rgba[6];
00132 } mappings[MAX_IDX] = 
00133 {
00134    {
00135       IDX_LUMINANCE,
00136       MAP4(0,0,0,ONE),
00137       MAP1(0)
00138    },
00139 
00140    {
00141       IDX_ALPHA,
00142       MAP4(ZERO, ZERO, ZERO, 0),
00143       MAP1(3)
00144    },
00145 
00146    {
00147       IDX_INTENSITY,
00148       MAP4(0, 0, 0, 0),
00149       MAP1(0),
00150    },
00151 
00152    {
00153       IDX_LUMINANCE_ALPHA,
00154       MAP4(0,0,0,1),
00155       MAP2(0,3)
00156    },
00157 
00158    {
00159       IDX_RGB,
00160       MAP4(0,1,2,ONE),
00161       MAP3(0,1,2)
00162    },
00163 
00164    {
00165       IDX_RGBA,
00166       MAP4(0,1,2,3),
00167       MAP4(0,1,2,3),
00168    },
00169 
00170 
00171    {
00172       IDX_RED,
00173       MAP4(0, ZERO, ZERO, ONE),
00174       MAP1(0),
00175    },
00176 
00177    {
00178       IDX_GREEN,
00179       MAP4(ZERO, 0, ZERO, ONE),
00180       MAP1(1),
00181    },
00182 
00183    {
00184       IDX_BLUE,
00185       MAP4(ZERO, ZERO, 0, ONE),
00186       MAP1(2),
00187    },
00188 
00189    {
00190       IDX_BGR,
00191       MAP4(2,1,0,ONE),
00192       MAP3(2,1,0)
00193    },
00194 
00195    {
00196       IDX_BGRA,
00197       MAP4(2,1,0,3),
00198       MAP4(2,1,0,3)
00199    },
00200 
00201    {
00202       IDX_ABGR,
00203       MAP4(3,2,1,0),
00204       MAP4(3,2,1,0)
00205    },
00206 };
00207 
00208 
00209 
00213 static int
00214 get_map_idx(GLenum value)
00215 {
00216    switch (value) {
00217    case GL_LUMINANCE: return IDX_LUMINANCE;
00218    case GL_ALPHA: return IDX_ALPHA;
00219    case GL_INTENSITY: return IDX_INTENSITY;
00220    case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
00221    case GL_RGB: return IDX_RGB;
00222    case GL_RGBA: return IDX_RGBA;
00223    case GL_RED: return IDX_RED;
00224    case GL_GREEN: return IDX_GREEN;
00225    case GL_BLUE: return IDX_BLUE;
00226    case GL_BGR: return IDX_BGR;
00227    case GL_BGRA: return IDX_BGRA;
00228    case GL_ABGR_EXT: return IDX_ABGR;
00229    default:
00230       _mesa_problem(NULL, "Unexpected inFormat");
00231       return 0;
00232    }
00233 }   
00234 
00235 
00244 static void
00245 compute_component_mapping(GLenum inFormat, GLenum outFormat, 
00246               GLubyte *map)
00247 {
00248    const int inFmt = get_map_idx(inFormat);
00249    const int outFmt = get_map_idx(outFormat);
00250    const GLubyte *in2rgba = mappings[inFmt].to_rgba;
00251    const GLubyte *rgba2out = mappings[outFmt].from_rgba;
00252    int i;
00253    
00254    for (i = 0; i < 4; i++)
00255       map[i] = in2rgba[rgba2out[i]];
00256 
00257    map[ZERO] = ZERO;
00258    map[ONE] = ONE;   
00259 
00260 /*
00261    _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
00262         inFormat, _mesa_lookup_enum_by_nr(inFormat),
00263         outFormat, _mesa_lookup_enum_by_nr(outFormat),
00264         map[0], 
00265         map[1], 
00266         map[2], 
00267         map[3], 
00268         map[4], 
00269         map[5]); 
00270 */
00271 }
00272 
00273 
00274 #if !FEATURE_convolve
00275 static void
00276 _mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
00277                                    GLsizei *srcWidth, GLsizei *srcHeight)
00278 {
00279    /* no-op */
00280 }
00281 #endif
00282 
00283 
00307 static GLfloat *
00308 make_temp_float_image(GLcontext *ctx, GLuint dims,
00309                       GLenum logicalBaseFormat,
00310                       GLenum textureBaseFormat,
00311                       GLint srcWidth, GLint srcHeight, GLint srcDepth,
00312                       GLenum srcFormat, GLenum srcType,
00313                       const GLvoid *srcAddr,
00314                       const struct gl_pixelstore_attrib *srcPacking)
00315 {
00316    GLuint transferOps = ctx->_ImageTransferState;
00317    GLfloat *tempImage;
00318 
00319    ASSERT(dims >= 1 && dims <= 3);
00320 
00321    ASSERT(logicalBaseFormat == GL_RGBA ||
00322           logicalBaseFormat == GL_RGB ||
00323           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
00324           logicalBaseFormat == GL_LUMINANCE ||
00325           logicalBaseFormat == GL_ALPHA ||
00326           logicalBaseFormat == GL_INTENSITY ||
00327           logicalBaseFormat == GL_COLOR_INDEX ||
00328           logicalBaseFormat == GL_DEPTH_COMPONENT);
00329 
00330    ASSERT(textureBaseFormat == GL_RGBA ||
00331           textureBaseFormat == GL_RGB ||
00332           textureBaseFormat == GL_LUMINANCE_ALPHA ||
00333           textureBaseFormat == GL_LUMINANCE ||
00334           textureBaseFormat == GL_ALPHA ||
00335           textureBaseFormat == GL_INTENSITY ||
00336           textureBaseFormat == GL_COLOR_INDEX ||
00337           textureBaseFormat == GL_DEPTH_COMPONENT);
00338 
00339    /* conventional color image */
00340 
00341    if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
00342        (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
00343        (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
00344       /* need image convolution */
00345       const GLuint preConvTransferOps
00346          = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
00347       const GLuint postConvTransferOps
00348          = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
00349       GLint img, row;
00350       GLint convWidth, convHeight;
00351       GLfloat *convImage;
00352 
00353       /* pre-convolution image buffer (3D) */
00354       tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
00355                                            * 4 * sizeof(GLfloat));
00356       if (!tempImage)
00357          return NULL;
00358 
00359       /* post-convolution image buffer (2D) */
00360       convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
00361                                            * 4 * sizeof(GLfloat));
00362       if (!convImage) {
00363          _mesa_free(tempImage);
00364          return NULL;
00365       }
00366 
00367       /* loop over 3D image slices */
00368       for (img = 0; img < srcDepth; img++) {
00369          GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
00370 
00371          /* unpack and do transfer ops up to convolution */
00372          for (row = 0; row < srcHeight; row++) {
00373             const GLvoid *src = _mesa_image_address(dims, srcPacking,
00374                                               srcAddr, srcWidth, srcHeight,
00375                                               srcFormat, srcType, img, row, 0);
00376             _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
00377                                           srcFormat, srcType, src,
00378                                           srcPacking,
00379                                           preConvTransferOps);
00380             dst += srcWidth * 4;
00381          }
00382 
00383          /* size after optional convolution */
00384          convWidth = srcWidth;
00385          convHeight = srcHeight;
00386 
00387 #if FEATURE_convolve
00388          /* do convolution */
00389          {
00390             GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
00391             if (dims == 1) {
00392                ASSERT(ctx->Pixel.Convolution1DEnabled);
00393                _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
00394             }
00395             else {
00396                if (ctx->Pixel.Convolution2DEnabled) {
00397                   _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
00398                                           src, convImage);
00399                }
00400                else {
00401                   ASSERT(ctx->Pixel.Separable2DEnabled);
00402                   _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
00403                                            src, convImage);
00404                }
00405             }
00406          }
00407 #endif
00408          /* do post-convolution transfer and pack into tempImage */
00409          {
00410             const GLint logComponents
00411                = _mesa_components_in_format(logicalBaseFormat);
00412             const GLfloat *src = convImage;
00413             GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
00414             for (row = 0; row < convHeight; row++) {
00415                _mesa_pack_rgba_span_float(ctx, convWidth,
00416                                           (GLfloat (*)[4]) src,
00417                                           logicalBaseFormat, GL_FLOAT,
00418                                           dst, &ctx->DefaultPacking,
00419                                           postConvTransferOps);
00420                src += convWidth * 4;
00421                dst += convWidth * logComponents;
00422             }
00423          }
00424       } /* loop over 3D image slices */
00425 
00426       _mesa_free(convImage);
00427 
00428       /* might need these below */
00429       srcWidth = convWidth;
00430       srcHeight = convHeight;
00431    }
00432    else {
00433       /* no convolution */
00434       const GLint components = _mesa_components_in_format(logicalBaseFormat);
00435       const GLint srcStride = _mesa_image_row_stride(srcPacking,
00436                                                  srcWidth, srcFormat, srcType);
00437       GLfloat *dst;
00438       GLint img, row;
00439 
00440       tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
00441                                            * components * sizeof(GLfloat));
00442       if (!tempImage)
00443          return NULL;
00444 
00445       dst = tempImage;
00446       for (img = 0; img < srcDepth; img++) {
00447          const GLubyte *src
00448             = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
00449                                                     srcWidth, srcHeight,
00450                                                     srcFormat, srcType,
00451                                                     img, 0, 0);
00452          for (row = 0; row < srcHeight; row++) {
00453             _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
00454                                           dst, srcFormat, srcType, src,
00455                                           srcPacking, transferOps);
00456             dst += srcWidth * components;
00457             src += srcStride;
00458          }
00459       }
00460    }
00461 
00462    if (logicalBaseFormat != textureBaseFormat) {
00463       /* more work */
00464       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
00465       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
00466       GLfloat *newImage;
00467       GLint i, n;
00468       GLubyte map[6];
00469 
00470       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
00471       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
00472              textureBaseFormat == GL_LUMINANCE_ALPHA);
00473 
00474       /* The actual texture format should have at least as many components
00475        * as the logical texture format.
00476        */
00477       ASSERT(texComponents >= logComponents);
00478 
00479       newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
00480                                           * texComponents * sizeof(GLfloat));
00481       if (!newImage) {
00482          _mesa_free(tempImage);
00483          return NULL;
00484       }
00485 
00486       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
00487 
00488       n = srcWidth * srcHeight * srcDepth;
00489       for (i = 0; i < n; i++) {
00490          GLint k;
00491          for (k = 0; k < texComponents; k++) {
00492             GLint j = map[k];
00493             if (j == ZERO)
00494                newImage[i * texComponents + k] = 0.0F;
00495             else if (j == ONE)
00496                newImage[i * texComponents + k] = 1.0F;
00497             else
00498                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
00499          }
00500       }
00501 
00502       _mesa_free(tempImage);
00503       tempImage = newImage;
00504    }
00505 
00506    return tempImage;
00507 }
00508 
00509 
00533 GLchan *
00534 _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
00535                            GLenum logicalBaseFormat,
00536                            GLenum textureBaseFormat,
00537                            GLint srcWidth, GLint srcHeight, GLint srcDepth,
00538                            GLenum srcFormat, GLenum srcType,
00539                            const GLvoid *srcAddr,
00540                            const struct gl_pixelstore_attrib *srcPacking)
00541 {
00542    GLuint transferOps = ctx->_ImageTransferState;
00543    const GLint components = _mesa_components_in_format(logicalBaseFormat);
00544    GLboolean freeSrcImage = GL_FALSE;
00545    GLint img, row;
00546    GLchan *tempImage, *dst;
00547 
00548    ASSERT(dims >= 1 && dims <= 3);
00549 
00550    ASSERT(logicalBaseFormat == GL_RGBA ||
00551           logicalBaseFormat == GL_RGB ||
00552           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
00553           logicalBaseFormat == GL_LUMINANCE ||
00554           logicalBaseFormat == GL_ALPHA ||
00555           logicalBaseFormat == GL_INTENSITY);
00556 
00557    ASSERT(textureBaseFormat == GL_RGBA ||
00558           textureBaseFormat == GL_RGB ||
00559           textureBaseFormat == GL_LUMINANCE_ALPHA ||
00560           textureBaseFormat == GL_LUMINANCE ||
00561           textureBaseFormat == GL_ALPHA ||
00562           textureBaseFormat == GL_INTENSITY);
00563 
00564 #if FEATURE_convolve
00565    if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
00566        (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
00567        (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
00568       /* get convolved image */
00569       GLfloat *convImage = make_temp_float_image(ctx, dims,
00570                                                  logicalBaseFormat,
00571                                                  logicalBaseFormat,
00572                                                  srcWidth, srcHeight, srcDepth,
00573                                                  srcFormat, srcType,
00574                                                  srcAddr, srcPacking);
00575       if (!convImage)
00576          return NULL;
00577       /* the convolved image is our new source image */
00578       srcAddr = convImage;
00579       srcFormat = logicalBaseFormat;
00580       srcType = GL_FLOAT;
00581       srcPacking = &ctx->DefaultPacking;
00582       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
00583       transferOps = 0;
00584       freeSrcImage = GL_TRUE;
00585    }
00586 #endif
00587 
00588    /* unpack and transfer the source image */
00589    tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
00590                                        * components * sizeof(GLchan));
00591    if (!tempImage)
00592       return NULL;
00593 
00594    dst = tempImage;
00595    for (img = 0; img < srcDepth; img++) {
00596       const GLint srcStride = _mesa_image_row_stride(srcPacking,
00597                                                      srcWidth, srcFormat,
00598                                                      srcType);
00599       const GLubyte *src
00600          = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
00601                                                  srcWidth, srcHeight,
00602                                                  srcFormat, srcType,
00603                                                  img, 0, 0);
00604       for (row = 0; row < srcHeight; row++) {
00605          _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
00606                                       srcFormat, srcType, src, srcPacking,
00607                                       transferOps);
00608          dst += srcWidth * components;
00609          src += srcStride;
00610       }
00611    }
00612 
00613    /* If we made a temporary image for convolution, free it here */
00614    if (freeSrcImage) {
00615       _mesa_free((void *) srcAddr);
00616    }
00617 
00618    if (logicalBaseFormat != textureBaseFormat) {
00619       /* one more conversion step */
00620       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
00621       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
00622       GLchan *newImage;
00623       GLint i, n;
00624       GLubyte map[6];
00625 
00626       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
00627       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
00628              textureBaseFormat == GL_LUMINANCE_ALPHA);
00629 
00630       /* The actual texture format should have at least as many components
00631        * as the logical texture format.
00632        */
00633       ASSERT(texComponents >= logComponents);
00634 
00635       newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
00636                                          * texComponents * sizeof(GLchan));
00637       if (!newImage) {
00638          _mesa_free(tempImage);
00639          return NULL;
00640       }
00641 
00642       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
00643 
00644       n = srcWidth * srcHeight * srcDepth;
00645       for (i = 0; i < n; i++) {
00646          GLint k;
00647          for (k = 0; k < texComponents; k++) {
00648             GLint j = map[k];
00649             if (j == ZERO)
00650                newImage[i * texComponents + k] = 0;
00651             else if (j == ONE)
00652                newImage[i * texComponents + k] = CHAN_MAX;
00653             else
00654                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
00655          }
00656       }
00657 
00658       _mesa_free(tempImage);
00659       tempImage = newImage;
00660    }
00661 
00662    return tempImage;
00663 }
00664 
00665 
00677 static void
00678 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, 
00679              GLuint srcComponents, const GLubyte *map, GLuint count)
00680 {
00681 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
00682    do {                                              \
00683       GLuint i;                                      \
00684       for (i = 0; i < count; i++) {                  \
00685          GLuint j;                                   \
00686          if (srcComps == 4) {                        \
00687             COPY_4UBV(tmp, src);                     \
00688          }                                           \
00689          else {                                      \
00690             for (j = 0; j < srcComps; j++) {         \
00691                tmp[j] = src[j];                      \
00692             }                                        \
00693          }                                           \
00694          src += srcComps;                            \
00695          for (j = 0; j < dstComps; j++) {            \
00696             dst[j] = tmp[map[j]];                    \
00697          }                                           \
00698          dst += dstComps;                            \
00699       }                                              \
00700    } while (0)
00701 
00702    GLubyte tmp[6];
00703 
00704    tmp[ZERO] = 0x0;
00705    tmp[ONE] = 0xff;
00706 
00707    ASSERT(srcComponents <= 4);
00708    ASSERT(dstComponents <= 4);
00709 
00710    switch (dstComponents) {
00711    case 4:
00712       switch (srcComponents) {
00713       case 4:
00714          SWZ_CPY(dst, src, count, 4, 4);
00715          break;
00716       case 3:
00717          SWZ_CPY(dst, src, count, 4, 3);
00718          break;
00719       case 2:
00720          SWZ_CPY(dst, src, count, 4, 2);
00721          break;
00722       case 1:
00723          SWZ_CPY(dst, src, count, 4, 1);
00724          break;
00725       default:
00726          ;
00727       }
00728       break;
00729    case 3:
00730       switch (srcComponents) {
00731       case 4:
00732          SWZ_CPY(dst, src, count, 3, 4);
00733          break;
00734       case 3:
00735          SWZ_CPY(dst, src, count, 3, 3);
00736          break;
00737       case 2:
00738          SWZ_CPY(dst, src, count, 3, 2);
00739          break;
00740       case 1:
00741          SWZ_CPY(dst, src, count, 3, 1);
00742          break;
00743       default:
00744          ;
00745       }
00746       break;
00747    case 2:
00748       switch (srcComponents) {
00749       case 4:
00750          SWZ_CPY(dst, src, count, 2, 4);
00751          break;
00752       case 3:
00753          SWZ_CPY(dst, src, count, 2, 3);
00754          break;
00755       case 2:
00756          SWZ_CPY(dst, src, count, 2, 2);
00757          break;
00758       case 1:
00759          SWZ_CPY(dst, src, count, 2, 1);
00760          break;
00761       default:
00762          ;
00763       }
00764       break;
00765    case 1:
00766       switch (srcComponents) {
00767       case 4:
00768          SWZ_CPY(dst, src, count, 1, 4);
00769          break;
00770       case 3:
00771          SWZ_CPY(dst, src, count, 1, 3);
00772          break;
00773       case 2:
00774          SWZ_CPY(dst, src, count, 1, 2);
00775          break;
00776       case 1:
00777          SWZ_CPY(dst, src, count, 1, 1);
00778          break;
00779       default:
00780          ;
00781       }
00782       break;
00783    default:
00784       ;
00785    }
00786 #undef SWZ_CPY
00787 }
00788 
00789 
00790 
00791 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
00792 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
00793 
00794 /* Deal with the _REV input types:
00795  */
00796 static const GLubyte *
00797 type_mapping( GLenum srcType )
00798 {
00799    switch (srcType) {
00800    case GL_UNSIGNED_BYTE:
00801       return map_identity;
00802    case GL_UNSIGNED_INT_8_8_8_8:
00803       return _mesa_little_endian() ? map_3210 : map_identity;
00804    case GL_UNSIGNED_INT_8_8_8_8_REV:
00805       return _mesa_little_endian() ? map_identity : map_3210;
00806    default:
00807       return NULL;
00808    }
00809 }
00810 
00811 /* Mapping required if input type is 
00812  */
00813 static const GLubyte *
00814 byteswap_mapping( GLboolean swapBytes,
00815           GLenum srcType )
00816 {
00817    if (!swapBytes) 
00818       return map_identity;
00819 
00820    switch (srcType) {
00821    case GL_UNSIGNED_BYTE:
00822       return map_identity;
00823    case GL_UNSIGNED_INT_8_8_8_8:
00824    case GL_UNSIGNED_INT_8_8_8_8_REV:
00825       return map_3210;
00826    default:
00827       return NULL;
00828    }
00829 }
00830 
00831 
00832 
00836 static void
00837 _mesa_swizzle_ubyte_image(GLcontext *ctx, 
00838               GLuint dimensions,
00839               GLenum srcFormat,
00840               GLenum srcType,
00841 
00842               GLenum baseInternalFormat,
00843 
00844               const GLubyte *rgba2dst,
00845               GLuint dstComponents,
00846 
00847               GLvoid *dstAddr,
00848               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
00849               GLint dstRowStride,
00850                           const GLuint *dstImageOffsets,
00851 
00852               GLint srcWidth, GLint srcHeight, GLint srcDepth,
00853               const GLvoid *srcAddr,
00854               const struct gl_pixelstore_attrib *srcPacking )
00855 {
00856    GLint srcComponents = _mesa_components_in_format(srcFormat);
00857    const GLubyte *srctype2ubyte, *swap;
00858    GLubyte map[4], src2base[6], base2rgba[6];
00859    GLint i;
00860    const GLint srcRowStride =
00861       _mesa_image_row_stride(srcPacking, srcWidth,
00862                              srcFormat, GL_UNSIGNED_BYTE);
00863    const GLint srcImageStride
00864       = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
00865                                  GL_UNSIGNED_BYTE);
00866    const GLubyte *srcImage
00867       = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
00868                                               srcWidth, srcHeight, srcFormat,
00869                                               GL_UNSIGNED_BYTE, 0, 0, 0);
00870 
00871    (void) ctx;
00872 
00873    /* Translate from src->baseInternal->GL_RGBA->dst.  This will
00874     * correctly deal with RGBA->RGB->RGBA conversions where the final
00875     * A value must be 0xff regardless of the incoming alpha values.
00876     */
00877    compute_component_mapping(srcFormat, baseInternalFormat, src2base);
00878    compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
00879    swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
00880    srctype2ubyte = type_mapping(srcType);
00881 
00882 
00883    for (i = 0; i < 4; i++)
00884       map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
00885 
00886 /*    _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
00887 
00888    if (srcRowStride == dstRowStride &&
00889        srcComponents == dstComponents &&
00890        srcRowStride == srcWidth * srcComponents &&
00891        dimensions < 3) {
00892       /* 1 and 2D images only */
00893       GLubyte *dstImage = (GLubyte *) dstAddr
00894          + dstYoffset * dstRowStride
00895          + dstXoffset * dstComponents;
00896       swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, 
00897            srcWidth * srcHeight);
00898    }
00899    else {
00900       GLint img, row;
00901       for (img = 0; img < srcDepth; img++) {
00902          const GLubyte *srcRow = srcImage;
00903          GLubyte *dstRow = (GLubyte *) dstAddr
00904             + dstImageOffsets[dstZoffset + img] * dstComponents
00905             + dstYoffset * dstRowStride
00906             + dstXoffset * dstComponents;
00907          for (row = 0; row < srcHeight; row++) {
00908         swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
00909             dstRow += dstRowStride;
00910             srcRow += srcRowStride;
00911          }
00912          srcImage += srcImageStride;
00913       }
00914    }
00915 }
00916 
00917 
00923 static void
00924 memcpy_texture(GLcontext *ctx,
00925            GLuint dimensions,
00926                const struct gl_texture_format *dstFormat,
00927                GLvoid *dstAddr,
00928                GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
00929                GLint dstRowStride,
00930                const GLuint *dstImageOffsets,
00931                GLint srcWidth, GLint srcHeight, GLint srcDepth,
00932                GLenum srcFormat, GLenum srcType,
00933                const GLvoid *srcAddr,
00934                const struct gl_pixelstore_attrib *srcPacking)
00935 {
00936    const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
00937                                                      srcFormat, srcType);
00938    const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
00939                                       srcWidth, srcHeight, srcFormat, srcType);
00940    const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
00941         srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
00942    const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
00943 
00944 #if 0
00945    /* XXX update/re-enable for dstImageOffsets array */
00946    const GLint bytesPerImage = srcHeight * bytesPerRow;
00947    const GLint bytesPerTexture = srcDepth * bytesPerImage;
00948    GLubyte *dstImage = (GLubyte *) dstAddr
00949                      + dstZoffset * dstImageStride
00950                      + dstYoffset * dstRowStride
00951                      + dstXoffset * dstFormat->TexelBytes;
00952 
00953    if (dstRowStride == srcRowStride &&
00954        dstRowStride == bytesPerRow &&
00955        ((dstImageStride == srcImageStride &&
00956          dstImageStride == bytesPerImage) ||
00957         (srcDepth == 1))) {
00958       /* one big memcpy */
00959       ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
00960    }
00961    else
00962    {
00963       GLint img, row;
00964       for (img = 0; img < srcDepth; img++) {
00965          const GLubyte *srcRow = srcImage;
00966          GLubyte *dstRow = dstImage;
00967          for (row = 0; row < srcHeight; row++) {
00968             ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
00969             dstRow += dstRowStride;
00970             srcRow += srcRowStride;
00971          }
00972          srcImage += srcImageStride;
00973          dstImage += dstImageStride;
00974       }
00975    }
00976 #endif
00977 
00978    GLint img, row;
00979    for (img = 0; img < srcDepth; img++) {
00980       const GLubyte *srcRow = srcImage;
00981       GLubyte *dstRow = (GLubyte *) dstAddr
00982          + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
00983          + dstYoffset * dstRowStride
00984          + dstXoffset * dstFormat->TexelBytes;
00985       for (row = 0; row < srcHeight; row++) {
00986          ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
00987          dstRow += dstRowStride;
00988          srcRow += srcRowStride;
00989       }
00990       srcImage += srcImageStride;
00991    }
00992 }
00993 
00994 
00995 
01006 GLboolean
01007 _mesa_texstore_rgba(TEXSTORE_PARAMS)
01008 {
01009    const GLint components = _mesa_components_in_format(baseInternalFormat);
01010 
01011    ASSERT(dstFormat == &_mesa_texformat_rgba ||
01012           dstFormat == &_mesa_texformat_rgb ||
01013           dstFormat == &_mesa_texformat_alpha ||
01014           dstFormat == &_mesa_texformat_luminance ||
01015           dstFormat == &_mesa_texformat_luminance_alpha ||
01016           dstFormat == &_mesa_texformat_intensity);
01017    ASSERT(baseInternalFormat == GL_RGBA ||
01018           baseInternalFormat == GL_RGB ||
01019           baseInternalFormat == GL_ALPHA ||
01020           baseInternalFormat == GL_LUMINANCE ||
01021           baseInternalFormat == GL_LUMINANCE_ALPHA ||
01022           baseInternalFormat == GL_INTENSITY);
01023    ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
01024 
01025    if (!ctx->_ImageTransferState &&
01026        !srcPacking->SwapBytes &&
01027        baseInternalFormat == srcFormat &&
01028        srcType == CHAN_TYPE) {
01029       /* simple memcpy path */
01030       memcpy_texture(ctx, dims,
01031                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01032                      dstRowStride,
01033                      dstImageOffsets,
01034                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01035                      srcAddr, srcPacking);
01036    }
01037    else if (!ctx->_ImageTransferState &&
01038             !srcPacking->SwapBytes &&
01039             dstFormat == &_mesa_texformat_rgb &&
01040             srcFormat == GL_RGBA &&
01041             srcType == CHAN_TYPE) {
01042       /* extract RGB from RGBA */
01043       GLint img, row, col;
01044       for (img = 0; img < srcDepth; img++) {
01045          GLchan *dstImage = (GLchan *)
01046             ((GLubyte *) dstAddr
01047              + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01048              + dstYoffset * dstRowStride
01049              + dstXoffset * dstFormat->TexelBytes);
01050 
01051          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
01052                                                  srcWidth, srcFormat, srcType);
01053          GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
01054                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
01055          GLchan *dstRow = dstImage;
01056          for (row = 0; row < srcHeight; row++) {
01057             for (col = 0; col < srcWidth; col++) {
01058                dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
01059                dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
01060                dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
01061             }
01062             dstRow += dstRowStride / sizeof(GLchan);
01063             srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
01064          }
01065       }
01066    }
01067    else if (!ctx->_ImageTransferState &&
01068         CHAN_TYPE == GL_UNSIGNED_BYTE &&
01069         (srcType == GL_UNSIGNED_BYTE ||
01070          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
01071          srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
01072         can_swizzle(baseInternalFormat) &&
01073         can_swizzle(srcFormat)) {
01074 
01075       const GLubyte *dstmap;
01076       GLuint components;
01077 
01078       /* dstmap - how to swizzle from RGBA to dst format:
01079        */
01080       if (dstFormat == &_mesa_texformat_rgba) {
01081      dstmap = mappings[IDX_RGBA].from_rgba;
01082      components = 4;
01083       }
01084       else if (dstFormat == &_mesa_texformat_rgb) {
01085      dstmap = mappings[IDX_RGB].from_rgba;
01086      components = 3;
01087       }
01088       else if (dstFormat == &_mesa_texformat_alpha) {
01089      dstmap = mappings[IDX_ALPHA].from_rgba;
01090      components = 1;
01091       }
01092       else if (dstFormat == &_mesa_texformat_luminance) {
01093      dstmap = mappings[IDX_LUMINANCE].from_rgba;
01094      components = 1;
01095       }
01096       else if (dstFormat == &_mesa_texformat_luminance_alpha) {
01097      dstmap = mappings[IDX_LUMINANCE_ALPHA].from_rgba;
01098      components = 2;
01099       }
01100       else if (dstFormat == &_mesa_texformat_intensity) {
01101      dstmap = mappings[IDX_INTENSITY].from_rgba;
01102      components = 1;
01103       }
01104       else {
01105          _mesa_problem(ctx, "Unexpected dstFormat in _mesa_texstore_rgba");
01106          return GL_FALSE;
01107       }
01108 
01109       _mesa_swizzle_ubyte_image(ctx, dims,
01110                 srcFormat,
01111                 srcType,
01112                 baseInternalFormat,
01113                 dstmap, components,
01114                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
01115                 dstRowStride, dstImageOffsets,
01116                 srcWidth, srcHeight, srcDepth, srcAddr,
01117                 srcPacking);      
01118    }
01119    else {
01120       /* general path */
01121       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01122                                                  baseInternalFormat,
01123                                                  dstFormat->BaseFormat,
01124                                                  srcWidth, srcHeight, srcDepth,
01125                                                  srcFormat, srcType, srcAddr,
01126                                                  srcPacking);
01127       const GLchan *src = tempImage;
01128       GLint bytesPerRow;
01129       GLint img, row;
01130       if (!tempImage)
01131          return GL_FALSE;
01132       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01133       bytesPerRow = srcWidth * components * sizeof(GLchan);
01134       for (img = 0; img < srcDepth; img++) {
01135          GLubyte *dstRow = (GLubyte *) dstAddr
01136             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01137             + dstYoffset * dstRowStride
01138             + dstXoffset * dstFormat->TexelBytes;
01139          for (row = 0; row < srcHeight; row++) {
01140             _mesa_memcpy(dstRow, src, bytesPerRow);
01141             dstRow += dstRowStride;
01142             src += srcWidth * components;
01143          }
01144       }
01145 
01146       _mesa_free((void *) tempImage);
01147    }
01148    return GL_TRUE;
01149 }
01150 
01151 
01155 GLboolean
01156 _mesa_texstore_z32(TEXSTORE_PARAMS)
01157 {
01158    const GLuint depthScale = 0xffffffff;
01159    (void) dims;
01160    ASSERT(dstFormat == &_mesa_texformat_z32);
01161    ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
01162 
01163    if (ctx->Pixel.DepthScale == 1.0f &&
01164        ctx->Pixel.DepthBias == 0.0f &&
01165        !srcPacking->SwapBytes &&
01166        baseInternalFormat == GL_DEPTH_COMPONENT &&
01167        srcFormat == GL_DEPTH_COMPONENT &&
01168        srcType == GL_UNSIGNED_INT) {
01169       /* simple memcpy path */
01170       memcpy_texture(ctx, dims,
01171                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01172                      dstRowStride,
01173                      dstImageOffsets,
01174                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01175                      srcAddr, srcPacking);
01176    }
01177    else {
01178       /* general path */
01179       GLint img, row;
01180       for (img = 0; img < srcDepth; img++) {
01181          GLubyte *dstRow = (GLubyte *) dstAddr
01182             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01183             + dstYoffset * dstRowStride
01184             + dstXoffset * dstFormat->TexelBytes;
01185          for (row = 0; row < srcHeight; row++) {
01186             const GLvoid *src = _mesa_image_address(dims, srcPacking,
01187                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
01188             _mesa_unpack_depth_span(ctx, srcWidth,
01189                                     GL_UNSIGNED_INT, (GLuint *) dstRow,
01190                                     depthScale, srcType, src, srcPacking);
01191             dstRow += dstRowStride;
01192          }
01193       }
01194    }
01195    return GL_TRUE;
01196 }
01197 
01198 #define STRIDE_3D 0
01199 
01203 GLboolean
01204 _mesa_texstore_z16(TEXSTORE_PARAMS)
01205 {
01206    const GLuint depthScale = 0xffff;
01207    (void) dims;
01208    ASSERT(dstFormat == &_mesa_texformat_z16);
01209    ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
01210 
01211    if (ctx->Pixel.DepthScale == 1.0f &&
01212        ctx->Pixel.DepthBias == 0.0f &&
01213        !srcPacking->SwapBytes &&
01214        baseInternalFormat == GL_DEPTH_COMPONENT &&
01215        srcFormat == GL_DEPTH_COMPONENT &&
01216        srcType == GL_UNSIGNED_SHORT) {
01217       /* simple memcpy path */
01218       memcpy_texture(ctx, dims,
01219                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01220                      dstRowStride,
01221                      dstImageOffsets,
01222                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01223                      srcAddr, srcPacking);
01224    }
01225    else {
01226       /* general path */
01227       GLint img, row;
01228       for (img = 0; img < srcDepth; img++) {
01229          GLubyte *dstRow = (GLubyte *) dstAddr
01230             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01231             + dstYoffset * dstRowStride
01232             + dstXoffset * dstFormat->TexelBytes;
01233          for (row = 0; row < srcHeight; row++) {
01234             const GLvoid *src = _mesa_image_address(dims, srcPacking,
01235                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
01236             GLushort *dst16 = (GLushort *) dstRow;
01237             _mesa_unpack_depth_span(ctx, srcWidth,
01238                                     GL_UNSIGNED_SHORT, dst16, depthScale,
01239                                     srcType, src, srcPacking);
01240             dstRow += dstRowStride;
01241          }
01242       }
01243    }
01244    return GL_TRUE;
01245 }
01246 
01247 
01251 GLboolean
01252 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
01253 {
01254    ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
01255           dstFormat == &_mesa_texformat_rgb565_rev);
01256    ASSERT(dstFormat->TexelBytes == 2);
01257 
01258    if (!ctx->_ImageTransferState &&
01259        !srcPacking->SwapBytes &&
01260        dstFormat == &_mesa_texformat_rgb565 &&
01261        baseInternalFormat == GL_RGB &&
01262        srcFormat == GL_RGB &&
01263        srcType == GL_UNSIGNED_SHORT_5_6_5) {
01264       /* simple memcpy path */
01265       memcpy_texture(ctx, dims,
01266                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01267                      dstRowStride,
01268                      dstImageOffsets,
01269                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01270                      srcAddr, srcPacking);
01271    }
01272    else if (!ctx->_ImageTransferState &&
01273             !srcPacking->SwapBytes &&
01274             baseInternalFormat == GL_RGB &&
01275             srcFormat == GL_RGB &&
01276             srcType == GL_UNSIGNED_BYTE &&
01277             dims == 2) {
01278       /* do optimized tex store */
01279       const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
01280                                                         srcFormat, srcType);
01281       const GLubyte *src = (const GLubyte *)
01282          _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
01283                              srcFormat, srcType, 0, 0, 0);
01284       GLubyte *dst = (GLubyte *) dstAddr
01285                    + dstYoffset * dstRowStride
01286                    + dstXoffset * dstFormat->TexelBytes;
01287       GLint row, col;
01288       for (row = 0; row < srcHeight; row++) {
01289          const GLubyte *srcUB = (const GLubyte *) src;
01290          GLushort *dstUS = (GLushort *) dst;
01291          /* check for byteswapped format */
01292          if (dstFormat == &_mesa_texformat_rgb565) {
01293             for (col = 0; col < srcWidth; col++) {
01294                dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
01295                srcUB += 3;
01296             }
01297          }
01298          else {
01299             for (col = 0; col < srcWidth; col++) {
01300                dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
01301                srcUB += 3;
01302             }
01303          }
01304          dst += dstRowStride;
01305          src += srcRowStride;
01306       }
01307    }
01308    else {
01309       /* general path */
01310       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01311                                                  baseInternalFormat,
01312                                                  dstFormat->BaseFormat,
01313                                                  srcWidth, srcHeight, srcDepth,
01314                                                  srcFormat, srcType, srcAddr,
01315                                                  srcPacking);
01316       const GLchan *src = tempImage;
01317       GLint img, row, col;
01318       if (!tempImage)
01319          return GL_FALSE;
01320       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01321       for (img = 0; img < srcDepth; img++) {
01322          GLubyte *dstRow = (GLubyte *) dstAddr
01323             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01324             + dstYoffset * dstRowStride
01325             + dstXoffset * dstFormat->TexelBytes;
01326          for (row = 0; row < srcHeight; row++) {
01327             GLushort *dstUS = (GLushort *) dstRow;
01328             /* check for byteswapped format */
01329             if (dstFormat == &_mesa_texformat_rgb565) {
01330                for (col = 0; col < srcWidth; col++) {
01331                   dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
01332                                                CHAN_TO_UBYTE(src[GCOMP]),
01333                                                CHAN_TO_UBYTE(src[BCOMP]) );
01334                   src += 3;
01335                }
01336             }
01337             else {
01338                for (col = 0; col < srcWidth; col++) {
01339                   dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
01340                                                    CHAN_TO_UBYTE(src[GCOMP]),
01341                                                    CHAN_TO_UBYTE(src[BCOMP]) );
01342                   src += 3;
01343                }
01344             }
01345             dstRow += dstRowStride;
01346          }
01347       }
01348       _mesa_free((void *) tempImage);
01349    }
01350    return GL_TRUE;
01351 }
01352 
01353 
01357 GLboolean
01358 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
01359 {
01360    const GLboolean littleEndian = _mesa_little_endian();
01361 
01362    ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
01363           dstFormat == &_mesa_texformat_rgba8888_rev);
01364    ASSERT(dstFormat->TexelBytes == 4);
01365 
01366    if (!ctx->_ImageTransferState &&
01367        !srcPacking->SwapBytes &&
01368        dstFormat == &_mesa_texformat_rgba8888 &&
01369        baseInternalFormat == GL_RGBA &&
01370       ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
01371        (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
01372        (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
01373        (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
01374        /* simple memcpy path */
01375       memcpy_texture(ctx, dims,
01376                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01377                      dstRowStride,
01378                      dstImageOffsets,
01379                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01380                      srcAddr, srcPacking);
01381    }
01382    else if (!ctx->_ImageTransferState &&
01383        !srcPacking->SwapBytes &&
01384        dstFormat == &_mesa_texformat_rgba8888_rev &&
01385        baseInternalFormat == GL_RGBA &&
01386       ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
01387        (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
01388        (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
01389        (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
01390       /* simple memcpy path */
01391       memcpy_texture(ctx, dims,
01392                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01393                      dstRowStride,
01394                      dstImageOffsets,
01395                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01396                      srcAddr, srcPacking);
01397    }
01398    else if (!ctx->_ImageTransferState &&
01399         (srcType == GL_UNSIGNED_BYTE ||
01400          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
01401          srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
01402         can_swizzle(baseInternalFormat) &&
01403         can_swizzle(srcFormat)) {
01404 
01405       GLubyte dstmap[4];
01406 
01407       /* dstmap - how to swizzle from RGBA to dst format:
01408        */
01409       if ((littleEndian && dstFormat == &_mesa_texformat_rgba8888) ||
01410       (!littleEndian && dstFormat == &_mesa_texformat_rgba8888_rev)) {
01411      dstmap[3] = 0;
01412      dstmap[2] = 1;
01413      dstmap[1] = 2;
01414      dstmap[0] = 3;
01415       }
01416       else {
01417      dstmap[3] = 3;
01418      dstmap[2] = 2;
01419      dstmap[1] = 1;
01420      dstmap[0] = 0;
01421       }
01422       
01423       _mesa_swizzle_ubyte_image(ctx, dims,
01424                 srcFormat,
01425                 srcType,
01426                 baseInternalFormat,
01427                 dstmap, 4,
01428                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
01429                 dstRowStride, dstImageOffsets,
01430                 srcWidth, srcHeight, srcDepth, srcAddr,
01431                 srcPacking);      
01432    }
01433    else {
01434       /* general path */
01435       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01436                                                  baseInternalFormat,
01437                                                  dstFormat->BaseFormat,
01438                                                  srcWidth, srcHeight, srcDepth,
01439                                                  srcFormat, srcType, srcAddr,
01440                                                  srcPacking);
01441       const GLchan *src = tempImage;
01442       GLint img, row, col;
01443       if (!tempImage)
01444          return GL_FALSE;
01445       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01446       for (img = 0; img < srcDepth; img++) {
01447          GLubyte *dstRow = (GLubyte *) dstAddr
01448             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01449             + dstYoffset * dstRowStride
01450             + dstXoffset * dstFormat->TexelBytes;
01451          for (row = 0; row < srcHeight; row++) {
01452             GLuint *dstUI = (GLuint *) dstRow;
01453             if (dstFormat == &_mesa_texformat_rgba8888) {
01454                for (col = 0; col < srcWidth; col++) {
01455                   dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
01456                                                 CHAN_TO_UBYTE(src[GCOMP]),
01457                                                 CHAN_TO_UBYTE(src[BCOMP]),
01458                                                 CHAN_TO_UBYTE(src[ACOMP]) );
01459                   src += 4;
01460                }
01461             }
01462             else {
01463                for (col = 0; col < srcWidth; col++) {
01464                   dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
01465                                                     CHAN_TO_UBYTE(src[GCOMP]),
01466                                                     CHAN_TO_UBYTE(src[BCOMP]),
01467                                                     CHAN_TO_UBYTE(src[ACOMP]) );
01468                   src += 4;
01469                }
01470             }
01471             dstRow += dstRowStride;
01472          }
01473       }
01474       _mesa_free((void *) tempImage);
01475    }
01476    return GL_TRUE;
01477 }
01478 
01479 
01480 GLboolean
01481 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
01482 {
01483    const GLboolean littleEndian = _mesa_little_endian();
01484 
01485    ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
01486           dstFormat == &_mesa_texformat_argb8888_rev);
01487    ASSERT(dstFormat->TexelBytes == 4);
01488 
01489    if (!ctx->_ImageTransferState &&
01490        !srcPacking->SwapBytes &&
01491        dstFormat == &_mesa_texformat_argb8888 &&
01492        baseInternalFormat == GL_RGBA &&
01493        srcFormat == GL_BGRA &&
01494        ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
01495         srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
01496       /* simple memcpy path (little endian) */
01497       memcpy_texture(ctx, dims,
01498                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01499                      dstRowStride,
01500                      dstImageOffsets,
01501                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01502                      srcAddr, srcPacking);
01503    }
01504    else if (!ctx->_ImageTransferState &&
01505        !srcPacking->SwapBytes &&
01506        dstFormat == &_mesa_texformat_argb8888_rev &&
01507        baseInternalFormat == GL_RGBA &&
01508        srcFormat == GL_BGRA &&
01509        ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
01510         srcType == GL_UNSIGNED_INT_8_8_8_8)) {
01511       /* simple memcpy path (big endian) */
01512       memcpy_texture(ctx, dims,
01513                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01514                      dstRowStride,
01515                      dstImageOffsets,
01516                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01517                      srcAddr, srcPacking);
01518    }
01519    else if (!ctx->_ImageTransferState &&
01520             !srcPacking->SwapBytes &&
01521         dstFormat == &_mesa_texformat_argb8888 &&
01522             srcFormat == GL_RGB &&
01523         (baseInternalFormat == GL_RGBA ||
01524          baseInternalFormat == GL_RGB) &&
01525             srcType == GL_UNSIGNED_BYTE) {
01526       int img, row, col;
01527       for (img = 0; img < srcDepth; img++) {
01528          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
01529                                                  srcWidth, srcFormat, srcType);
01530          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
01531                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
01532          GLubyte *dstRow = (GLubyte *) dstAddr
01533             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01534             + dstYoffset * dstRowStride
01535             + dstXoffset * dstFormat->TexelBytes;
01536          for (row = 0; row < srcHeight; row++) {
01537             GLuint *d4 = (GLuint *) dstRow;
01538             for (col = 0; col < srcWidth; col++) {
01539                d4[col] = PACK_COLOR_8888(0xff,
01540                                          srcRow[col * 3 + RCOMP],
01541                                          srcRow[col * 3 + GCOMP],
01542                                          srcRow[col * 3 + BCOMP]);
01543             }
01544             dstRow += dstRowStride;
01545             srcRow += srcRowStride;
01546          }
01547       }
01548    }
01549    else if (!ctx->_ImageTransferState &&
01550             !srcPacking->SwapBytes &&
01551         dstFormat == &_mesa_texformat_argb8888 &&
01552             srcFormat == GL_RGBA &&
01553         baseInternalFormat == GL_RGBA &&
01554             srcType == GL_UNSIGNED_BYTE) {
01555       /* same as above case, but src data has alpha too */
01556       GLint img, row, col;
01557       /* For some reason, streaming copies to write-combined regions
01558        * are extremely sensitive to the characteristics of how the
01559        * source data is retrieved.  By reordering the source reads to
01560        * be in-order, the speed of this operation increases by half.
01561        * Strangely the same isn't required for the RGB path, above.
01562        */
01563       for (img = 0; img < srcDepth; img++) {
01564          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
01565                                                  srcWidth, srcFormat, srcType);
01566          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
01567                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
01568          GLubyte *dstRow = (GLubyte *) dstAddr
01569             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01570             + dstYoffset * dstRowStride
01571             + dstXoffset * dstFormat->TexelBytes;
01572          for (row = 0; row < srcHeight; row++) {
01573             GLuint *d4 = (GLuint *) dstRow;
01574             for (col = 0; col < srcWidth; col++) {
01575                d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
01576                                          srcRow[col * 4 + RCOMP],
01577                                          srcRow[col * 4 + GCOMP],
01578                                          srcRow[col * 4 + BCOMP]);
01579             }
01580             dstRow += dstRowStride;
01581             srcRow += srcRowStride;
01582          }
01583       }
01584    }
01585    else if (!ctx->_ImageTransferState &&
01586         (srcType == GL_UNSIGNED_BYTE ||
01587          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
01588          srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
01589         can_swizzle(baseInternalFormat) &&     
01590         can_swizzle(srcFormat)) {
01591 
01592       GLubyte dstmap[4];
01593 
01594       /* dstmap - how to swizzle from RGBA to dst format:
01595        */
01596       if ((littleEndian && dstFormat == &_mesa_texformat_argb8888) ||
01597       (!littleEndian && dstFormat == &_mesa_texformat_argb8888_rev)) {
01598      dstmap[3] = 3;     /* alpha */
01599      dstmap[2] = 0;     /* red */
01600      dstmap[1] = 1;     /* green */
01601      dstmap[0] = 2;     /* blue */
01602       }
01603       else {
01604      assert((littleEndian && dstFormat == &_mesa_texformat_argb8888_rev) ||
01605         (!littleEndian && dstFormat == &_mesa_texformat_argb8888));
01606      dstmap[3] = 2;
01607      dstmap[2] = 1;
01608      dstmap[1] = 0;
01609      dstmap[0] = 3;
01610       }
01611  
01612       _mesa_swizzle_ubyte_image(ctx, dims,
01613                 srcFormat,
01614                 srcType,
01615 
01616                 baseInternalFormat,
01617                 dstmap, 4,
01618                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
01619                 dstRowStride,
01620                                 dstImageOffsets,
01621                 srcWidth, srcHeight, srcDepth, srcAddr,
01622                 srcPacking);      
01623    }
01624    else {
01625       /* general path */
01626       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01627                                                  baseInternalFormat,
01628                                                  dstFormat->BaseFormat,
01629                                                  srcWidth, srcHeight, srcDepth,
01630                                                  srcFormat, srcType, srcAddr,
01631                                                  srcPacking);
01632       const GLchan *src = tempImage;
01633       GLint img, row, col;
01634       if (!tempImage)
01635          return GL_FALSE;
01636       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01637       for (img = 0; img < srcDepth; img++) {
01638          GLubyte *dstRow = (GLubyte *) dstAddr
01639             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01640             + dstYoffset * dstRowStride
01641             + dstXoffset * dstFormat->TexelBytes;
01642          for (row = 0; row < srcHeight; row++) {
01643             GLuint *dstUI = (GLuint *) dstRow;
01644             if (dstFormat == &_mesa_texformat_argb8888) {
01645                for (col = 0; col < srcWidth; col++) {
01646                   dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
01647                                                 CHAN_TO_UBYTE(src[RCOMP]),
01648                                                 CHAN_TO_UBYTE(src[GCOMP]),
01649                                                 CHAN_TO_UBYTE(src[BCOMP]) );
01650                   src += 4;
01651                }
01652             }
01653             else {
01654                for (col = 0; col < srcWidth; col++) {
01655                   dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
01656                                                     CHAN_TO_UBYTE(src[RCOMP]),
01657                                                     CHAN_TO_UBYTE(src[GCOMP]),
01658                                                     CHAN_TO_UBYTE(src[BCOMP]) );
01659                   src += 4;
01660                }
01661             }
01662             dstRow += dstRowStride;
01663          }
01664       }
01665       _mesa_free((void *) tempImage);
01666    }
01667    return GL_TRUE;
01668 }
01669 
01670 
01671 GLboolean
01672 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
01673 {
01674    const GLboolean littleEndian = _mesa_little_endian();
01675 
01676    ASSERT(dstFormat == &_mesa_texformat_rgb888);
01677    ASSERT(dstFormat->TexelBytes == 3);
01678 
01679    if (!ctx->_ImageTransferState &&
01680        !srcPacking->SwapBytes &&
01681        baseInternalFormat == GL_RGB &&
01682        srcFormat == GL_BGR &&
01683        srcType == GL_UNSIGNED_BYTE &&
01684        littleEndian) {
01685       /* simple memcpy path */
01686       memcpy_texture(ctx, dims,
01687                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01688                      dstRowStride,
01689                      dstImageOffsets,
01690                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01691                      srcAddr, srcPacking);
01692    }
01693    else if (!ctx->_ImageTransferState &&
01694             !srcPacking->SwapBytes &&
01695             srcFormat == GL_RGBA &&
01696             srcType == GL_UNSIGNED_BYTE) {
01697       /* extract RGB from RGBA */
01698       GLint img, row, col;
01699       for (img = 0; img < srcDepth; img++) {
01700          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
01701                                                  srcWidth, srcFormat, srcType);
01702          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
01703                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
01704          GLubyte *dstRow = (GLubyte *) dstAddr
01705             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01706             + dstYoffset * dstRowStride
01707             + dstXoffset * dstFormat->TexelBytes;
01708          for (row = 0; row < srcHeight; row++) {
01709             for (col = 0; col < srcWidth; col++) {
01710                dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
01711                dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
01712                dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
01713             }
01714             dstRow += dstRowStride;
01715             srcRow += srcRowStride;
01716          }
01717       }
01718    }
01719    else if (!ctx->_ImageTransferState &&
01720         srcType == GL_UNSIGNED_BYTE &&
01721         can_swizzle(baseInternalFormat) &&
01722         can_swizzle(srcFormat)) {
01723 
01724       GLubyte dstmap[4];
01725 
01726       /* dstmap - how to swizzle from RGBA to dst format:
01727        */
01728       dstmap[0] = 2;
01729       dstmap[1] = 1;
01730       dstmap[2] = 0;
01731       dstmap[3] = ONE;      /* ? */
01732       
01733       _mesa_swizzle_ubyte_image(ctx, dims,
01734                 srcFormat,
01735                 srcType,
01736                 baseInternalFormat,
01737                 dstmap, 3,
01738                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
01739                 dstRowStride, dstImageOffsets,
01740                 srcWidth, srcHeight, srcDepth, srcAddr,
01741                 srcPacking);      
01742    }
01743    else {
01744       /* general path */
01745       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01746                                                  baseInternalFormat,
01747                                                  dstFormat->BaseFormat,
01748                                                  srcWidth, srcHeight, srcDepth,
01749                                                  srcFormat, srcType, srcAddr,
01750                                                  srcPacking);
01751       const GLchan *src = (const GLchan *) tempImage;
01752       GLint img, row, col;
01753       if (!tempImage)
01754          return GL_FALSE;
01755       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01756       for (img = 0; img < srcDepth; img++) {
01757          GLubyte *dstRow = (GLubyte *) dstAddr
01758             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01759             + dstYoffset * dstRowStride
01760             + dstXoffset * dstFormat->TexelBytes;
01761          for (row = 0; row < srcHeight; row++) {
01762 #if 0
01763             if (littleEndian) {
01764                for (col = 0; col < srcWidth; col++) {
01765                   dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
01766                   dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
01767                   dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
01768                   srcUB += 3;
01769                }
01770             }
01771             else {
01772                for (col = 0; col < srcWidth; col++) {
01773                   dstRow[col * 3 + 0] = srcUB[BCOMP];
01774                   dstRow[col * 3 + 1] = srcUB[GCOMP];
01775                   dstRow[col * 3 + 2] = srcUB[RCOMP];
01776                   srcUB += 3;
01777                }
01778             }
01779 #else
01780             for (col = 0; col < srcWidth; col++) {
01781                dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
01782                dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
01783                dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
01784                src += 3;
01785             }
01786 #endif
01787             dstRow += dstRowStride;
01788          }
01789       }
01790       _mesa_free((void *) tempImage);
01791    }
01792    return GL_TRUE;
01793 }
01794 
01795 
01796 GLboolean
01797 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
01798 {
01799    const GLboolean littleEndian = _mesa_little_endian();
01800 
01801    ASSERT(dstFormat == &_mesa_texformat_bgr888);
01802    ASSERT(dstFormat->TexelBytes == 3);
01803 
01804    if (!ctx->_ImageTransferState &&
01805        !srcPacking->SwapBytes &&
01806        baseInternalFormat == GL_RGB &&
01807        srcFormat == GL_RGB &&
01808        srcType == GL_UNSIGNED_BYTE &&
01809        littleEndian) {
01810       /* simple memcpy path */
01811       memcpy_texture(ctx, dims,
01812                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01813                      dstRowStride,
01814                      dstImageOffsets,
01815                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01816                      srcAddr, srcPacking);
01817    }
01818    else if (!ctx->_ImageTransferState &&
01819             !srcPacking->SwapBytes &&
01820             srcFormat == GL_RGBA &&
01821             srcType == GL_UNSIGNED_BYTE) {
01822       /* extract BGR from RGBA */
01823       int img, row, col;
01824       for (img = 0; img < srcDepth; img++) {
01825          const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
01826                                                  srcWidth, srcFormat, srcType);
01827          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
01828                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
01829          GLubyte *dstRow = (GLubyte *) dstAddr
01830             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01831             + dstYoffset * dstRowStride
01832             + dstXoffset * dstFormat->TexelBytes;
01833          for (row = 0; row < srcHeight; row++) {
01834             for (col = 0; col < srcWidth; col++) {
01835                dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
01836                dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
01837                dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
01838             }
01839             dstRow += dstRowStride;
01840             srcRow += srcRowStride;
01841          }
01842       }
01843    }
01844    else if (!ctx->_ImageTransferState &&
01845         srcType == GL_UNSIGNED_BYTE &&
01846         can_swizzle(baseInternalFormat) &&
01847         can_swizzle(srcFormat)) {
01848 
01849       GLubyte dstmap[4];
01850 
01851       /* dstmap - how to swizzle from RGBA to dst format:
01852        */
01853       dstmap[0] = 0;
01854       dstmap[1] = 1;
01855       dstmap[2] = 2;
01856       dstmap[3] = ONE;      /* ? */
01857       
01858       _mesa_swizzle_ubyte_image(ctx, dims,
01859                 srcFormat,
01860                 srcType,
01861                 baseInternalFormat,
01862                 dstmap, 3,
01863                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
01864                 dstRowStride, dstImageOffsets,
01865                 srcWidth, srcHeight, srcDepth, srcAddr,
01866                 srcPacking);      
01867    }   
01868    else {
01869       /* general path */
01870       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01871                                                  baseInternalFormat,
01872                                                  dstFormat->BaseFormat,
01873                                                  srcWidth, srcHeight, srcDepth,
01874                                                  srcFormat, srcType, srcAddr,
01875                                                  srcPacking);
01876       const GLchan *src = (const GLchan *) tempImage;
01877       GLint img, row, col;
01878       if (!tempImage)
01879          return GL_FALSE;
01880       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01881       for (img = 0; img < srcDepth; img++) {
01882          GLubyte *dstRow = (GLubyte *) dstAddr
01883             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01884             + dstYoffset * dstRowStride
01885             + dstXoffset * dstFormat->TexelBytes;
01886          for (row = 0; row < srcHeight; row++) {
01887             for (col = 0; col < srcWidth; col++) {
01888                dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
01889                dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
01890                dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
01891                src += 3;
01892             }
01893             dstRow += dstRowStride;
01894          }
01895       }
01896       _mesa_free((void *) tempImage);
01897    }
01898    return GL_TRUE;
01899 }
01900 
01901 GLboolean
01902 _mesa_texstore_rgba4444(TEXSTORE_PARAMS)
01903 {
01904    ASSERT(dstFormat == &_mesa_texformat_rgba4444);
01905    ASSERT(dstFormat->TexelBytes == 2);
01906 
01907    if (!ctx->_ImageTransferState &&
01908        !srcPacking->SwapBytes &&
01909        dstFormat == &_mesa_texformat_rgba4444 &&
01910        baseInternalFormat == GL_RGBA &&
01911        srcFormat == GL_RGBA &&
01912        srcType == GL_UNSIGNED_SHORT_4_4_4_4){
01913       /* simple memcpy path */
01914       memcpy_texture(ctx, dims,
01915                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01916                      dstRowStride,
01917                      dstImageOffsets,
01918                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01919                      srcAddr, srcPacking);
01920    }
01921    else {
01922       /* general path */
01923       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01924                                                  baseInternalFormat,
01925                                                  dstFormat->BaseFormat,
01926                                                  srcWidth, srcHeight, srcDepth,
01927                                                  srcFormat, srcType, srcAddr,
01928                                                  srcPacking);
01929       const GLchan *src = tempImage;
01930       GLint img, row, col;
01931       if (!tempImage)
01932          return GL_FALSE;
01933       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01934       for (img = 0; img < srcDepth; img++) {
01935          GLubyte *dstRow = (GLubyte *) dstAddr
01936             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01937             + dstYoffset * dstRowStride
01938             + dstXoffset * dstFormat->TexelBytes;
01939          for (row = 0; row < srcHeight; row++) {
01940             GLushort *dstUS = (GLushort *) dstRow;
01941         for (col = 0; col < srcWidth; col++) {
01942           dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]),
01943                         CHAN_TO_UBYTE(src[GCOMP]),
01944                         CHAN_TO_UBYTE(src[BCOMP]),
01945                         CHAN_TO_UBYTE(src[ACOMP]) );
01946           src += 4;
01947             }
01948             dstRow += dstRowStride;
01949          }
01950       }
01951       _mesa_free((void *) tempImage);
01952    }
01953    return GL_TRUE;
01954 }
01955 
01956 GLboolean
01957 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
01958 {
01959    ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
01960           dstFormat == &_mesa_texformat_argb4444_rev);
01961    ASSERT(dstFormat->TexelBytes == 2);
01962 
01963    if (!ctx->_ImageTransferState &&
01964        !srcPacking->SwapBytes &&
01965        dstFormat == &_mesa_texformat_argb4444 &&
01966        baseInternalFormat == GL_RGBA &&
01967        srcFormat == GL_BGRA &&
01968        srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
01969       /* simple memcpy path */
01970       memcpy_texture(ctx, dims,
01971                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
01972                      dstRowStride,
01973                      dstImageOffsets,
01974                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
01975                      srcAddr, srcPacking);
01976    }
01977    else {
01978       /* general path */
01979       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
01980                                                  baseInternalFormat,
01981                                                  dstFormat->BaseFormat,
01982                                                  srcWidth, srcHeight, srcDepth,
01983                                                  srcFormat, srcType, srcAddr,
01984                                                  srcPacking);
01985       const GLchan *src = tempImage;
01986       GLint img, row, col;
01987       if (!tempImage)
01988          return GL_FALSE;
01989       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
01990       for (img = 0; img < srcDepth; img++) {
01991          GLubyte *dstRow = (GLubyte *) dstAddr
01992             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
01993             + dstYoffset * dstRowStride
01994             + dstXoffset * dstFormat->TexelBytes;
01995          for (row = 0; row < srcHeight; row++) {
01996             GLushort *dstUS = (GLushort *) dstRow;
01997             if (dstFormat == &_mesa_texformat_argb4444) {
01998                for (col = 0; col < srcWidth; col++) {
01999                   dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
02000                                                 CHAN_TO_UBYTE(src[RCOMP]),
02001                                                 CHAN_TO_UBYTE(src[GCOMP]),
02002                                                 CHAN_TO_UBYTE(src[BCOMP]) );
02003                   src += 4;
02004                }
02005             }
02006             else {
02007                for (col = 0; col < srcWidth; col++) {
02008                   dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
02009                                                     CHAN_TO_UBYTE(src[RCOMP]),
02010                                                     CHAN_TO_UBYTE(src[GCOMP]),
02011                                                     CHAN_TO_UBYTE(src[BCOMP]) );
02012                   src += 4;
02013                }
02014             }
02015             dstRow += dstRowStride;
02016          }
02017       }
02018       _mesa_free((void *) tempImage);
02019    }
02020    return GL_TRUE;
02021 }
02022 
02023 GLboolean
02024 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
02025 {
02026    ASSERT(dstFormat == &_mesa_texformat_rgba5551);
02027    ASSERT(dstFormat->TexelBytes == 2);
02028 
02029    if (!ctx->_ImageTransferState &&
02030        !srcPacking->SwapBytes &&
02031        dstFormat == &_mesa_texformat_rgba5551 &&
02032        baseInternalFormat == GL_RGBA &&
02033        srcFormat == GL_RGBA &&
02034        srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
02035       /* simple memcpy path */
02036       memcpy_texture(ctx, dims,
02037                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02038                      dstRowStride,
02039                      dstImageOffsets,
02040                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02041                      srcAddr, srcPacking);
02042    }
02043    else {
02044       /* general path */
02045       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
02046                                                  baseInternalFormat,
02047                                                  dstFormat->BaseFormat,
02048                                                  srcWidth, srcHeight, srcDepth,
02049                                                  srcFormat, srcType, srcAddr,
02050                                                  srcPacking);
02051       const GLchan *src =tempImage;
02052       GLint img, row, col;
02053       if (!tempImage)
02054          return GL_FALSE;
02055       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02056       for (img = 0; img < srcDepth; img++) {
02057          GLubyte *dstRow = (GLubyte *) dstAddr
02058             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02059             + dstYoffset * dstRowStride
02060             + dstXoffset * dstFormat->TexelBytes;
02061          for (row = 0; row < srcHeight; row++) {
02062             GLushort *dstUS = (GLushort *) dstRow;
02063         for (col = 0; col < srcWidth; col++) {
02064            dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
02065                          CHAN_TO_UBYTE(src[GCOMP]),
02066                          CHAN_TO_UBYTE(src[BCOMP]),
02067                          CHAN_TO_UBYTE(src[ACOMP]) );
02068           src += 4;
02069         }
02070             dstRow += dstRowStride;
02071          }
02072       }
02073       _mesa_free((void *) tempImage);
02074    }
02075    return GL_TRUE;
02076 }
02077 
02078 GLboolean
02079 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
02080 {
02081    ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
02082           dstFormat == &_mesa_texformat_argb1555_rev);
02083    ASSERT(dstFormat->TexelBytes == 2);
02084 
02085    if (!ctx->_ImageTransferState &&
02086        !srcPacking->SwapBytes &&
02087        dstFormat == &_mesa_texformat_argb1555 &&
02088        baseInternalFormat == GL_RGBA &&
02089        srcFormat == GL_BGRA &&
02090        srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
02091       /* simple memcpy path */
02092       memcpy_texture(ctx, dims,
02093                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02094                      dstRowStride,
02095                      dstImageOffsets,
02096                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02097                      srcAddr, srcPacking);
02098    }
02099    else {
02100       /* general path */
02101       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
02102                                                  baseInternalFormat,
02103                                                  dstFormat->BaseFormat,
02104                                                  srcWidth, srcHeight, srcDepth,
02105                                                  srcFormat, srcType, srcAddr,
02106                                                  srcPacking);
02107       const GLchan *src =tempImage;
02108       GLint img, row, col;
02109       if (!tempImage)
02110          return GL_FALSE;
02111       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02112       for (img = 0; img < srcDepth; img++) {
02113          GLubyte *dstRow = (GLubyte *) dstAddr
02114             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02115             + dstYoffset * dstRowStride
02116             + dstXoffset * dstFormat->TexelBytes;
02117          for (row = 0; row < srcHeight; row++) {
02118             GLushort *dstUS = (GLushort *) dstRow;
02119             if (dstFormat == &_mesa_texformat_argb1555) {
02120                for (col = 0; col < srcWidth; col++) {
02121                   dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
02122                                                 CHAN_TO_UBYTE(src[RCOMP]),
02123                                                 CHAN_TO_UBYTE(src[GCOMP]),
02124                                                 CHAN_TO_UBYTE(src[BCOMP]) );
02125                   src += 4;
02126                }
02127             }
02128             else {
02129                for (col = 0; col < srcWidth; col++) {
02130                   dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
02131                                                     CHAN_TO_UBYTE(src[RCOMP]),
02132                                                     CHAN_TO_UBYTE(src[GCOMP]),
02133                                                     CHAN_TO_UBYTE(src[BCOMP]) );
02134                   src += 4;
02135                }
02136             }
02137             dstRow += dstRowStride;
02138          }
02139       }
02140       _mesa_free((void *) tempImage);
02141    }
02142    return GL_TRUE;
02143 }
02144 
02145 
02146 GLboolean
02147 _mesa_texstore_al88(TEXSTORE_PARAMS)
02148 {
02149    const GLboolean littleEndian = _mesa_little_endian();
02150 
02151    ASSERT(dstFormat == &_mesa_texformat_al88 ||
02152           dstFormat == &_mesa_texformat_al88_rev);
02153    ASSERT(dstFormat->TexelBytes == 2);
02154 
02155    if (!ctx->_ImageTransferState &&
02156        !srcPacking->SwapBytes &&
02157        dstFormat == &_mesa_texformat_al88 &&
02158        baseInternalFormat == GL_LUMINANCE_ALPHA &&
02159        srcFormat == GL_LUMINANCE_ALPHA &&
02160        srcType == GL_UNSIGNED_BYTE &&
02161        littleEndian) {
02162       /* simple memcpy path */
02163       memcpy_texture(ctx, dims,
02164                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02165                      dstRowStride,
02166                      dstImageOffsets,
02167                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02168                      srcAddr, srcPacking);
02169    }
02170    else if (!ctx->_ImageTransferState &&
02171         littleEndian &&
02172         srcType == GL_UNSIGNED_BYTE &&
02173         can_swizzle(baseInternalFormat) &&
02174         can_swizzle(srcFormat)) {
02175 
02176       GLubyte dstmap[4];
02177 
02178       /* dstmap - how to swizzle from RGBA to dst format:
02179        */
02180       if ((littleEndian && dstFormat == &_mesa_texformat_al88) ||
02181       (!littleEndian && dstFormat == &_mesa_texformat_al88_rev)) {
02182      dstmap[0] = 0;
02183      dstmap[1] = 3;
02184       }
02185       else {
02186      dstmap[0] = 3;
02187      dstmap[1] = 0;
02188       }
02189       dstmap[2] = ZERO;     /* ? */
02190       dstmap[3] = ONE;      /* ? */
02191       
02192       _mesa_swizzle_ubyte_image(ctx, dims,
02193                 srcFormat,
02194                 srcType,
02195                 baseInternalFormat,
02196                 dstmap, 2,
02197                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
02198                 dstRowStride, dstImageOffsets,
02199                 srcWidth, srcHeight, srcDepth, srcAddr,
02200                 srcPacking);      
02201    }   
02202    else {
02203       /* general path */
02204       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
02205                                                  baseInternalFormat,
02206                                                  dstFormat->BaseFormat,
02207                                                  srcWidth, srcHeight, srcDepth,
02208                                                  srcFormat, srcType, srcAddr,
02209                                                  srcPacking);
02210       const GLchan *src = tempImage;
02211       GLint img, row, col;
02212       if (!tempImage)
02213          return GL_FALSE;
02214       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02215       for (img = 0; img < srcDepth; img++) {
02216          GLubyte *dstRow = (GLubyte *) dstAddr
02217             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02218             + dstYoffset * dstRowStride
02219             + dstXoffset * dstFormat->TexelBytes;
02220          for (row = 0; row < srcHeight; row++) {
02221             GLushort *dstUS = (GLushort *) dstRow;
02222             if (dstFormat == &_mesa_texformat_al88) {
02223                for (col = 0; col < srcWidth; col++) {
02224                   /* src[0] is luminance, src[1] is alpha */
02225                  dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
02226                                              CHAN_TO_UBYTE(src[0]) );
02227                  src += 2;
02228                }
02229             }
02230             else {
02231                for (col = 0; col < srcWidth; col++) {
02232                   /* src[0] is luminance, src[1] is alpha */
02233                  dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
02234                                                  CHAN_TO_UBYTE(src[0]) );
02235                  src += 2;
02236                }
02237             }
02238             dstRow += dstRowStride;
02239          }
02240       }
02241       _mesa_free((void *) tempImage);
02242    }
02243    return GL_TRUE;
02244 }
02245 
02246 
02247 GLboolean
02248 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
02249 {
02250    ASSERT(dstFormat == &_mesa_texformat_rgb332);
02251    ASSERT(dstFormat->TexelBytes == 1);
02252 
02253    if (!ctx->_ImageTransferState &&
02254        !srcPacking->SwapBytes &&
02255        baseInternalFormat == GL_RGB &&
02256        srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
02257       /* simple memcpy path */
02258       memcpy_texture(ctx, dims,
02259                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02260                      dstRowStride,
02261                      dstImageOffsets,
02262                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02263                      srcAddr, srcPacking);
02264    }
02265    else {
02266       /* general path */
02267       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
02268                                                  baseInternalFormat,
02269                                                  dstFormat->BaseFormat,
02270                                                  srcWidth, srcHeight, srcDepth,
02271                                                  srcFormat, srcType, srcAddr,
02272                                                  srcPacking);
02273       const GLchan *src = tempImage;
02274       GLint img, row, col;
02275       if (!tempImage)
02276          return GL_FALSE;
02277       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02278       for (img = 0; img < srcDepth; img++) {
02279          GLubyte *dstRow = (GLubyte *) dstAddr
02280             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02281             + dstYoffset * dstRowStride
02282             + dstXoffset * dstFormat->TexelBytes;
02283          for (row = 0; row < srcHeight; row++) {
02284             for (col = 0; col < srcWidth; col++) {
02285                dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
02286                                              CHAN_TO_UBYTE(src[GCOMP]),
02287                                              CHAN_TO_UBYTE(src[BCOMP]) );
02288                src += 3;
02289             }
02290             dstRow += dstRowStride;
02291          }
02292       }
02293       _mesa_free((void *) tempImage);
02294    }
02295    return GL_TRUE;
02296 }
02297 
02298 
02302 GLboolean
02303 _mesa_texstore_a8(TEXSTORE_PARAMS)
02304 {
02305    ASSERT(dstFormat == &_mesa_texformat_a8 ||
02306           dstFormat == &_mesa_texformat_l8 ||
02307           dstFormat == &_mesa_texformat_i8);
02308    ASSERT(dstFormat->TexelBytes == 1);
02309 
02310    if (!ctx->_ImageTransferState &&
02311        !srcPacking->SwapBytes &&
02312        baseInternalFormat == srcFormat &&
02313        srcType == GL_UNSIGNED_BYTE) {
02314       /* simple memcpy path */
02315       memcpy_texture(ctx, dims,
02316                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02317                      dstRowStride,
02318                      dstImageOffsets,
02319                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02320                      srcAddr, srcPacking);
02321    }
02322    else if (!ctx->_ImageTransferState &&
02323         srcType == GL_UNSIGNED_BYTE &&
02324         can_swizzle(baseInternalFormat) &&
02325         can_swizzle(srcFormat)) {
02326 
02327       GLubyte dstmap[4];
02328 
02329       /* dstmap - how to swizzle from RGBA to dst format:
02330        */
02331       if (dstFormat == &_mesa_texformat_a8) {
02332      dstmap[0] = 3;
02333       }
02334       else {
02335      dstmap[0] = 0;
02336       }
02337       dstmap[1] = ZERO;     /* ? */
02338       dstmap[2] = ZERO;     /* ? */
02339       dstmap[3] = ONE;      /* ? */
02340       
02341       _mesa_swizzle_ubyte_image(ctx, dims,
02342                 srcFormat,
02343                 srcType,
02344                 baseInternalFormat,
02345                 dstmap, 1,
02346                 dstAddr, dstXoffset, dstYoffset, dstZoffset,
02347                 dstRowStride, dstImageOffsets,
02348                 srcWidth, srcHeight, srcDepth, srcAddr,
02349                 srcPacking);      
02350    }   
02351    else {
02352       /* general path */
02353       const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
02354                                                  baseInternalFormat,
02355                                                  dstFormat->BaseFormat,
02356                                                  srcWidth, srcHeight, srcDepth,
02357                                                  srcFormat, srcType, srcAddr,
02358                                                  srcPacking);
02359       const GLchan *src = tempImage;
02360       GLint img, row, col;
02361       if (!tempImage)
02362          return GL_FALSE;
02363       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02364       for (img = 0; img < srcDepth; img++) {
02365          GLubyte *dstRow = (GLubyte *) dstAddr
02366             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02367             + dstYoffset * dstRowStride
02368             + dstXoffset * dstFormat->TexelBytes;
02369          for (row = 0; row < srcHeight; row++) {
02370             for (col = 0; col < srcWidth; col++) {
02371                dstRow[col] = CHAN_TO_UBYTE(src[col]);
02372             }
02373             dstRow += dstRowStride;
02374             src += srcWidth;
02375          }
02376       }
02377       _mesa_free((void *) tempImage);
02378    }
02379    return GL_TRUE;
02380 }
02381 
02382 
02383 
02384 GLboolean
02385 _mesa_texstore_ci8(TEXSTORE_PARAMS)
02386 {
02387    (void) dims; (void) baseInternalFormat;
02388    ASSERT(dstFormat == &_mesa_texformat_ci8);
02389    ASSERT(dstFormat->TexelBytes == 1);
02390    ASSERT(baseInternalFormat == GL_COLOR_INDEX);
02391 
02392    if (!ctx->_ImageTransferState &&
02393        !srcPacking->SwapBytes &&
02394        srcFormat == GL_COLOR_INDEX &&
02395        srcType == GL_UNSIGNED_BYTE) {
02396       /* simple memcpy path */
02397       memcpy_texture(ctx, dims,
02398                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02399                      dstRowStride,
02400                      dstImageOffsets,
02401                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02402                      srcAddr, srcPacking);
02403    }
02404    else {
02405       /* general path */
02406       GLint img, row;
02407       for (img = 0; img < srcDepth; img++) {
02408          GLubyte *dstRow = (GLubyte *) dstAddr
02409             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02410             + dstYoffset * dstRowStride
02411             + dstXoffset * dstFormat->TexelBytes;
02412          for (row = 0; row < srcHeight; row++) {
02413             const GLvoid *src = _mesa_image_address(dims, srcPacking,
02414                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
02415             _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
02416                                     srcType, src, srcPacking,
02417                                     ctx->_ImageTransferState);
02418             dstRow += dstRowStride;
02419          }
02420       }
02421    }
02422    return GL_TRUE;
02423 }
02424 
02425 
02429 GLboolean
02430 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
02431 {
02432    const GLboolean littleEndian = _mesa_little_endian();
02433    (void) ctx; (void) dims; (void) baseInternalFormat;
02434 
02435    ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
02436           (dstFormat == &_mesa_texformat_ycbcr_rev));
02437    ASSERT(dstFormat->TexelBytes == 2);
02438    ASSERT(ctx->Extensions.MESA_ycbcr_texture);
02439    ASSERT(srcFormat == GL_YCBCR_MESA);
02440    ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
02441           (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
02442    ASSERT(baseInternalFormat == GL_YCBCR_MESA);
02443 
02444    /* always just memcpy since no pixel transfer ops apply */
02445    memcpy_texture(ctx, dims,
02446                   dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02447                   dstRowStride,
02448                   dstImageOffsets,
02449                   srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02450                   srcAddr, srcPacking);
02451 
02452    /* Check if we need byte swapping */
02453    /* XXX the logic here _might_ be wrong */
02454    if (srcPacking->SwapBytes ^
02455        (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
02456        (dstFormat == &_mesa_texformat_ycbcr_rev) ^
02457        !littleEndian) {
02458       GLint img, row;
02459       for (img = 0; img < srcDepth; img++) {
02460          GLubyte *dstRow = (GLubyte *) dstAddr
02461             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02462             + dstYoffset * dstRowStride
02463             + dstXoffset * dstFormat->TexelBytes;
02464          for (row = 0; row < srcHeight; row++) {
02465             _mesa_swap2((GLushort *) dstRow, srcWidth);
02466             dstRow += dstRowStride;
02467          }
02468       }
02469    }
02470    return GL_TRUE;
02471 }
02472 
02473 
02474 
02478 GLboolean
02479 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
02480 {
02481    const GLfloat depthScale = (GLfloat) 0xffffff;
02482 
02483    ASSERT(dstFormat == &_mesa_texformat_z24_s8);
02484    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
02485    ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
02486 
02487    if (ctx->Pixel.DepthScale == 1.0f &&
02488        ctx->Pixel.DepthBias == 0.0f &&
02489        !srcPacking->SwapBytes) {
02490       /* simple path */
02491       memcpy_texture(ctx, dims,
02492                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02493                      dstRowStride,
02494                      dstImageOffsets,
02495                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02496                      srcAddr, srcPacking);
02497    }
02498    else {
02499       /* general path */
02500       const GLint srcRowStride
02501          = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
02502          / sizeof(GLuint);
02503       GLint img, row;
02504 
02505       for (img = 0; img < srcDepth; img++) {
02506          GLuint *dstRow = (GLuint *) dstAddr
02507             + dstImageOffsets[dstZoffset + img]
02508             + dstYoffset * dstRowStride / sizeof(GLuint)
02509             + dstXoffset;
02510          const GLuint *src
02511             = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
02512                                                    srcWidth, srcHeight,
02513                                                    srcFormat, srcType,
02514                                                    img, 0, 0);
02515          for (row = 0; row < srcHeight; row++) {
02516             GLubyte stencil[MAX_WIDTH];
02517             GLint i;
02518             /* the 24 depth bits will be in the high position: */
02519             _mesa_unpack_depth_span(ctx, srcWidth,
02520                                     GL_UNSIGNED_INT_24_8_EXT, /* dst type */
02521                                     dstRow, /* dst addr */
02522                                     (GLuint) depthScale,
02523                                     srcType, src, srcPacking);
02524             /* get the 8-bit stencil values */
02525             _mesa_unpack_stencil_span(ctx, srcWidth,
02526                                       GL_UNSIGNED_BYTE, /* dst type */
02527                                       stencil, /* dst addr */
02528                                       srcType, src, srcPacking,
02529                                       ctx->_ImageTransferState);
02530             /* merge stencil values into depth values */
02531             for (i = 0; i < srcWidth; i++)
02532                dstRow[i] |= stencil[i];
02533 
02534             src += srcRowStride;
02535             dstRow += dstRowStride / sizeof(GLuint);
02536          }
02537       }
02538    }
02539    return GL_TRUE;
02540 }
02541 
02542 
02546 GLboolean
02547 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
02548 {
02549    const GLuint depthScale = 0xffffff;
02550    const GLint srcRowStride
02551       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
02552       / sizeof(GLuint);
02553    GLint img, row;
02554 
02555    ASSERT(dstFormat == &_mesa_texformat_s8_z24);
02556    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
02557    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
02558 
02559    /* In case we only upload depth we need to preserve the stencil */
02560    if (srcFormat == GL_DEPTH_COMPONENT) {
02561       for (img = 0; img < srcDepth; img++) {
02562          GLuint *dstRow = (GLuint *) dstAddr
02563             + dstImageOffsets[dstZoffset + img]
02564             + dstYoffset * dstRowStride / sizeof(GLuint)
02565             + dstXoffset;
02566          const GLuint *src
02567             = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
02568                   srcWidth, srcHeight,
02569                   srcFormat, srcType,
02570                   img, 0, 0);
02571          for (row = 0; row < srcHeight; row++) {
02572             GLuint depth[MAX_WIDTH];
02573             GLint i;
02574             _mesa_unpack_depth_span(ctx, srcWidth,
02575                                     GL_UNSIGNED_INT, /* dst type */
02576                                     depth, /* dst addr */
02577                                     depthScale,
02578                                     srcType, src, srcPacking);
02579 
02580             for (i = 0; i < srcWidth; i++)
02581                dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
02582 
02583             src += srcRowStride;
02584             dstRow += dstRowStride / sizeof(GLuint);
02585          }
02586       }
02587    }
02588    else {
02589       for (img = 0; img < srcDepth; img++) {
02590          GLuint *dstRow = (GLuint *) dstAddr
02591             + dstImageOffsets[dstZoffset + img]
02592             + dstYoffset * dstRowStride / sizeof(GLuint)
02593             + dstXoffset;
02594          const GLuint *src
02595             = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
02596                   srcWidth, srcHeight,
02597                   srcFormat, srcType,
02598                   img, 0, 0);
02599          for (row = 0; row < srcHeight; row++) {
02600             GLubyte stencil[MAX_WIDTH];
02601             GLint i;
02602             /* the 24 depth bits will be in the low position: */
02603             _mesa_unpack_depth_span(ctx, srcWidth,
02604                                     GL_UNSIGNED_INT, /* dst type */
02605                                     dstRow, /* dst addr */
02606                                     depthScale,
02607                                     srcType, src, srcPacking);
02608             /* get the 8-bit stencil values */
02609             _mesa_unpack_stencil_span(ctx, srcWidth,
02610                                       GL_UNSIGNED_BYTE, /* dst type */
02611                                       stencil, /* dst addr */
02612                                       srcType, src, srcPacking,
02613                                       ctx->_ImageTransferState);
02614             /* merge stencil values into depth values */
02615             for (i = 0; i < srcWidth; i++)
02616                dstRow[i] |= stencil[i] << 24;
02617 
02618             src += srcRowStride;
02619             dstRow += dstRowStride / sizeof(GLuint);
02620          }
02621       }
02622    }
02623    return GL_TRUE;
02624 }
02625 
02635 GLboolean
02636 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
02637 {
02638    const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
02639 
02640    ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
02641           dstFormat == &_mesa_texformat_rgb_float32 ||
02642           dstFormat == &_mesa_texformat_alpha_float32 ||
02643           dstFormat == &_mesa_texformat_luminance_float32 ||
02644           dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
02645           dstFormat == &_mesa_texformat_intensity_float32);
02646    ASSERT(baseInternalFormat == GL_RGBA ||
02647           baseInternalFormat == GL_RGB ||
02648           baseInternalFormat == GL_ALPHA ||
02649           baseInternalFormat == GL_LUMINANCE ||
02650           baseInternalFormat == GL_LUMINANCE_ALPHA ||
02651           baseInternalFormat == GL_INTENSITY);
02652    ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
02653 
02654    if (!ctx->_ImageTransferState &&
02655        !srcPacking->SwapBytes &&
02656        baseInternalFormat == srcFormat &&
02657        srcType == GL_FLOAT) {
02658       /* simple memcpy path */
02659       memcpy_texture(ctx, dims,
02660                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02661                      dstRowStride,
02662                      dstImageOffsets,
02663                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02664                      srcAddr, srcPacking);
02665    }
02666    else {
02667       /* general path */
02668       const GLfloat *tempImage = make_temp_float_image(ctx, dims,
02669                                                  baseInternalFormat,
02670                                                  dstFormat->BaseFormat,
02671                                                  srcWidth, srcHeight, srcDepth,
02672                                                  srcFormat, srcType, srcAddr,
02673                                                  srcPacking);
02674       const GLfloat *srcRow = tempImage;
02675       GLint bytesPerRow;
02676       GLint img, row;
02677       if (!tempImage)
02678          return GL_FALSE;
02679       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02680       bytesPerRow = srcWidth * components * sizeof(GLfloat);
02681       for (img = 0; img < srcDepth; img++) {
02682          GLubyte *dstRow = (GLubyte *) dstAddr
02683             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02684             + dstYoffset * dstRowStride
02685             + dstXoffset * dstFormat->TexelBytes;
02686          for (row = 0; row < srcHeight; row++) {
02687             _mesa_memcpy(dstRow, srcRow, bytesPerRow);
02688             dstRow += dstRowStride;
02689             srcRow += srcWidth * components;
02690          }
02691       }
02692 
02693       _mesa_free((void *) tempImage);
02694    }
02695    return GL_TRUE;
02696 }
02697 
02698 
02702 GLboolean
02703 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
02704 {
02705    const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
02706 
02707    ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
02708           dstFormat == &_mesa_texformat_rgb_float16 ||
02709           dstFormat == &_mesa_texformat_alpha_float16 ||
02710           dstFormat == &_mesa_texformat_luminance_float16 ||
02711           dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
02712           dstFormat == &_mesa_texformat_intensity_float16);
02713    ASSERT(baseInternalFormat == GL_RGBA ||
02714           baseInternalFormat == GL_RGB ||
02715           baseInternalFormat == GL_ALPHA ||
02716           baseInternalFormat == GL_LUMINANCE ||
02717           baseInternalFormat == GL_LUMINANCE_ALPHA ||
02718           baseInternalFormat == GL_INTENSITY);
02719    ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
02720 
02721    if (!ctx->_ImageTransferState &&
02722        !srcPacking->SwapBytes &&
02723        baseInternalFormat == srcFormat &&
02724        srcType == GL_HALF_FLOAT_ARB) {
02725       /* simple memcpy path */
02726       memcpy_texture(ctx, dims,
02727                      dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
02728                      dstRowStride,
02729                      dstImageOffsets,
02730                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
02731                      srcAddr, srcPacking);
02732    }
02733    else {
02734       /* general path */
02735       const GLfloat *tempImage = make_temp_float_image(ctx, dims,
02736                                                  baseInternalFormat,
02737                                                  dstFormat->BaseFormat,
02738                                                  srcWidth, srcHeight, srcDepth,
02739                                                  srcFormat, srcType, srcAddr,
02740                                                  srcPacking);
02741       const GLfloat *src = tempImage;
02742       GLint img, row;
02743       if (!tempImage)
02744          return GL_FALSE;
02745       _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
02746       for (img = 0; img < srcDepth; img++) {
02747          GLubyte *dstRow = (GLubyte *) dstAddr
02748             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
02749             + dstYoffset * dstRowStride
02750             + dstXoffset * dstFormat->TexelBytes;
02751          for (row = 0; row < srcHeight; row++) {
02752             GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
02753             GLint i;
02754             for (i = 0; i < srcWidth * components; i++) {
02755                dstTexel[i] = _mesa_float_to_half(src[i]);
02756             }
02757             dstRow += dstRowStride;
02758             src += srcWidth * components;
02759          }
02760       }
02761 
02762       _mesa_free((void *) tempImage);
02763    }
02764    return GL_TRUE;
02765 }
02766 
02767 
02768 #if FEATURE_EXT_texture_sRGB
02769 GLboolean
02770 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
02771 {
02772    const GLboolean littleEndian = _mesa_little_endian();
02773    const struct gl_texture_format *newDstFormat;
02774    StoreTexImageFunc store;
02775    GLboolean k;
02776 
02777    ASSERT(dstFormat == &_mesa_texformat_srgb8);
02778 
02779    /* reuse normal rgb texstore code */
02780    if (littleEndian) {
02781       newDstFormat = &_mesa_texformat_bgr888;
02782       store = _mesa_texstore_bgr888;
02783    }
02784    else {
02785       newDstFormat = &_mesa_texformat_rgb888;
02786       store = _mesa_texstore_rgb888;
02787    }
02788 
02789    k = store(ctx, dims, baseInternalFormat,
02790              newDstFormat, dstAddr,
02791              dstXoffset, dstYoffset, dstZoffset,
02792              dstRowStride, dstImageOffsets,
02793              srcWidth, srcHeight, srcDepth,
02794              srcFormat, srcType,
02795              srcAddr, srcPacking);
02796    return k;
02797 }
02798 
02799 
02800 GLboolean
02801 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
02802 {
02803    const GLboolean littleEndian = _mesa_little_endian();
02804    const struct gl_texture_format *newDstFormat;
02805    GLboolean k;
02806 
02807    ASSERT(dstFormat == &_mesa_texformat_srgba8);
02808 
02809    /* reuse normal rgba texstore code */
02810    if (littleEndian)
02811       newDstFormat = &_mesa_texformat_rgba8888_rev;
02812    else
02813       newDstFormat = &_mesa_texformat_rgba8888;
02814 
02815    k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
02816                                newDstFormat, dstAddr,
02817                                dstXoffset, dstYoffset, dstZoffset,
02818                                dstRowStride, dstImageOffsets,
02819                                srcWidth, srcHeight, srcDepth,
02820                                srcFormat, srcType,
02821                                srcAddr, srcPacking);
02822    return k;
02823 }
02824 
02825 
02826 GLboolean
02827 _mesa_texstore_sl8(TEXSTORE_PARAMS)
02828 {
02829    const struct gl_texture_format *newDstFormat;
02830    GLboolean k;
02831 
02832    ASSERT(dstFormat == &_mesa_texformat_sl8);
02833 
02834    newDstFormat = &_mesa_texformat_l8;
02835 
02836    /* _mesa_textore_a8 handles luminance8 too */
02837    k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
02838                          newDstFormat, dstAddr,
02839                          dstXoffset, dstYoffset, dstZoffset,
02840                          dstRowStride, dstImageOffsets,
02841                          srcWidth, srcHeight, srcDepth,
02842                          srcFormat, srcType,
02843                          srcAddr, srcPacking);
02844    return k;
02845 }
02846 
02847 
02848 GLboolean
02849 _mesa_texstore_sla8(TEXSTORE_PARAMS)
02850 {
02851    const GLboolean littleEndian = _mesa_little_endian();
02852    const struct gl_texture_format *newDstFormat;
02853    GLboolean k;
02854 
02855    ASSERT(dstFormat == &_mesa_texformat_sla8);
02856 
02857    /* reuse normal luminance/alpha texstore code */
02858    if (littleEndian)
02859       newDstFormat = &_mesa_texformat_al88;
02860    else
02861       newDstFormat = &_mesa_texformat_al88_rev;
02862 
02863    k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
02864                            newDstFormat, dstAddr,
02865                            dstXoffset, dstYoffset, dstZoffset,
02866                            dstRowStride, dstImageOffsets,
02867                            srcWidth, srcHeight, srcDepth,
02868                            srcFormat, srcType,
02869                            srcAddr, srcPacking);
02870    return k;
02871 }
02872 
02873 #endif /* FEATURE_EXT_texture_sRGB */
02874 
02875 
02882 const GLvoid *
02883 _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
02884                 GLsizei width, GLsizei height, GLsizei depth,
02885                 GLenum format, GLenum type, const GLvoid *pixels,
02886                 const struct gl_pixelstore_attrib *unpack,
02887                 const char *funcName)
02888 {
02889    GLubyte *buf;
02890 
02891    if (unpack->BufferObj->Name == 0) {
02892       /* no PBO */
02893       return pixels;
02894    }
02895    if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
02896                                   format, type, pixels)) {
02897       _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
02898       return NULL;
02899    }
02900 
02901    buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
02902                                           GL_READ_ONLY_ARB, unpack->BufferObj);
02903    if (!buf) {
02904       _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
02905       return NULL;
02906    }
02907 
02908    return ADD_POINTERS(buf, pixels);
02909 }
02910 
02911 
02919 const GLvoid *
02920 _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
02921                                  GLsizei imageSize, const GLvoid *pixels,
02922                                  const struct gl_pixelstore_attrib *packing,
02923                                  const char *funcName)
02924 {
02925    GLubyte *buf;
02926 
02927    if (packing->BufferObj->Name == 0) {
02928       /* not using a PBO - return pointer unchanged */
02929       return pixels;
02930    }
02931    if ((const GLubyte *) pixels + imageSize >
02932        ((const GLubyte *) 0) + packing->BufferObj->Size) {
02933       /* out of bounds read! */
02934       _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
02935       return NULL;
02936    }
02937 
02938    buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
02939                                          GL_READ_ONLY_ARB, packing->BufferObj);
02940    if (!buf) {
02941       _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
02942       return NULL;
02943    }
02944 
02945    return ADD_POINTERS(buf, pixels);
02946 }
02947 
02948 
02953 void
02954 _mesa_unmap_teximage_pbo(GLcontext *ctx,
02955                          const struct gl_pixelstore_attrib *unpack)
02956 {
02957    if (unpack->BufferObj->Name) {
02958       ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
02959                               unpack->BufferObj);
02960    }
02961 }
02962 
02963 
02964 
02968 static void
02969 fetch_texel_float_to_chan(const struct gl_texture_image *texImage,
02970                           GLint i, GLint j, GLint k, GLchan *texelOut)
02971 {
02972    GLfloat temp[4];
02973    ASSERT(texImage->FetchTexelf);
02974    texImage->FetchTexelf(texImage, i, j, k, temp);
02975    if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
02976        texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
02977       /* just one channel */
02978       UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
02979    }
02980    else {
02981       /* four channels */
02982       UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
02983       UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
02984       UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
02985       UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
02986    }
02987 }
02988 
02989 
02993 static void
02994 fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
02995                           GLint i, GLint j, GLint k, GLfloat *texelOut)
02996 {
02997    GLchan temp[4];
02998    ASSERT(texImage->FetchTexelc);
02999    texImage->FetchTexelc(texImage, i, j, k, temp);
03000    if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
03001        texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
03002       /* just one channel */
03003       texelOut[0] = CHAN_TO_FLOAT(temp[0]);
03004    }
03005    else {
03006       /* four channels */
03007       texelOut[0] = CHAN_TO_FLOAT(temp[0]);
03008       texelOut[1] = CHAN_TO_FLOAT(temp[1]);
03009       texelOut[2] = CHAN_TO_FLOAT(temp[2]);
03010       texelOut[3] = CHAN_TO_FLOAT(temp[3]);
03011    }
03012 }
03013 
03014 
03018 void
03019 _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
03020 {
03021    ASSERT(dims == 1 || dims == 2 || dims == 3);
03022    ASSERT(texImage->TexFormat);
03023 
03024    switch (dims) {
03025    case 1:
03026       texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
03027       texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
03028       break;
03029    case 2:
03030       texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
03031       texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
03032       break;
03033    case 3:
03034       texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
03035       texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
03036       break;
03037    default:
03038       ;
03039    }
03040 
03041    /* now check if we need to use a float/chan adaptor */
03042    if (!texImage->FetchTexelc) {
03043       texImage->FetchTexelc = fetch_texel_float_to_chan;
03044    }
03045    else if (!texImage->FetchTexelf) {
03046       texImage->FetchTexelf = fetch_texel_chan_to_float;
03047    }
03048 
03049 
03050    ASSERT(texImage->FetchTexelc);
03051    ASSERT(texImage->FetchTexelf);
03052 }
03053 
03054 
03066 static void
03067 choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
03068                       GLuint dims,
03069                       GLenum format, GLenum type, GLint internalFormat)
03070 {
03071    ASSERT(dims == 1 || dims == 2 || dims == 3);
03072    ASSERT(ctx->Driver.ChooseTextureFormat);
03073 
03074    texImage->TexFormat
03075       = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
03076 
03077    ASSERT(texImage->TexFormat);
03078 
03079    _mesa_set_fetch_functions(texImage, dims);
03080 
03081    if (texImage->TexFormat->TexelBytes == 0) {
03082       /* must be a compressed format */
03083       texImage->IsCompressed = GL_TRUE;
03084       texImage->CompressedSize =
03085          ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
03086                                            texImage->Height, texImage->Depth,
03087                                            texImage->TexFormat->MesaFormat);
03088    }
03089    else {
03090       /* non-compressed format */
03091       texImage->IsCompressed = GL_FALSE;
03092       texImage->CompressedSize = 0;
03093    }
03094 }
03095 
03096 
03097 
03106 void
03107 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
03108                        GLint internalFormat,
03109                        GLint width, GLint border,
03110                        GLenum format, GLenum type, const GLvoid *pixels,
03111                        const struct gl_pixelstore_attrib *packing,
03112                        struct gl_texture_object *texObj,
03113                        struct gl_texture_image *texImage)
03114 {
03115    GLint sizeInBytes;
03116    (void) border;
03117 
03118    choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
03119 
03120    /* allocate memory */
03121    if (texImage->IsCompressed)
03122       sizeInBytes = texImage->CompressedSize;
03123    else
03124       sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes;
03125    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
03126    if (!texImage->Data) {
03127       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
03128       return;
03129    }
03130 
03131    pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
03132                                         pixels, packing, "glTexImage1D");
03133    if (!pixels) {
03134       /* Note: we check for a NULL image pointer here, _after_ we allocated
03135        * memory for the texture.  That's what the GL spec calls for.
03136        */
03137       return;
03138    }
03139    else {
03140       const GLint dstRowStride = 0;
03141       GLboolean success;
03142       ASSERT(texImage->TexFormat->StoreImage);
03143       success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
03144                                                 texImage->TexFormat,
03145                                                 texImage->Data,
03146                                                 0, 0, 0,  /* dstX/Y/Zoffset */
03147                                                 dstRowStride,
03148                                                 texImage->ImageOffsets,
03149                                                 width, 1, 1,
03150                                                 format, type, pixels, packing);
03151       if (!success) {
03152          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
03153       }
03154    }
03155 
03156    /* GL_SGIS_generate_mipmap */
03157    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03158       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03159    }
03160 
03161    _mesa_unmap_teximage_pbo(ctx, packing);
03162 }
03163 
03164 
03175 void
03176 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
03177                        GLint internalFormat,
03178                        GLint width, GLint height, GLint border,
03179                        GLenum format, GLenum type, const void *pixels,
03180                        const struct gl_pixelstore_attrib *packing,
03181                        struct gl_texture_object *texObj,
03182                        struct gl_texture_image *texImage)
03183 {
03184    GLint texelBytes, sizeInBytes;
03185    (void) border;
03186 
03187    choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
03188 
03189    texelBytes = texImage->TexFormat->TexelBytes;
03190 
03191    /* allocate memory */
03192    if (texImage->IsCompressed)
03193       sizeInBytes = texImage->CompressedSize;
03194    else
03195       sizeInBytes = texImage->Width * texImage->Height * texelBytes;
03196    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
03197    if (!texImage->Data) {
03198       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
03199       return;
03200    }
03201 
03202    pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
03203                                         pixels, packing, "glTexImage2D");
03204    if (!pixels) {
03205       /* Note: we check for a NULL image pointer here, _after_ we allocated
03206        * memory for the texture.  That's what the GL spec calls for.
03207        */
03208       return;
03209    }
03210    else {
03211       GLint dstRowStride;
03212       GLboolean success;
03213       if (texImage->IsCompressed) {
03214          dstRowStride
03215             = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
03216       }
03217       else {
03218          dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
03219       }
03220       ASSERT(texImage->TexFormat->StoreImage);
03221       success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
03222                                                 texImage->TexFormat,
03223                                                 texImage->Data,
03224                                                 0, 0, 0,  /* dstX/Y/Zoffset */
03225                                                 dstRowStride,
03226                                                 texImage->ImageOffsets,
03227                                                 width, height, 1,
03228                                                 format, type, pixels, packing);
03229       if (!success) {
03230          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
03231       }
03232    }
03233 
03234    /* GL_SGIS_generate_mipmap */
03235    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03236       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03237    }
03238 
03239    _mesa_unmap_teximage_pbo(ctx, packing);
03240 }
03241 
03242 
03243 
03249 void
03250 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
03251                        GLint internalFormat,
03252                        GLint width, GLint height, GLint depth, GLint border,
03253                        GLenum format, GLenum type, const void *pixels,
03254                        const struct gl_pixelstore_attrib *packing,
03255                        struct gl_texture_object *texObj,
03256                        struct gl_texture_image *texImage)
03257 {
03258    GLint texelBytes, sizeInBytes;
03259    (void) border;
03260 
03261    choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
03262 
03263    texelBytes = texImage->TexFormat->TexelBytes;
03264 
03265    /* allocate memory */
03266    if (texImage->IsCompressed)
03267       sizeInBytes = texImage->CompressedSize;
03268    else
03269       sizeInBytes = width * height * depth * texelBytes;
03270    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
03271    if (!texImage->Data) {
03272       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
03273       return;
03274    }
03275 
03276    pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
03277                                         type, pixels, packing, "glTexImage3D");
03278    if (!pixels) {
03279       /* Note: we check for a NULL image pointer here, _after_ we allocated
03280        * memory for the texture.  That's what the GL spec calls for.
03281        */
03282       return;
03283    }
03284    else {
03285       GLint dstRowStride;
03286       GLboolean success;
03287       if (texImage->IsCompressed) {
03288          dstRowStride
03289             = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
03290       }
03291       else {
03292          dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
03293       }
03294       ASSERT(texImage->TexFormat->StoreImage);
03295       success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
03296                                                 texImage->TexFormat,
03297                                                 texImage->Data,
03298                                                 0, 0, 0,  /* dstX/Y/Zoffset */
03299                                                 dstRowStride,
03300                                                 texImage->ImageOffsets,
03301                                                 width, height, depth,
03302                                                 format, type, pixels, packing);
03303       if (!success) {
03304          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
03305       }
03306    }
03307 
03308    /* GL_SGIS_generate_mipmap */
03309    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03310       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03311    }
03312 
03313    _mesa_unmap_teximage_pbo(ctx, packing);
03314 }
03315 
03316 
03317 
03318 
03319 /*
03320  * This is the software fallback for Driver.TexSubImage1D()
03321  * and Driver.CopyTexSubImage1D().
03322  */
03323 void
03324 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
03325                           GLint xoffset, GLint width,
03326                           GLenum format, GLenum type, const void *pixels,
03327                           const struct gl_pixelstore_attrib *packing,
03328                           struct gl_texture_object *texObj,
03329                           struct gl_texture_image *texImage)
03330 {
03331    /* get pointer to src pixels (may be in a pbo which we'll map here) */
03332    pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
03333                                         pixels, packing, "glTexSubImage1D");
03334    if (!pixels)
03335       return;
03336 
03337    {
03338       const GLint dstRowStride = 0;
03339       GLboolean success;
03340       ASSERT(texImage->TexFormat->StoreImage);
03341       success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
03342                                                 texImage->TexFormat,
03343                                                 texImage->Data,
03344                                                 xoffset, 0, 0,  /* offsets */
03345                                                 dstRowStride,
03346                                                 texImage->ImageOffsets,
03347                                                 width, 1, 1,
03348                                                 format, type, pixels, packing);
03349       if (!success) {
03350          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
03351       }
03352    }
03353 
03354    /* GL_SGIS_generate_mipmap */
03355    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03356       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03357    }
03358 
03359    _mesa_unmap_teximage_pbo(ctx, packing);
03360 }
03361 
03362 
03363 
03368 void
03369 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
03370                           GLint xoffset, GLint yoffset,
03371                           GLint width, GLint height,
03372                           GLenum format, GLenum type, const void *pixels,
03373                           const struct gl_pixelstore_attrib *packing,
03374                           struct gl_texture_object *texObj,
03375                           struct gl_texture_image *texImage)
03376 {
03377    /* get pointer to src pixels (may be in a pbo which we'll map here) */
03378    pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
03379                                         pixels, packing, "glTexSubImage2D");
03380    if (!pixels)
03381       return;
03382 
03383    {
03384       GLint dstRowStride = 0;
03385       GLboolean success;
03386       if (texImage->IsCompressed) {
03387          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
03388                                                     texImage->Width);
03389       }
03390       else {
03391          dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
03392       }
03393       ASSERT(texImage->TexFormat->StoreImage);
03394       success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
03395                                                 texImage->TexFormat,
03396                                                 texImage->Data,
03397                                                 xoffset, yoffset, 0,
03398                                                 dstRowStride,
03399                                                 texImage->ImageOffsets,
03400                                                 width, height, 1,
03401                                                 format, type, pixels, packing);
03402       if (!success) {
03403          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
03404       }
03405    }
03406 
03407    /* GL_SGIS_generate_mipmap */
03408    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03409       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03410    }
03411 
03412    _mesa_unmap_teximage_pbo(ctx, packing);
03413 }
03414 
03415 
03416 /*
03417  * This is the software fallback for Driver.TexSubImage3D().
03418  * and Driver.CopyTexSubImage3D().
03419  */
03420 void
03421 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
03422                           GLint xoffset, GLint yoffset, GLint zoffset,
03423                           GLint width, GLint height, GLint depth,
03424                           GLenum format, GLenum type, const void *pixels,
03425                           const struct gl_pixelstore_attrib *packing,
03426                           struct gl_texture_object *texObj,
03427                           struct gl_texture_image *texImage)
03428 {
03429    /* get pointer to src pixels (may be in a pbo which we'll map here) */
03430    pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
03431                                         type, pixels, packing,
03432                                         "glTexSubImage3D");
03433    if (!pixels)
03434       return;
03435 
03436    {
03437       GLint dstRowStride;
03438       GLboolean success;
03439       if (texImage->IsCompressed) {
03440          dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
03441                                                     texImage->Width);
03442       }
03443       else {
03444          dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
03445       }
03446       ASSERT(texImage->TexFormat->StoreImage);
03447       success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
03448                                                 texImage->TexFormat,
03449                                                 texImage->Data,
03450                                                 xoffset, yoffset, zoffset,
03451                                                 dstRowStride,
03452                                                 texImage->ImageOffsets,
03453                                                 width, height, depth,
03454                                                 format, type, pixels, packing);
03455       if (!success) {
03456          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
03457       }
03458    }
03459 
03460    /* GL_SGIS_generate_mipmap */
03461    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03462       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03463    }
03464 
03465    _mesa_unmap_teximage_pbo(ctx, packing);
03466 }
03467 
03468 
03469 /*
03470  * Fallback for Driver.CompressedTexImage1D()
03471  */
03472 void
03473 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
03474                                   GLint internalFormat,
03475                                   GLint width, GLint border,
03476                                   GLsizei imageSize, const GLvoid *data,
03477                                   struct gl_texture_object *texObj,
03478                                   struct gl_texture_image *texImage)
03479 {
03480    /* this space intentionally left blank */
03481    (void) ctx;
03482    (void) target; (void) level;
03483    (void) internalFormat;
03484    (void) width; (void) border;
03485    (void) imageSize; (void) data;
03486    (void) texObj;
03487    (void) texImage;
03488 }
03489 
03490 
03491 
03495 void
03496 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
03497                                   GLint internalFormat,
03498                                   GLint width, GLint height, GLint border,
03499                                   GLsizei imageSize, const GLvoid *data,
03500                                   struct gl_texture_object *texObj,
03501                                   struct gl_texture_image *texImage)
03502 {
03503    (void) width; (void) height; (void) border;
03504 
03505    /* This is pretty simple, basically just do a memcpy without worrying
03506     * about the usual image unpacking or image transfer operations.
03507     */
03508    ASSERT(texObj);
03509    ASSERT(texImage);
03510    ASSERT(texImage->Width > 0);
03511    ASSERT(texImage->Height > 0);
03512    ASSERT(texImage->Depth == 1);
03513    ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
03514 
03515    choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
03516 
03517    /* allocate storage */
03518    texImage->Data = _mesa_alloc_texmemory(imageSize);
03519    if (!texImage->Data) {
03520       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
03521       return;
03522    }
03523 
03524    data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
03525                                                  &ctx->Unpack,
03526                                                  "glCompressedTexImage2D");
03527    if (!data)
03528       return;
03529 
03530    /* copy the data */
03531    ASSERT(texImage->CompressedSize == (GLuint) imageSize);
03532    MEMCPY(texImage->Data, data, imageSize);
03533 
03534    /* GL_SGIS_generate_mipmap */
03535    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03536       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03537    }
03538 
03539    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
03540 }
03541 
03542 
03543 
03544 /*
03545  * Fallback for Driver.CompressedTexImage3D()
03546  */
03547 void
03548 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
03549                                   GLint internalFormat,
03550                                   GLint width, GLint height, GLint depth,
03551                                   GLint border,
03552                                   GLsizei imageSize, const GLvoid *data,
03553                                   struct gl_texture_object *texObj,
03554                                   struct gl_texture_image *texImage)
03555 {
03556    /* this space intentionally left blank */
03557    (void) ctx;
03558    (void) target; (void) level;
03559    (void) internalFormat;
03560    (void) width; (void) height; (void) depth;
03561    (void) border;
03562    (void) imageSize; (void) data;
03563    (void) texObj;
03564    (void) texImage;
03565 }
03566 
03567 
03568 
03572 void
03573 _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
03574                                      GLint level,
03575                                      GLint xoffset, GLsizei width,
03576                                      GLenum format,
03577                                      GLsizei imageSize, const GLvoid *data,
03578                                      struct gl_texture_object *texObj,
03579                                      struct gl_texture_image *texImage)
03580 {
03581    /* there are no compressed 1D texture formats yet */
03582    (void) ctx;
03583    (void) target; (void) level;
03584    (void) xoffset; (void) width;
03585    (void) format;
03586    (void) imageSize; (void) data;
03587    (void) texObj;
03588    (void) texImage;
03589 }
03590 
03591 
03595 void
03596 _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
03597                                      GLint level,
03598                                      GLint xoffset, GLint yoffset,
03599                                      GLsizei width, GLsizei height,
03600                                      GLenum format,
03601                                      GLsizei imageSize, const GLvoid *data,
03602                                      struct gl_texture_object *texObj,
03603                                      struct gl_texture_image *texImage)
03604 {
03605    GLint bytesPerRow, destRowStride, srcRowStride;
03606    GLint i, rows;
03607    GLubyte *dest;
03608    const GLubyte *src;
03609    const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
03610 
03611    (void) format;
03612 
03613    /* these should have been caught sooner */
03614    ASSERT((width & 3) == 0 || width == 2 || width == 1);
03615    ASSERT((height & 3) == 0 || height == 2 || height == 1);
03616    ASSERT((xoffset & 3) == 0);
03617    ASSERT((yoffset & 3) == 0);
03618 
03619    /* get pointer to src pixels (may be in a pbo which we'll map here) */
03620    data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
03621                                                  &ctx->Unpack,
03622                                                  "glCompressedTexSubImage2D");
03623    if (!data)
03624       return;
03625 
03626    srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
03627    src = (const GLubyte *) data;
03628 
03629    destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
03630    dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
03631                                          texImage->TexFormat->MesaFormat,
03632                                          texImage->Width,
03633                                          (GLubyte *) texImage->Data);
03634 
03635    bytesPerRow = srcRowStride;
03636    rows = height / 4;
03637 
03638    for (i = 0; i < rows; i++) {
03639       MEMCPY(dest, src, bytesPerRow);
03640       dest += destRowStride;
03641       src += srcRowStride;
03642    }
03643 
03644    /* GL_SGIS_generate_mipmap */
03645    if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
03646       ctx->Driver.GenerateMipmap(ctx, target, texObj);
03647    }
03648 
03649    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
03650 }
03651 
03652 
03656 void
03657 _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
03658                                 GLint level,
03659                                 GLint xoffset, GLint yoffset, GLint zoffset,
03660                                 GLsizei width, GLsizei height, GLsizei depth,
03661                                 GLenum format,
03662                                 GLsizei imageSize, const GLvoid *data,
03663                                 struct gl_texture_object *texObj,
03664                                 struct gl_texture_image *texImage)
03665 {
03666    /* there are no compressed 3D texture formats yet */
03667    (void) ctx;
03668    (void) target; (void) level;
03669    (void) xoffset; (void) yoffset; (void) zoffset;
03670    (void) width; (void) height; (void) depth;
03671    (void) format;
03672    (void) imageSize; (void) data;
03673    (void) texObj;
03674    (void) texImage;
03675 }
03676 
03677 
03678 
03679 
03680 #if FEATURE_EXT_texture_sRGB
03681 
03685 static GLboolean
03686 is_srgb_teximage(const struct gl_texture_image *texImage)
03687 {
03688    switch (texImage->TexFormat->MesaFormat) {
03689    case MESA_FORMAT_SRGB8:
03690    case MESA_FORMAT_SRGBA8:
03691    case MESA_FORMAT_SL8:
03692    case MESA_FORMAT_SLA8:
03693       return GL_TRUE;
03694    default:
03695       return GL_FALSE;
03696    }
03697 }
03698 
03699 #endif /* FEATURE_EXT_texture_sRGB */
03700 
03701 
03706 void
03707 _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
03708                    GLenum format, GLenum type, GLvoid *pixels,
03709                    struct gl_texture_object *texObj,
03710                    struct gl_texture_image *texImage)
03711 {
03712    const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
03713 
03714    if (ctx->Pack.BufferObj->Name) {
03715       /* Packing texture image into a PBO.
03716        * Map the (potentially) VRAM-based buffer into our process space so
03717        * we can write into it with the code below.
03718        * A hardware driver might use a sophisticated blit to move the
03719        * texture data to the PBO if the PBO is in VRAM along with the texture.
03720        */
03721       GLubyte *buf = (GLubyte *)
03722          ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
03723                                GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
03724       if (!buf) {
03725          /* buffer is already mapped - that's an error */
03726          _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
03727          return;
03728       }
03729       /* <pixels> was an offset into the PBO.
03730        * Now make it a real, client-side pointer inside the mapped region.
03731        */
03732       pixels = ADD_POINTERS(buf, pixels);
03733    }
03734    else if (!pixels) {
03735       /* not an error */
03736       return;
03737    }
03738 
03739    {
03740       const GLint width = texImage->Width;
03741       const GLint height = texImage->Height;
03742       const GLint depth = texImage->Depth;
03743       GLint img, row;
03744       for (img = 0; img < depth; img++) {
03745          for (row = 0; row < height; row++) {
03746             /* compute destination address in client memory */
03747             GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
03748                                                 width, height, format, type,
03749                                                 img, row, 0);
03750             assert(dest);
03751 
03752             if (format == GL_COLOR_INDEX) {
03753                GLuint indexRow[MAX_WIDTH];
03754                GLint col;
03755                /* Can't use FetchTexel here because that returns RGBA */
03756                if (texImage->TexFormat->IndexBits == 8) {
03757                   const GLubyte *src = (const GLubyte *) texImage->Data;
03758                   src += width * (img * texImage->Height + row);
03759                   for (col = 0; col < width; col++) {
03760                      indexRow[col] = src[col];
03761                   }
03762                }
03763                else if (texImage->TexFormat->IndexBits == 16) {
03764                   const GLushort *src = (const GLushort *) texImage->Data;
03765                   src += width * (img * texImage->Height + row);
03766                   for (col = 0; col < width; col++) {
03767                      indexRow[col] = src[col];
03768                   }
03769                }
03770                else {
03771                   _mesa_problem(ctx,
03772                                 "Color index problem in _mesa_GetTexImage");
03773                }
03774                _mesa_pack_index_span(ctx, width, type, dest,
03775                                      indexRow, &ctx->Pack,
03776                                      0 /* no image transfer */);
03777             }
03778             else if (format == GL_DEPTH_COMPONENT) {
03779                GLfloat depthRow[MAX_WIDTH];
03780                GLint col;
03781                for (col = 0; col < width; col++) {
03782                   (*texImage->FetchTexelf)(texImage, col, row, img,
03783                                            depthRow + col);
03784                }
03785                _mesa_pack_depth_span(ctx, width, dest, type,
03786                                      depthRow, &ctx->Pack);
03787             }
03788             else if (format == GL_DEPTH_STENCIL_EXT) {
03789                /* XXX Note: we're bypassing texImage->FetchTexel()! */
03790                const GLuint *src = (const GLuint *) texImage->Data;
03791                src += width * row + width * height * img;
03792                _mesa_memcpy(dest, src, width * sizeof(GLuint));
03793                if (ctx->Pack.SwapBytes) {
03794                   _mesa_swap4((GLuint *) dest, width);
03795                }
03796             }
03797             else if (format == GL_YCBCR_MESA) {
03798                /* No pixel transfer */
03799                const GLint rowstride = texImage->RowStride;
03800                MEMCPY(dest,
03801                       (const GLushort *) texImage->Data + row * rowstride,
03802                       width * sizeof(GLushort));
03803                /* check for byte swapping */
03804                if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
03805                     && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
03806                    (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
03807                     && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
03808                   if (!ctx->Pack.SwapBytes)
03809                      _mesa_swap2((GLushort *) dest, width);
03810                }
03811                else if (ctx->Pack.SwapBytes) {
03812                   _mesa_swap2((GLushort *) dest, width);
03813                }
03814             }
03815 #if FEATURE_EXT_texture_sRGB
03816             else if (is_srgb_teximage(texImage)) {
03817                /* no pixel transfer and no non-linear to linear conversion */
03818                const GLint comps = texImage->TexFormat->TexelBytes;
03819                const GLint rowstride = comps * texImage->RowStride;
03820                MEMCPY(dest,
03821                       (const GLubyte *) texImage->Data + row * rowstride,
03822                       comps * width * sizeof(GLubyte));
03823             }
03824 #endif /* FEATURE_EXT_texture_sRGB */
03825             else {
03826                /* general case:  convert row to RGBA format */
03827                GLfloat rgba[MAX_WIDTH][4];
03828                GLint col;
03829                GLbitfield transferOps = 0x0;
03830 
03831                if (type == GL_FLOAT && 
03832                    ((ctx->Color.ClampReadColor == GL_TRUE) ||
03833                     (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&
03834                      texImage->TexFormat->DataType != GL_FLOAT)))
03835                   transferOps |= IMAGE_CLAMP_BIT;
03836 
03837                for (col = 0; col < width; col++) {
03838                   (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
03839                   if (texImage->TexFormat->BaseFormat == GL_ALPHA) {
03840                      rgba[col][RCOMP] = 0.0;
03841                      rgba[col][GCOMP] = 0.0;
03842                      rgba[col][BCOMP] = 0.0;
03843                   }
03844                   else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE) {
03845                      rgba[col][GCOMP] = 0.0;
03846                      rgba[col][BCOMP] = 0.0;
03847                      rgba[col][ACOMP] = 1.0;
03848                   }
03849                   else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE_ALPHA) {
03850                      rgba[col][GCOMP] = 0.0;
03851                      rgba[col][BCOMP] = 0.0;
03852                   }
03853                   else if (texImage->TexFormat->BaseFormat == GL_INTENSITY) {
03854                      rgba[col][GCOMP] = 0.0;
03855                      rgba[col][BCOMP] = 0.0;
03856                      rgba[col][ACOMP] = 1.0;
03857                   }
03858                }
03859                _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
03860                                           format, type, dest,
03861                                           &ctx->Pack, transferOps /*image xfer ops*/);
03862             } /* format */
03863          } /* row */
03864       } /* img */
03865    }
03866 
03867    if (ctx->Pack.BufferObj->Name) {
03868       ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
03869                               ctx->Pack.BufferObj);
03870    }
03871 }
03872 
03873 
03874 
03879 void
03880 _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
03881                               GLvoid *img,
03882                               struct gl_texture_object *texObj,
03883                               struct gl_texture_image *texImage)
03884 {
03885    GLuint size;
03886 
03887    if (ctx->Pack.BufferObj->Name) {
03888       /* pack texture image into a PBO */
03889       GLubyte *buf;
03890       if ((const GLubyte *) img + texImage->CompressedSize >
03891           (const GLubyte *) ctx->Pack.BufferObj->Size) {
03892          _mesa_error(ctx, GL_INVALID_OPERATION,
03893                      "glGetCompressedTexImage(invalid PBO access)");
03894          return;
03895       }
03896       buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
03897                                               GL_WRITE_ONLY_ARB,
03898                                               ctx->Pack.BufferObj);
03899       if (!buf) {
03900          /* buffer is already mapped - that's an error */
03901          _mesa_error(ctx, GL_INVALID_OPERATION,
03902                      "glGetCompressedTexImage(PBO is mapped)");
03903          return;
03904       }
03905       img = ADD_POINTERS(buf, img);
03906    }
03907    else if (!img) {
03908       /* not an error */
03909       return;
03910    }
03911 
03912    /* don't use texImage->CompressedSize since that may be padded out */
03913    size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height,
03914                                         texImage->Depth,
03915                                         texImage->TexFormat->MesaFormat);
03916 
03917    /* just memcpy, no pixelstore or pixel transfer */
03918    _mesa_memcpy(img, texImage->Data, size);
03919 
03920    if (ctx->Pack.BufferObj->Name) {
03921       ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
03922                               ctx->Pack.BufferObj);
03923    }
03924 }

Generated on Sun May 27 2012 04:19:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.