diff --git a/png.c b/png.c index c53acd1298..a1973dcc8f 100644 --- a/png.c +++ b/png.c @@ -1544,56 +1544,59 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) * Adobe Wide Gamut RGB * 0.258728243040113 0.724682314948566 0.016589442011321 */ - int error = 0; - - /* By the argument above overflow should be impossible here, however the - * code now simply returns a failure code. The xy subtracts in the arguments - * to png_muldiv are *not* checked for overflow because the checks at the - * start guarantee they are in the range 0..110000 and png_fixed_point is a - * 32-bit signed number. - */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 8) == 0) - return 1; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 8) == 0) - return 1; - denominator = png_fp_sub(left, right, &error); - if (error) return 1; + { + int error = 0; - /* Now find the red numerator. */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 8) == 0) - return 1; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 8) == 0) - return 1; + /* By the argument above overflow should be impossible here, however the + * code now simply returns a failure code. The xy subtracts in the + * arguments to png_muldiv are *not* checked for overflow because the + * checks at the start guarantee they are in the range 0..110000 and + * png_fixed_point is a 32-bit signed number. + */ + if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 8) == 0) + return 1; + if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 8) == + 0) + return 1; + denominator = png_fp_sub(left, right, &error); + if (error) return 1; - /* Overflow is possible here and it indicates an extreme set of PNG cHRM - * chunk values. This calculation actually returns the reciprocal of the - * scale value because this allows us to delay the multiplication of white-y - * into the denominator, which tends to produce a small number. - */ - if (png_muldiv(&red_inverse, xy->whitey, denominator, - png_fp_sub(left, right, &error)) == 0 || error || - red_inverse <= xy->whitey /* r+g+b scales = white scale */) - return 1; + /* Now find the red numerator. */ + if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 8) == 0) + return 1; + if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 8) == + 0) + return 1; - /* Similarly for green_inverse: */ - if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 8) == 0) - return 1; - if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 8) == 0) - return 1; - if (png_muldiv(&green_inverse, xy->whitey, denominator, - png_fp_sub(left, right, &error)) == 0 || error || - green_inverse <= xy->whitey) - return 1; + /* Overflow is possible here and it indicates an extreme set of PNG cHRM + * chunk values. This calculation actually returns the reciprocal of the + * scale value because this allows us to delay the multiplication of + * white-y into the denominator, which tends to produce a small number. + */ + if (png_muldiv(&red_inverse, xy->whitey, denominator, + png_fp_sub(left, right, &error)) == 0 || error || + red_inverse <= xy->whitey /* r+g+b scales = white scale */) + return 1; - /* And the blue scale, the checks above guarantee this can't overflow but it - * can still produce 0 for extreme cHRM values. - */ - blue_scale = png_fp_sub(png_fp_sub(png_reciprocal(xy->whitey), - png_reciprocal(red_inverse), &error), - png_reciprocal(green_inverse), &error); - if (error || blue_scale <= 0) - return 1; + /* Similarly for green_inverse: */ + if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 8) == 0) + return 1; + if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 8) == 0) + return 1; + if (png_muldiv(&green_inverse, xy->whitey, denominator, + png_fp_sub(left, right, &error)) == 0 || error || + green_inverse <= xy->whitey) + return 1; + /* And the blue scale, the checks above guarantee this can't overflow but + * it can still produce 0 for extreme cHRM values. + */ + blue_scale = png_fp_sub(png_fp_sub(png_reciprocal(xy->whitey), + png_reciprocal(red_inverse), &error), + png_reciprocal(green_inverse), &error); + if (error || blue_scale <= 0) + return 1; + } /* And fill in the png_XYZ. Again the subtracts are safe because of the * checks on the xy values at the start (the subtracts just calculate the diff --git a/png.h b/png.h index 59cf832486..e3ced9e9c5 100644 --- a/png.h +++ b/png.h @@ -2005,27 +2005,27 @@ PNG_EXPORT(251, void, png_set_cICP, (png_const_structrp png_ptr, #ifdef PNG_cLLI_SUPPORTED PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI, (png_const_structrp png_ptr, png_const_inforp info_ptr, double *maximum_content_light_level, - double *maximum_frame_average_light_level)); + double *maximum_frame_average_light_level)) PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed, (png_const_structrp png_ptr, png_const_inforp info_ptr, /* The values below are in cd/m2 (nits) and are scaled by 10,000; not * 100,000 as in the case of png_fixed_point. */ png_uint_32p maximum_content_light_level_scaled_by_10000, - png_uint_32p maximum_frame_average_light_level_scaled_by_10000)); + png_uint_32p maximum_frame_average_light_level_scaled_by_10000)) #endif #ifdef PNG_cLLI_SUPPORTED PNG_FP_EXPORT(254, void, png_set_cLLI, (png_const_structrp png_ptr, png_inforp info_ptr, double maximum_content_light_level, - double maximum_frame_average_light_level)); + double maximum_frame_average_light_level)) PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed, (png_const_structrp png_ptr, png_inforp info_ptr, /* The values below are in cd/m2 (nits) and are scaled by 10,000; not * 100,000 as in the case of png_fixed_point. */ png_uint_32 maximum_content_light_level_scaled_by_10000, - png_uint_32 maximum_frame_average_light_level_scaled_by_10000)); + png_uint_32 maximum_frame_average_light_level_scaled_by_10000)) #endif #ifdef PNG_eXIf_SUPPORTED @@ -2083,7 +2083,7 @@ PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV, (png_const_structrp png_ptr, double *green_x, double *green_y, double *blue_x, double *blue_y, /* Mastering display luminance in cd/m2 (nits). */ double *mastering_display_maximum_luminance, - double *mastering_display_minimum_luminance)); + double *mastering_display_minimum_luminance)) PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed, (png_const_structrp png_ptr, png_const_inforp info_ptr, @@ -2095,7 +2095,7 @@ PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed, * 10,000. */ png_uint_32p mastering_display_maximum_luminance_scaled_by_10000, - png_uint_32p mastering_display_minimum_luminance_scaled_by_10000)); + png_uint_32p mastering_display_minimum_luminance_scaled_by_10000)) #endif #ifdef PNG_mDCV_SUPPORTED @@ -2108,7 +2108,7 @@ PNG_FP_EXPORT(258, void, png_set_mDCV, (png_const_structrp png_ptr, double green_y, double blue_x, double blue_y, /* Mastering display luminance in cd/m2 (nits). */ double mastering_display_maximum_luminance, - double mastering_display_minimum_luminance)); + double mastering_display_minimum_luminance)) PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, (png_const_structrp png_ptr, png_inforp info_ptr, @@ -2123,7 +2123,7 @@ PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, (png_const_structrp png_ptr, * must be zero. */ png_uint_32 mastering_display_maximum_luminance_scaled_by_10000, - png_uint_32 mastering_display_minimum_luminance_scaled_by_10000)); + png_uint_32 mastering_display_minimum_luminance_scaled_by_10000)) #endif #ifdef PNG_oFFs_SUPPORTED