Fixed out-of-bounds memory write problem (CONVERT_TEXEL_DWORD macro).
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 21 Feb 2002 15:12:31 +0000 (15:12 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 21 Feb 2002 15:12:31 +0000 (15:12 +0000)
Renamed 'packing' to 'unpacking' since we're moving data from client -> GL.
Rnamed DST_ROW_WIDTH to DST_ROW_BYTES.

src/mesa/main/texutil.c
src/mesa/main/texutil_tmp.h

index 6231f58..0ac9277 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: texutil.c,v 1.25 2001/06/15 15:22:08 brianp Exp $ */
+/* $Id: texutil.c,v 1.26 2002/02/21 15:12:31 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.0.2
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -52,7 +52,7 @@ struct gl_texture_convert {
                                         /* Needed for subimage replacement */
    GLenum format, type;                 /* Source (user) format and type */
 
-   const struct gl_pixelstore_attrib *packing;
+   const struct gl_pixelstore_attrib *unpacking;
 
    const GLvoid *srcImage;
    GLvoid *dstImage;
@@ -63,7 +63,7 @@ struct gl_texture_convert {
 typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
 
 #define CONVERT_STRIDE_BIT     0x1
-#define CONVERT_PACKING_BIT    0x2
+#define CONVERT_UNPACKING_BIT  0x2
 
 
 
@@ -681,23 +681,23 @@ static convert_func gl_convert_texsubimage3d_tab[] = {
 
 /* See if we need to care about the pixel store attributes when we're
  * converting the texture image.  This should be stored as
- * packing->_SomeBoolean and updated when the values change, to avoid
+ * unpacking->_SomeBoolean and updated when the values change, to avoid
  * testing every time...
  */
 static INLINE GLboolean
-convert_needs_packing( const struct gl_pixelstore_attrib *packing,
+convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking,
                       GLenum format, GLenum type )
 {
-   if ( ( packing->Alignment == 1 ||
-         ( packing->Alignment == 4 &&  /* Pick up the common Q3A case... */
+   if ( ( unpacking->Alignment == 1 ||
+         ( unpacking->Alignment == 4 &&   /* Pick up the common Q3A case... */
            format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
-       packing->RowLength == 0 &&
-       packing->SkipPixels == 0 &&
-       packing->SkipRows == 0 &&
-       packing->ImageHeight == 0 &&
-       packing->SkipImages == 0 &&
-       packing->SwapBytes == GL_FALSE &&
-       packing->LsbFirst == GL_FALSE ) {
+       unpacking->RowLength == 0 &&
+       unpacking->SkipPixels == 0 &&
+       unpacking->SkipRows == 0 &&
+       unpacking->ImageHeight == 0 &&
+       unpacking->SkipImages == 0 &&
+       unpacking->SwapBytes == GL_FALSE &&
+       unpacking->LsbFirst == GL_FALSE ) {
       return GL_FALSE;
    } else {
       return GL_TRUE;
@@ -710,12 +710,12 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
                             GLint xoffset,
                             GLint width,
                             GLenum format, GLenum type,
-                            const struct gl_pixelstore_attrib *packing,
+                            const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
    struct gl_texture_convert convert;
 
-   ASSERT( packing );
+   ASSERT( unpacking );
    ASSERT( srcImage );
    ASSERT( dstImage );
 
@@ -730,14 +730,14 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
    convert.height = 1;
    convert.format = format;
    convert.type = type;
-   convert.packing = packing;
+   convert.unpacking = unpacking;
    convert.srcImage = srcImage;
    convert.dstImage = dstImage;
 
    convert.index = 0;
 
-   if ( convert_needs_packing( packing, format, type ) )
-      convert.index |= CONVERT_PACKING_BIT;
+   if ( convert_needs_unpacking( unpacking, format, type ) )
+      convert.index |= CONVERT_UNPACKING_BIT;
 
    return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
 }
@@ -764,7 +764,7 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
  *   width, height - incoming image size, also size of dest region.
  *   dstImageWidth - width (row stride) of dest image in pixels
  *   format, type - incoming image format and type
- *   packing - describes incoming image packing
+ *   unpacking - describes incoming image unpacking
  *   srcImage - pointer to source image
  *   destImage - pointer to dest image
  */
@@ -774,12 +774,12 @@ _mesa_convert_texsubimage2d( GLint mesaFormat,
                             GLint width, GLint height,
                             GLint destImageWidth,
                             GLenum format, GLenum type,
-                            const struct gl_pixelstore_attrib *packing,
+                            const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
    struct gl_texture_convert convert;
 
-   ASSERT( packing );
+   ASSERT( unpacking );
    ASSERT( srcImage );
    ASSERT( dstImage );
 
@@ -795,14 +795,14 @@ _mesa_convert_texsubimage2d( GLint mesaFormat,
    convert.dstImageWidth = destImageWidth;
    convert.format = format;
    convert.type = type;
-   convert.packing = packing;
+   convert.unpacking = unpacking;
    convert.srcImage = srcImage;
    convert.dstImage = dstImage;
 
    convert.index = 0;
 
-   if ( convert_needs_packing( packing, format, type ) )
-      convert.index |= CONVERT_PACKING_BIT;
+   if ( convert_needs_unpacking( unpacking, format, type ) )
+      convert.index |= CONVERT_UNPACKING_BIT;
 
    if ( width != destImageWidth )
       convert.index |= CONVERT_STRIDE_BIT;
@@ -816,12 +816,12 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
                             GLint width, GLint height, GLint depth,
                             GLint dstImageWidth, GLint dstImageHeight,
                             GLenum format, GLenum type,
-                            const struct gl_pixelstore_attrib *packing,
+                            const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
    struct gl_texture_convert convert;
 
-   ASSERT( packing );
+   ASSERT( unpacking );
    ASSERT( srcImage );
    ASSERT( dstImage );
 
@@ -840,14 +840,14 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
    convert.dstImageHeight = dstImageHeight;
    convert.format = format;
    convert.type = type;
-   convert.packing = packing;
+   convert.unpacking = unpacking;
    convert.srcImage = srcImage;
    convert.dstImage = dstImage;
 
    convert.index = 0;
 
-   if ( convert_needs_packing( packing, format, type ) )
-      convert.index |= CONVERT_PACKING_BIT;
+   if ( convert_needs_unpacking( unpacking, format, type ) )
+      convert.index |= CONVERT_UNPACKING_BIT;
 
    if ( width != dstImageWidth || height != dstImageHeight )
       convert.index |= CONVERT_STRIDE_BIT;
index ec6274c..3d2ecd9 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: texutil_tmp.h,v 1.8 2001/04/20 19:21:41 brianp Exp $ */
+/* $Id: texutil_tmp.h,v 1.9 2002/02/21 15:12:31 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.0.2
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -33,7 +33,7 @@
 
 
 #define DST_TEXEL_BYTES                (4 / DST_TEXELS_PER_DWORD)
-#define DST_ROW_WIDTH          (convert->width * DST_TEXEL_BYTES)
+#define DST_ROW_BYTES          (convert->width * DST_TEXEL_BYTES)
 #define DST_ROW_STRIDE         (convert->dstImageWidth * DST_TEXEL_BYTES)
 #define DST_IMG_STRIDE         (convert->dstImageWidth *               \
                                 convert->dstImageHeight * DST_TEXEL_BYTES)
@@ -49,22 +49,27 @@ TAG(texsubimage2d)( struct gl_texture_convert *convert )
    GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
                            (convert->yoffset * convert->dstImageWidth +
                             convert->xoffset) * DST_TEXEL_BYTES);
-   GLint dwords, i;
-   (void) dwords; (void) i;
 
 #if DEBUG_TEXUTIL
    fprintf( stderr, __FUNCTION__ "\n" );
 #endif
 
 #ifdef CONVERT_DIRECT
-   MEMCPY( dst, src, convert->height * DST_ROW_WIDTH );
+   MEMCPY( dst, src, convert->height * DST_ROW_BYTES );
 #else
-   dwords = (convert->width * convert->height +
-            DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
-
-   for ( i = 0 ; i < dwords ; i++ ) {
-      CONVERT_TEXEL_DWORD( *dst++, src );
-      src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+   {
+      const GLint texels = convert->width * convert->height;
+      const GLint dwords = texels / DST_TEXELS_PER_DWORD;
+      const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
+      GLint i;
+      for ( i = 0 ; i < dwords ; i++ ) {
+         CONVERT_TEXEL_DWORD( *dst++, src );
+         src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+      }
+      for ( i = 0; i < leftover; i++ ) {
+         CONVERT_TEXEL( *dst++, src );
+         src += SRC_TEXEL_BYTES;
+      }
    }
 #endif
 
@@ -81,22 +86,26 @@ TAG(texsubimage3d)( struct gl_texture_convert *convert )
                            ((convert->zoffset * convert->height +
                              convert->yoffset) * convert->width +
                             convert->xoffset) * DST_TEXEL_BYTES);
-   GLint dwords, i;
-   (void) dwords; (void) i;
-
 #if DEBUG_TEXUTIL
    fprintf( stderr, __FUNCTION__ "\n" );
 #endif
 
 #ifdef CONVERT_DIRECT
-   MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_WIDTH );
+   MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_BYTES );
 #else
-   dwords = (convert->width * convert->height * convert->depth +
-            DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
-
-   for ( i = 0 ; i < dwords ; i++ ) {
-      CONVERT_TEXEL_DWORD( *dst++, src );
-      src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+   {
+      const GLint texels = convert->width * convert->height * convert->depth;
+      const GLint dwords = texels / DST_TEXELS_PER_DWORD;
+      const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
+      GLint i;
+      for ( i = 0 ; i < dwords ; i++ ) {
+         CONVERT_TEXEL_DWORD( *dst++, src );
+         src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+      }
+      for ( i = 0; i < leftover; i++ ) {
+         CONVERT_TEXEL( *dst++, src );
+         src += SRC_TEXEL_BYTES;
+      }
    }
 #endif
 
@@ -182,42 +191,56 @@ TAG(texsubimage3d_stride)( struct gl_texture_convert *convert )
  * PRE: Require pixelstore attribs, width == dstImageWidth.
  */
 static GLboolean
-TAG(texsubimage2d_pack)( struct gl_texture_convert *convert )
+TAG(texsubimage2d_unpack)( struct gl_texture_convert *convert )
 {
    const GLubyte *src = (const GLubyte *)
-      _mesa_image_address( convert->packing, convert->srcImage,
+      _mesa_image_address( convert->unpacking, convert->srcImage,
                           convert->width, convert->height,
                           convert->format, convert->type, 0, 0, 0 );
    const GLint srcRowStride =
-      _mesa_image_row_stride( convert->packing, convert->width,
+      _mesa_image_row_stride( convert->unpacking, convert->width,
                              convert->format, convert->type );
-   GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
-                           (convert->yoffset * convert->width +
-                            convert->xoffset) * DST_TEXEL_BYTES);
-   GLint width;
    GLint row, col;
-   (void) col;
 
 #if DEBUG_TEXUTIL
    fprintf( stderr, __FUNCTION__ "\n" );
 #endif
 
-   width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
-           & ~(DST_TEXELS_PER_DWORD - 1));
-
-   for ( row = 0 ; row < convert->height ; row++ ) {
+   if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
+      /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
+       * or width = 2 and texels/dword = 4).
+       */
+      DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+                                   (convert->yoffset * convert->width +
+                                    convert->xoffset) * DST_TEXEL_BYTES);
+      for ( row = 0 ; row < convert->height ; row++ ) {
+         const GLubyte *srcRow = src;
+         for ( col = 0; col < convert->width; col++ ) {
+            CONVERT_TEXEL(*dst, src);
+            src += SRC_TEXEL_BYTES;
+         }
+         src = srcRow + srcRowStride;
+      }
+   }
+   else {
+      /* the common case */
+      GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+                               (convert->yoffset * convert->width +
+                                convert->xoffset) * DST_TEXEL_BYTES);
+      for ( row = 0 ; row < convert->height ; row++ ) {
 #ifdef CONVERT_DIRECT
-      MEMCPY( dst, src, DST_ROW_STRIDE );
-      src += srcRowStride;
-      dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
+         MEMCPY( dst, src, DST_ROW_STRIDE );
+         src += srcRowStride;
+         dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
 #else
-      const GLubyte *srcRow = src;
-      for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
-        CONVERT_TEXEL_DWORD( *dst++, src );
-        src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
-      }
-      src = srcRow + srcRowStride;
+         const GLubyte *srcRow = src;
+         for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
+            CONVERT_TEXEL_DWORD( *dst++, src );
+            src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+         }
+         src = srcRow + srcRowStride;
 #endif
+      }
    }
 
    return GL_TRUE;
@@ -226,44 +249,69 @@ TAG(texsubimage2d_pack)( struct gl_texture_convert *convert )
 /* PRE: as above, height == dstImageHeight also.
  */
 static GLboolean
-TAG(texsubimage3d_pack)( struct gl_texture_convert *convert )
+TAG(texsubimage3d_unpack)( struct gl_texture_convert *convert )
 {
    const GLubyte *src = (const GLubyte *)
-      _mesa_image_address( convert->packing, convert->srcImage,
+      _mesa_image_address( convert->unpacking, convert->srcImage,
                           convert->width, convert->height,
                           convert->format, convert->type, 0, 0, 0 );
+   const GLint srcImgStride = (const GLubyte *)
+      _mesa_image_address( convert->unpacking, convert->srcImage,
+                          convert->width, convert->height,
+                          convert->format, convert->type, 1, 0, 0 ) - src;
    const GLint srcRowStride =
-      _mesa_image_row_stride( convert->packing, convert->width,
+      _mesa_image_row_stride( convert->unpacking, convert->width,
                              convert->format, convert->type );
-   GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
-                           ((convert->zoffset * convert->height +
-                             convert->yoffset) * convert->width +
-                            convert->xoffset) * DST_TEXEL_BYTES);
-   GLint width;
    GLint row, col, img;
-   (void) col;
 
 #if DEBUG_TEXUTIL
    fprintf( stderr, __FUNCTION__ "\n" );
 #endif
 
-   width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
-           & ~(DST_TEXELS_PER_DWORD - 1));
-
-   for ( img = 0 ; img < convert->depth ; img++ ) {
-      for ( row = 0 ; row < convert->height ; row++ ) {
+   if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
+      /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
+       * or width = 2 and texels/dword = 4).
+       */
+      DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+                                   ((convert->zoffset * convert->height +
+                                     convert->yoffset) * convert->width +
+                                    convert->xoffset) * DST_TEXEL_BYTES);
+      for ( img = 0 ; img < convert->depth ; img++ ) {
+         const GLubyte *srcImage = src;
+         for ( row = 0 ; row < convert->height ; row++ ) {
+            const GLubyte *srcRow = src;
+            for ( col = 0; col < convert->width; col++ ) {
+               CONVERT_TEXEL(*dst, src);
+               src += SRC_TEXEL_BYTES;
+            }
+            src = srcRow + srcRowStride;
+         }
+         src = srcImage + srcImgStride;
+      }
+   }
+   else {
+      /* the common case */
+      GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+                               ((convert->zoffset * convert->height +
+                                 convert->yoffset) * convert->width +
+                                convert->xoffset) * DST_TEXEL_BYTES);
+      for ( img = 0 ; img < convert->depth ; img++ ) {
+         const GLubyte *srcImage = src;
+         for ( row = 0 ; row < convert->height ; row++ ) {
 #ifdef CONVERT_DIRECT
-        MEMCPY( dst, src, DST_ROW_STRIDE );
-        src += srcRowStride;
-        dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
+            MEMCPY( dst, src, DST_ROW_STRIDE );
+            src += srcRowStride;
+            dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
 #else
-        const GLubyte *srcRow = src;
-        for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
-           CONVERT_TEXEL_DWORD( *dst++, src );
-           src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
-        }
-        src = srcRow + srcRowStride;
+            const GLubyte *srcRow = src;
+            for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
+               CONVERT_TEXEL_DWORD( *dst++, src );
+               src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+            }
+            src = srcRow + srcRowStride;
 #endif
+         }
+         src = srcImage + srcImgStride;
       }
    }
 
@@ -276,14 +324,14 @@ TAG(texsubimage3d_pack)( struct gl_texture_convert *convert )
  * PRE: Require pixelstore attribs, width != dstImageWidth.
  */
 static GLboolean
-TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
+TAG(texsubimage2d_stride_unpack)( struct gl_texture_convert *convert )
 {
    const GLubyte *src = (const GLubyte *)
-      _mesa_image_address( convert->packing, convert->srcImage,
+      _mesa_image_address( convert->unpacking, convert->srcImage,
                           convert->width, convert->height,
                           convert->format, convert->type, 0, 0, 0 );
    const GLint srcRowStride =
-      _mesa_image_row_stride( convert->packing, convert->width,
+      _mesa_image_row_stride( convert->unpacking, convert->width,
                              convert->format, convert->type );
    DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
                                (convert->yoffset * convert->dstImageWidth +
@@ -304,7 +352,7 @@ TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
 
    for ( row = 0 ; row < convert->height ; row++ ) {
 #ifdef CONVERT_DIRECT
-      MEMCPY( dst, src, DST_ROW_WIDTH );
+      MEMCPY( dst, src, DST_ROW_BYTES );
       src += srcRowStride;
       dst += convert->dstImageWidth;
 #else
@@ -324,14 +372,18 @@ TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
 /* PRE: As above, or height != dstImageHeight also.
  */
 static GLboolean
-TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
+TAG(texsubimage3d_stride_unpack)( struct gl_texture_convert *convert )
 {
    const GLubyte *src = (const GLubyte *)
-      _mesa_image_address( convert->packing, convert->srcImage,
+      _mesa_image_address( convert->unpacking, convert->srcImage,
                           convert->width, convert->height,
                           convert->format, convert->type, 0, 0, 0 );
+   const GLint srcImgStride = (const GLubyte *)
+      _mesa_image_address( convert->unpacking, convert->srcImage,
+                          convert->width, convert->height,
+                          convert->format, convert->type, 1, 0, 0 ) - src;
    const GLint srcRowStride =
-      _mesa_image_row_stride( convert->packing, convert->width,
+      _mesa_image_row_stride( convert->unpacking, convert->width,
                              convert->format, convert->type );
    DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
                                ((convert->zoffset * convert->dstImageHeight +
@@ -352,9 +404,10 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
 #endif
 
    for ( img = 0 ; img < convert->depth ; img++ ) {
+      const GLubyte *srcImage = src;
       for ( row = 0 ; row < convert->height ; row++ ) {
 #ifdef CONVERT_DIRECT
-        MEMCPY( dst, src, DST_ROW_WIDTH );
+        MEMCPY( dst, src, DST_ROW_BYTES );
         src += srcRowStride;
         dst += convert->dstImageWidth;
 #else
@@ -367,7 +420,7 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
         dst += adjust;
 #endif
       }
-      /* FIXME: ... */
+      src = srcImage + srcImgStride;
    }
 
    return GL_TRUE;
@@ -378,15 +431,15 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
 static convert_func TAG(texsubimage2d_tab)[] = {
    TAG(texsubimage2d),
    TAG(texsubimage2d_stride),
-   TAG(texsubimage2d_pack),
-   TAG(texsubimage2d_stride_pack),
+   TAG(texsubimage2d_unpack),
+   TAG(texsubimage2d_stride_unpack),
 };
 
 static convert_func TAG(texsubimage3d_tab)[] = {
    TAG(texsubimage3d),
    TAG(texsubimage3d_stride),
-   TAG(texsubimage3d_pack),
-   TAG(texsubimage3d_stride_pack),
+   TAG(texsubimage3d_unpack),
+   TAG(texsubimage3d_stride_unpack),
 };
 
 
@@ -397,7 +450,7 @@ static convert_func TAG(texsubimage3d_tab)[] = {
 
 #undef SRC_TEXEL_BYTES
 #undef DST_TEXEL_BYTES
-#undef DST_ROW_WIDTH
+#undef DST_ROW_BYTES
 #undef DST_ROW_STRIDE
 
 #undef CONVERT_TEXEL