Bug 1463424 - Fix divide by zeroes in qcms. r=Bas
authorNicolas Silva <nsilva@mozilla.com>
Mon, 28 May 2018 11:34:03 +0200
changeset 420143 39607a36ad6b04083f56fe0a10861cd486a1d399
parent 420142 d58738b1b97dbc905b0064839dd76a591a9e50ad
child 420144 046f5a3c578243d3df738b05e3eda361d3809409
push id34065
push useraciure@mozilla.com
push dateMon, 28 May 2018 21:54:18 +0000
treeherdermozilla-central@35aa0dde259f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1463424
milestone62.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 1463424 - Fix divide by zeroes in qcms. r=Bas
gfx/qcms/matrix.c
gfx/qcms/transform.c
--- a/gfx/qcms/matrix.c
+++ b/gfx/qcms/matrix.c
@@ -59,20 +59,21 @@ struct matrix matrix_invert(struct matri
 	static int a[3] = { 2, 2, 1 };
 	static int b[3] = { 1, 0, 0 };
 
 	/* inv  (A) = 1/det (A) * adj (A) */
 	float det = matrix_det(mat);
 
 	if (det == 0) {
 		dest_mat.invalid = true;
-	} else {
-		dest_mat.invalid = false;
+		return dest_mat;
 	}
 
+	dest_mat.invalid = false;
+
 	det = 1/det;
 
 	for (j = 0; j < 3; j++) {
 		for (i = 0; i < 3; i++) {
 			double p;
 			int ai = a[i];
 			int aj = a[j];
 			int bi = b[i];
--- a/gfx/qcms/transform.c
+++ b/gfx/qcms/transform.c
@@ -163,16 +163,19 @@ static struct matrix build_RGB_to_XYZ_tr
 	primaries.m[2][2] = 1 - xb - yb;
 	primaries.invalid = false;
 
 	white_point.v[0] = xn/yn;
 	white_point.v[1] = 1.;
 	white_point.v[2] = (1.0-xn-yn)/yn;
 
 	primaries_invert = matrix_invert(primaries);
+	if (primaries_invert.invalid) {
+		return matrix_invalid();
+	}
 
 	coefs = matrix_eval(primaries_invert, white_point);
 
 	result.m[0][0] = coefs.v[0]*xr;
 	result.m[0][1] = coefs.v[1]*xg;
 	result.m[0][2] = coefs.v[2]*xb;
 
 	result.m[1][0] = coefs.v[0]*yr;
@@ -220,16 +223,19 @@ compute_chromatic_adaption(struct CIE_XY
 {
 	struct matrix chad_inv;
 	struct vector cone_source_XYZ, cone_source_rgb;
 	struct vector cone_dest_XYZ, cone_dest_rgb;
 	struct matrix cone, tmp;
 
 	tmp = chad;
 	chad_inv = matrix_invert(tmp);
+	if (chad_inv.invalid) {
+		return matrix_invalid();
+	}
 
 	cone_source_XYZ.v[0] = source_white_point.X;
 	cone_source_XYZ.v[1] = source_white_point.Y;
 	cone_source_XYZ.v[2] = source_white_point.Z;
 
 	cone_dest_XYZ.v[0] = dest_white_point.X;
 	cone_dest_XYZ.v[1] = dest_white_point.Y;
 	cone_dest_XYZ.v[2] = dest_white_point.Z;
@@ -267,22 +273,26 @@ adaption_matrix(struct CIE_XYZ source_il
 }
 
 /* from lcms: cmsAdaptMatrixToD50 */
 static struct matrix adapt_matrix_to_D50(struct matrix r, qcms_CIE_xyY source_white_pt)
 {
 	struct CIE_XYZ Dn;
 	struct matrix Bradford;
 
-	if (source_white_pt.y == 0.0)
+	if (source_white_pt.y == 0.0) {
 		return matrix_invalid();
+	}
 
 	Dn = xyY2XYZ(source_white_pt);
 
 	Bradford = adaption_matrix(Dn, D50_XYZ);
+	if (Bradford.invalid) {
+		return matrix_invalid();
+	}
 	return matrix_multiply(Bradford, r);
 }
 
 qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries)
 {
 	struct matrix colorants;
 	colorants = build_RGB_to_XYZ_transfer_matrix(white_point, primaries);
 	colorants = adapt_matrix_to_D50(colorants, white_point);