Bug 791422. Support more flexibiltiy qcms output format. r=BenWa
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Wed, 03 Oct 2012 19:04:25 -0400
changeset 109166 bd16a5d51273ef974bd40eba689e0cd1e60a300c
parent 109165 6967936b81eeda54d974a7438f55b85103624e5f
child 109167 972c376d08b537e30f8495ee420800cb1f3fe520
push id23612
push useremorley@mozilla.com
push dateThu, 04 Oct 2012 15:19:09 +0000
treeherdermozilla-central@0d90d5f3da5a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBenWa
bugs791422
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 791422. Support more flexibiltiy qcms output format. r=BenWa This will help support Chrome and should also let us output directly to a cairo compatible format.
gfx/qcms/qcmsint.h
gfx/qcms/transform-sse1.c
gfx/qcms/transform-sse2.c
gfx/qcms/transform.c
--- a/gfx/qcms/qcmsint.h
+++ b/gfx/qcms/qcmsint.h
@@ -269,8 +269,31 @@ void qcms_transform_data_rgb_out_lut_sse
                                           unsigned char *dest,
                                           size_t length);
 void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
                                           unsigned char *src,
                                           unsigned char *dest,
                                           size_t length);
 
 extern qcms_bool qcms_supports_iccv4;
+
+#ifdef NATIVE_OUTPUT
+# define RGB_OUTPUT_COMPONENTS 4
+# define RGBA_OUTPUT_COMPONENTS 4
+# ifdef IS_LITTLE_ENDIAN
+#  define OUTPUT_INDEX_A 3
+#  define OUTPUT_INDEX_R 2
+#  define OUTPUT_INDEX_G 1
+#  define OUTPUT_INDEX_B 0
+# else
+#  define OUTPUT_INDEX_A 0
+#  define OUTPUT_INDEX_R 1
+#  define OUTPUT_INDEX_G 2
+#  define OUTPUT_INDEX_B 3
+# endif
+#else
+# define RGB_OUTPUT_COMPONENTS 3
+# define RGBA_OUTPUT_COMPONENTS 4
+# define OUTPUT_R_INDEX 0
+# define OUTPUT_G_INDEX 1
+# define OUTPUT_B_INDEX 2
+# define OUTPUT_A_INDEX 3
+#endif
--- a/gfx/qcms/transform-sse1.c
+++ b/gfx/qcms/transform-sse1.c
@@ -90,20 +90,20 @@ void qcms_transform_data_rgb_out_lut_sse
 
         /* load for next loop while store completes */
         vec_r = _mm_load_ss(&igtbl_r[src[0]]);
         vec_g = _mm_load_ss(&igtbl_g[src[1]]);
         vec_b = _mm_load_ss(&igtbl_b[src[2]]);
         src += 3;
 
         /* use calc'd indices to output RGB values */
-        dest[0] = otdata_r[output[0]];
-        dest[1] = otdata_g[output[1]];
-        dest[2] = otdata_b[output[2]];
-        dest += 3;
+        dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+        dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+        dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
+        dest += RGB_OUTPUT_COMPONENTS;
     }
 
     /* handle final (maybe only) pixel */
 
     vec_r = _mm_shuffle_ps(vec_r, vec_r, 0);
     vec_g = _mm_shuffle_ps(vec_g, vec_g, 0);
     vec_b = _mm_shuffle_ps(vec_b, vec_b, 0);
 
@@ -115,19 +115,19 @@ void qcms_transform_data_rgb_out_lut_sse
     vec_r  = _mm_max_ps(min, vec_r);
     vec_r  = _mm_min_ps(max, vec_r);
     result = _mm_mul_ps(vec_r, scale);
 
     *((__m64 *)&output[0]) = _mm_cvtps_pi32(result);
     result = _mm_movehl_ps(result, result);
     *((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
 
-    dest[0] = otdata_r[output[0]];
-    dest[1] = otdata_g[output[1]];
-    dest[2] = otdata_b[output[2]];
+    dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+    dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+    dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
 
     _mm_empty();
 }
 
 void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
                                            unsigned char *src,
                                            unsigned char *dest,
                                            size_t length)
@@ -192,17 +192,17 @@ void qcms_transform_data_rgba_out_lut_ss
         vec_b = _mm_shuffle_ps(vec_b, vec_b, 0);
 
         /* gamma * matrix */
         vec_r = _mm_mul_ps(vec_r, mat0);
         vec_g = _mm_mul_ps(vec_g, mat1);
         vec_b = _mm_mul_ps(vec_b, mat2);
 
         /* store alpha for this pixel; load alpha for next */
-        dest[3] = alpha;
+        dest[OUTPUT_A_INDEX] = alpha;
         alpha   = src[3];
 
         /* crunch, crunch, crunch */
         vec_r  = _mm_add_ps(vec_r, _mm_add_ps(vec_g, vec_b));
         vec_r  = _mm_max_ps(min, vec_r);
         vec_r  = _mm_min_ps(max, vec_r);
         result = _mm_mul_ps(vec_r, scale);
 
@@ -213,41 +213,41 @@ void qcms_transform_data_rgba_out_lut_ss
 
         /* load gamma values for next loop while store completes */
         vec_r = _mm_load_ss(&igtbl_r[src[0]]);
         vec_g = _mm_load_ss(&igtbl_g[src[1]]);
         vec_b = _mm_load_ss(&igtbl_b[src[2]]);
         src += 4;
 
         /* use calc'd indices to output RGB values */
-        dest[0] = otdata_r[output[0]];
-        dest[1] = otdata_g[output[1]];
-        dest[2] = otdata_b[output[2]];
+        dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+        dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+        dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
         dest += 4;
     }
 
     /* handle final (maybe only) pixel */
 
     vec_r = _mm_shuffle_ps(vec_r, vec_r, 0);
     vec_g = _mm_shuffle_ps(vec_g, vec_g, 0);
     vec_b = _mm_shuffle_ps(vec_b, vec_b, 0);
 
     vec_r = _mm_mul_ps(vec_r, mat0);
     vec_g = _mm_mul_ps(vec_g, mat1);
     vec_b = _mm_mul_ps(vec_b, mat2);
 
-    dest[3] = alpha;
+    dest[OUTPUT_A_INDEX] = alpha;
 
     vec_r  = _mm_add_ps(vec_r, _mm_add_ps(vec_g, vec_b));
     vec_r  = _mm_max_ps(min, vec_r);
     vec_r  = _mm_min_ps(max, vec_r);
     result = _mm_mul_ps(vec_r, scale);
 
     *((__m64 *)&output[0]) = _mm_cvtps_pi32(result);
     result = _mm_movehl_ps(result, result);
     *((__m64 *)&output[2]) = _mm_cvtps_pi32(result);
 
-    dest[0] = otdata_r[output[0]];
-    dest[1] = otdata_g[output[1]];
-    dest[2] = otdata_b[output[2]];
+    dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+    dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+    dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
 
     _mm_empty();
 }
--- a/gfx/qcms/transform-sse2.c
+++ b/gfx/qcms/transform-sse2.c
@@ -88,20 +88,20 @@ void qcms_transform_data_rgb_out_lut_sse
 
         /* load for next loop while store completes */
         vec_r = _mm_load_ss(&igtbl_r[src[0]]);
         vec_g = _mm_load_ss(&igtbl_g[src[1]]);
         vec_b = _mm_load_ss(&igtbl_b[src[2]]);
         src += 3;
 
         /* use calc'd indices to output RGB values */
-        dest[0] = otdata_r[output[0]];
-        dest[1] = otdata_g[output[1]];
-        dest[2] = otdata_b[output[2]];
-        dest += 3;
+        dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+        dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+        dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
+        dest += RGB_OUTPUT_COMPONENTS;
     }
 
     /* handle final (maybe only) pixel */
 
     vec_r = _mm_shuffle_ps(vec_r, vec_r, 0);
     vec_g = _mm_shuffle_ps(vec_g, vec_g, 0);
     vec_b = _mm_shuffle_ps(vec_b, vec_b, 0);
 
@@ -111,19 +111,19 @@ void qcms_transform_data_rgb_out_lut_sse
 
     vec_r  = _mm_add_ps(vec_r, _mm_add_ps(vec_g, vec_b));
     vec_r  = _mm_max_ps(min, vec_r);
     vec_r  = _mm_min_ps(max, vec_r);
     result = _mm_mul_ps(vec_r, scale);
 
     _mm_store_si128((__m128i*)output, _mm_cvtps_epi32(result));
 
-    dest[0] = otdata_r[output[0]];
-    dest[1] = otdata_g[output[1]];
-    dest[2] = otdata_b[output[2]];
+    dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+    dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+    dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
 }
 
 void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
                                            unsigned char *src,
                                            unsigned char *dest,
                                            size_t length)
 {
     unsigned int i;
@@ -186,17 +186,17 @@ void qcms_transform_data_rgba_out_lut_ss
         vec_b = _mm_shuffle_ps(vec_b, vec_b, 0);
 
         /* gamma * matrix */
         vec_r = _mm_mul_ps(vec_r, mat0);
         vec_g = _mm_mul_ps(vec_g, mat1);
         vec_b = _mm_mul_ps(vec_b, mat2);
 
         /* store alpha for this pixel; load alpha for next */
-        dest[3] = alpha;
+        dest[OUTPUT_A_INDEX] = alpha;
         alpha   = src[3];
 
         /* crunch, crunch, crunch */
         vec_r  = _mm_add_ps(vec_r, _mm_add_ps(vec_g, vec_b));
         vec_r  = _mm_max_ps(min, vec_r);
         vec_r  = _mm_min_ps(max, vec_r);
         result = _mm_mul_ps(vec_r, scale);
 
@@ -205,39 +205,39 @@ void qcms_transform_data_rgba_out_lut_ss
 
         /* load gamma values for next loop while store completes */
         vec_r = _mm_load_ss(&igtbl_r[src[0]]);
         vec_g = _mm_load_ss(&igtbl_g[src[1]]);
         vec_b = _mm_load_ss(&igtbl_b[src[2]]);
         src += 4;
 
         /* use calc'd indices to output RGB values */
-        dest[0] = otdata_r[output[0]];
-        dest[1] = otdata_g[output[1]];
-        dest[2] = otdata_b[output[2]];
-        dest += 4;
+        dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+        dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+        dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
+        dest += RGBA_OUTPUT_COMPONENTS;
     }
 
     /* handle final (maybe only) pixel */
 
     vec_r = _mm_shuffle_ps(vec_r, vec_r, 0);
     vec_g = _mm_shuffle_ps(vec_g, vec_g, 0);
     vec_b = _mm_shuffle_ps(vec_b, vec_b, 0);
 
     vec_r = _mm_mul_ps(vec_r, mat0);
     vec_g = _mm_mul_ps(vec_g, mat1);
     vec_b = _mm_mul_ps(vec_b, mat2);
 
-    dest[3] = alpha;
+    dest[OUTPUT_A_INDEX] = alpha;
 
     vec_r  = _mm_add_ps(vec_r, _mm_add_ps(vec_g, vec_b));
     vec_r  = _mm_max_ps(min, vec_r);
     vec_r  = _mm_min_ps(max, vec_r);
     result = _mm_mul_ps(vec_r, scale);
 
     _mm_store_si128((__m128i*)output, _mm_cvtps_epi32(result));
 
-    dest[0] = otdata_r[output[0]];
-    dest[1] = otdata_g[output[1]];
-    dest[2] = otdata_b[output[2]];
+    dest[OUTPUT_R_INDEX] = otdata_r[output[0]];
+    dest[OUTPUT_G_INDEX] = otdata_g[output[1]];
+    dest[OUTPUT_B_INDEX] = otdata_b[output[2]];
 }
 
 
--- a/gfx/qcms/transform.c
+++ b/gfx/qcms/transform.c
@@ -246,19 +246,20 @@ static void qcms_transform_data_rgb_out_
 		float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b;
 		float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b;
 		float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b;
 
 		float out_device_r = pow(out_linear_r, transform->out_gamma_r);
 		float out_device_g = pow(out_linear_g, transform->out_gamma_g);
 		float out_device_b = pow(out_linear_b, transform->out_gamma_b);
 
-		*dest++ = clamp_u8(255*out_device_r);
-		*dest++ = clamp_u8(255*out_device_g);
-		*dest++ = clamp_u8(255*out_device_b);
+		dest[OUTPUT_R_INDEX] = clamp_u8(255*out_device_r);
+		dest[OUTPUT_G_INDEX] = clamp_u8(255*out_device_g);
+		dest[OUTPUT_B_INDEX] = clamp_u8(255*out_device_b);
+		dest += RGB_OUTPUT_COMPONENTS;
 	}
 }
 #endif
 
 static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	for (i = 0; i < length; i++) {
@@ -266,19 +267,20 @@ static void qcms_transform_data_gray_out
 		unsigned char device = *src++;
 
 		float linear = transform->input_gamma_table_gray[device];
 
                 out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
 		out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
 		out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
 
-		*dest++ = clamp_u8(out_device_r*255);
-		*dest++ = clamp_u8(out_device_g*255);
-		*dest++ = clamp_u8(out_device_b*255);
+		dest[OUTPUT_R_INDEX] = clamp_u8(out_device_r*255);
+		dest[OUTPUT_G_INDEX] = clamp_u8(out_device_g*255);
+		dest[OUTPUT_B_INDEX] = clamp_u8(out_device_b*255);
+		dest += RGB_OUTPUT_COMPONENTS;
 	}
 }
 
 /* Alpha is not corrected.
    A rationale for this is found in Alvy Ray's "Should Alpha Be Nonlinear If
    RGB Is?" Tech Memo 17 (December 14, 1998).
 	See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf
 */
@@ -292,59 +294,62 @@ static void qcms_transform_data_graya_ou
 		unsigned char alpha = *src++;
 
 		float linear = transform->input_gamma_table_gray[device];
 
                 out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
 		out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
 		out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
 
-		*dest++ = clamp_u8(out_device_r*255);
-		*dest++ = clamp_u8(out_device_g*255);
-		*dest++ = clamp_u8(out_device_b*255);
-		*dest++ = alpha;
+		dest[OUTPUT_R_INDEX] = clamp_u8(out_device_r*255);
+		dest[OUTPUT_G_INDEX] = clamp_u8(out_device_g*255);
+		dest[OUTPUT_B_INDEX] = clamp_u8(out_device_b*255);
+		dest[OUTPUT_A_INDEX] = alpha;
+		dest += RGBA_OUTPUT_COMPONENTS;
 	}
 }
 
 
 static void qcms_transform_data_gray_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	for (i = 0; i < length; i++) {
 		unsigned char device = *src++;
 		uint16_t gray;
 
 		float linear = transform->input_gamma_table_gray[device];
 
 		/* we could round here... */
 		gray = linear * PRECACHE_OUTPUT_MAX;
 
-		*dest++ = transform->output_table_r->data[gray];
-		*dest++ = transform->output_table_g->data[gray];
-		*dest++ = transform->output_table_b->data[gray];
+		dest[OUTPUT_R_INDEX] = transform->output_table_r->data[gray];
+		dest[OUTPUT_G_INDEX] = transform->output_table_g->data[gray];
+		dest[OUTPUT_B_INDEX] = transform->output_table_b->data[gray];
+		dest += RGB_OUTPUT_COMPONENTS;
 	}
 }
 
 static void qcms_transform_data_graya_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	for (i = 0; i < length; i++) {
 		unsigned char device = *src++;
 		unsigned char alpha = *src++;
 		uint16_t gray;
 
 		float linear = transform->input_gamma_table_gray[device];
 
 		/* we could round here... */
 		gray = linear * PRECACHE_OUTPUT_MAX;
 
-		*dest++ = transform->output_table_r->data[gray];
-		*dest++ = transform->output_table_g->data[gray];
-		*dest++ = transform->output_table_b->data[gray];
-		*dest++ = alpha;
+		dest[OUTPUT_R_INDEX] = transform->output_table_r->data[gray];
+		dest[OUTPUT_G_INDEX] = transform->output_table_g->data[gray];
+		dest[OUTPUT_B_INDEX] = transform->output_table_b->data[gray];
+		dest[OUTPUT_A_INDEX] = alpha;
+		dest += RGBA_OUTPUT_COMPONENTS;
 	}
 }
 
 static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	float (*mat)[4] = transform->matrix;
 	for (i = 0; i < length; i++) {
@@ -365,19 +370,20 @@ static void qcms_transform_data_rgb_out_
 		out_linear_g = clamp_float(out_linear_g);
 		out_linear_b = clamp_float(out_linear_b);
 
 		/* we could round here... */
 		r = out_linear_r * PRECACHE_OUTPUT_MAX;
 		g = out_linear_g * PRECACHE_OUTPUT_MAX;
 		b = out_linear_b * PRECACHE_OUTPUT_MAX;
 
-		*dest++ = transform->output_table_r->data[r];
-		*dest++ = transform->output_table_g->data[g];
-		*dest++ = transform->output_table_b->data[b];
+		dest[OUTPUT_R_INDEX] = transform->output_table_r->data[r];
+		dest[OUTPUT_G_INDEX] = transform->output_table_g->data[g];
+		dest[OUTPUT_A_INDEX] = transform->output_table_b->data[b];
+		dest += RGB_OUTPUT_COMPONENTS;
 	}
 }
 
 static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	float (*mat)[4] = transform->matrix;
 	for (i = 0; i < length; i++) {
@@ -399,20 +405,21 @@ static void qcms_transform_data_rgba_out
 		out_linear_g = clamp_float(out_linear_g);
 		out_linear_b = clamp_float(out_linear_b);
 
 		/* we could round here... */
 		r = out_linear_r * PRECACHE_OUTPUT_MAX;
 		g = out_linear_g * PRECACHE_OUTPUT_MAX;
 		b = out_linear_b * PRECACHE_OUTPUT_MAX;
 
-		*dest++ = transform->output_table_r->data[r];
-		*dest++ = transform->output_table_g->data[g];
-		*dest++ = transform->output_table_b->data[b];
-		*dest++ = alpha;
+		dest[OUTPUT_R_INDEX] = transform->output_table_r->data[r];
+		dest[OUTPUT_G_INDEX] = transform->output_table_g->data[g];
+		dest[OUTPUT_B_INDEX] = transform->output_table_b->data[b];
+		dest[OUTPUT_A_INDEX] = alpha;
+		dest += RGBA_OUTPUT_COMPONENTS;
 	}
 }
 
 // Not used
 /* 
 static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
 	unsigned int i;
 	int xy_len = 1;
@@ -572,20 +579,21 @@ static void qcms_transform_data_tetra_cl
 				}
 			}
 		}
 				
 		clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz;
 		clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
 		clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
 
-		*dest++ = clamp_u8(clut_r*255.0f);
-		*dest++ = clamp_u8(clut_g*255.0f);
-		*dest++ = clamp_u8(clut_b*255.0f);
-		*dest++ = in_a;
+		dest[OUTPUT_R_INDEX] = clamp_u8(clut_r*255.0f);
+		dest[OUTPUT_G_INDEX] = clamp_u8(clut_g*255.0f);
+		dest[OUTPUT_B_INDEX] = clamp_u8(clut_b*255.0f);
+		dest[OUTPUT_A_INDEX] = in_a;
+		dest += RGBA_OUTPUT_COMPONENTS;
 	}	
 }
 
 // Using lcms' tetra interpolation code.
 static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) {
 	unsigned int i;
 	int xy_len = 1;
 	int x_len = transform->grid_size;
@@ -686,19 +694,20 @@ static void qcms_transform_data_tetra_cl
 				}
 			}
 		}
 				
 		clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz;
 		clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
 		clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
 
-		*dest++ = clamp_u8(clut_r*255.0f);
-		*dest++ = clamp_u8(clut_g*255.0f);
-		*dest++ = clamp_u8(clut_b*255.0f);
+		dest[OUTPUT_R_INDEX] = clamp_u8(clut_r*255.0f);
+		dest[OUTPUT_G_INDEX] = clamp_u8(clut_g*255.0f);
+		dest[OUTPUT_B_INDEX] = clamp_u8(clut_b*255.0f);
+		dest += RGB_OUTPUT_COMPONENTS;
 	}	
 }
 
 static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	float (*mat)[4] = transform->matrix;
 	for (i = 0; i < length; i++) {
@@ -721,19 +730,20 @@ static void qcms_transform_data_rgb_out_
 
 		out_device_r = lut_interp_linear(out_linear_r, 
 				transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
 		out_device_g = lut_interp_linear(out_linear_g, 
 				transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
 		out_device_b = lut_interp_linear(out_linear_b, 
 				transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
 
-		*dest++ = clamp_u8(out_device_r*255);
-		*dest++ = clamp_u8(out_device_g*255);
-		*dest++ = clamp_u8(out_device_b*255);
+		dest[OUTPUT_R_INDEX] = clamp_u8(out_device_r*255);
+		dest[OUTPUT_G_INDEX] = clamp_u8(out_device_g*255);
+		dest[OUTPUT_B_INDEX] = clamp_u8(out_device_b*255);
+		dest += RGB_OUTPUT_COMPONENTS;
 	}
 }
 
 static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	unsigned int i;
 	float (*mat)[4] = transform->matrix;
 	for (i = 0; i < length; i++) {
@@ -757,20 +767,21 @@ static void qcms_transform_data_rgba_out
 
 		out_device_r = lut_interp_linear(out_linear_r, 
 				transform->output_gamma_lut_r, transform->output_gamma_lut_r_length);
 		out_device_g = lut_interp_linear(out_linear_g, 
 				transform->output_gamma_lut_g, transform->output_gamma_lut_g_length);
 		out_device_b = lut_interp_linear(out_linear_b, 
 				transform->output_gamma_lut_b, transform->output_gamma_lut_b_length);
 
-		*dest++ = clamp_u8(out_device_r*255);
-		*dest++ = clamp_u8(out_device_g*255);
-		*dest++ = clamp_u8(out_device_b*255);
-		*dest++ = alpha;
+		dest[OUTPUT_R_INDEX] = clamp_u8(out_device_r*255);
+		dest[OUTPUT_G_INDEX] = clamp_u8(out_device_g*255);
+		dest[OUTPUT_B_INDEX] = clamp_u8(out_device_b*255);
+		dest[OUTPUT_A_INDEX] = alpha;
+		dest += RGBA_OUTPUT_COMPONENTS;
 	}
 }
 
 #if 0
 static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length)
 {
 	int i;
 	float (*mat)[4] = transform->matrix;