Bug 489133 - Handle bad cHRM chunks in PNGs. r=joe
--- 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);