swrast: Mark MAX_GLUINT literal with u suffix.
[mesa.git] / src / mesa / swrast / s_zoom.c
index eb44c88b076df38ea41a8f37acefa1671d82fe67..9879e2a5f104a506f6d460b0a9907dced3fb8693 100644 (file)
@@ -1,8 +1,7 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5.2
  *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  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"),
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "glheader.h"
-#include "macros.h"
-#include "imports.h"
-#include "colormac.h"
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/format_pack.h"
 
 #include "s_context.h"
 #include "s_span.h"
  * Compute the bounds of the region resulting from zooming a pixel span.
  * The resulting region will be entirely inside the window/scissor bounds
  * so no additional clipping is needed.
- * \param imageX, imageY  position of the overall image being drawn
+ * \param imageX, imageY  position of the mage being drawn (gl WindowPos)
  * \param spanX, spanY  position of span being drawing
+ * \param width  number of pixels in span
  * \param x0, x1  returned X bounds of zoomed region [x0, x1)
  * \param y0, y1  returned Y bounds of zoomed region [y0, y1)
  * \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped
  */
 static GLboolean
-compute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY,
+compute_zoomed_bounds(struct gl_context *ctx, GLint imageX, GLint imageY,
                       GLint spanX, GLint spanY, GLint width,
                       GLint *x0, GLint *x1, GLint *y0, GLint *y1)
 {
    const struct gl_framebuffer *fb = ctx->DrawBuffer;
    GLint c0, c1, r0, r1;
 
-   ASSERT(spanX >= imageX);
-   ASSERT(spanY >= imageY);
+   assert(spanX >= imageX);
+   assert(spanY >= imageY);
 
    /*
     * Compute destination columns: [c0, c1)
@@ -98,9 +99,13 @@ compute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY,
 
 
 /**
- * Can use this for unzooming X or Y values.
+ * Convert a zoomed x image coordinate back to an unzoomed x coord.
+ * 'zx' is screen position of a pixel in the zoomed image, who's left edge
+ * is at 'imageX'.
+ * return corresponding x coord in the original, unzoomed image.
+ * This can use this for unzooming X or Y values.
  */
-static INLINE GLint
+static inline GLint
 unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
 {
    /*
@@ -108,7 +113,10 @@ unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
    zx - imageX = (x - imageX) * zoomX;
    (zx - imageX) / zoomX = x - imageX;
    */
-   GLint x = imageX + (GLint) ((zx - imageX) / zoomX);
+   GLint x;
+   if (zoomX < 0.0)
+      zx++;
+   x = imageX + (GLint) ((zx - imageX) / zoomX);
    return x;
 }
 
@@ -119,11 +127,11 @@ unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
  * index/depth_span().
  */
 static void
-zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
+zoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span,
            const GLvoid *src, GLenum format )
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan zoomed;
-   SWspanarrays zoomed_arrays;  /* this is big! */
    GLint x0, x1, y0, y1;
    GLint zoomedWidth;
 
@@ -132,36 +140,40 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
       return;  /* totally clipped */
    }
 
+   if (!swrast->ZoomedArrays) {
+      /* allocate on demand */
+      swrast->ZoomedArrays = (SWspanarrays *) calloc(1, sizeof(SWspanarrays));
+      if (!swrast->ZoomedArrays)
+         return;
+   }
+
    zoomedWidth = x1 - x0;
-   ASSERT(zoomedWidth > 0);
-   ASSERT(zoomedWidth <= MAX_WIDTH);
+   assert(zoomedWidth > 0);
+   assert(zoomedWidth <= SWRAST_MAX_WIDTH);
 
    /* no pixel arrays! must be horizontal spans. */
-   ASSERT((span->arrayMask & SPAN_XY) == 0);
-   ASSERT(span->primitive == GL_BITMAP);
+   assert((span->arrayMask & SPAN_XY) == 0);
+   assert(span->primitive == GL_BITMAP);
 
-   INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
+   INIT_SPAN(zoomed, GL_BITMAP);
    zoomed.x = x0;
    zoomed.end = zoomedWidth;
-   zoomed.array = &zoomed_arrays;
-   zoomed_arrays.ChanType = span->array->ChanType;
-   /* XXX temporary */
-#if CHAN_TYPE == GL_UNSIGNED_BYTE
-   zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz1.spec;
-#elif CHAN_TYPE == GL_UNSIGNED_SHORT
-   zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz2.spec;
-#else
-   zoomed_arrays.rgba = zoomed_arrays.color.sz4.rgba;
-   zoomed_arrays.spec = zoomed_arrays.color.sz4.spec;
-#endif
-
-
-   /* copy fog interp info */
-   zoomed.fog = span->fog;
-   zoomed.fogStep = span->fogStep;
-   /* XXX copy texcoord info? */
+   zoomed.array = swrast->ZoomedArrays;
+   zoomed.array->ChanType = span->array->ChanType;
+   if (zoomed.array->ChanType == GL_UNSIGNED_BYTE)
+      zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8;
+   else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT)
+      zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16;
+   else
+      zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[VARYING_SLOT_COL0];
+
+   COPY_4V(zoomed.attrStart[VARYING_SLOT_POS], span->attrStart[VARYING_SLOT_POS]);
+   COPY_4V(zoomed.attrStepX[VARYING_SLOT_POS], span->attrStepX[VARYING_SLOT_POS]);
+   COPY_4V(zoomed.attrStepY[VARYING_SLOT_POS], span->attrStepY[VARYING_SLOT_POS]);
+
+   zoomed.attrStart[VARYING_SLOT_FOGC][0] = span->attrStart[VARYING_SLOT_FOGC][0];
+   zoomed.attrStepX[VARYING_SLOT_FOGC][0] = span->attrStepX[VARYING_SLOT_FOGC][0];
+   zoomed.attrStepY[VARYING_SLOT_FOGC][0] = span->attrStepY[VARYING_SLOT_FOGC][0];
 
    if (format == GL_RGBA || format == GL_RGB) {
       /* copy Z info */
@@ -170,16 +182,8 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
       /* we'll generate an array of colorss */
       zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
       zoomed.arrayMask |= SPAN_RGBA;
-      ASSERT(span->arrayMask & SPAN_RGBA);
-   }
-   else if (format == GL_COLOR_INDEX) {
-      /* copy Z info */
-      zoomed.z = span->z;
-      zoomed.zStep = span->zStep;
-      /* we'll generate an array of color indexes */
-      zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
-      zoomed.arrayMask |= SPAN_INDEX;
-      ASSERT(span->arrayMask & SPAN_INDEX);
+      zoomed.arrayAttribs |= VARYING_BIT_COL0;  /* we'll produce these values */
+      assert(span->arrayMask & SPAN_RGBA);
    }
    else if (format == GL_DEPTH_COMPONENT) {
       /* Copy color info */
@@ -194,7 +198,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
       /* we'll generate an array of depth values */
       zoomed.interpMask = span->interpMask & ~SPAN_Z;
       zoomed.arrayMask |= SPAN_Z;
-      ASSERT(span->arrayMask & SPAN_Z);
+      assert(span->arrayMask & SPAN_Z);
    }
    else {
       _mesa_problem(ctx, "Bad format in zoom_span");
@@ -208,9 +212,9 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
          GLint i;
          for (i = 0; i < zoomedWidth; i++) {
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-            ASSERT(j >= 0);
-            ASSERT(j < span->end);
-            COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]);
+            assert(j >= 0);
+            assert(j < (GLint) span->end);
+            COPY_4UBV(zoomed.array->rgba8[i], rgba[j]);
          }
       }
       else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -218,9 +222,9 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
          GLint i;
          for (i = 0; i < zoomedWidth; i++) {
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-            ASSERT(j >= 0);
-            ASSERT(j < span->end);
-            COPY_4V(zoomed.array->color.sz2.rgba[i], rgba[j]);
+            assert(j >= 0);
+            assert(j < (GLint) span->end);
+            COPY_4V(zoomed.array->rgba16[i], rgba[j]);
          }
       }
       else {
@@ -228,9 +232,9 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
          GLint i;
          for (i = 0; i < zoomedWidth; i++) {
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-            ASSERT(j >= 0);
-            ASSERT(j < span->end);
-            COPY_4V(zoomed.array->color.sz4.rgba[i], rgba[j]);
+            assert(j >= 0);
+            assert(j < (GLint) span->end);
+            COPY_4V(zoomed.array->attribs[VARYING_SLOT_COL0][i], rgba[j]);
          }
       }
    }
@@ -240,12 +244,12 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
          GLint i;
          for (i = 0; i < zoomedWidth; i++) {
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-            ASSERT(j >= 0);
-            ASSERT(j < span->end);
-            zoomed.array->color.sz1.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz1.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz1.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz1.rgba[i][3] = 0xff;
+            assert(j >= 0);
+            assert(j < (GLint) span->end);
+            zoomed.array->rgba8[i][0] = rgb[j][0];
+            zoomed.array->rgba8[i][1] = rgb[j][1];
+            zoomed.array->rgba8[i][2] = rgb[j][2];
+            zoomed.array->rgba8[i][3] = 0xff;
          }
       }
       else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
@@ -253,12 +257,12 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
          GLint i;
          for (i = 0; i < zoomedWidth; i++) {
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-            ASSERT(j >= 0);
-            ASSERT(j < span->end);
-            zoomed.array->color.sz2.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz2.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz2.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz2.rgba[i][3] = 0xffff;
+            assert(j >= 0);
+            assert(j < (GLint) span->end);
+            zoomed.array->rgba16[i][0] = rgb[j][0];
+            zoomed.array->rgba16[i][1] = rgb[j][1];
+            zoomed.array->rgba16[i][2] = rgb[j][2];
+            zoomed.array->rgba16[i][3] = 0xffff;
          }
       }
       else {
@@ -266,36 +270,26 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
          GLint i;
          for (i = 0; i < zoomedWidth; i++) {
             GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-            ASSERT(j >= 0);
-            ASSERT(j < span->end);
-            zoomed.array->color.sz4.rgba[i][0] = rgb[j][0];
-            zoomed.array->color.sz4.rgba[i][1] = rgb[j][1];
-            zoomed.array->color.sz4.rgba[i][2] = rgb[j][2];
-            zoomed.array->color.sz4.rgba[i][3] = 1.0F;
+            assert(j >= 0);
+            assert(j < (GLint) span->end);
+            zoomed.array->attribs[VARYING_SLOT_COL0][i][0] = rgb[j][0];
+            zoomed.array->attribs[VARYING_SLOT_COL0][i][1] = rgb[j][1];
+            zoomed.array->attribs[VARYING_SLOT_COL0][i][2] = rgb[j][2];
+            zoomed.array->attribs[VARYING_SLOT_COL0][i][3] = 1.0F;
          }
       }
    }
-   else if (format == GL_COLOR_INDEX) {
-      const GLuint *indexes = (const GLuint *) src;
-      GLint i;
-      for (i = 0; i < zoomedWidth; i++) {
-         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-         ASSERT(j >= 0);
-         ASSERT(j < span->end);
-         zoomed.array->index[i] = indexes[j];
-      }
-   }
    else if (format == GL_DEPTH_COMPONENT) {
       const GLuint *zValues = (const GLuint *) src;
       GLint i;
       for (i = 0; i < zoomedWidth; i++) {
          GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
-         ASSERT(j >= 0);
-         ASSERT(j < span->end);
+         assert(j >= 0);
+         assert(j < (GLint) span->end);
          zoomed.array->z[i] = zValues[j];
       }
-      /* Now, fall into either the RGB or COLOR_INDEX path below */
-      format = ctx->Visual.rgbMode ? GL_RGBA : GL_COLOR_INDEX;
+      /* Now, fall into the RGB path below */
+      format = GL_RGBA;
    }
 
    /* write the span in rows [r0, r1) */
@@ -305,72 +299,52 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
        * Also, clipping may change the span end value, so store it as well.
        */
       const GLint end = zoomed.end; /* save */
-      /* use specular color array for temp storage */
-      void *rgbaSave = zoomed.array->spec;
+      void *rgbaSave;
       const GLint pixelSize =
          (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) :
          ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort)
           : 4 * sizeof(GLfloat));
-      if (y1 - y0 > 1) {
-         MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize);
-      }
-      for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
-         _swrast_write_rgba_span(ctx, &zoomed);
-         zoomed.end = end;  /* restore */
-         if (y1 - y0 > 1) {
-            /* restore the colors */
-            MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize);
-         }
+
+      rgbaSave = malloc(zoomed.end * pixelSize);
+      if (!rgbaSave) {
+         return;
       }
-   }
-   else if (format == GL_COLOR_INDEX) {
-      /* use specular color array for temp storage */
-      GLuint *indexSave = (GLuint *) zoomed.array->spec;
-      const GLint end = zoomed.end; /* save */
+
       if (y1 - y0 > 1) {
-         MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
+         memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize);
       }
       for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
-         _swrast_write_index_span(ctx, &zoomed);
+         _swrast_write_rgba_span(ctx, &zoomed);
          zoomed.end = end;  /* restore */
          if (y1 - y0 > 1) {
             /* restore the colors */
-            MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
+            memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize);
          }
       }
-   }
-}
 
-
-void
-_swrast_write_zoomed_rgba_span( GLcontext *ctx, GLint imgX, GLint imgY,
-                               const SWspan *span,
-                               CONST GLchan rgba[][4])
-{
-   zoom_span(ctx, imgX, imgY, span, (const GLvoid *) rgba, GL_RGBA);
+      free(rgbaSave);
+   }
 }
 
 
 void
-_swrast_write_zoomed_rgb_span(GLcontext *ctx, GLint imgX, GLint imgY,
-                              const SWspan *span,
-                              CONST GLchan rgb[][3])
+_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+                               const SWspan *span, const GLvoid *rgba)
 {
-   zoom_span(ctx, imgX, imgY, span, (const GLvoid *) rgb, GL_RGB);
+   zoom_span(ctx, imgX, imgY, span, rgba, GL_RGBA);
 }
 
 
 void
-_swrast_write_zoomed_index_span(GLcontext *ctx, GLint imgX, GLint imgY,
-                                const SWspan *span)
+_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+                              const SWspan *span, const GLvoid *rgb)
 {
-   zoom_span(ctx, imgX, imgY, span,
-             (const GLvoid *) span->array->index, GL_COLOR_INDEX);
+   zoom_span(ctx, imgX, imgY, span, rgb, GL_RGB);
 }
 
 
 void
-_swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY,
                                 const SWspan *span)
 {
    zoom_span(ctx, imgX, imgY, span,
@@ -383,11 +357,11 @@ _swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY,
  * No per-fragment operations are applied.
  */
 void
-_swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY,
                                   GLint width, GLint spanX, GLint spanY,
-                                  const GLstencil stencil[])
+                                  const GLubyte stencil[])
 {
-   GLstencil zoomedVals[MAX_WIDTH];
+   GLubyte *zoomedVals;
    GLint x0, x1, y0, y1, y;
    GLint i, zoomedWidth;
 
@@ -397,14 +371,18 @@ _swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,
    }
 
    zoomedWidth = x1 - x0;
-   ASSERT(zoomedWidth > 0);
-   ASSERT(zoomedWidth <= MAX_WIDTH);
+   assert(zoomedWidth > 0);
+   assert(zoomedWidth <= SWRAST_MAX_WIDTH);
+
+   zoomedVals = malloc(zoomedWidth * sizeof(GLubyte));
+   if (!zoomedVals)
+      return;
 
    /* zoom the span horizontally */
    for (i = 0; i < zoomedWidth; i++) {
       GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
-      ASSERT(j >= 0);
-      ASSERT(j < width);
+      assert(j >= 0);
+      assert(j < width);
       zoomedVals[i] = stencil[j];
    }
 
@@ -412,21 +390,23 @@ _swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,
    for (y = y0; y < y1; y++) {
       _swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals);
    }
+
+   free(zoomedVals);
 }
 
 
 /**
- * Zoom/write z values (16 or 32-bit).
+ * Zoom/write 32-bit Z values.
  * No per-fragment operations are applied.
  */
 void
-_swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY,
                             GLint width, GLint spanX, GLint spanY,
-                            const GLvoid *z)
+                            const GLuint *zVals)
 {
-   struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer;
-   GLushort zoomedVals16[MAX_WIDTH];
-   GLuint zoomedVals32[MAX_WIDTH];
+   struct gl_renderbuffer *rb =
+      ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+   GLuint *zoomedVals;
    GLint x0, x1, y0, y1, y;
    GLint i, zoomedWidth;
 
@@ -436,32 +416,26 @@ _swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY,
    }
 
    zoomedWidth = x1 - x0;
-   ASSERT(zoomedWidth > 0);
-   ASSERT(zoomedWidth <= MAX_WIDTH);
+   assert(zoomedWidth > 0);
+   assert(zoomedWidth <= SWRAST_MAX_WIDTH);
+
+   zoomedVals = malloc(zoomedWidth * sizeof(GLuint));
+   if (!zoomedVals)
+      return;
 
    /* zoom the span horizontally */
-   if (rb->DataType == GL_UNSIGNED_SHORT) {
-      for (i = 0; i < zoomedWidth; i++) {
-         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
-         ASSERT(j >= 0);
-         ASSERT(j < width);
-         zoomedVals16[i] = ((GLushort *) z)[j];
-      }
-      z = zoomedVals16;
-   }
-   else {
-      ASSERT(rb->DataType == GL_UNSIGNED_INT);
-      for (i = 0; i < zoomedWidth; i++) {
-         GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
-         ASSERT(j >= 0);
-         ASSERT(j < width);
-         zoomedVals32[i] = ((GLuint *) z)[j];
-      }
-      z = zoomedVals32;
+   for (i = 0; i < zoomedWidth; i++) {
+      GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
+      assert(j >= 0);
+      assert(j < width);
+      zoomedVals[i] = zVals[j];
    }
 
    /* write the zoomed spans */
    for (y = y0; y < y1; y++) {
-      rb->PutRow(ctx, rb, zoomedWidth, x0, y, z, NULL);
+      GLubyte *dst = _swrast_pixel_address(rb, x0, y);
+      _mesa_pack_uint_z_row(rb->Format, zoomedWidth, zoomedVals, dst);
    }
+
+   free(zoomedVals);
 }