[libpng17] Added byte, short and other overflow checking

Added 'assert' based overflow checking for debug builds for char
and short assignments. Simply ignore the error in release builds
(a truncated value will be used without warning). Controlled by
PNG_RANGE_CHECK_SUPPORTED.
This commit is contained in:
John Bowler 2015-03-22 15:57:53 -05:00 committed by Glenn Randers-Pehrson
parent 382de60042
commit 82fa6aed0e
14 changed files with 618 additions and 508 deletions

View File

@ -760,6 +760,11 @@ Version 1.7.0beta57 [March 16, 2015]
Version 1.7.0beta58 [March 22, 2015]
Implemented affirm() support and usage.
Remove pnglibconf.dfn and pnglibconf.pre with "make clean".
Added byte, short and other overflow checking
Added 'assert' based overflow checking for debug builds for char
and short assignments. Simply ignore the error in release builds
(a truncated value will be used without warning). Controlled by
PNG_RANGE_CHECK_SUPPORTED.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -5050,6 +5050,11 @@ Version 1.7.0beta57 [March 16, 2015]
Version 1.7.0beta58 [March 22, 2015]
Implemented affirm() support and usage.
Remove pnglibconf.dfn and pnglibconf.pre with "make clean".
Added byte, short and other overflow checking
Added 'assert' based overflow checking for debug builds for char
and short assignments. Simply ignore the error in release builds
(a truncated value will be used without warning). Controlled by
PNG_RANGE_CHECK_SUPPORTED.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

136
png.c
View File

@ -35,7 +35,7 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
if (num_bytes > 8)
png_error(png_ptr, "Too many bytes for PNG signature");
png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
png_ptr->sig_bytes = png_check_byte(png_ptr, num_bytes < 0 ? 0 : num_bytes);
}
/* Checks whether the supplied bytes match the PNG signature. We allow
@ -753,9 +753,9 @@ void PNGAPI
png_build_grayscale_palette(int bit_depth, png_colorp palette)
{
int num_palette;
int color_inc;
png_byte color_inc;
int i;
int v;
png_byte v;
png_debug(1, "in png_do_build_grayscale_palette");
@ -790,12 +790,8 @@ png_build_grayscale_palette(int bit_depth, png_colorp palette)
break;
}
for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
{
palette[i].red = (png_byte)v;
palette[i].green = (png_byte)v;
palette[i].blue = (png_byte)v;
}
for (i = 0, v = 0; i < num_palette; ++i, v = PNG_BYTE(v+color_inc))
palette[i].red = palette[i].green = palette[i].blue = v;
}
#endif
@ -1653,7 +1649,7 @@ png_icc_tag_char(png_uint_32 byte)
{
byte &= 0xff;
if (byte >= 32 && byte <= 126)
return (char)byte;
return (char)/*SAFE*/byte;
else
return '?';
}
@ -2931,7 +2927,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
--exp_b10;
}
*ascii++ = (char)(48 + (int)d), ++cdigits;
*ascii++ = png_check_char(png_ptr, 48 + (int)d), ++cdigits;
}
}
while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
@ -2941,7 +2937,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
/* Check for an exponent, if we don't need one we are
* done and just need to terminate the string. At
* this point exp_b10==(-1) is effectively if flag - it got
* to '-1' because of the decrement after outputing
* to '-1' because of the decrement after outputting
* the decimal point above (the exponent required is
* *not* -1!)
*/
@ -2949,7 +2945,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
{
/* The following only happens if we didn't output the
* leading zeros above for negative exponent, so this
* doest add to the digit requirement. Note that the
* doesn't add to the digit requirement. Note that the
* two zeros here can only be output if the two leading
* zeros were *not* output, so this doesn't increase
* the output count.
@ -2994,7 +2990,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
while (uexp_b10 > 0)
{
exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
exponent[cdigits++] = (char)/*SAFE*/(48 + uexp_b10 % 10);
uexp_b10 /= 10;
}
}
@ -3064,7 +3060,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
/* Split the low digit off num: */
unsigned int tmp = num/10;
num -= tmp*10;
digits[ndigits++] = (char)(48 + num);
digits[ndigits++] = png_check_char(png_ptr, 48 + num);
/* Record the first non-zero digit, note that this is a number
* starting at 1, it's not actually the array index.
*/
@ -3623,7 +3619,7 @@ png_exp(png_fixed_point x)
}
static png_byte
png_exp8bit(png_fixed_point lg2)
png_exp8bit(png_const_structrp png_ptr, png_fixed_point lg2)
{
/* Get a 32-bit value: */
png_uint_32 x = png_exp(lg2);
@ -3633,11 +3629,12 @@ png_exp8bit(png_fixed_point lg2)
* step.
*/
x -= x >> 8;
return (png_byte)((x + 0x7fffffU) >> 24);
return png_check_byte(png_ptr, (x + 0x7fffffU) >> 24);
PNG_UNUSEDRC(png_ptr)
}
static png_uint_16
png_exp16bit(png_fixed_point lg2)
png_exp16bit(png_const_structrp png_ptr, png_fixed_point lg2)
{
/* Get a 32-bit value: */
png_uint_32 x = png_exp(lg2);
@ -3645,11 +3642,13 @@ png_exp16bit(png_fixed_point lg2)
/* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
x -= x >> 16;
return (png_uint_16)((x + 32767U) >> 16);
PNG_UNUSED(png_ptr)
}
#endif /* FLOATING_ARITHMETIC */
png_byte
png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
png_gamma_8bit_correct(png_const_structrp png_ptr, png_uint_32 value,
png_fixed_point gamma_val)
{
if (value > 0 && value < 255)
{
@ -3679,24 +3678,27 @@ png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
* 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;
if (r >= 0 && r <= 255)
return (png_byte)/*SAFE*/r;
# else
png_int_32 lg2 = png_log8bit(value);
png_fixed_point res;
if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
return png_exp8bit(res);
/* Overflow. */
value = 0;
return png_exp8bit(png_ptr, res);
# endif
/* Overflow. */
png_warning(png_ptr, "8-bit gamma overflow");
return 0;
}
return (png_byte)value;
return png_check_byte(png_ptr, value);
}
png_uint_16
png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
png_gamma_16bit_correct(png_const_structrp png_ptr, png_uint_32 value,
png_fixed_point gamma_val)
{
if (value > 0 && value < 65535)
{
@ -3708,36 +3710,22 @@ png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
*/
double r = floor(65535.*pow((png_int_32)value/65535.,
gamma_val*.00001)+.5);
return (png_uint_16)r;
if (r >= 0 && r <= 65535)
return (png_uint_16)/*SAFE*/r;
# else
png_int_32 lg2 = png_log16bit(value);
png_fixed_point res;
if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
return png_exp16bit(res);
/* Overflow. */
value = 0;
return png_exp16bit(png_ptr, res);
# endif
/* Overflow. */
png_warning(png_ptr, "16-bit gamma overflow");
return 0;
}
return (png_uint_16)value;
}
/* This does the right thing based on the bit_depth field of the
* png_struct, interpreting values as 8-bit or 16-bit. While the result
* is nominally a 16-bit value if bit depth is 8 then the result is
* 8-bit (as are the arguments.)
*/
png_uint_16 /* PRIVATE */
png_gamma_correct(png_structrp png_ptr, unsigned int value,
png_fixed_point gamma_val)
{
if (png_ptr->bit_depth == 8)
return png_gamma_8bit_correct(value, gamma_val);
else
return png_gamma_16bit_correct(value, gamma_val);
return png_check_u16(png_ptr, value);
}
#define PNG_GAMMA_TABLE_8 0 /* 8-bit entries in png_byte */
@ -3756,7 +3744,8 @@ typedef struct
} gamma_table_data;
static unsigned int
write_gamma_table_entry(const gamma_table_data *data, png_uint_32 i)
write_gamma_table_entry(png_const_structrp png_ptr,
const gamma_table_data *data, png_uint_32 i)
/* Calculate and write a single entry into table[i], the value of the entry
* written is returned.
*/
@ -3769,7 +3758,7 @@ write_gamma_table_entry(const gamma_table_data *data, png_uint_32 i)
*/
if ((data->output == PNG_GAMMA_TABLE_8) != (data->adjust != 0))
{
out = png_gamma_8bit_correct((unsigned int)in, data->gamma);
out = png_gamma_8bit_correct(png_ptr, in, data->gamma);
if (data->adjust != 0)
out *= 257U;
@ -3777,24 +3766,25 @@ write_gamma_table_entry(const gamma_table_data *data, png_uint_32 i)
else /* 16-bit correction */
{
out = png_gamma_16bit_correct((unsigned int)in, data->gamma);
out = png_gamma_16bit_correct(png_ptr, in, data->gamma);
if (data->adjust != 0)
out = PNG_DIV257(out);
}
PNG_UNUSEDRC(png_ptr)
if (data->output == PNG_GAMMA_TABLE_8)
((png_bytep)data->table)[i] = (png_byte)out;
png_upcast(png_bytep, data->table)[i] = png_check_byte(png_ptr, out);
else
((png_uint_16p)data->table)[i] = (png_uint_16)out;
png_upcast(png_uint_16p, data->table)[i] = png_check_u16(png_ptr, out);
return out;
}
static void
write_gamma_table(const gamma_table_data *data, png_uint_32 lo,
unsigned int loval, png_uint_32 hi, unsigned int hival)
write_gamma_table(png_const_structrp png_ptr, const gamma_table_data *data,
png_uint_32 lo, unsigned int loval, png_uint_32 hi, unsigned int hival)
/* Fill in gamma table entries between lo and hi, exclusive. The entries at
* table[lo] and table[hi] have already been written, the intervening entries
* are written.
@ -3807,15 +3797,15 @@ write_gamma_table(const gamma_table_data *data, png_uint_32 lo,
/* All intervening entries must be the same. */
if (data->output == PNG_GAMMA_TABLE_8)
{
png_bytep table8 = ((png_bytep)data->table);
png_bytep table8 = png_voidcast(png_bytep, data->table);
while (++lo < hi)
table8[lo] = (png_byte)loval;
table8[lo] = png_check_byte(png_ptr, loval);
}
else
{
png_uint_16p table16 = ((png_uint_16p)data->table);
png_uint_16p table16 = png_voidcast(png_uint_16p, data->table);
while (++lo < hi)
table16[lo] = (png_uint_16)loval;
@ -3825,15 +3815,15 @@ write_gamma_table(const gamma_table_data *data, png_uint_32 lo,
else
{
png_uint_32 mid = (lo+hi) >> 1;
unsigned int midval = write_gamma_table_entry(data, mid);
unsigned int midval = write_gamma_table_entry(png_ptr, data, mid);
/* The algorithm used is to divide the entries to be written in half
* and fill in the middle. For all practical tables with significant
* gamma this will result in a performance gain because the expensive
* gamma correction arithmetic is avoided for some entries.
*/
write_gamma_table(data, lo, loval, mid, midval);
write_gamma_table(data, mid, midval, hi, hival);
write_gamma_table(png_ptr, data, lo, loval, mid, midval);
write_gamma_table(png_ptr, data, mid, midval, hi, hival);
}
}
}
@ -4029,7 +4019,7 @@ png_build_gamma_table(png_structrp png_ptr, png_fixed_point gamma_val,
}
if (png_gamma_significant(gamma_val) != 0)
write_gamma_table(&data, 0, 0, size-1, hival);
write_gamma_table(png_ptr, &data, 0, 0, size-1, hival);
else /* gamma_val not significant */
{
@ -4040,28 +4030,29 @@ png_build_gamma_table(png_structrp png_ptr, png_fixed_point gamma_val,
if (data.adjust)
for (i=1; i<size-1; ++i)
table8[i] = (png_byte)PNG_DIV257((i * data.mult + data.add) >>
data.shift);
table8[i] = png_check_byte(png_ptr,
PNG_DIV257((i * data.mult + data.add) >> data.shift));
else
for (i=1; i<size-1; ++i)
table8[i] = (png_byte)((i * data.mult + data.add) >> data.shift);
table8[i] = png_check_byte(png_ptr,
(i * data.mult + data.add) >> data.shift);
}
else
{
png_uint_32 i;
png_uint_16p table16 = ((png_uint_16p)data.table);
png_uint_16p table16 = (png_uint_16p)data.table;
if (data.adjust)
for (i=1; i<size-1; ++i)
table16[i] = (png_uint_16)(((i * data.mult + data.add) >>
data.shift) * 257U);
table16[i] = png_check_u16(png_ptr,
((i * data.mult + data.add) >> data.shift) * 257U);
else
for (i=1; i<size-1; ++i)
table16[i] = (png_uint_16)((i * data.mult + data.add) >>
data.shift);
table16[i] = png_check_u16(png_ptr,
(i * data.mult + data.add) >> data.shift);
}
}
@ -4171,8 +4162,9 @@ png_build_gamma_tables(png_structrp png_ptr, int bit_depth)
else
sig_bit = png_ptr->sig_bit.gray;
/* shift == insignificant bits */
if (sig_bit > 0 && sig_bit < 16U)
shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
shift = png_check_byte(png_ptr, 16U - sig_bit);
else
shift = 0; /* keep all 16 bits */
@ -4233,7 +4225,7 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
int setting = (2 + (onoff != 0)) << option;
int current = png_ptr->options;
png_ptr->options = (png_byte)((current & ~mask) | setting);
png_ptr->options = png_check_byte(png_ptr, (current & ~mask) | setting);
return (current & mask) >> option;
}

View File

@ -454,7 +454,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
else
{
buffer[iout++] = (char)c;
buffer[iout++] = png_check_char(png_ptr, c);
}
}
@ -1143,4 +1143,56 @@ PNG_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
# endif /* AFFIRM_ERROR */
}
#ifdef PNG_RANGE_CHECK_SUPPORTED
/* The character/byte checking APIs, these do their own calls to png_assert
* because the caller provides the position.
*/
char /* PRIVATE */
png_char_affirm(png_const_structrp png_ptr, unsigned int position, int c)
{
if (c >= CHAR_MIN && c <= CHAR_MAX)
return (char)/*SAFE*/c;
# if PNG_AFFIRM_ERROR
/* testing in RC: no condition */
png_affirm(png_ptr, position);
# else
png_affirm(png_ptr, "(char) range", position);
# endif
}
png_byte /* PRIVATE */
png_byte_affirm(png_const_structrp png_ptr, unsigned int position, int b)
{
/* For the type png_byte the limits.h values are ignored and we check
* against the values PNG expects to store in a byte:
*/
if (b >= 0 && b <= 255)
return (png_byte)/*SAFE*/b;
# if PNG_AFFIRM_ERROR
/* testing in RC: no condition */
png_affirm(png_ptr, position);
# else
png_affirm(png_ptr, "PNG byte range", position);
# endif
}
#if INT_MAX >= 65535
png_uint_16 /* PRIVATE */
png_u16_affirm(png_const_structrp png_ptr, unsigned int position, int b)
{
/* Check against the PNG 16-bit limit, as with png_byte. */
if (b >= 0 && b <= 65535)
return (png_uint_16)/*SAFE*/b;
# if PNG_AFFIRM_ERROR
/* testing in RC: no condition */
png_affirm(png_ptr, position);
# else
png_affirm(png_ptr, "PNG 16-bit range", position);
# endif
}
#endif /* INT_MAX >= 65535 */
#endif /* RANGE_CHECK */
#endif /* READ || WRITE */

View File

@ -1117,7 +1117,7 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
return info_ptr->unknown_chunks_num;
}
return (0);
return 0;
}
#endif
@ -1125,7 +1125,9 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
png_byte PNGAPI
png_get_rgb_to_gray_status (png_const_structrp png_ptr)
{
return (png_byte)((png_ptr ? png_ptr->rgb_to_gray_status : 0) & 0xff);
if (png_ptr)
return png_ptr->rgb_to_gray_status;
return 0;
}
#endif
@ -1133,7 +1135,9 @@ png_get_rgb_to_gray_status (png_const_structrp png_ptr)
png_voidp PNGAPI
png_get_user_chunk_ptr(png_const_structrp png_ptr)
{
return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
if (png_ptr)
return png_ptr->user_chunk_ptr;
return NULL;
}
#endif

View File

@ -159,17 +159,16 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{
png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
num_to_check = 8 - num_checked;
unsigned int num_checked = png_ptr->sig_bytes;
unsigned int num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check)
{
num_to_check = png_ptr->buffer_size;
}
num_to_check = (int)/*SAFE*/png_ptr->buffer_size;
png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
num_to_check);
png_ptr->sig_bytes = (png_byte)((png_ptr->sig_bytes + num_to_check) & 0xff);
png_ptr->sig_bytes = png_check_byte(png_ptr,
png_ptr->sig_bytes + num_to_check);
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
{

114
pngread.c
View File

@ -337,6 +337,7 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
/* TODO: explain the +256 */
*(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
*(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
}
@ -360,6 +361,7 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
/* TODO: explain the +65536 */
png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
*(rp ) = (png_byte)((red >> 8) & 0xff);
@ -1670,7 +1672,8 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
switch (encoding)
{
case P_FILE:
value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
value = png_gamma_16bit_correct(display->image->opaque->png_ptr,
value*257, display->gamma_to_linear);
break;
case P_sRGB:
@ -1722,7 +1725,7 @@ png_colormap_compose(png_image_read_control *display,
}
else /* P_sRGB */
f = PNG_sRGB_FROM_LINEAR(f);
f = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, f);
return f;
}
@ -1762,9 +1765,9 @@ png_create_colormap_entry(png_image_read_control *display,
{
png_fixed_point g = display->gamma_to_linear;
red = png_gamma_16bit_correct(red*257, g);
green = png_gamma_16bit_correct(green*257, g);
blue = png_gamma_16bit_correct(blue*257, g);
red = png_gamma_16bit_correct(image->opaque->png_ptr, red*257, g);
green = png_gamma_16bit_correct(image->opaque->png_ptr, green*257, g);
blue = png_gamma_16bit_correct(image->opaque->png_ptr, blue*257, g);
if (convert_to_Y != 0 || output_encoding == P_LINEAR)
{
@ -1774,9 +1777,9 @@ png_create_colormap_entry(png_image_read_control *display,
else
{
red = PNG_sRGB_FROM_LINEAR(red * 255);
green = PNG_sRGB_FROM_LINEAR(green * 255);
blue = PNG_sRGB_FROM_LINEAR(blue * 255);
red = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, red * 255);
green = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, green * 255);
blue = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, blue * 255);
encoding = P_sRGB;
}
}
@ -1794,7 +1797,7 @@ png_create_colormap_entry(png_image_read_control *display,
}
else if (encoding == P_sRGB &&
(convert_to_Y != 0 || output_encoding == P_LINEAR))
(convert_to_Y != 0 || output_encoding == P_LINEAR))
{
/* The values are 8-bit sRGB values, but must be converted to 16-bit
* linear.
@ -1812,8 +1815,7 @@ png_create_colormap_entry(png_image_read_control *display,
if (convert_to_Y != 0)
{
/* NOTE: these values are copied from png_do_rgb_to_gray */
png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green +
(png_uint_32)2366 * blue;
png_uint_32 y = 6968 * red + 23434 * green + 2366 * blue;
if (output_encoding == P_LINEAR)
y = (y + 16384) >> 15;
@ -1823,7 +1825,8 @@ png_create_colormap_entry(png_image_read_control *display,
/* y is scaled by 32768, we need it scaled by 255: */
y = (y + 128) >> 8;
y *= 255;
y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
y = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, (y + 64) >> 7);
alpha = PNG_DIV257(alpha);
encoding = P_sRGB;
}
@ -1832,9 +1835,10 @@ png_create_colormap_entry(png_image_read_control *display,
else if (output_encoding == P_sRGB)
{
red = PNG_sRGB_FROM_LINEAR(red * 255);
green = PNG_sRGB_FROM_LINEAR(green * 255);
blue = PNG_sRGB_FROM_LINEAR(blue * 255);
red = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, red * 255);
green = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, green * 255);
blue = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr,
blue * 255);
alpha = PNG_DIV257(alpha);
encoding = P_sRGB;
}
@ -1870,7 +1874,8 @@ png_create_colormap_entry(png_image_read_control *display,
switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
{
case 4:
entry[afirst ? 0 : 3] = (png_uint_16)alpha;
entry[afirst ? 0 : 3] = png_check_u16(image->opaque->png_ptr,
alpha);
/* FALL THROUGH */
case 3:
@ -1886,13 +1891,14 @@ png_create_colormap_entry(png_image_read_control *display,
else
red = green = blue = 0;
}
entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
entry[afirst + 1] = (png_uint_16)green;
entry[afirst + bgr] = (png_uint_16)red;
entry[afirst + (2 ^ bgr)] = png_check_u16(image->opaque->png_ptr,
blue);
entry[afirst + 1] = png_check_u16(image->opaque->png_ptr, green);
entry[afirst + bgr] = png_check_u16(image->opaque->png_ptr, red);
break;
case 2:
entry[1 ^ afirst] = (png_uint_16)alpha;
entry[1 ^ afirst] = png_check_u16(image->opaque->png_ptr, alpha);
/* FALL THROUGH */
case 1:
@ -1904,7 +1910,7 @@ png_create_colormap_entry(png_image_read_control *display,
else
green = 0;
}
entry[afirst] = (png_uint_16)green;
entry[afirst] = png_check_u16(image->opaque->png_ptr, green);
break;
default:
@ -1918,20 +1924,29 @@ png_create_colormap_entry(png_image_read_control *display,
entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
png_affirmpp(image->opaque->png_ptr, output_encoding == P_sRGB);
switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
{
case 4:
entry[afirst ? 0 : 3] = (png_byte)alpha;
entry[afirst ? 0 : 3] = png_check_byte(image->opaque->png_ptr,
alpha);
case 3:
entry[afirst + (2 ^ bgr)] = (png_byte)blue;
entry[afirst + 1] = (png_byte)green;
entry[afirst + bgr] = (png_byte)red;
entry[afirst + (2 ^ bgr)] = png_check_byte(
image->opaque->png_ptr, blue);
entry[afirst + 1] = png_check_byte(image->opaque->png_ptr,
green);
entry[afirst + bgr] = png_check_byte(image->opaque->png_ptr,
red);
break;
case 2:
entry[1 ^ afirst] = (png_byte)alpha;
entry[1 ^ afirst] = png_check_byte(image->opaque->png_ptr,
alpha);
case 1:
entry[afirst] = (png_byte)green;
entry[afirst] = png_check_byte(image->opaque->png_ptr, green);
break;
default:
@ -2053,7 +2068,8 @@ make_rgb_colormap(png_image_read_control *display)
/* Return a palette index to the above palette given three 8-bit sRGB values. */
#define PNG_RGB_INDEX(r,g,b) \
((png_byte)(0xff & (6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))))
(png_check_byte(image->opaque->png_ptr,\
6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
static int
png_image_read_colormap(png_voidp argument)
@ -2260,7 +2276,7 @@ png_image_read_colormap(png_voidp argument)
if (output_encoding == P_LINEAR)
{
gray = PNG_sRGB_FROM_LINEAR(gray * 255);
gray = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, gray * 255);
/* And make sure the corresponding palette entry
* matches.
@ -2375,7 +2391,7 @@ png_image_read_colormap(png_voidp argument)
if (output_encoding == P_LINEAR)
{
gray = PNG_sRGB_FROM_LINEAR(gray * 255);
gray = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, gray * 255);
/* And make sure the corresponding palette entry matches. */
png_create_colormap_entry(display, gray, back_g, back_g,
@ -2463,9 +2479,9 @@ png_image_read_colormap(png_voidp argument)
png_uint_32 gray = png_sRGB_table[g*51] * alpha;
png_create_colormap_entry(display, i++,
PNG_sRGB_FROM_LINEAR(gray + back_rx),
PNG_sRGB_FROM_LINEAR(gray + back_gx),
PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, gray + back_rx),
PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, gray + back_gx),
PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, gray + back_bx), 255, P_sRGB);
}
}
@ -2566,7 +2582,8 @@ png_image_read_colormap(png_voidp argument)
if (output_encoding == P_sRGB)
gray = png_sRGB_table[gray]; /* now P_LINEAR */
gray = PNG_DIV257(png_gamma_16bit_correct(gray,
gray = PNG_DIV257(png_gamma_16bit_correct(
image->opaque->png_ptr, gray,
png_ptr->colorspace.gamma)); /* now P_FILE */
/* And make sure the corresponding palette entry contains
@ -2578,7 +2595,7 @@ png_image_read_colormap(png_voidp argument)
else if (output_encoding == P_LINEAR)
{
gray = PNG_sRGB_FROM_LINEAR(gray * 255);
gray = PNG_sRGB_FROM_LINEAR(image->opaque->png_ptr, gray * 255);
/* And make sure the corresponding palette entry matches.
*/
@ -2685,9 +2702,9 @@ png_image_read_colormap(png_voidp argument)
if (output_encoding == P_LINEAR)
{
r = PNG_sRGB_FROM_LINEAR(back_r * 255);
g = PNG_sRGB_FROM_LINEAR(back_g * 255);
b = PNG_sRGB_FROM_LINEAR(back_b * 255);
r = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, back_r * 255);
g = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, back_g * 255);
b = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, back_b * 255);
}
else
@ -3008,7 +3025,7 @@ png_image_read_and_map(png_voidp argument)
entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
}
*outrow = (png_byte)entry;
*outrow = png_check_byte(image->opaque->png_ptr, entry);
}
break;
@ -3025,8 +3042,7 @@ png_image_read_and_map(png_voidp argument)
*outrow = gray;
else
*outrow =
(png_byte)(0xff & (PNG_CMAP_TRANS_BACKGROUND+1));
*outrow = PNG_CMAP_TRANS_BACKGROUND+1;
}
break;
@ -3081,7 +3097,7 @@ png_image_read_and_map(png_voidp argument)
if (inrow[0] & 0x80) back_i += 1; /* blue */
if (inrow[0] & 0x40) back_i += 1;
*outrow = (png_byte)back_i;
*outrow = png_check_byte(image->opaque->png_ptr, back_i);
}
inrow += 4;
@ -3329,10 +3345,10 @@ png_image_read_composite(png_voidp argument)
* therefore appropriate for the sRGB to linear
* conversion table.
*/
component = PNG_sRGB_FROM_LINEAR(component);
component = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, component);
}
outrow[c] = (png_byte)component;
outrow[c] = png_check_byte(image->opaque->png_ptr, component);
}
}
@ -3481,10 +3497,11 @@ png_image_read_background(png_voidp argument)
component = png_sRGB_table[component] * alpha;
component += png_sRGB_table[outrow[0]] *
(255-alpha);
component = PNG_sRGB_FROM_LINEAR(component);
component = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, component);
}
outrow[0] = (png_byte)component;
outrow[0] = png_check_byte(image->opaque->png_ptr,
component);
}
inrow += 2; /* gray and alpha channel */
@ -3521,10 +3538,11 @@ png_image_read_background(png_voidp argument)
{
component = png_sRGB_table[component] * alpha;
component += background * (255-alpha);
component = PNG_sRGB_FROM_LINEAR(component);
component = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, component);
}
outrow[0] = (png_byte)component;
outrow[0] = png_check_byte(image->opaque->png_ptr,
component);
}
else

File diff suppressed because it is too large Load Diff

View File

@ -777,8 +777,8 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte buf[13];
png_uint_32 width, height;
int bit_depth, color_type, compression_type, filter_type;
int interlace_type;
png_byte bit_depth, color_type, compression_type, filter_type;
png_byte interlace_type;
png_debug(1, "in png_handle_IHDR");
@ -805,13 +805,13 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* Set internal variables */
png_ptr->width = width;
png_ptr->height = height;
png_ptr->bit_depth = (png_byte)bit_depth;
png_ptr->interlaced = (png_byte)interlace_type;
png_ptr->color_type = (png_byte)color_type;
png_ptr->bit_depth = bit_depth;
png_ptr->interlaced = interlace_type;
png_ptr->color_type = color_type;
#ifdef PNG_MNG_FEATURES_SUPPORTED
png_ptr->filter_type = (png_byte)filter_type;
png_ptr->filter_type = filter_type;
#endif
png_ptr->compression_type = (png_byte)compression_type;
png_ptr->compression_type = compression_type;
/* Find number of channels */
switch (png_ptr->color_type)
@ -836,8 +836,8 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
/* Set up other useful info */
png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
png_ptr->channels);
png_ptr->pixel_depth = png_check_byte(png_ptr, png_ptr->bit_depth *
png_ptr->channels);
png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
png_debug1(3, "channels = %d", png_ptr->channels);
@ -2717,9 +2717,9 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
{
PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
/* The following is safe because of the PNG_SIZE_MAX init above */
png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
png_ptr->unknown_chunk.size = (png_size_t)/*SAFE*/length;
/* 'mode' is a flag array, only the bottom four bits matter here */
png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
png_ptr->unknown_chunk.location = PNG_BYTE(png_ptr->mode & 0xf);
if (length == 0)
png_ptr->unknown_chunk.data = NULL;
@ -3199,7 +3199,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
if (m != 0) /* something to copy */
{
if (m != 0xff)
*dp = (png_byte)((*dp & ~m) | (*sp & m));
*dp = png_check_byte(png_ptr, (*dp & ~m) | (*sp & m));
else
*dp = *sp;
}
@ -3451,7 +3451,8 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
/* Restore the overwritten bits from the last byte if necessary. */
if (end_ptr != NULL)
*end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
*end_ptr = png_check_byte(png_ptr,
(end_byte & end_mask) | (*end_ptr & ~end_mask));
}
#ifdef PNG_READ_INTERLACING_SUPPORTED
@ -3505,12 +3506,12 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
for (i = 0; i < row_info->width; i++)
{
v = (png_byte)((*sp >> sshift) & 0x01);
v = PNG_BYTE((*sp >> sshift) & 0x01);
for (j = 0; j < jstop; j++)
{
unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
tmp |= v << dshift;
*dp = (png_byte)(tmp & 0xff);
*dp = png_check_byte(0/*TODO:fixme*/, tmp);
if (dshift == s_end)
{
@ -3568,12 +3569,12 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
png_byte v;
int j;
v = (png_byte)((*sp >> sshift) & 0x03);
v = PNG_BYTE((*sp >> sshift) & 0x03);
for (j = 0; j < jstop; j++)
{
unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
tmp |= v << dshift;
*dp = (png_byte)(tmp & 0xff);
*dp = PNG_BYTE(tmp);
if (dshift == s_end)
{
@ -3628,14 +3629,14 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
for (i = 0; i < row_info->width; i++)
{
png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
png_byte v = PNG_BYTE((*sp >> sshift) & 0x0f);
int j;
for (j = 0; j < jstop; j++)
{
unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
tmp |= v << dshift;
*dp = (png_byte)(tmp & 0xff);
*dp = png_check_byte(0/*TODO:fixme*/, tmp);
if (dshift == s_end)
{
@ -4352,7 +4353,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
/* This value is stored in png_struct and double checked in the row read
* code.
*/
png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
png_ptr->maximum_pixel_depth = png_check_byte(png_ptr, max_pixel_depth);
png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
/* Align the width on the next larger 8 pixels. Mainly used

View File

@ -217,11 +217,11 @@ png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
info_ptr->width = width;
info_ptr->height = height;
info_ptr->bit_depth = (png_byte)bit_depth;
info_ptr->color_type = (png_byte)color_type;
info_ptr->compression_type = (png_byte)compression_type;
info_ptr->filter_type = (png_byte)filter_type;
info_ptr->interlace_type = (png_byte)interlace_type;
info_ptr->bit_depth = png_check_byte(png_ptr, bit_depth);
info_ptr->color_type = png_check_byte(png_ptr, color_type);
info_ptr->compression_type = png_check_byte(png_ptr, compression_type);
info_ptr->filter_type = png_check_byte(png_ptr, filter_type);
info_ptr->interlace_type = png_check_byte(png_ptr, interlace_type);
png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
@ -239,7 +239,8 @@ png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
info_ptr->channels++;
info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
info_ptr->pixel_depth = png_check_byte(png_ptr, info_ptr->channels *
info_ptr->bit_depth);
info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
}
@ -256,7 +257,7 @@ png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
info_ptr->x_offset = offset_x;
info_ptr->y_offset = offset_y;
info_ptr->offset_unit_type = (png_byte)unit_type;
info_ptr->offset_unit_type = png_check_byte(png_ptr, unit_type);
info_ptr->valid |= PNG_INFO_oFFs;
}
#endif
@ -312,8 +313,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug(3, "storing X0, X1, type, and nparams in info");
info_ptr->pcal_X0 = X0;
info_ptr->pcal_X1 = X1;
info_ptr->pcal_type = (png_byte)type;
info_ptr->pcal_nparams = (png_byte)nparams;
info_ptr->pcal_type = png_check_byte(png_ptr, type);
info_ptr->pcal_nparams = png_check_byte(png_ptr, nparams);
length = strlen(units) + 1;
png_debug1(3, "allocating units for info (%lu bytes)",
@ -392,7 +393,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
png_error(png_ptr, "Invalid sCAL height");
info_ptr->scal_unit = (png_byte)unit;
info_ptr->scal_unit = png_check_byte(png_ptr, unit);
++lengthw;
@ -505,7 +506,7 @@ png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
info_ptr->x_pixels_per_unit = res_x;
info_ptr->y_pixels_per_unit = res_y;
info_ptr->phys_unit_type = (png_byte)unit_type;
info_ptr->phys_unit_type = png_check_byte(png_ptr, unit_type);
info_ptr->valid |= PNG_INFO_pHYs;
}
#endif
@ -1140,7 +1141,7 @@ check_location(png_const_structrp png_ptr, int location)
png_app_warning(png_ptr,
"png_set_unknown_chunks now expects a valid location");
/* Use the old behavior */
location = (png_byte)(png_ptr->mode &
location = png_check_byte(png_ptr, png_ptr->mode &
(PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
}
@ -1159,7 +1160,7 @@ check_location(png_const_structrp png_ptr, int location)
/* The cast is safe because 'location' is a bit mask and only the low four
* bits are significant.
*/
return (png_byte)location;
return png_check_byte(png_ptr, location);
}
void PNGAPI
@ -1309,7 +1310,8 @@ png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
static unsigned int
add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
add_one_chunk(png_const_structrp png_ptr, png_bytep list, unsigned int count,
png_const_bytep add, int keep)
{
unsigned int i;
@ -1320,7 +1322,7 @@ add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
{
if (memcmp(list, add, 4) == 0)
{
list[4] = (png_byte)keep;
list[4] = png_check_byte(png_ptr, keep);
return count;
}
@ -1330,10 +1332,11 @@ add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
{
++count;
memcpy(list, add, 4);
list[4] = (png_byte)keep;
list[4] = png_check_byte(png_ptr, keep);
}
return count;
PNG_UNUSEDRC(png_ptr)
}
void PNGAPI
@ -1451,7 +1454,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
for (i=0; i<num_chunks; ++i)
{
old_num_chunks = add_one_chunk(new_list, old_num_chunks,
old_num_chunks = add_one_chunk(png_ptr, new_list, old_num_chunks,
chunk_list+5*i, keep);
}

View File

@ -273,10 +273,7 @@ png_do_invert(png_row_infop row_info, png_bytep row)
png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i++)
{
*rp = (png_byte)((~(*rp)) & 0xff);
rp++;
}
*rp++ ^= 0xff;
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
@ -287,10 +284,7 @@ png_do_invert(png_row_infop row_info, png_bytep row)
png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 2)
{
*rp = (png_byte)((~(*rp)) & 0xff);
rp += 2;
}
*rp ^= 0xff, rp += 2;
}
#ifdef PNG_16BIT_SUPPORTED
@ -302,11 +296,7 @@ png_do_invert(png_row_infop row_info, png_bytep row)
png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 4)
{
*rp = (png_byte)((~(*rp)) & 0xff);
*(rp + 1) = (png_byte)((~(*(rp + 1))) & 0xff);
rp += 4;
}
*rp++ ^= 0xff, *rp++ ^= 0xff, rp += 2;
}
#endif
}
@ -804,9 +794,10 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp
#endif
png_ptr->user_transform_ptr = user_transform_ptr;
png_ptr->user_transform_depth = (png_byte)(user_transform_depth & 0xff);
png_ptr->user_transform_channels =
(png_byte)(user_transform_channels & 0xff);
png_ptr->user_transform_depth = png_check_byte(png_ptr,
user_transform_depth);
png_ptr->user_transform_channels = png_check_byte(png_ptr,
user_transform_channels);
}
#endif

View File

@ -225,7 +225,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
for (j = 0; j<jend; ++j)
info_ptr->trans_alpha[j] =
(png_byte)((255 - info_ptr->trans_alpha[j]) & 0xff);
png_check_byte(png_ptr, 255 - info_ptr->trans_alpha[j]);
}
#endif
png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
@ -462,11 +462,11 @@ png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
png_debug(1, "in png_convert_from_struct_tm");
ptime->year = (png_uint_16)(1900 + ttime->tm_year);
ptime->month = (png_byte)((ttime->tm_mon + 1) & 0xff);
ptime->day = (png_byte)(ttime->tm_mday & 0xff);
ptime->hour = (png_byte)(ttime->tm_hour & 0xff);
ptime->minute = (png_byte)(ttime->tm_min & 0xff);
ptime->second = (png_byte)(ttime->tm_sec & 0xff);
ptime->month = png_check_byte(0/*TODO: fixme*/, ttime->tm_mon + 1);
ptime->day = png_check_byte(0/*TODO: fixme*/, ttime->tm_mday);
ptime->hour = png_check_byte(0/*TODO: fixme*/, ttime->tm_hour);
ptime->minute = png_check_byte(0/*TODO: fixme*/, ttime->tm_min);
ptime->second = png_check_byte(0/*TODO: fixme*/, ttime->tm_sec);
}
void PNGAPI
@ -669,12 +669,12 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
*(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp + 1) = (png_byte)(red & 0xff);
*(rp + 4) = (png_byte)((blue >> 8) & 0xff);
*(rp + 5) = (png_byte)(blue & 0xff);
png_uint_32 red = (s0 - s1) & 0xffff;
png_uint_32 blue = (s2 - s1) & 0xffff;
*(rp ) = png_check_byte(0/*TODO: fixme*/, red >> 8);
*(rp + 1) = PNG_BYTE(red);
*(rp + 4) = png_check_byte(0/*TODO: fixme*/, blue >> 8);
*(rp + 5) = PNG_BYTE(blue);
}
}
#endif /* WRITE_16BIT */
@ -818,7 +818,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
row_info.channels = png_ptr->usr_channels;
row_info.bit_depth = png_ptr->usr_bit_depth;
row_info.pixel_depth =
(png_byte)(0xff & (row_info.bit_depth * row_info.channels));
png_check_byte(png_ptr, row_info.bit_depth * row_info.channels);
row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
png_debug1(3, "row_info->color_type = %d", row_info.color_type);
@ -1103,7 +1103,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
* TODO: this field could probably be removed if neither READ nor
* WRITE_FILTER are supported.
*/
png_ptr->do_filter = (png_byte)filters; /* SAFE: checked above */
png_ptr->do_filter = png_check_byte(png_ptr, filters);
}
/* This allows us to influence the way in which libpng chooses the "best"
@ -1190,7 +1190,7 @@ png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
}
/* Safe to set this now */
png_ptr->num_prev_filters = (png_byte)(num_weights & 0xff);
png_ptr->num_prev_filters = png_check_byte(png_ptr, num_weights);
}
/* If, in the future, there are other filter methods, this would
@ -1833,8 +1833,8 @@ png_write_image_16bit(png_voidp argument)
#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
static png_byte
png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
png_uint_32 reciprocal/*from the above macro*/)
png_unpremultiply(png_const_structrp png_ptr, png_uint_32 component,
png_uint_32 alpha, png_uint_32 reciprocal/*from the above macro*/)
{
/* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
* is represented as some other value there is more likely to be a
@ -1870,11 +1870,13 @@ png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
component *= 255;
/* Convert the component to sRGB. */
return (png_byte)(PNG_sRGB_FROM_LINEAR(component) & 0xff);
return PNG_sRGB_FROM_LINEAR(png_ptr, component);
}
else
return 0;
PNG_UNUSEDRC(png_ptr)
}
static int
@ -1919,7 +1921,7 @@ png_write_image_8bit(png_voidp argument)
while (out_ptr < row_end)
{
png_uint_16 alpha = in_ptr[aindex];
png_byte alphabyte = (png_byte)(PNG_DIV257(alpha) & 0xff);
png_byte alphabyte = png_check_byte(png_ptr, PNG_DIV257(alpha));
png_uint_32 reciprocal = 0;
int c;
@ -1931,7 +1933,8 @@ png_write_image_8bit(png_voidp argument)
c = channels;
do /* always at least one channel */
*out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
*out_ptr++ = png_unpremultiply(png_ptr, *in_ptr++, alpha,
reciprocal);
while (--c > 0);
/* Skip to next component (skip the intervening alpha channel) */
@ -1962,7 +1965,7 @@ png_write_image_8bit(png_voidp argument)
png_uint_32 component = *in_ptr++;
component *= 255;
*out_ptr++ = (png_byte)(PNG_sRGB_FROM_LINEAR(component) & 0xff);
*out_ptr++ = PNG_sRGB_FROM_LINEAR(png_ptr, component);
}
png_write_row(png_ptr, output_row);
@ -2021,23 +2024,25 @@ png_image_set_PLTE(png_image_write_control *display)
{
if (channels >= 3) /* RGB */
{
palette[i].blue = (png_byte)(0xff & PNG_sRGB_FROM_LINEAR(255 *
entry[(2 ^ bgr)]));
palette[i].green = (png_byte)(0xff & PNG_sRGB_FROM_LINEAR(255 *
entry[1]));
palette[i].red = (png_byte)(0xff & PNG_sRGB_FROM_LINEAR(255 *
entry[bgr]));
palette[i].blue = PNG_sRGB_FROM_LINEAR(
display->image->opaque->png_ptr, 255 * entry[(2 ^ bgr)]);
palette[i].green = PNG_sRGB_FROM_LINEAR(
display->image->opaque->png_ptr, 255 * entry[1]);
palette[i].red = PNG_sRGB_FROM_LINEAR(
display->image->opaque->png_ptr, 255 * entry[bgr]);
}
else /* Gray */
palette[i].blue = palette[i].red = palette[i].green =
(png_byte)(PNG_sRGB_FROM_LINEAR((255 * *entry)) & 0xff);
PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr,
255 * *entry);
}
else /* alpha */
{
png_uint_16 alpha = entry[afirst ? 0 : channels-1];
png_byte alphabyte = (png_byte)(PNG_DIV257(alpha) & 0xff);
png_byte alphabyte = png_check_byte(
display->image->opaque->png_ptr, PNG_DIV257(alpha));
png_uint_32 reciprocal = 0;
/* Calculate a reciprocal, as in the png_write_image_8bit code above
@ -2053,17 +2058,21 @@ png_image_set_PLTE(png_image_write_control *display)
if (channels >= 3) /* RGB */
{
palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
palette[i].blue = png_unpremultiply(
display->image->opaque->png_ptr, entry[afirst + (2 ^ bgr)],
alpha, reciprocal);
palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
palette[i].green = png_unpremultiply(
display->image->opaque->png_ptr, entry[afirst + 1], alpha,
reciprocal);
palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
palette[i].red = png_unpremultiply(
display->image->opaque->png_ptr, entry[afirst + bgr], alpha,
reciprocal);
}
else /* gray */
palette[i].blue = palette[i].red = palette[i].green =
png_unpremultiply(entry[afirst], alpha, reciprocal);
png_unpremultiply(display->image->opaque->png_ptr,
entry[afirst], alpha, reciprocal);
}
}

View File

@ -17,6 +17,21 @@
#ifdef PNG_WRITE_SUPPORTED
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
/* This is here because png_row_info doesn't contain a png_ptr, so at present
* the transform routines can't signal an error. Instead we pass '0' as
* as png_ptr to png_check_byte in the non-release cases and do a hard cast
* in release.
*
* TODO: fix this.
*/
#ifdef PNG_RANGE_CHECK_SUPPORTED
# define CB(b) png_check_byte(0, b)
# define CU(u) png_check_u16(0, u)
#else
# define CB(b) ((png_byte)(b))
# define CU(u) ((png_uint_16)(u))
#endif
#ifdef PNG_WRITE_PACK_SUPPORTED
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
* row_info bit depth should be 8 (one pixel per byte). The channels
@ -57,14 +72,14 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
else
{
mask = 0x80;
*dp = (png_byte)(v & 0xff);
*dp = CB(v);
dp++;
v = 0;
}
}
if (mask != 0x80)
*dp = (png_byte)(v & 0xff);
*dp = CB(v);
break;
}
@ -85,13 +100,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
png_byte value;
value = (png_byte)(*sp & 0x03);
value = PNG_BYTE(*sp & 0x03);
v |= (value << shift);
if (shift == 0)
{
shift = 6;
*dp = (png_byte)(v & 0xff);
*dp = CB(v);
dp++;
v = 0;
}
@ -103,7 +118,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
}
if (shift != 6)
*dp = (png_byte)(v & 0xff);
*dp = CB(v);
break;
}
@ -124,13 +139,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
png_byte value;
value = (png_byte)(*sp & 0x0f);
value = PNG_BYTE(*sp & 0x0f);
v |= (value << shift);
if (shift == 0)
{
shift = 4;
*dp = (png_byte)(v & 0xff);
*dp = CB(v);
dp++;
v = 0;
}
@ -142,7 +157,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
}
if (shift != 4)
*dp = (png_byte)(v & 0xff);
*dp = CB(v);
break;
}
@ -151,9 +166,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
break;
}
row_info->bit_depth = (png_byte)(bit_depth & 0xff);
row_info->pixel_depth =
(png_byte)((bit_depth * row_info->channels) & 0xff);
row_info->bit_depth = CB(bit_depth);
row_info->pixel_depth = CB(bit_depth * row_info->channels);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
row_info->width);
}
@ -242,7 +256,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
out |= (v >> (-j)) & mask;
}
*bp = (png_byte)(out & 0xff);
*bp = CB(out);
}
}
@ -271,7 +285,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
out |= v >> (-j);
}
*bp = (png_byte)(out & 0xff);
*bp = CB(out);
}
}
@ -298,8 +312,8 @@ png_do_shift(png_row_infop row_info, png_bytep row,
else
value |= v >> (-j);
}
*bp++ = (png_byte)((value >> 8) & 0xff);
*bp++ = (png_byte)(value & 0xff);
*bp++ = CB(value >> 8);
*bp++ = PNG_BYTE(value);
}
}
}
@ -424,7 +438,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = *(sp++);
*/
sp+=3; dp = sp;
*(dp++) = (png_byte)((255 - *(sp++)) & 0xff);
*(dp++) = CB(255 - *(sp++));
}
}
@ -447,8 +461,8 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = *(sp++);
*/
sp+=6; dp = sp;
*(dp++) = (png_byte)((255 - *(sp++)) & 0xff);
*(dp++) = (png_byte)((255 - *(sp++)) & 0xff);
*(dp++) = CB(255 - *(sp++));
*(dp++) = CB(255 - *(sp++));
}
}
#endif /* WRITE_16BIT */
@ -466,7 +480,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = (png_byte)((255 - *(sp++)) & 0xff);
*(dp++) = CB(255 - *(sp++));
}
}
@ -485,8 +499,8 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = *(sp++);
*/
sp+=2; dp = sp;
*(dp++) = (png_byte)((255 - *(sp++)) & 0xff);
*(dp++) = (png_byte)((255 - *(sp++)) & 0xff);
*(dp++) = CB(255 - *(sp++));
*(dp++) = CB(255 - *(sp++));
}
}
#endif /* WRITE_16BIT */

View File

@ -24,10 +24,10 @@
void PNGAPI
png_save_uint_32(png_bytep buf, png_uint_32 i)
{
buf[0] = (png_byte)((i >> 24) & 0xff);
buf[1] = (png_byte)((i >> 16) & 0xff);
buf[2] = (png_byte)((i >> 8) & 0xff);
buf[3] = (png_byte)(i & 0xff);
buf[0] = PNG_BYTE(i >> 24);
buf[1] = PNG_BYTE(i >> 16);
buf[2] = PNG_BYTE(i >> 8);
buf[3] = PNG_BYTE(i);
}
/* Place a 16-bit number into a buffer in PNG byte order.
@ -37,8 +37,8 @@ png_save_uint_32(png_bytep buf, png_uint_32 i)
void PNGAPI
png_save_uint_16(png_bytep buf, unsigned int i)
{
buf[0] = (png_byte)((i >> 8) & 0xff);
buf[1] = (png_byte)(i & 0xff);
buf[0] = PNG_BYTE(i >> 8);
buf[1] = PNG_BYTE(i);
}
#endif
@ -279,10 +279,10 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size)
z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
data[0] = (png_byte)(z_cmf & 0xff);
data[0] = png_check_byte(0/*TODO: fixme*/, z_cmf);
tmp = data[1] & 0xe0;
tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
data[1] = (png_byte)(tmp & 0xff);
data[1] = png_check_byte(0/*TODO: fixme*/, tmp);
}
}
}
@ -874,17 +874,18 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
#endif
/* Save the relevant information */
png_ptr->bit_depth = (png_byte)(bit_depth & 0xff);
png_ptr->color_type = (png_byte)(color_type & 0xff);
png_ptr->interlaced = (png_byte)(interlace_type & 0xff);
png_ptr->bit_depth = png_check_byte(png_ptr, bit_depth);
png_ptr->color_type = png_check_byte(png_ptr, color_type);
png_ptr->interlaced = png_check_byte(png_ptr, interlace_type);
#ifdef PNG_MNG_FEATURES_SUPPORTED
png_ptr->filter_type = (png_byte)(filter_type & 0xff);
png_ptr->filter_type = png_check_byte(png_ptr, filter_type);
#endif
png_ptr->compression_type = (png_byte)(compression_type & 0xff);
png_ptr->compression_type = png_check_byte(png_ptr, compression_type);
png_ptr->width = width;
png_ptr->height = height;
png_ptr->pixel_depth = (png_byte)((bit_depth * png_ptr->channels) & 0xff);
png_ptr->pixel_depth = png_check_byte(png_ptr,
bit_depth * png_ptr->channels);
png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
/* Set the usr info, so any transformations can modify it */
png_ptr->usr_width = png_ptr->width;
@ -894,11 +895,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
/* Pack the header information into the buffer */
png_save_uint_32(buf, width);
png_save_uint_32(buf + 4, height);
buf[8] = (png_byte)(bit_depth & 0xff);
buf[9] = (png_byte)(color_type & 0xff);
buf[10] = (png_byte)(compression_type & 0xff);
buf[11] = (png_byte)(filter_type & 0xff);
buf[12] = (png_byte)(interlace_type & 0xff);
buf[8] = png_check_byte(png_ptr, bit_depth);
buf[9] = png_check_byte(png_ptr, color_type);
buf[10] = png_check_byte(png_ptr, compression_type);
buf[11] = png_check_byte(png_ptr, filter_type);
buf[12] = png_check_byte(png_ptr, interlace_type);
/* Write the chunk */
png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
@ -1183,7 +1184,7 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
png_warning(png_ptr,
"Invalid sRGB rendering intent specified");
buf[0]=(png_byte)(srgb_intent & 0xff);
buf[0] = png_check_byte(png_ptr, srgb_intent);
png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
}
#endif
@ -1273,10 +1274,9 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_write_chunk_header(png_ptr, png_sPLT,
(png_uint_32)(name_len + 2 + palette_size));
png_write_chunk_data(png_ptr, (png_bytep)new_name,
(png_size_t)(name_len + 1));
png_write_chunk_data(png_ptr, new_name, name_len + 1);
png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
png_write_chunk_data(png_ptr, &spalette->depth, 1);
/* Loop through each palette entry, writing appropriately */
#ifdef PNG_POINTER_INDEXING_SUPPORTED
@ -1284,10 +1284,10 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
{
if (spalette->depth == 8)
{
entrybuf[0] = (png_byte)(ep->red & 0xff);
entrybuf[1] = (png_byte)(ep->green & 0xff);
entrybuf[2] = (png_byte)(ep->blue & 0xff);
entrybuf[3] = (png_byte)(ep->alpha & 0xff);
entrybuf[0] = png_check_byte(png_ptr, ep->red);
entrybuf[1] = png_check_byte(png_ptr, ep->green);
entrybuf[2] = png_check_byte(png_ptr, ep->blue);
entrybuf[3] = png_check_byte(png_ptr, ep->alpha);
png_save_uint_16(entrybuf + 4, ep->frequency);
}
@ -1308,10 +1308,10 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
{
if (spalette->depth == 8)
{
entrybuf[0] = (png_byte)(ep[i].red & 0xff);
entrybuf[1] = (png_byte)(ep[i].green & 0xff);
entrybuf[2] = (png_byte)(ep[i].blue & 0xff);
entrybuf[3] = (png_byte)(ep[i].alpha & 0xff);
entrybuf[0] = png_check_byte(png_ptr, ep[i].red);
entrybuf[1] = png_check_byte(png_ptr, ep[i].green);
entrybuf[2] = png_check_byte(png_ptr, ep[i].blue);
entrybuf[3] = png_check_byte(png_ptr, ep[i].alpha);
png_save_uint_16(entrybuf + 4, ep[i].frequency);
}
@ -1347,8 +1347,8 @@ png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
{
png_byte maxbits;
maxbits = (png_byte)((color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
png_ptr->usr_bit_depth) & 0xff);
maxbits = png_check_byte(png_ptr, color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
png_ptr->usr_bit_depth);
if (sbit->red == 0 || sbit->red > maxbits ||
sbit->green == 0 || sbit->green > maxbits ||
@ -1789,7 +1789,7 @@ png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
png_save_int_32(buf, x_offset);
png_save_int_32(buf + 4, y_offset);
buf[8] = (png_byte)(unit_type & 0xff);
buf[8] = png_check_byte(png_ptr, unit_type);
png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
}
@ -1844,8 +1844,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_write_chunk_data(png_ptr, new_purpose, purpose_len);
png_save_int_32(buf, X0);
png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)(type & 0xff);
buf[9] = (png_byte)(nparams & 0xff);
buf[8] = png_check_byte(png_ptr, type);
buf[9] = png_check_byte(png_ptr, nparams);
png_write_chunk_data(png_ptr, buf, (png_size_t)10);
png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
@ -1880,7 +1880,7 @@ png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
return;
}
buf[0] = (png_byte)(unit & 0xff);
buf[0] = png_check_byte(png_ptr, unit);
memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
@ -1905,7 +1905,7 @@ png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
png_save_uint_32(buf, x_pixels_per_unit);
png_save_uint_32(buf + 4, y_pixels_per_unit);
buf[8] = (png_byte)(unit_type & 0xff);
buf[8] = png_check_byte(png_ptr, unit_type);
png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
}
@ -2018,7 +2018,7 @@ png_write_start_row(png_structrp png_ptr)
/* 1.5.6: added to allow checking in the row write code. */
png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
png_ptr->maximum_pixel_depth = (png_byte)(usr_pixel_depth & 0xff);
png_ptr->maximum_pixel_depth = png_check_byte(png_ptr, usr_pixel_depth);
/* Set up row buffer */
png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
@ -2046,7 +2046,8 @@ png_write_start_row(png_structrp png_ptr)
png_write_alloc_filter_row_buffers(png_ptr, filters);
png_ptr->do_filter = (png_byte)filters; /* in case it was changed above */
/* in case it was changed above */
png_ptr->do_filter = png_check_byte(png_ptr, filters);
#else
png_ptr->do_filter = PNG_FILTER_NONE;
#endif /* WRITE_FILTER */
@ -2214,7 +2215,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
if (shift == 0)
{
shift = 7;
*dp++ = (png_byte)(d & 0xff);
*dp++ = png_check_byte(0/*TODO: fixme*/, d);
d = 0;
}
@ -2223,7 +2224,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
}
if (shift != 7)
*dp = (png_byte)(d & 0xff);
*dp = png_check_byte(0/*TODO: fixme*/, d);
break;
}
@ -2252,7 +2253,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
if (shift == 0)
{
shift = 6;
*dp++ = (png_byte)(d & 0xff);
*dp++ = png_check_byte(0/*TODO: fixme*/, d);
d = 0;
}
@ -2260,7 +2261,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
shift -= 2;
}
if (shift != 6)
*dp = (png_byte)(d & 0xff);
*dp = png_check_byte(0/*TODO: fixme*/, d);
break;
}
@ -2288,7 +2289,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
if (shift == 0)
{
shift = 4;
*dp++ = (png_byte)(d & 0xff);
*dp++ = png_check_byte(0/*TODO: fixme*/, d);
d = 0;
}
@ -2296,7 +2297,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
shift -= 4;
}
if (shift != 4)
*dp = (png_byte)(d & 0xff);
*dp = png_check_byte(0/*TODO: fixme*/, d);
break;
}