Bug 1551084 - Part 5. Allow QCMS gray transforms to expand to add alpha. r=miko
☠☠ backed out by 1e50992f4133 ☠ ☠
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 10 May 2019 08:11:27 -0400
changeset 475784 af04f8907fab2f091180fe0c762dc54fd9091c5c
parent 475783 2a5ae3eb40ce2eb31f3708a8c82690fa8858ce14
child 475785 1e50992f413317d69190830a556daea79d98fed3
push id86473
push userrgurzau@mozilla.com
push dateMon, 27 May 2019 21:57:53 +0000
treeherderautoland@92582acb077d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiko
bugs1551084
milestone69.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 1551084 - Part 5. Allow QCMS gray transforms to expand to add alpha. r=miko Differential Revision: https://phabricator.services.mozilla.com/D30822
gfx/qcms/transform.cpp
--- a/gfx/qcms/transform.cpp
+++ b/gfx/qcms/transform.cpp
@@ -355,93 +355,115 @@ static void qcms_transform_data_rgb_out_
 #endif
 
 /* 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
 */
 
-template <size_t kRIndex, size_t kGIndex, size_t kBIndex, size_t kAIndex = NO_A_INDEX>
+template <size_t kRIndex, size_t kGIndex, size_t kBIndex,
+          size_t kInAIndex = NO_A_INDEX, size_t kOutAIndex = kInAIndex>
 static void qcms_transform_data_gray_template_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
-	const unsigned int components = A_INDEX_COMPONENTS(kAIndex);
+	const unsigned int components = A_INDEX_COMPONENTS(kOutAIndex);
 	unsigned int i;
 	for (i = 0; i < length; i++) {
 		float out_device_r, out_device_g, out_device_b;
 		unsigned char device = *src++;
-		unsigned char alpha;
-		if (kAIndex != NO_A_INDEX) {
+		unsigned char alpha = 0xFF;
+		if (kInAIndex != NO_A_INDEX) {
 			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[kRIndex] = clamp_u8(out_device_r*255);
 		dest[kGIndex] = clamp_u8(out_device_g*255);
 		dest[kBIndex] = clamp_u8(out_device_b*255);
-		if (kAIndex != NO_A_INDEX) {
-			dest[kAIndex] = alpha;
+		if (kOutAIndex != NO_A_INDEX) {
+			dest[kOutAIndex] = alpha;
 		}
 		dest += components;
 	}
 }
 
 static void qcms_transform_data_gray_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
 	qcms_transform_data_gray_template_lut<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX>(transform, src, dest, length);
 }
 
+static void qcms_transform_data_gray_rgba_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
+{
+	qcms_transform_data_gray_template_lut<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, NO_A_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
+}
+
+static void qcms_transform_data_gray_bgra_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
+{
+	qcms_transform_data_gray_template_lut<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, NO_A_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
+}
+
 static void qcms_transform_data_graya_rgba_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
 	qcms_transform_data_gray_template_lut<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
 }
 
 static void qcms_transform_data_graya_bgra_out_lut(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
 	qcms_transform_data_gray_template_lut<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
 }
 
-template <size_t kRIndex, size_t kGIndex, size_t kBIndex, size_t kAIndex = NO_A_INDEX>
+template <size_t kRIndex, size_t kGIndex, size_t kBIndex,
+          size_t kInAIndex = NO_A_INDEX, size_t kOutAIndex = kInAIndex>
 static void qcms_transform_data_gray_template_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
-	const unsigned int components = A_INDEX_COMPONENTS(kAIndex);
+	const unsigned int components = A_INDEX_COMPONENTS(kOutAIndex);
 	unsigned int i;
 	for (i = 0; i < length; i++) {
 		unsigned char device = *src++;
-		unsigned char alpha;
-		if (kAIndex != NO_A_INDEX) {
+		unsigned char alpha = 0xFF;
+		if (kInAIndex != NO_A_INDEX) {
 		       alpha = *src++;
 		}
 		uint16_t gray;
 
 		float linear = transform->input_gamma_table_gray[device];
 
 		/* we could round here... */
 		gray = linear * PRECACHE_OUTPUT_MAX;
 
 		dest[kRIndex] = transform->output_table_r->data[gray];
 		dest[kGIndex] = transform->output_table_g->data[gray];
 		dest[kBIndex] = transform->output_table_b->data[gray];
-		if (kAIndex != NO_A_INDEX) {
-			dest[kAIndex] = alpha;
+		if (kOutAIndex != NO_A_INDEX) {
+			dest[kOutAIndex] = alpha;
 		}
 		dest += components;
 	}
 }
 
 static void qcms_transform_data_gray_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
 	qcms_transform_data_gray_template_precache<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX>(transform, src, dest, length);
 }
 
+static void qcms_transform_data_gray_rgba_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
+{
+	qcms_transform_data_gray_template_precache<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, NO_A_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
+}
+
+static void qcms_transform_data_gray_bgra_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
+{
+	qcms_transform_data_gray_template_precache<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, NO_A_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
+}
+
 static void qcms_transform_data_graya_rgba_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
 	qcms_transform_data_gray_template_precache<RGBA_R_INDEX, RGBA_G_INDEX, RGBA_B_INDEX, RGBA_A_INDEX>(transform, src, dest, length);
 }
 
 static void qcms_transform_data_graya_bgra_out_precache(const qcms_transform *transform, const unsigned char *src, unsigned char *dest, size_t length)
 {
 	qcms_transform_data_gray_template_precache<BGRA_R_INDEX, BGRA_G_INDEX, BGRA_B_INDEX, BGRA_A_INDEX>(transform, src, dest, length);
@@ -1112,17 +1134,17 @@ qcms_transform* qcms_transform_create(
 	bool match = false;
 	if (in_type == QCMS_DATA_RGB_8) {
 		match = out_type == QCMS_DATA_RGB_8;
 	} else if (in_type == QCMS_DATA_RGBA_8) {
 		match = out_type == QCMS_DATA_RGBA_8;
 	} else if (in_type == QCMS_DATA_BGRA_8) {
 		match = out_type == QCMS_DATA_BGRA_8;
 	} else if (in_type == QCMS_DATA_GRAY_8) {
-		match = out_type == QCMS_DATA_RGB_8;
+		match = out_type == QCMS_DATA_RGB_8 || out_type == QCMS_DATA_RGBA_8 || out_type == QCMS_DATA_BGRA_8;
 	} else if (in_type == QCMS_DATA_GRAYA_8) {
 		match = out_type == QCMS_DATA_RGBA_8 || out_type == QCMS_DATA_BGRA_8;
 	}
 	if (!match) {
 		assert(0 && "input/output type");
 		return NULL;
 	}
 
@@ -1278,30 +1300,46 @@ qcms_transform* qcms_transform_create(
 	} else if (in->color_space == GRAY_SIGNATURE) {
 		transform->input_gamma_table_gray = build_input_gamma_table(in->grayTRC);
 		if (!transform->input_gamma_table_gray) {
 			qcms_transform_release(transform);
 			return NO_MEM_TRANSFORM;
 		}
 
 		if (precache) {
-			if (in_type == QCMS_DATA_GRAY_8) {
+			if (out_type == QCMS_DATA_RGB_8) {
 				transform->transform_fn = qcms_transform_data_gray_out_precache;
 			} else if (out_type == QCMS_DATA_RGBA_8) {
-				transform->transform_fn = qcms_transform_data_graya_rgba_out_precache;
+				if (in_type == QCMS_DATA_GRAY_8) {
+					transform->transform_fn = qcms_transform_data_gray_rgba_out_precache;
+				} else {
+					transform->transform_fn = qcms_transform_data_graya_rgba_out_precache;
+				}
 			} else if (out_type == QCMS_DATA_BGRA_8) {
-				transform->transform_fn = qcms_transform_data_graya_bgra_out_precache;
+				if (in_type == QCMS_DATA_GRAY_8) {
+					transform->transform_fn = qcms_transform_data_gray_bgra_out_precache;
+				} else {
+					transform->transform_fn = qcms_transform_data_graya_bgra_out_precache;
+				}
 			}
 		} else {
-			if (in_type == QCMS_DATA_GRAY_8) {
+			if (out_type == QCMS_DATA_RGB_8) {
 				transform->transform_fn = qcms_transform_data_gray_out_lut;
 			} else if (out_type == QCMS_DATA_RGBA_8) {
-				transform->transform_fn = qcms_transform_data_graya_rgba_out_lut;
+				if (in_type == QCMS_DATA_GRAY_8) {
+					transform->transform_fn = qcms_transform_data_gray_rgba_out_lut;
+				} else {
+					transform->transform_fn = qcms_transform_data_graya_rgba_out_lut;
+				}
 			} else if (out_type == QCMS_DATA_BGRA_8) {
-				transform->transform_fn = qcms_transform_data_graya_bgra_out_lut;
+				if (in_type == QCMS_DATA_GRAY_8) {
+					transform->transform_fn = qcms_transform_data_gray_bgra_out_lut;
+				} else {
+					transform->transform_fn = qcms_transform_data_graya_bgra_out_lut;
+				}
 			}
 		}
 	} else {
 		assert(0 && "unexpected colorspace");
 		qcms_transform_release(transform);
 		return NULL;
 	}
 	assert(transform->transform_fn);