[libpng16] Fixed GCC unsigned int->float warnings. Various versions of GCC
seem to generate warnings when an unsigned value is implicitly converted to double. This is probably a GCC bug but this change avoids the issue by explicitly converting to (int) where safe.
This commit is contained in:
parent
5be76ae252
commit
c9720568d0
4
CHANGES
4
CHANGES
@ -5053,6 +5053,10 @@ Version 1.6.15beta05 [November 5, 2014]
|
||||
example.c, pngtest.c, and applications in the contrib directory.
|
||||
Avoid out-of-bounds memory access in png_user_version_check().
|
||||
Simplified and future-proofed png_user_version_check().
|
||||
Fixed GCC unsigned int->float warnings. Various versions of GCC
|
||||
seem to generate warnings when an unsigned value is implicitly
|
||||
converted to double. This is probably a GCC bug but this change
|
||||
avoids the issue by explicitly converting to (int) where safe.
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
45
png.c
45
png.c
@ -3719,7 +3719,31 @@ png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
|
||||
if (value > 0 && value < 255)
|
||||
{
|
||||
# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
double r = floor(255*pow(value/255.,gamma_val*.00001)+.5);
|
||||
/* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
|
||||
* convert this to a floating point value. This includes values that
|
||||
* would overflow if 'value' were to be converted to 'int'.
|
||||
*
|
||||
* Apparently GCC, however, does an intermediate convertion to (int)
|
||||
* on some (ARM) but not all (x86) platforms, possibly because of
|
||||
* hardware FP limitations. (E.g. if the hardware convertion always
|
||||
* assumes the integer register contains a signed value.) This results
|
||||
* in ANSI-C undefined behavior for large values.
|
||||
*
|
||||
* Other implementations on the same machine might actually be ANSI-C90
|
||||
* conformant and therefore compile spurious extra code for the large
|
||||
* values.
|
||||
*
|
||||
* We can be reasonably sure that an unsigned to float convertion
|
||||
* won't be faster than an int to float one. Therefore this code
|
||||
* assumes responsibility for the undefined behavior, which it knows
|
||||
* can't happen because of the check above.
|
||||
*
|
||||
* Note the argument to this routine is an (unsigned int) because, on
|
||||
* 16-bit platforms, it is assigned a value which might be out of
|
||||
* range for an (int); that would result in undefined behavior in the
|
||||
* caller if the *argument* ('value') were to be declared (int).
|
||||
*/
|
||||
double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
|
||||
return (png_byte)r;
|
||||
# else
|
||||
png_int_32 lg2 = png_log8bit(value);
|
||||
@ -3743,7 +3767,13 @@ png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
|
||||
if (value > 0 && value < 65535)
|
||||
{
|
||||
# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5);
|
||||
/* The same (unsigned int)->(double) constraints apply here as above,
|
||||
* however in this case the (unsigned int) to (int) convertion can
|
||||
* overflow on an ANSI-C90 compliant system so the cast needs to ensure
|
||||
* that this is not possible.
|
||||
*/
|
||||
double r = floor(65535*pow((png_int_32)value/65535.,
|
||||
gamma_val*.00001)+.5);
|
||||
return (png_uint_16)r;
|
||||
# else
|
||||
png_int_32 lg2 = png_log16bit(value);
|
||||
@ -3797,6 +3827,12 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
|
||||
{
|
||||
/* Various values derived from 'shift': */
|
||||
PNG_CONST unsigned int num = 1U << (8U - shift);
|
||||
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
/* CSE the division and work round wacky GCC warnings (see the comments
|
||||
* in png_gamma_8bit_correct for where these come from.)
|
||||
*/
|
||||
PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);
|
||||
#endif
|
||||
PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
|
||||
PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
|
||||
unsigned int i;
|
||||
@ -3828,7 +3864,10 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
|
||||
png_uint_32 ig = (j << (8-shift)) + i;
|
||||
# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
|
||||
/* Inline the 'max' scaling operation: */
|
||||
double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5);
|
||||
/* See png_gamma_8bit_correct for why the cast to (int) is
|
||||
* required here.
|
||||
*/
|
||||
double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
|
||||
sub_table[j] = (png_uint_16)d;
|
||||
# else
|
||||
if (shift != 0)
|
||||
|
Loading…
Reference in New Issue
Block a user