consolidate image transfer operations in new _mesa_apply_rgba_transfer_ops() function
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 28 Feb 2004 21:10:19 +0000 (21:10 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 28 Feb 2004 21:10:19 +0000 (21:10 +0000)
src/mesa/main/image.c
src/mesa/main/image.h
src/mesa/main/mtypes.h
src/mesa/swrast/s_copypix.c

index 23adb693b5a4c746b67f7e085f665e6892a6bcb8..7defce8813bee28802cf821eace01f6a495f50cd 100644 (file)
@@ -911,6 +911,83 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
 }
 
 
+/**
+ * Apply various pixel transfer operations to an array of RGBA pixels
+ * as indicated by the transferOps bitmask
+ */
+void
+_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,
+                              GLuint n, GLfloat rgba[][4])
+{
+   /* scale & bias */
+   if (transferOps & IMAGE_SCALE_BIAS_BIT) {
+      _mesa_scale_and_bias_rgba(ctx, n, rgba,
+                                ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
+                                ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
+                                ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
+                                ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
+   }
+   /* color map lookup */
+   if (transferOps & IMAGE_MAP_COLOR_BIT) {
+      _mesa_map_rgba( ctx, n, rgba );
+   }
+   /* GL_COLOR_TABLE lookup */
+   if (transferOps & IMAGE_COLOR_TABLE_BIT) {
+      _mesa_lookup_rgba_float(&ctx->ColorTable, n, rgba);
+   }
+   /* convolution */
+   if (transferOps & IMAGE_CONVOLUTION_BIT) {
+      /* this has to be done in the calling code */
+      _mesa_problem(ctx, "IMAGE_CONVOLUTION_BIT set in _mesa_apply_transfer_ops");
+   }
+   /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
+   if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
+      _mesa_scale_and_bias_rgba(ctx, n, rgba,
+                                ctx->Pixel.PostConvolutionScale[RCOMP],
+                                ctx->Pixel.PostConvolutionScale[GCOMP],
+                                ctx->Pixel.PostConvolutionScale[BCOMP],
+                                ctx->Pixel.PostConvolutionScale[ACOMP],
+                                ctx->Pixel.PostConvolutionBias[RCOMP],
+                                ctx->Pixel.PostConvolutionBias[GCOMP],
+                                ctx->Pixel.PostConvolutionBias[BCOMP],
+                                ctx->Pixel.PostConvolutionBias[ACOMP]);
+   }
+   /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
+   if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
+      _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, n, rgba);
+   }
+   /* color matrix transform */
+   if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
+      _mesa_transform_rgba(ctx, n, rgba);
+   }
+   /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
+   if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
+      _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, n, rgba);
+   }
+   /* update histogram count */
+   if (transferOps & IMAGE_HISTOGRAM_BIT) {
+      _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
+   }
+   /* update min/max values */
+   if (transferOps & IMAGE_MIN_MAX_BIT) {
+      _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
+   }
+
+#if CHAN_TYPE != GL_FLOAT
+   if (transferOps & IMAGE_CLAMP_BIT) {
+      GLuint i;
+      for (i = 0; i < n; i++) {
+         rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
+         rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
+         rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
+         rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
+      }
+   }
+#endif
+}
+
+
+
 /*
  * Used to pack an array [][4] of RGBA GLchan colors as specified
  * by the dstFormat, dstType and dstPacking.  Used by glReadPixels,
@@ -934,70 +1011,15 @@ _mesa_pack_rgba_span_float( GLcontext *ctx,
       DEFMARRAY(GLfloat, rgbaCopy, MAX_WIDTH, 4);  /* mac 32k limitation */
       CHECKARRAY(rgbaCopy, return);  /* mac 32k limitation */
 
-      for (i = 0; i < n; i++) {
-         rgbaCopy[i][0] = rgbaIn[i][0];
-         rgbaCopy[i][1] = rgbaIn[i][1];
-         rgbaCopy[i][2] = rgbaIn[i][2];
-         rgbaCopy[i][3] = rgbaIn[i][3];
-      }
+      _mesa_memcpy(rgbaCopy, rgbaIn, n * 4 * sizeof(GLfloat));
 
       rgba = (GLfloat (*)[4]) rgbaCopy;
 
-      /* scale & bias */
-      if (transferOps & IMAGE_SCALE_BIAS_BIT) {
-         _mesa_scale_and_bias_rgba(ctx, n, rgba,
-                                   ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
-                                   ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
-                                   ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
-                                   ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
-      }
-      /* color map lookup */
-      if (transferOps & IMAGE_MAP_COLOR_BIT) {
-         _mesa_map_rgba( ctx, n, rgba );
-      }
-      /* GL_COLOR_TABLE lookup */
-      if (transferOps & IMAGE_COLOR_TABLE_BIT) {
-         _mesa_lookup_rgba_float(&ctx->ColorTable, n, rgba);
-      }
-      /* convolution */
-      if (transferOps & IMAGE_CONVOLUTION_BIT) {
-         /* this has to be done in the calling code */
-      }
-      /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
-      if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
-         _mesa_scale_and_bias_rgba(ctx, n, rgba,
-                                   ctx->Pixel.PostConvolutionScale[RCOMP],
-                                   ctx->Pixel.PostConvolutionScale[GCOMP],
-                                   ctx->Pixel.PostConvolutionScale[BCOMP],
-                                   ctx->Pixel.PostConvolutionScale[ACOMP],
-                                   ctx->Pixel.PostConvolutionBias[RCOMP],
-                                   ctx->Pixel.PostConvolutionBias[GCOMP],
-                                   ctx->Pixel.PostConvolutionBias[BCOMP],
-                                   ctx->Pixel.PostConvolutionBias[ACOMP]);
-      }
-      /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
-      if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
-         _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, n, rgba);
-      }
-      /* color matrix transform */
-      if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
-         _mesa_transform_rgba(ctx, n, rgba);
-      }
-      /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
-      if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
-         _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, n, rgba);
-      }
-      /* update histogram count */
-      if (transferOps & IMAGE_HISTOGRAM_BIT) {
-         _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
-      }
-      /* min/max here */
-      if (transferOps & IMAGE_MIN_MAX_BIT) {
-         _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
-         if (ctx->MinMax.Sink) {
-            UNDEFARRAY(rgbaCopy);  /* mac 32k limitation */
-            return;
-         }
+      _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
+
+      if ((transferOps & IMAGE_MIN_MAX_BIT) && ctx->MinMax.Sink) {
+         UNDEFARRAY(rgbaCopy);  /* mac 32k limitation */
+         return;
       }
       UNDEFARRAY(rgbaCopy);  /* mac 32k limitation */
    }
@@ -1008,7 +1030,6 @@ _mesa_pack_rgba_span_float( GLcontext *ctx,
 
    /* XXX clamp rgba to [0,1]? */
 
-
    if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
       for (i = 0; i < n; i++) {
          GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
@@ -1919,11 +1940,11 @@ _mesa_pack_rgba_span_float( GLcontext *ctx,
  */
 void
 _mesa_pack_rgba_span_chan( GLcontext *ctx,
-                      GLuint n, CONST GLchan srcRgba[][4],
-                      GLenum dstFormat, GLenum dstType,
-                      GLvoid *dstAddr,
-                      const struct gl_pixelstore_attrib *dstPacking,
-                      GLuint transferOps)
+                           GLuint n, CONST GLchan srcRgba[][4],
+                           GLenum dstFormat, GLenum dstType,
+                           GLvoid *dstAddr,
+                           const struct gl_pixelstore_attrib *dstPacking,
+                           GLuint transferOps)
 {
    ASSERT((ctx->NewState & _NEW_PIXEL) == 0 || transferOps == 0);
 
@@ -2910,81 +2931,26 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
             /* Convert indexes to RGBA */
             _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
          }
+
+         /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
+          * with color indexes.
+          */
+         transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
       }
       else {
+         /* non-color index data */
          extract_float_rgba(n, rgba, srcFormat, srcType, source,
                             srcPacking->SwapBytes);
-
-         /* scale and bias colors */
-         if (transferOps & IMAGE_SCALE_BIAS_BIT) {
-            _mesa_scale_and_bias_rgba(ctx, n, rgba,
-                                   ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
-                                   ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
-                                   ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
-                                   ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
-         }
-         /* color map lookup */
-         if (transferOps & IMAGE_MAP_COLOR_BIT) {
-            _mesa_map_rgba(ctx, n, rgba);
-         }
       }
 
-      if (transferOps) {
-         /* GL_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->ColorTable, n, rgba);
-         }
-         /* convolution */
-         if (transferOps & IMAGE_CONVOLUTION_BIT) {
-            /* this has to be done in the calling code */
-         }
-         /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
-         if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
-            _mesa_scale_and_bias_rgba(ctx, n, rgba,
-                                      ctx->Pixel.PostConvolutionScale[RCOMP],
-                                      ctx->Pixel.PostConvolutionScale[GCOMP],
-                                      ctx->Pixel.PostConvolutionScale[BCOMP],
-                                      ctx->Pixel.PostConvolutionScale[ACOMP],
-                                      ctx->Pixel.PostConvolutionBias[RCOMP],
-                                      ctx->Pixel.PostConvolutionBias[GCOMP],
-                                      ctx->Pixel.PostConvolutionBias[BCOMP],
-                                      ctx->Pixel.PostConvolutionBias[ACOMP]);
-         }
-         /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, n, rgba);
-         }
-         /* color matrix transform */
-         if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
-            _mesa_transform_rgba(ctx, n, rgba);
-         }
-         /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, n, rgba);
-         }
-         /* update histogram count */
-         if (transferOps & IMAGE_HISTOGRAM_BIT) {
-            _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
-         }
-         /* min/max here */
-         if (transferOps & IMAGE_MIN_MAX_BIT) {
-            _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
-         }
-      }
-
-      /* clamp to [0,1] */
 #if CHAN_TYPE != GL_FLOAT
-      {
-         GLuint i;
-         for (i = 0; i < n; i++) {
-            rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
-            rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
-            rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
-            rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
-         }
-      }
+      transferOps |= IMAGE_CLAMP_BIT;
 #endif
 
+      if (transferOps) {
+         _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
+      }
+
       /* Now determine which color channels we need to produce.
        * And determine the dest index (offset) within each color tuple.
        */
@@ -3188,81 +3154,26 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
             /* Convert indexes to RGBA */
             _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
          }
+
+         /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
+          * with color indexes.
+          */
+         transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
       }
       else {
+         /* non-color index data */
          extract_float_rgba(n, rgba, srcFormat, srcType, source,
                             srcPacking->SwapBytes);
-
-         /* scale and bias colors */
-         if (transferOps & IMAGE_SCALE_BIAS_BIT) {
-            _mesa_scale_and_bias_rgba(ctx, n, rgba,
-                                   ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
-                                   ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
-                                   ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
-                                   ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
-         }
-         /* color map lookup */
-         if (transferOps & IMAGE_MAP_COLOR_BIT) {
-            _mesa_map_rgba(ctx, n, rgba);
-         }
-      }
-
-      if (transferOps) {
-         /* GL_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->ColorTable, n, rgba);
-         }
-         /* convolution */
-         if (transferOps & IMAGE_CONVOLUTION_BIT) {
-            /* XXX to do */
-         }
-         /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
-         if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
-            _mesa_scale_and_bias_rgba(ctx, n, rgba,
-                                      ctx->Pixel.PostConvolutionScale[RCOMP],
-                                      ctx->Pixel.PostConvolutionScale[GCOMP],
-                                      ctx->Pixel.PostConvolutionScale[BCOMP],
-                                      ctx->Pixel.PostConvolutionScale[ACOMP],
-                                      ctx->Pixel.PostConvolutionBias[RCOMP],
-                                      ctx->Pixel.PostConvolutionBias[GCOMP],
-                                      ctx->Pixel.PostConvolutionBias[BCOMP],
-                                      ctx->Pixel.PostConvolutionBias[ACOMP]);
-         }
-         /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, n, rgba);
-         }
-         /* color matrix transform */
-         if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
-            _mesa_transform_rgba(ctx, n, rgba);
-         }
-         /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, n, rgba);
-         }
-         /* update histogram count */
-         if (transferOps & IMAGE_HISTOGRAM_BIT) {
-            _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
-         }
-         /* min/max here */
-         if (transferOps & IMAGE_MIN_MAX_BIT) {
-            _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
-         }
       }
 
-      /* clamp to [0,1] */
 #if CHAN_TYPE != GL_FLOAT
-      if (clamp) {
-         GLuint i;
-         for (i = 0; i < n; i++) {
-            rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
-            rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
-            rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
-            rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
-         }
-      }
+      transferOps |= IMAGE_CLAMP_BIT;
 #endif
 
+      if (transferOps) {
+         _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
+      }
+
       /* Now determine which color channels we need to produce.
        * And determine the dest index (offset) within each color tuple.
        */
index 81d74a48479af906b0a5c2feef2b860538387da7..cd79d5f223f37728ecf0dbba920af5a7a88151ee 100644 (file)
@@ -5,9 +5,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  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"),
@@ -96,6 +96,10 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
                    GLubyte *dest, const struct gl_pixelstore_attrib *packing );
 
 
+extern void
+_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,
+                              GLuint n, GLfloat rgba[][4]);
+
 extern void
 _mesa_pack_rgba_span_float( GLcontext *ctx,
                             GLuint n, CONST GLfloat rgba[][4],
index 18e1563102194e8ccb793b492299e7e9fe5439ed..d1cfa4597bc2d507dfd562bb3867cfc8a2ec0bb6 100644 (file)
@@ -1943,6 +1943,8 @@ struct matrix_stack
 #define IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT   0x100
 #define IMAGE_HISTOGRAM_BIT                       0x200
 #define IMAGE_MIN_MAX_BIT                         0x400
+#define IMAGE_CLAMP_BIT                           0x800 /* extra */
+
 
 /** Transfer ops up to convolution */
 #define IMAGE_PRE_CONVOLUTION_BITS (IMAGE_SCALE_BIAS_BIT |     \
index 51c2f9a6e0f38d0f4ffa8966c0c83dfd921d53d5..9176755e35345bbfab905f493ec59030687d5eee 100644 (file)
@@ -166,26 +166,12 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
       _swrast_use_draw_buffer(ctx);
    }
 
-   /* do image transfer ops up until convolution */
+   /* do the image transfer ops which preceed convolution */
    for (row = 0; row < height; row++) {
       GLfloat (*rgba)[4] = (GLfloat (*)[4]) (tmpImage + row * width * 4);
-
-      /* scale & bias */
-      if (transferOps & IMAGE_SCALE_BIAS_BIT) {
-         _mesa_scale_and_bias_rgba(ctx, width, rgba,
-                                   ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
-                                   ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
-                                   ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
-                                   ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
-      }
-      /* color map lookup */
-      if (transferOps & IMAGE_MAP_COLOR_BIT) {
-         _mesa_map_rgba(ctx, width, rgba);
-      }
-      /* GL_COLOR_TABLE lookup */
-      if (transferOps & IMAGE_COLOR_TABLE_BIT) {
-         _mesa_lookup_rgba_float(&ctx->ColorTable, width, rgba);
-      }
+      _mesa_apply_rgba_transfer_ops(ctx,
+                                    transferOps & IMAGE_PRE_CONVOLUTION_BITS,
+                                    width, rgba);
    }
 
    /* do convolution */
@@ -198,32 +184,15 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
    }
    FREE(tmpImage);
 
-   /* do remaining image transfer ops */
+   /* do remaining post-convolution image transfer ops */
    for (row = 0; row < height; row++) {
       GLfloat (*rgba)[4] = (GLfloat (*)[4]) (convImage + row * width * 4);
-
-      /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
-      if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
-         _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, width, rgba);
-      }
-      /* color matrix */
-      if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
-         _mesa_transform_rgba(ctx, width, rgba);
-      }
-      /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
-      if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
-         _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, width, rgba);
-      }
-      /* update histogram count */
-      if (transferOps & IMAGE_HISTOGRAM_BIT) {
-         _mesa_update_histogram(ctx, width, (CONST GLfloat (*)[4]) rgba);
-      }
-      /* update min/max */
-      if (transferOps & IMAGE_MIN_MAX_BIT) {
-         _mesa_update_minmax(ctx, width, (CONST GLfloat (*)[4]) rgba);
-      }
+      _mesa_apply_rgba_transfer_ops(ctx,
+                                    transferOps & IMAGE_POST_CONVOLUTION_BITS,
+                                    width, rgba);
    }
 
+   /* write the new image */
    for (row = 0; row < height; row++) {
       const GLfloat *src = convImage + row * width * 4;
       GLint i, dy;
@@ -398,59 +367,9 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
             rgbaFloat[k][BCOMP] = (GLfloat) span.array->rgba[k][BCOMP] * scale;
             rgbaFloat[k][ACOMP] = (GLfloat) span.array->rgba[k][ACOMP] * scale;
          }
-         /* scale & bias */
-         if (transferOps & IMAGE_SCALE_BIAS_BIT) {
-            _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat,
-                                   ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
-                                   ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
-                                   ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
-                                   ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
-         }
-         /* color map lookup */
-         if (transferOps & IMAGE_MAP_COLOR_BIT) {
-            _mesa_map_rgba(ctx, width, rgbaFloat);
-         }
-         /* GL_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->ColorTable, width, rgbaFloat);
-         }
-         /* convolution */
-         if (transferOps & IMAGE_CONVOLUTION_BIT) {
-            _mesa_problem(ctx, "Convolution should not be enabled in copy_rgba_pixels()");
-            return;
-         }
-         /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
-         if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
-            _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat,
-                                      ctx->Pixel.PostConvolutionScale[RCOMP],
-                                      ctx->Pixel.PostConvolutionScale[GCOMP],
-                                      ctx->Pixel.PostConvolutionScale[BCOMP],
-                                      ctx->Pixel.PostConvolutionScale[ACOMP],
-                                      ctx->Pixel.PostConvolutionBias[RCOMP],
-                                      ctx->Pixel.PostConvolutionBias[GCOMP],
-                                      ctx->Pixel.PostConvolutionBias[BCOMP],
-                                      ctx->Pixel.PostConvolutionBias[ACOMP]);
-         }
-         /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, width, rgbaFloat);
-         }
-         /* color matrix */
-         if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
-            _mesa_transform_rgba(ctx, width, rgbaFloat);
-         }
-         /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
-         if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
-            _mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, width, rgbaFloat);
-         }
-         /* update histogram count */
-         if (transferOps & IMAGE_HISTOGRAM_BIT) {
-            _mesa_update_histogram(ctx, width, (CONST GLfloat (*)[4]) rgbaFloat);
-         }
-         /* update min/max */
-         if (transferOps & IMAGE_MIN_MAX_BIT) {
-            _mesa_update_minmax(ctx, width, (CONST GLfloat (*)[4]) rgbaFloat);
-         }
+
+         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width, rgbaFloat);
+
          /* clamp to [0,1] and convert float back to chan */
          for (k = 0; k < width; k++) {
             GLint r = (GLint) (rgbaFloat[k][RCOMP] * CHAN_MAXF);