Bug 489133 - Handle bad cHRM chunks in PNGs. r=joe
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Tue, 21 Apr 2009 22:21:48 -0400
changeset 27598 2c04f555a23b5b49e58fd5a4a8e32980d82e563d
parent 27597 f517a1635447b31545e8f020be60a71b6e7a330d
child 27599 3c1e1b765d311287bc00462b5539eabfe9380423
push idunknown
push userunknown
push dateunknown
reviewersjoe
bugs489133
milestone1.9.2a1pre
Bug 489133 - Handle bad cHRM chunks in PNGs. r=joe
gfx/qcms/iccread.c
gfx/qcms/qcmsint.h
gfx/qcms/transform.c
--- a/gfx/qcms/iccread.c
+++ b/gfx/qcms/iccread.c
@@ -515,17 +515,20 @@ qcms_profile* qcms_profile_create_rgb_wi
 		qcms_CIE_xyYTRIPLE primaries,
 		float gamma)
 {
 	qcms_profile* profile = qcms_profile_create();
 	if (!profile)
 		return NO_MEM_PROFILE;
 
 	//XXX: should store the whitepoint
-	set_rgb_colorants(profile, white_point, primaries);
+	if (!set_rgb_colorants(profile, white_point, primaries)) {
+		qcms_profile_fini(profile);
+		return INVALID_PROFILE;
+	}
 
 	profile->redTRC = curve_from_gamma(gamma);
 	profile->blueTRC = curve_from_gamma(gamma);
 	profile->greenTRC = curve_from_gamma(gamma);
 
 	if (!profile->redTRC || !profile->blueTRC || !profile->greenTRC) {
 		qcms_profile_fini(profile);
 		return NO_MEM_PROFILE;
@@ -541,17 +544,20 @@ qcms_profile* qcms_profile_create_rgb_wi
 		qcms_CIE_xyYTRIPLE primaries,
 		uint16_t *table, int num_entries)
 {
 	qcms_profile* profile = qcms_profile_create();
 	if (!profile)
 		return NO_MEM_PROFILE;
 
 	//XXX: should store the whitepoint
-	set_rgb_colorants(profile, white_point, primaries);
+	if (!set_rgb_colorants(profile, white_point, primaries)) {
+		qcms_profile_fini(profile);
+		return INVALID_PROFILE;
+	}
 
 	profile->redTRC = curve_from_table(table, num_entries);
 	profile->blueTRC = curve_from_table(table, num_entries);
 	profile->greenTRC = curve_from_table(table, num_entries);
 
 	if (!profile->redTRC || !profile->blueTRC || !profile->greenTRC) {
 		qcms_profile_fini(profile);
 		return NO_MEM_PROFILE;
--- a/gfx/qcms/qcmsint.h
+++ b/gfx/qcms/qcmsint.h
@@ -134,9 +134,9 @@ static inline float s15Fixed16Number_to_
 }
 
 static inline s15Fixed16Number double_to_s15Fixed16Number(double v)
 {
 	return (int32_t)(v*65536);
 }
 
 void precache_release(struct precache_output *p);
-void set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries);
+qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries);
--- a/gfx/qcms/transform.c
+++ b/gfx/qcms/transform.c
@@ -517,34 +517,39 @@ static struct matrix adapt_matrix_to_D50
 		return matrix_invalid();
 
 	Dn = xyY2XYZ(source_white_pt);
 
 	Bradford = adaption_matrix(Dn, D50_XYZ);
 	return matrix_multiply(Bradford, r);
 }
 
-void set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries)
+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);
 
+	if (colorants.invalid)
+		return false;
+
 	/* note: there's a transpose type of operation going on here */
 	profile->redColorant.X = double_to_s15Fixed16Number(colorants.m[0][0]);
 	profile->redColorant.Y = double_to_s15Fixed16Number(colorants.m[1][0]);
 	profile->redColorant.Z = double_to_s15Fixed16Number(colorants.m[2][0]);
 
 	profile->greenColorant.X = double_to_s15Fixed16Number(colorants.m[0][1]);
 	profile->greenColorant.Y = double_to_s15Fixed16Number(colorants.m[1][1]);
 	profile->greenColorant.Z = double_to_s15Fixed16Number(colorants.m[2][1]);
 
 	profile->blueColorant.X = double_to_s15Fixed16Number(colorants.m[0][2]);
 	profile->blueColorant.Y = double_to_s15Fixed16Number(colorants.m[1][2]);
 	profile->blueColorant.Z = double_to_s15Fixed16Number(colorants.m[2][2]);
+
+	return true;
 }
 
 static uint16_t *invert_lut(uint16_t *table, int length)
 {
 	int i;
 	/* for now we invert the lut by creating a lut of the same size
 	 * and attempting to lookup a value for each entry using lut_inverse_interp16 */
 	uint16_t *output = malloc(sizeof(uint16_t)*length);